tizen 2.3.1 release
[framework/multimedia/gst-plugins-ext0.10.git] / drmsrc / src / gstdrmsrc.c
index 5e2776d..74bf4d2 100755 (executable)
 #endif
 #include "gstdrmsrc.h"
 
+#include "drm_util.h"
+#include <drm_client.h>
+#include <drm_client_types.h>
+
+#ifdef CONTROL_PAGECACHE
+#include <fcntl.h>
+#define DEFAULT_DO_FADVISE_THRESHOLD    (100 * 1024 * 1024)    /* 100 MB */
+#endif
+
 #define LOG_TRACE(message)  //g_print("DRM_SRC: %s: %d: %s - %s \n", __FILE__, __LINE__, __FUNCTION__, message);
 
 #define GST_TAG_PLAYREADY "playready_file_path"
 
 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS,GST_STATIC_CAPS_ANY);
 
+#ifdef CONTROL_PAGECACHE
+#if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)
+#define DRMSRC_FADVISE_DONT(x_fd, x_offset, x_length) \
+       do \
+       { \
+               if (posix_fadvise64(x_fd, x_offset, x_length, POSIX_FADV_DONTNEED) != 0) \
+               { \
+                       GST_ERROR("Set posix_fadvise with POSIX_FADV_DONTNEED failed"); \
+               } \
+       }while (0);
+#else
+#define DRMSRC_FADVISE_DONT(x_fd, x_offset, x_length) \
+       do \
+       { \
+               if (posix_fadvise(x_fd, x_offset, x_length, POSIX_FADV_DONTNEED) != 0) \
+               { \
+                       GST_ERROR("Set posix_fadvise with POSIX_FADV_DONTNEED failed"); \
+               } \
+       }while (0);
+#endif
+#endif
 
 GST_DEBUG_CATEGORY_STATIC (gst_drm_src_debug);
 #define GST_CAT_DEFAULT gst_drm_src_debug
 
 enum
 {
-       ARG_0,
-       ARG_LOCATION,
-       ARG_FD
+  ARG_0,
+  ARG_LOCATION,
+  ARG_FD,
+  IS_DRM
 };
 static void gst_drm_src_finalize (GObject * object);
 static void gst_drm_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec);
@@ -51,7 +82,9 @@ static gboolean gst_drm_src_is_seekable (GstBaseSrc * src);
 static gboolean gst_drm_src_get_size (GstBaseSrc * src, guint64 * size);
 static GstFlowReturn gst_drm_src_create (GstBaseSrc * src, guint64 offset, guint length, GstBuffer ** buffer);
 static void gst_drm_src_uri_handler_init (gpointer g_iface, gpointer iface_data);
-
+static gboolean gst_drm_src_query (GstBaseSrc * src, GstQuery * query);
+static GstStateChangeReturn gst_drm_src_change_state (GstElement * element,
+    GstStateChange transition);
 /**
  * This function does the following:
  *  1. Initializes GstDrmSrc ( defines gst_drm_get_type)
@@ -62,15 +95,15 @@ static void gst_drm_src_uri_handler_init (gpointer g_iface, gpointer iface_data)
  */
 static void _do_init (GType drmsrc_type)
 {
-       // 1. Initializes GstDrmSrc ( defines gst_drm_get_type)
-       static const GInterfaceInfo urihandler_info = {
-               gst_drm_src_uri_handler_init,
-               NULL,
-               NULL
-       };
-
-       g_type_add_interface_static (drmsrc_type, GST_TYPE_URI_HANDLER, &urihandler_info);
-       GST_DEBUG_CATEGORY_INIT (gst_drm_src_debug, "drmsrc", 0, "drmsrc element");
+  // 1. Initializes GstDrmSrc ( defines gst_drm_get_type)
+  static const GInterfaceInfo urihandler_info = {
+    gst_drm_src_uri_handler_init,
+    NULL,
+    NULL
+  };
+
+  g_type_add_interface_static (drmsrc_type, GST_TYPE_URI_HANDLER, &urihandler_info);
+  GST_DEBUG_CATEGORY_INIT (gst_drm_src_debug, "drmsrc", 0, "drmsrc element");
 }
 GST_BOILERPLATE_FULL (GstDrmSrc, gst_drm_src, GstBaseSrc, GST_TYPE_BASE_SRC,   _do_init);
 /**
@@ -84,15 +117,17 @@ GST_BOILERPLATE_FULL (GstDrmSrc, gst_drm_src, GstBaseSrc, GST_TYPE_BASE_SRC,   _
  */
 static void gst_drm_src_base_init (gpointer g_class)
 {
-       GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-       // 1. Sets the class details
-       gst_element_class_set_details_simple (gstelement_class,
-               "DRM Source",
-               "Source/File",
-               "Read from arbitrary point in a standard/DRM file",
-               "Kishore Arepalli  <kishore.a@samsung.com> and Sadanand Dodawadakar <sadanand.d@samsung.com>");
-      // 2. Adds the source pad template
-       gst_element_class_add_pad_template (gstelement_class, gst_static_pad_template_get (&srctemplate));
+  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
+
+  /*Sets the class details */
+  gst_element_class_set_details_simple (gstelement_class,
+    "DRM Source",
+    "Source/File",
+    "Read from arbitrary point in a standard/DRM file",
+    "Kishore Arepalli  <kishore.a@samsung.com> and Sadanand Dodawadakar <sadanand.d@samsung.com>");
+
+  /*Adds the source pad template */
+  gst_element_class_add_pad_template (gstelement_class, gst_static_pad_template_get (&srctemplate));
 }
 /**
  * This function does the following:
@@ -105,38 +140,46 @@ static void gst_drm_src_base_init (gpointer g_class)
  */
 static void gst_drm_src_class_init (GstDrmSrcClass * klass)
 {
-       GObjectClass *gobject_class;
-       GstElementClass *gstelement_class;
-       GstBaseSrcClass *gstbasesrc_class;
-       gobject_class = G_OBJECT_CLASS (klass);
-       gstelement_class = GST_ELEMENT_CLASS (klass);
-       gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
-       // Assigns the function pointers GObject class attributes
-       gobject_class->set_property = gst_drm_src_set_property;
-       gobject_class->get_property = gst_drm_src_get_property;
-       //  1. Installs the properties
-       g_object_class_install_property (gobject_class, ARG_FD,
-               g_param_spec_int ("fd", "File-descriptor",
-               "File-descriptor for the file being mmap()d", 0, G_MAXINT, 0,
-               G_PARAM_READABLE));
-       g_object_class_install_property (gobject_class, ARG_LOCATION,
-               g_param_spec_string ("location", "File Location",
-               "Location of the file to read", NULL, G_PARAM_READWRITE));
-
-       // 2. Assigns the function pointers GObject class attributes
-       gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_drm_src_finalize);
-       gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_drm_src_start);
-       gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_drm_src_stop);
-       gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_drm_src_is_seekable);
-       gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_drm_src_get_size);
-       gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_drm_src_create);
-
-
-       gst_tag_register (GST_TAG_PLAYREADY, GST_TAG_FLAG_META,
-                       G_TYPE_STRING,
-                       "PlayReady File Path",
-                       "a tag that is specific to PlayReady File",
-                       NULL);
+  GObjectClass *gobject_class;
+  GstBaseSrcClass *gstbasesrc_class;
+  gobject_class = G_OBJECT_CLASS (klass);
+  gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
+  GstElementClass *gstelement_class;
+  gstelement_class = (GstElementClass *) klass;
+  /* Assigns the function pointers GObject class attributes */
+  gobject_class->set_property = gst_drm_src_set_property;
+  gobject_class->get_property = gst_drm_src_get_property;
+
+  /* Installs the properties*/
+  g_object_class_install_property (gobject_class, ARG_FD,
+    g_param_spec_int ("fd", "File-descriptor",
+      "File-descriptor for the file being mmap()d", 0, G_MAXINT, 0,
+      G_PARAM_READABLE));
+
+  g_object_class_install_property (gobject_class, ARG_LOCATION,
+    g_param_spec_string ("location", "File Location",
+      "Location of the file to read", NULL,
+      G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, IS_DRM,
+    g_param_spec_boolean ("is-drm", "whether selected file type is drm or not",
+      "true, false", FALSE,
+      G_PARAM_READABLE));
+
+   /*Assigns the function pointers GObject class attributes */
+  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_drm_src_finalize);
+  gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_drm_src_start);
+  gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_drm_src_stop);
+  gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_drm_src_is_seekable);
+  gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_drm_src_get_size);
+  gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_drm_src_create);
+  gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_drm_src_query);
+  gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_drm_src_change_state);
+  gst_tag_register (GST_TAG_PLAYREADY, GST_TAG_FLAG_META,
+    G_TYPE_STRING,
+    "PlayReady File Path",
+    "a tag that is specific to PlayReady File",
+     NULL);
 }
 /**
  * This function does the following:
@@ -149,13 +192,21 @@ static void gst_drm_src_class_init (GstDrmSrcClass * klass)
  */
 static void gst_drm_src_init (GstDrmSrc * src, GstDrmSrcClass * g_class)
 {
-       // 1. Initilizes the parameters of GstDrmSrc
-       src->filename = NULL;
-       src->fd = 0;
-       src->uri = NULL;
-       src->is_regular = FALSE;
-       src->seekable = FALSE;
-       PROFILE_INIT;
+  /* Initilizes the parameters of GstDrmSrc */
+  src->filename = NULL;
+  src->fd = 0;
+  src->uri = NULL;
+  src->is_regular = FALSE;
+  src->is_oma = FALSE;
+  src->seekable = FALSE;
+  src->hfile = NULL;
+  src->event_posted = FALSE;
+  src->is_playready = FALSE;
+  src->is_drm = FALSE;
+  src->isopen = FALSE;
+#ifdef CONTROL_PAGECACHE
+  src->accum = 0;
+#endif
 }
 /**
  * This function does the following:
@@ -168,14 +219,14 @@ static void gst_drm_src_init (GstDrmSrc * src, GstDrmSrcClass * g_class)
  */
 static void gst_drm_src_finalize (GObject * object)
 {
-       GstDrmSrc *src;
-
-       src = GST_DRM_SRC (object);
-       //  1. deallocates the filename and uri
-       g_free (src->filename);
-       g_free (src->uri);
-       // 2. calls the parent class->finalize
-       G_OBJECT_CLASS (parent_class)->finalize (object);
+  GstDrmSrc *src;
+
+  src = GST_DRM_SRC (object);
+  /*. deallocates the filename and uri */
+  g_free (src->filename);
+  g_free (src->uri);
+  /* calls the parent class->finalize */
+  G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 /**
  * This function does the following:
@@ -190,35 +241,50 @@ static void gst_drm_src_finalize (GObject * object)
  */
 static gboolean gst_drm_src_set_location (GstDrmSrc * src, const gchar * location)
 {
-       GstState state;
-
-       GST_OBJECT_LOCK (src);
-       //  1. Checks the state
-       state = GST_STATE (src);
-       if (state != GST_STATE_READY && state != GST_STATE_NULL)
-       {
-               GST_DEBUG_OBJECT (src, "setting location in wrong state");
-               GST_OBJECT_UNLOCK (src);
-               return FALSE;
-       }
-       GST_OBJECT_UNLOCK (src);
-       g_free (src->filename);
-       g_free (src->uri);
-       //  2. Checks the filename
-       if (location == NULL)
-       {
-               src->filename = NULL;
-               src->uri = NULL;
-       }
-       else
-       {
-               // 3. Sets the filename
-               src->filename = g_strdup (location);
-               src->uri = gst_uri_construct ("file", src->filename);
-       }
-       g_object_notify (G_OBJECT (src), "location");
-       gst_uri_handler_new_uri (GST_URI_HANDLER (src), src->uri);
-       return TRUE;
+  GstState state;
+
+  GST_OBJECT_LOCK (src);
+
+  /* Checks the state */
+  state = GST_STATE (src);
+  if (state != GST_STATE_READY && state != GST_STATE_NULL) {
+    GST_DEBUG_OBJECT (src, "setting location in wrong state");
+    GST_OBJECT_UNLOCK (src);
+    return FALSE;
+  }
+  GST_OBJECT_UNLOCK (src);
+
+  g_free (src->filename);
+  g_free (src->uri);
+
+  /* Checks the filename */
+  if (location == NULL) {
+    src->filename = NULL;
+    src->uri = NULL;
+  } else {
+    /*. Sets the filename */
+    src->filename = g_strdup (location);
+#if 0
+    /*This below API is changing the filename in case of punctuation marks in filename*/
+    src->uri = gst_filename_to_uri (location, NULL);
+#else
+    src->uri = g_strdup_printf ("%s://%s", "file", src->filename);
+
+    drm_bool_type_e is_drm = DRM_FALSE;
+    if (drm_is_drm_file(src->filename, &is_drm) == DRM_RETURN_SUCCESS) {
+      if (is_drm == DRM_TRUE) {
+       src->is_drm = TRUE;
+      }
+    }
+    GST_DEBUG_OBJECT (src, "is drm : %d", src->is_drm);
+#endif
+    GST_INFO_OBJECT(src, "filename : %s", src->filename);
+    GST_INFO_OBJECT(src, "uri      : %s", src->uri);
+  }
+  g_object_notify (G_OBJECT (src), "location");
+  gst_uri_handler_new_uri (GST_URI_HANDLER (src), src->uri);
+
+  return TRUE;
 }
 /**
  * This function does the following:
@@ -233,20 +299,21 @@ static gboolean gst_drm_src_set_location (GstDrmSrc * src, const gchar * locatio
  */
 static void gst_drm_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec)
 {
-       GstDrmSrc *src;
-
-       g_return_if_fail (GST_IS_DRM_SRC (object));
-       src = GST_DRM_SRC (object);
-       switch (prop_id)
-       {
-               //  1. Sets the location of the file.
-               case ARG_LOCATION:
-                       gst_drm_src_set_location (src, g_value_get_string (value));
-                       break;
-               default:
-                       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-                       break;
-       }
+  GstDrmSrc *src;
+
+  g_return_if_fail (GST_IS_DRM_SRC (object));
+
+  src = GST_DRM_SRC (object);
+
+  switch (prop_id) {
+  //  1. Sets the location of the file.
+  case ARG_LOCATION:
+    gst_drm_src_set_location (src, g_value_get_string (value));
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    break;
+  }
 }
 /**
  * This function does the following:
@@ -262,26 +329,192 @@ static void gst_drm_src_set_property (GObject * object, guint prop_id, const GVa
  */
 static void gst_drm_src_get_property (GObject * object, guint prop_id, GValue * value,GParamSpec * pspec)
 {
-       GstDrmSrc *src;
-
-       g_return_if_fail (GST_IS_DRM_SRC (object));
-       src = GST_DRM_SRC (object);
-       switch (prop_id)
-       {
-               //  1. Provides the location of the file.
-               case ARG_LOCATION:
-                       g_value_set_string (value, src->filename);
-                       break;
-               // 2. Provides the file descriptor.
-               case ARG_FD:
-                       g_value_set_int (value, src->fd);
-                       break;
-               default:
-                       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-                       break;
-       }
+  GstDrmSrc *src;
+
+  g_return_if_fail (GST_IS_DRM_SRC (object));
+  src = GST_DRM_SRC (object);
+  switch (prop_id) {
+    case ARG_LOCATION:
+    g_value_set_string (value, src->filename);
+    break;
+    case ARG_FD:
+    g_value_set_int (value, src->fd);
+    break;
+    case IS_DRM:
+    g_value_set_boolean(value, src->is_drm);
+    break;
+    default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    break;
+  }
+}
+
+static GstStateChangeReturn
+gst_drm_src_change_state (GstElement * element, GstStateChange transition)
+{
+
+  GstDrmSrc *src = GST_DRM_SRC (element);
+  GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;
+  gboolean ret = FALSE;
+  drm_file_type_e file_type = DRM_TYPE_UNDEFINED;
+  switch (transition) {
+    case GST_STATE_CHANGE_NULL_TO_READY:{
+      GST_INFO_OBJECT(src,"change state from NULL to ready");
+      drm_result_e drm_result;
+      drm_result = drm_get_file_type (src->filename, &file_type);
+      if (file_type == DRM_TYPE_OMA_V1) {
+      /* Opens the DRM file if it is DRM */
+        if (!src->isopen) {
+          GST_DEBUG_OBJECT (src, "trying  to open drm util");
+          if (drm_util_open (&src->hfile, src->filename, file_type) == FALSE) {
+            GST_ERROR_OBJECT (src, "failed to open drm util");
+            return FALSE;
+          }
+          src->isopen=TRUE;
+        }
+      }
+    break;
+    }
+    case GST_STATE_CHANGE_READY_TO_PAUSED:{
+      GST_INFO_OBJECT(src,"change state from ready to paused");
+      drm_result_e drm_result;
+      drm_result = drm_get_file_type (src->filename, &file_type);
+      if (file_type == DRM_TYPE_OMA_V1){
+        ret = drm_process_request(DRM_REQUEST_TYPE_CLIENT_CLEAN_UP, NULL, NULL);
+        if (DRM_RETURN_SUCCESS == ret) {
+          GST_INFO("Clean Up successful!!");
+        } else {
+          GST_ERROR("Clean Up Failed!!, ret = 0x%x", ret);
+        }
+        ret = drm_trusted_handle_request(DRM_TRUSTED_REQ_TYPE_CLIENT_CLEAN_UP, NULL, NULL);
+        if (DRM_RETURN_SUCCESS == ret) {
+          GST_INFO("Clean Up successful!!");
+        } else {
+          GST_ERROR("Clean Up Failed!!, ret = 0x%x", ret);
+        }
+      }
+      break;
+    }
+    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:{
+      GST_INFO_OBJECT(src,"change state from paused to playing");
+      break;
+    }
+    default:
+      break;
+  }
+  result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+  switch (transition) {
+    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:{
+      GST_INFO_OBJECT(src,"change state from playing  to paused");
+      break;
+    }
+    case GST_STATE_CHANGE_PAUSED_TO_READY:{
+      GST_INFO_OBJECT(src,"change state from paused to ready");
+      if (src->hfile) {
+        if (src->isopen)
+          if (drm_util_close(&src->hfile))
+            src->isopen=FALSE;
+            src->hfile = NULL;
+#ifdef CONTROL_PAGECACHE
+           DRMSRC_FADVISE_DONT(src->hfile, 0, 0);
+           src->accum = 0;
+#endif
+      }
+      break;
+    }
+    case GST_STATE_CHANGE_READY_TO_NULL:{
+      GST_INFO_OBJECT(src,"change state from ready to null");
+      break;
+    }
+    default:
+    break;
+
+  }
+  return result;
 }
 
+
+
+
+/**
+ * This function does the following:
+ *  1. Seeks to the specified position for DRM file.
+ *  2. Allocates a buffer to push the data for DRM file.
+ *  3. Reads from the file and sets the related params for DRM file.
+ *
+ * @param   i_pDrmSrc    [in]   GstDrmSrc Structure
+ * @param   i_uiOffset    [in]   offset of the file to seek
+ * @param   length    [in]   size of the data in bytes
+ * @param   o_pBbuffer    [out]   GstBuffer to hold the contents
+ *
+ * @return  GstFlowReturn   Returns GST_FLOW_OK on success and ERROR on failure
+ */
+static GstFlowReturn  gst_drm_src_create_read_drm_file (GstDrmSrc* src, guint64 i_uiOffset, guint length, GstBuffer ** o_pBbuffer)
+{
+  GstBuffer *buf = NULL;
+  unsigned int readSize;
+
+  /* Seeks to the specified position for DRM file. */
+  if (G_UNLIKELY (src->read_position != i_uiOffset)) {
+    if (drm_util_seek (src->hfile, i_uiOffset, DRM_SEEK_SET) == FALSE)
+      goto FAILED;
+
+    src->read_position = i_uiOffset;
+  }
+
+  /* Allocates a buffer to push the data for DRM file. */
+  buf = gst_buffer_new_and_alloc (length);
+  if(buf == NULL) {
+    LOG_TRACE("Exit on error");
+    return GST_FLOW_ERROR;
+  }
+
+  /*. Reads from the file and sets the related params for DRM file. */
+  if (drm_util_read (src->hfile, GST_BUFFER_DATA(buf), GST_BUFFER_SIZE(buf), &readSize) == FALSE)
+    goto FAILED;
+
+  if(readSize <= 0) {
+    LOG_TRACE("Exit on error");
+    return GST_FLOW_ERROR;
+  }
+
+  #if 0 // Drm service can give lesser size block than requested thing.
+  if (G_UNLIKELY ((guint) readSize < length && i_pDrmSrc->seekable)) {
+  GST_ELEMENT_ERROR (i_pDrmSrc, RESOURCE, READ, (NULL),("unexpected end of file."));
+  gst_buffer_unref (buf);
+  return GST_FLOW_ERROR;
+  }
+  #endif
+
+  if (G_UNLIKELY (readSize == 0 && length > 0)) {
+    GST_DEBUG ("non-regular file hits EOS");
+    gst_buffer_unref (buf);
+    return GST_FLOW_UNEXPECTED;
+  }
+
+#ifdef CONTROL_PAGECACHE
+       src->accum += readSize;
+       if (src->accum >= DEFAULT_DO_FADVISE_THRESHOLD) {
+               DRMSRC_FADVISE_DONT(src->hfile, 0, 0);
+               src->accum = 0;
+       }
+#endif
+
+  length = readSize;
+  GST_BUFFER_SIZE (buf) = length;
+  GST_BUFFER_OFFSET (buf) = i_uiOffset;
+  GST_BUFFER_OFFSET_END (buf) = i_uiOffset + length;
+  *o_pBbuffer = buf;
+  src->read_position += length;
+
+  return GST_FLOW_OK;
+
+FAILED:
+{
+  GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
+  return GST_FLOW_ERROR;
+}
+}
 /**
  * This function does the following:
  *  1. Seeks to the specified position.
@@ -297,50 +530,67 @@ static void gst_drm_src_get_property (GObject * object, guint prop_id, GValue *
  */
 static GstFlowReturn gst_drm_src_create_read (GstDrmSrc * src, guint64 offset, guint length, GstBuffer ** buffer)
 {
-       int ret;
-       GstBuffer *buf;
-       // 1. Seeks to the specified position.
-       if (G_UNLIKELY (src->read_position != offset))
-       {
-               off_t res;
-               res = lseek (src->fd, offset, SEEK_SET);
-               if (G_UNLIKELY (res < 0 || res != offset))
-               {
-                       GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
-                       return GST_FLOW_ERROR;
-               }
-               src->read_position = offset;
-       }
-       // 2. Allocates a buffer to push the data
-       buf = gst_buffer_new_and_alloc (length);
-       GST_LOG_OBJECT (src, "Reading %d bytes", length);
-       // 3. Reads from the file and sets the related params
-       ret = read (src->fd, GST_BUFFER_DATA (buf), length);
-       if (G_UNLIKELY (ret < 0))
-       {
-               GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
-               gst_buffer_unref (buf);
-               return GST_FLOW_ERROR;
-       }
-       if (G_UNLIKELY ((guint) ret < length && src->seekable))
-       {
-               GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),("unexpected end of file."));
-               gst_buffer_unref (buf);
-               return GST_FLOW_ERROR;
-       }
-       if (G_UNLIKELY (ret == 0 && length > 0))
-       {
-               GST_DEBUG ("non-regular file hits EOS");
-               gst_buffer_unref (buf);
-               return GST_FLOW_UNEXPECTED;
+  int ret;
+  GstBuffer *buf;
+
+  /* Seeks to the specified position. */
+  if (G_UNLIKELY (src->read_position != offset)) {
+    off_t res;
+    res = lseek (src->fd, offset, SEEK_SET);
+    if (G_UNLIKELY (res < 0 || res != offset)) {
+      GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
+      return GST_FLOW_ERROR;
+    }
+    src->read_position = offset;
+  }
+
+  /* Allocates a buffer to push the data */
+  buf = gst_buffer_new_and_alloc (length);
+  if (NULL == buf) {
+    GST_ERROR_OBJECT (src, "failed to allocate memory..");
+    GST_ELEMENT_ERROR (src, RESOURCE, NO_SPACE_LEFT, (NULL), ("failed to allocate memory"));
+    return GST_FLOW_ERROR;
+  }
+
+  GST_LOG_OBJECT (src, "Reading %d bytes", length);
+
+  /*  Reads from the file and sets the related params */
+  ret = read (src->fd, GST_BUFFER_DATA (buf), length);
+  if (G_UNLIKELY (ret < 0)) {
+    GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
+    gst_buffer_unref (buf);
+    return GST_FLOW_ERROR;
+  }
+
+  if (G_UNLIKELY ((guint) ret < length && src->seekable)) {
+    GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),("unexpected end of file."));
+    gst_buffer_unref (buf);
+    return GST_FLOW_ERROR;
+  }
+
+  if (G_UNLIKELY (ret == 0 && length > 0)) {
+    GST_DEBUG ("non-regular file hits EOS");
+    gst_buffer_unref (buf);
+    return GST_FLOW_UNEXPECTED;
+  }
+
+#ifdef CONTROL_PAGECACHE
+       src->accum += ret;
+       if (src->accum >= DEFAULT_DO_FADVISE_THRESHOLD) {
+               DRMSRC_FADVISE_DONT(src->fd, 0, 0);
+               src->accum = 0;
        }
-       length = ret;
-       GST_BUFFER_SIZE (buf) = length;
-       GST_BUFFER_OFFSET (buf) = offset;
-       GST_BUFFER_OFFSET_END (buf) = offset + length;
-       *buffer = buf;
-       src->read_position += length;
-       return GST_FLOW_OK;
+       //DRMSRC_FADVISE_DONT(src->fd, offset, ret);
+#endif
+
+  length = ret;
+  GST_BUFFER_SIZE (buf) = length;
+  GST_BUFFER_OFFSET (buf) = offset;
+  GST_BUFFER_OFFSET_END (buf) = offset + length;
+  *buffer = buf;
+  src->read_position += length;
+
+  return GST_FLOW_OK;
 }
 /**
  * This function does the following:
@@ -354,13 +604,73 @@ static GstFlowReturn gst_drm_src_create_read (GstDrmSrc * src, guint64 offset, g
  */
 static GstFlowReturn gst_drm_src_create (GstBaseSrc * basesrc, guint64 offset, guint length, GstBuffer ** buffer)
 {
-       GstDrmSrc *src = GST_DRM_SRC (basesrc);
+  GstDrmSrc *src = GST_DRM_SRC (basesrc);
 
-       // 1. Calls DRM file read chain method for drm files.
+  if (src->is_playready && src->event_posted == FALSE) {
+    GstTagList *tags = NULL;
+    GST_DEBUG_OBJECT (src, "posting playready tags");
+    tags =  gst_tag_list_new_full (GST_TAG_PLAYREADY, src->filename, NULL);
+    if (tags) {
+      GstPad* src_pad = gst_element_get_static_pad (src, "src");
+      if (src_pad) {
+        if(!gst_pad_push_event (src_pad, gst_event_new_tag (tags))) {
+          GST_ERROR_OBJECT (src, "failed to push tags..");
+          gst_object_unref (src_pad);
+          return GST_FLOW_ERROR;
+        }
+        GST_DEBUG_OBJECT (src, "posting tags returns [%d]", src->event_posted);
+        src->event_posted = TRUE;
+        gst_object_unref (src_pad);
+      }
+    }
+  }
 
-       // 2. Calls normal file read chain method for standard files.
-       return gst_drm_src_create_read (src, offset, length, buffer);
+  if(src->is_oma == TRUE) /* Calls DRM file read chain method for drm files. */
+    return gst_drm_src_create_read_drm_file (src, offset, length, buffer);
+  else /* Calls normal file read chain method for standard files. */
+    return gst_drm_src_create_read (src, offset, length, buffer);
 }
+
+static gboolean
+gst_drm_src_query (GstBaseSrc * basesrc, GstQuery * query)
+{
+  gboolean ret = FALSE;
+  GstDrmSrc *src = GST_DRM_SRC (basesrc);
+
+  switch (GST_QUERY_TYPE (query)) {
+    case GST_QUERY_URI:
+      gst_query_set_uri (query, src->uri);
+      ret = TRUE;
+      break;
+    case GST_QUERY_CUSTOM:
+    {
+      GstStructure *s;
+      guint64 size = 0;
+      GValue v = { 0, { { 0 } } };
+      g_value_init(&v, G_TYPE_UINT64);
+
+      s = gst_query_get_structure (query);
+      if (gst_structure_has_name (s, "dynamic-size")) {
+        if (gst_drm_src_get_size (basesrc, &size)){
+          /* succedded. take size */
+          g_value_set_uint64 (&v, size);
+          gst_structure_set_value(s, "size", &v);
+          ret = TRUE;
+        }
+      }
+      break;
+    }
+    default:
+      ret = FALSE;
+      break;
+  }
+
+  if (!ret)
+    ret = GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query);
+
+  return ret;
+}
+
 /**
  *
  * @param   basesrc    [in]   BaseSrc Structure
@@ -369,8 +679,8 @@ static GstFlowReturn gst_drm_src_create (GstBaseSrc * basesrc, guint64 offset, g
  */
 static gboolean gst_drm_src_is_seekable (GstBaseSrc * basesrc)
 {
-       GstDrmSrc *src = GST_DRM_SRC (basesrc);
-       return src->seekable;
+  GstDrmSrc *src = GST_DRM_SRC (basesrc);
+  return src->seekable;
 }
 /**
  * This function does the following:
@@ -384,22 +694,43 @@ static gboolean gst_drm_src_is_seekable (GstBaseSrc * basesrc)
  */
 static gboolean gst_drm_src_get_size (GstBaseSrc * basesrc, guint64 * size)
 {
-       struct stat stat_results;
-       GstDrmSrc *src = GST_DRM_SRC (basesrc);
-       unsigned int offset;
+  struct stat stat_results;
+  GstDrmSrc *src = GST_DRM_SRC (basesrc);
+  unsigned int offset;
+
+  /* Gets the filesize for drm file by using seek oprations */
+  if(src->is_oma==TRUE) {
+    drm_util_seek (src->hfile, 0, DRM_SEEK_END);
+    if (drm_util_tell(src->hfile, &offset) == TRUE) {
+      /* FIXME : drm doesn't support 64 */
+      *size = offset;
+    }
+    drm_util_seek (src->hfile, 0, DRM_SEEK_SET);
+    src->read_position = 0;
+    return TRUE;
+  }
+
+  if (!src->seekable) {
+    GST_DEBUG_OBJECT (src, "non-seekable");
+    return FALSE;
+  }
 
-       //  1. Gets the filesize for drm file by using seek oprations
+  /* Gets the file size for standard file by using statistics */
+  if (fstat (src->fd, &stat_results) < 0)
+    return FALSE;
 
-       // 2. Gets the file size for standard file by using statistics
-       if (fstat (src->fd, &stat_results) < 0)
-               return FALSE;
-       *size = stat_results.st_size;
-       return TRUE;
+  *size = stat_results.st_size;
+  GST_DEBUG_OBJECT (src, "size : %"G_GUINT64_FORMAT, *size);
+  return TRUE;
 }
 /**
  * This function does the following:
  *  1. Checks the filename
  *  2. Opens the file and check statistics of the file
+ *  3. Checks whether DRM file or not.
+ *  4. Checks the DRM file type (supports only for OMA) if it is DRM
+ *  5. Opens the DRM file if it is DRM
+ *  6. Gets the DRM_FILE_HANDLE and sets the drm, seekable and regular flag.
  *  7. Checks the seeking for standard files
  *
  * @param   basesrc    [in]   BaseSrc Structure
@@ -408,67 +739,107 @@ static gboolean gst_drm_src_get_size (GstBaseSrc * basesrc, guint64 * size)
  */
 static gboolean gst_drm_src_start (GstBaseSrc * basesrc)
 {
-       GstDrmSrc *src = GST_DRM_SRC (basesrc);
-       struct stat stat_results;
-       off_t ret;
-PROFILE_FUNC_BEGIN;
-       // 1. Checks the filename
-       if (src->filename == NULL || src->filename[0] == '\0')
-       {
-               GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND,("No file name specified for reading."), (NULL));
-               return FALSE;
-       }
-       // 2. Opens the file and check statistics of the file
-       GST_INFO_OBJECT (src, "opening file %s", src->filename);
-       src->fd = open (src->filename, O_RDONLY | O_BINARY);
-       if (src->fd < 0)
-       {
-               if(errno == ENOENT)
-               {
-                       GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL),("No such file \"%s\"", src->filename));
-                       return FALSE;
-               }
-               GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("Could not open file \"%s\" for reading.", src->filename), GST_ERROR_SYSTEM);
-               return FALSE;
-       }
-       if (fstat (src->fd, &stat_results) < 0)
-       {
-               GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("Could not get info on \"%s\".", src->filename), (NULL));
-               close (src->fd);
-               return FALSE;
-       }
-       if (S_ISDIR (stat_results.st_mode))
-       {
-               GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("\"%s\" is a directory.", src->filename), (NULL));
-               close (src->fd);
-               return FALSE;
-       }
-       if (S_ISSOCK (stat_results.st_mode))
-       {
-               GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("File \"%s\" is a socket.", src->filename), (NULL));
-               close (src->fd);
-               return FALSE;
-       }
-       src->read_position = 0;
-
-       // 7. Checks the seeking for standard files
-       if (S_ISREG (stat_results.st_mode))
-               src->is_regular = TRUE;
-       ret = lseek (src->fd, 0, SEEK_END);
-       if (ret < 0)
-       {
-               GST_LOG_OBJECT (src, "disabling seeking, not in mmap mode and lseek "
-                       "failed: %s", g_strerror (errno));
-               src->seekable = FALSE;
-       }
-       else
-       {
-               src->seekable = TRUE;
-       }
-       lseek (src->fd, 0, SEEK_SET);
-       src->seekable = src->seekable && src->is_regular;
-       PROFILE_FUNC_END;
-       return TRUE;
+  GstDrmSrc *src = GST_DRM_SRC (basesrc);
+  struct stat stat_results;
+  drm_result_e drm_result;
+  drm_file_type_e file_type;
+  off_t ret;
+
+  /* Checks the filename */
+  if (src->filename == NULL || src->filename[0] == '\0') {
+    GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND,("No file name specified for reading."), (NULL));
+    return FALSE;
+  }
+
+  /*  Opens the file and check statistics of the file */
+  GST_INFO_OBJECT (src, "opening file %s", src->filename);
+  src->fd = open (src->filename, O_RDONLY | O_BINARY);
+  if (src->fd < 0) {
+    if(errno == ENOENT) {
+      GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL),("No such file \"%s\"", src->filename));
+      return FALSE;
+    }
+    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("Could not open file \"%s\" for reading.", src->filename), GST_ERROR_SYSTEM);
+    return FALSE;
+  }
+
+  if (fstat (src->fd, &stat_results) < 0) {
+    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("Could not get info on \"%s\".", src->filename), (NULL));
+    close (src->fd);
+    return FALSE;
+  }
+
+  if (S_ISDIR (stat_results.st_mode)) {
+    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("\"%s\" is a directory.", src->filename), (NULL));
+    close (src->fd);
+    return FALSE;
+  }
+
+  if (S_ISSOCK (stat_results.st_mode)) {
+    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("File \"%s\" is a socket.", src->filename), (NULL));
+    close (src->fd);
+    return FALSE;
+  }
+
+  src->read_position = 0;
+
+
+  /* Checks whether DRM file or not.*/
+  drm_result = drm_get_file_type (src->filename, &file_type);
+  if (drm_result != DRM_RETURN_SUCCESS) {
+    GST_ERROR_OBJECT (src,"Error in drm_get_file_type(), error=%d", drm_result);
+    return FALSE;
+  }
+  GST_DEBUG_OBJECT (src, "file_path = [%s], file_type = [%d]", src->filename, file_type);
+
+#if 0
+  if (DRM_TYPE_UNDEFINED != file_type) {
+    drm_bool_type_e is_drm = DRM_FALSE;
+    if (drm_is_drm_file(src->filename, &is_drm) == DRM_RETURN_SUCCESS) {
+      if (is_drm == DRM_TRUE) {
+       src->is_drm = TRUE;
+      }
+    }
+    GST_DEBUG_OBJECT (src, "is drm = [%d]", src->is_drm);
+  }
+#endif
+
+  /* We handles as DRM file if it is drm with OMA type */
+  if (file_type == DRM_TYPE_OMA_V1) { /* FIMXE: what about DRM_TYPE_OMA_V2  */
+    // Gets the DRM_FILE_HANDLE and sets the drm, seekable and regular flags.
+    drm_util_seek (src->hfile, 0, DRM_SEEK_END);
+    drm_util_seek (src->hfile, 0, DRM_SEEK_SET);
+
+    src->seekable      = TRUE;
+    src->is_regular    = TRUE;
+    src->is_oma        = TRUE;
+
+    LOG_TRACE("Exit");
+    return TRUE;
+  }
+
+  if (file_type == DRM_TYPE_PLAYREADY || file_type == DRM_TYPE_PLAYREADY_ENVELOPE) { /* FIXME: what is envelope?? */
+    src->is_playready = TRUE;
+    src->event_posted = FALSE;
+  }
+
+  /* Checks the seeking for standard files */
+  if (S_ISREG (stat_results.st_mode))
+    src->is_regular = TRUE;
+
+  ret = lseek (src->fd, 0, SEEK_END);
+  if (ret < 0) {
+    GST_LOG_OBJECT (src, "disabling seeking, not in mmap mode and lseek failed: %s", g_strerror (errno));
+    src->seekable = FALSE;
+  } else {
+    src->seekable = TRUE;
+  }
+
+  lseek (src->fd, 0, SEEK_SET);
+  src->seekable = src->seekable && src->is_regular;
+
+
+  return TRUE;
 }
 /**
  * This function does the following:
@@ -480,15 +851,22 @@ PROFILE_FUNC_BEGIN;
  */
 static gboolean gst_drm_src_stop (GstBaseSrc * basesrc)
 {
-       GstDrmSrc *src = GST_DRM_SRC (basesrc);
-
-       // 1. Closes the file desciptor and resets the flags
-       if(src->fd > 0)
-               close (src->fd);
-       src->fd = 0;
-       src->is_regular = FALSE;
-//     PROFILE_SHOW_RESULT;
-       return TRUE;
+  GstDrmSrc *src = GST_DRM_SRC (basesrc);
+  // 1. Closes the file desciptor and resets the flags
+  if(src->fd > 0) {
+#ifdef CONTROL_PAGECACHE
+       DRMSRC_FADVISE_DONT(src->fd, 0, 0);
+       src->accum = 0;
+#endif
+    close (src->fd);
+  }
+
+  src->fd = 0;
+  src->is_regular = FALSE;
+  src->event_posted = FALSE;
+  src->is_playready = FALSE;
+
+  return TRUE;
 }
 /**
  *
@@ -499,7 +877,7 @@ static gboolean gst_drm_src_stop (GstBaseSrc * basesrc)
 
 static GstURIType gst_drm_src_uri_get_type (void)
 {
-       return GST_URI_SRC;
+  return GST_URI_SRC;
 }
 
 /**
@@ -513,8 +891,8 @@ static GstURIType gst_drm_src_uri_get_type (void)
 
 static gchar ** gst_drm_src_uri_get_protocols (void)
 {
-       static gchar *protocols[] = { "file", NULL };
-       return protocols;
+  static gchar *protocols[] = { "file", NULL };
+  return protocols;
 }
 /**
  *
@@ -524,8 +902,8 @@ static gchar ** gst_drm_src_uri_get_protocols (void)
  */
 static const gchar * gst_drm_src_uri_get_uri (GstURIHandler *handler)
 {
-       GstDrmSrc *src = GST_DRM_SRC (handler);
-       return src->uri;
+  GstDrmSrc *src = GST_DRM_SRC (handler);
+  return src->uri;
 }
 /**
  * This function does the following:
@@ -540,46 +918,50 @@ static const gchar * gst_drm_src_uri_get_uri (GstURIHandler *handler)
  */
 static gboolean gst_drm_src_uri_set_uri (GstURIHandler *handler, const gchar * uri)
 {
-       gchar *protocol, *location;
-       gboolean ret;
-       GstDrmSrc *src = GST_DRM_SRC (handler);
-       // 1. Checks the protocol
-       protocol = gst_uri_get_protocol (uri);
-       if (strcmp (protocol, "file") != 0)
-       {
-               g_free (protocol);
-               return FALSE;
-       }
-       g_free (protocol);
-       if (g_str_has_prefix (uri, "file://localhost/"))
-       {
-               char *tmp;
-               tmp = g_strconcat ("file://", uri + 16, NULL);
-               location = gst_uri_get_location (tmp);
-               g_free (tmp);
-       }
-       else if (strcmp (uri, "file://") == 0)
-       {
-               gst_drm_src_set_location (src, NULL);
-               return TRUE;
-       }
-       else
-       {
-               location = gst_uri_get_location (uri);
-       }
-       if (!location)
-               return FALSE;
-       // 2. Checks the whether it is absolute or not
-       if (!g_path_is_absolute (location))
-       {
-               g_free (location);
-               return FALSE;
-       }
-       // 3 sets the location
-       ret = gst_drm_src_set_location (src, location);
-       g_free (location);
-       return ret;
+  gchar *location, *hostname = NULL;
+  gboolean ret = FALSE;
+  GstDrmSrc *src = GST_DRM_SRC (handler);
+  GError *error = NULL;
+
+  if (strcmp (uri, "file://") == 0) {
+    /* Special case for "file://" as this is used by some applications
+     *  to test with gst_element_make_from_uri if there's an element
+     *  that supports the URI protocol. */
+    gst_drm_src_set_location (src, NULL);
+    return TRUE;
+  }
+
+  location = g_filename_from_uri (uri, &hostname, &error);
+
+  if (!location || error) {
+    if (error) {
+      GST_WARNING_OBJECT (src, "Invalid URI '%s' for filesrc: %s", uri,
+          error->message);
+      g_error_free (error);
+    } else {
+      GST_WARNING_OBJECT (src, "Invalid URI '%s' for filesrc", uri);
+    }
+    goto beach;
+  }
+
+  if ((hostname) && (strcmp (hostname, "localhost"))) {
+    /* Only 'localhost' is permitted */
+    GST_WARNING_OBJECT (src, "Invalid hostname '%s' for filesrc", hostname);
+    goto beach;
+  }
+
+  ret = gst_drm_src_set_location (src, location);
+
+beach:
+  if (location)
+    g_free (location);
+  if (hostname)
+    g_free (hostname);
+
+  return ret;
 }
+
+
 /**
  * This function does the following:
  *  1. Assignes the function pointer for URI related stuff
@@ -591,12 +973,13 @@ static gboolean gst_drm_src_uri_set_uri (GstURIHandler *handler, const gchar * u
  */
 static void gst_drm_src_uri_handler_init (gpointer g_iface, gpointer iface_data)
 {
-       GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
-       // 1. Assigning the function pointer for URI related stuff
-       iface->get_type = gst_drm_src_uri_get_type;
-       iface->get_protocols = gst_drm_src_uri_get_protocols;
-       iface->get_uri = gst_drm_src_uri_get_uri;
-       iface->set_uri = gst_drm_src_uri_set_uri;
+  GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
+
+  /* Assigning the function pointer for URI related stuff */
+  iface->get_type = gst_drm_src_uri_get_type;
+  iface->get_protocols = gst_drm_src_uri_get_protocols;
+  iface->get_uri = gst_drm_src_uri_get_uri;
+  iface->set_uri = gst_drm_src_uri_set_uri;
 }
 /**
  * This function does the following:
@@ -608,7 +991,7 @@ static void gst_drm_src_uri_handler_init (gpointer g_iface, gpointer iface_data)
  */
 static gboolean plugin_init(GstPlugin* i_pPlugin)
 {
-       return gst_element_register(i_pPlugin, "drmsrc", GST_RANK_NONE, GST_TYPE_DRM_SRC);;
+  return gst_element_register(i_pPlugin, "drmsrc", GST_RANK_NONE, GST_TYPE_DRM_SRC);
 }
 /**
  * This function does the following:
@@ -616,12 +999,12 @@ static gboolean plugin_init(GstPlugin* i_pPlugin)
  *
  */
 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
-                                                GST_VERSION_MINOR,
-                                                "drmsrc",
-                                                "Plugin to read data from standad/DRM File",
-                                                plugin_init,
-                                                VERSION,
-                                                "LGPL",
-                                                "Samsung Electronics Co",
-                                                "http://www.samsung.com/")
+  GST_VERSION_MINOR,
+  "drmsrc",
+  "Plugin to read data from standad/DRM File",
+  plugin_init,
+  VERSION,
+  "LGPL",
+  "Samsung Electronics Co",
+  "http://www.samsung.com/")