46617177d04fe27966efb63509e53107c1caf459
[framework/multimedia/gst-plugins-ext0.10.git] / drmsrc / src / gstdrmsrc.c
1 /*
2  * drmsrc
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>
7  *
8  * This library is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU Lesser General Public License as published by the
10  * Free Software Foundation; either version 2.1 of the License, or (at your option)
11  * any later version.
12  *
13  * This library is distributed in the hope that it will be useful, but WITHOUT ANY
14  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16  * License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this library; if not, write to the Free Software Foundation, Inc., 51
20  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  *
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27 #include "gstdrmsrc.h"
28
29
30 #define LOG_TRACE(message)  //g_print("DRM_SRC: %s: %d: %s - %s \n", __FILE__, __LINE__, __FUNCTION__, message);
31
32 #define GST_TAG_PLAYREADY "playready_file_path"
33
34 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS,GST_STATIC_CAPS_ANY);
35
36
37 GST_DEBUG_CATEGORY_STATIC (gst_drm_src_debug);
38 #define GST_CAT_DEFAULT gst_drm_src_debug
39
40 enum
41 {
42         ARG_0,
43         ARG_LOCATION,
44         ARG_FD,
45         IS_DRM
46 };
47 static void gst_drm_src_finalize (GObject * object);
48 static void gst_drm_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec);
49 static void gst_drm_src_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec);
50 static gboolean gst_drm_src_start (GstBaseSrc * basesrc);
51 static gboolean gst_drm_src_stop (GstBaseSrc * basesrc);
52 static gboolean gst_drm_src_is_seekable (GstBaseSrc * src);
53 static gboolean gst_drm_src_get_size (GstBaseSrc * src, guint64 * size);
54 static GstFlowReturn gst_drm_src_create (GstBaseSrc * src, guint64 offset, guint length, GstBuffer ** buffer);
55 static void gst_drm_src_uri_handler_init (gpointer g_iface, gpointer iface_data);
56 /**
57  * This function does the following:
58  *  1. Initializes GstDrmSrc ( defines gst_drm_get_type)
59  *
60  * @param   drmsrc_type    [out]  GType
61  *
62  * @return  void
63  */
64 static void _do_init (GType drmsrc_type)
65 {
66        // 1. Initializes GstDrmSrc ( defines gst_drm_get_type)
67         static const GInterfaceInfo urihandler_info = {
68                 gst_drm_src_uri_handler_init,
69                 NULL,
70                 NULL
71         };
72
73         g_type_add_interface_static (drmsrc_type, GST_TYPE_URI_HANDLER, &urihandler_info);
74         GST_DEBUG_CATEGORY_INIT (gst_drm_src_debug, "drmsrc", 0, "drmsrc element");
75 }
76 GST_BOILERPLATE_FULL (GstDrmSrc, gst_drm_src, GstBaseSrc, GST_TYPE_BASE_SRC,   _do_init);
77 /**
78  * This function does the following:
79  *  1. Sets the class details
80  *  2. Adds the source pad template
81  *
82  * @param   g_class    [out]   gpointer
83  *
84  * @return  void
85  */
86 static void gst_drm_src_base_init (gpointer g_class)
87 {
88         GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
89         // 1. Sets the class details
90         gst_element_class_set_details_simple (gstelement_class,
91                 "DRM Source",
92                 "Source/File",
93                 "Read from arbitrary point in a standard/DRM file",
94                 "Kishore Arepalli  <kishore.a@samsung.com> and Sadanand Dodawadakar <sadanand.d@samsung.com>");
95       // 2. Adds the source pad template
96         gst_element_class_add_pad_template (gstelement_class, gst_static_pad_template_get (&srctemplate));
97 }
98 /**
99  * This function does the following:
100  *  1. Installs the properties
101  *  2. Assigns the function pointers GObject class attributes
102  *
103  * @param   klass    [out]   GstDrmSrcClass Structure
104  *
105  * @return  void
106  */
107 static void gst_drm_src_class_init (GstDrmSrcClass * klass)
108 {
109         GObjectClass *gobject_class;
110         GstElementClass *gstelement_class;
111         GstBaseSrcClass *gstbasesrc_class;
112         gobject_class = G_OBJECT_CLASS (klass);
113         gstelement_class = GST_ELEMENT_CLASS (klass);
114         gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
115         // Assigns the function pointers GObject class attributes
116         gobject_class->set_property = gst_drm_src_set_property;
117         gobject_class->get_property = gst_drm_src_get_property;
118         //  1. Installs the properties
119         g_object_class_install_property (gobject_class, ARG_FD,
120                 g_param_spec_int ("fd", "File-descriptor",
121                 "File-descriptor for the file being mmap()d", 0, G_MAXINT, 0,
122                 G_PARAM_READABLE));
123         g_object_class_install_property (gobject_class, ARG_LOCATION,
124                 g_param_spec_string ("location", "File Location",
125                 "Location of the file to read", NULL, G_PARAM_READWRITE));
126         g_object_class_install_property (gobject_class, IS_DRM,
127                 g_param_spec_boolean ("is-drm", "whether selected file type is drm or not",
128                 "true, false", FALSE, G_PARAM_READWRITE));      
129         // 2. Assigns the function pointers GObject class attributes
130         gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_drm_src_finalize);
131         gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_drm_src_start);
132         gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_drm_src_stop);
133         gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_drm_src_is_seekable);
134         gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_drm_src_get_size);
135         gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_drm_src_create);
136
137
138         gst_tag_register (GST_TAG_PLAYREADY, GST_TAG_FLAG_META,
139                         G_TYPE_STRING,
140                         "PlayReady File Path",
141                         "a tag that is specific to PlayReady File",
142                         NULL);
143 }
144 /**
145  * This function does the following:
146  *  1. Initilizes the parameters of GstDrmSrc
147  *
148  * @param   src    [out]   GstDrmSrc structure
149  * @param   g_class    [in]   GstDrmSrcClass structure
150  *
151  * @return  gboolean   Returns TRUE on success and FALSE on ERROR
152  */
153 static void gst_drm_src_init (GstDrmSrc * src, GstDrmSrcClass * g_class)
154 {
155         // 1. Initilizes the parameters of GstDrmSrc
156         src->filename = NULL;
157         src->fd = 0;
158         src->uri = NULL;
159         src->is_regular = FALSE;
160         src->drm_file = FALSE;
161         src->seekable = FALSE;
162         src->hfile = NULL;
163         src->event_posted = FALSE;
164         src->is_playready = FALSE;
165         PROFILE_INIT;
166 }
167 /**
168  * This function does the following:
169  *  1. deallocates the filename and uri
170  *  2. calls the parent class->finalize
171  *
172  * @param   object    [in]   GObject Structure
173  *
174  * @return  void
175  */
176 static void gst_drm_src_finalize (GObject * object)
177 {
178         GstDrmSrc *src;
179
180         src = GST_DRM_SRC (object);
181         //  1. deallocates the filename and uri
182         g_free (src->filename);
183         g_free (src->uri);
184         // 2. calls the parent class->finalize
185         G_OBJECT_CLASS (parent_class)->finalize (object);
186 }
187 /**
188  * This function does the following:
189  *  1. Checks the state
190  *  2. Checks the filename
191  *  3. Sets the filename
192  *
193  * @param   src    [in]   GstDrmSrc Structure
194  * @param   location    [in]   location of the file
195  *
196  * @return  gboolean   Returns TRUE on success and FALSE on ERROR
197  */
198 static gboolean gst_drm_src_set_location (GstDrmSrc * src, const gchar * location)
199 {
200         GstState state;
201
202         GST_OBJECT_LOCK (src);
203         //  1. Checks the state
204         state = GST_STATE (src);
205         if (state != GST_STATE_READY && state != GST_STATE_NULL)
206         {
207                 GST_DEBUG_OBJECT (src, "setting location in wrong state");
208                 GST_OBJECT_UNLOCK (src);
209                 return FALSE;
210         }
211         GST_OBJECT_UNLOCK (src);
212         g_free (src->filename);
213         g_free (src->uri);
214         //  2. Checks the filename
215         if (location == NULL)
216         {
217                 src->filename = NULL;
218                 src->uri = NULL;
219         }
220         else
221         {
222                 // 3. Sets the filename
223                 src->filename = g_strdup (location);
224                 src->uri = gst_uri_construct ("file", src->filename);
225         }
226         g_object_notify (G_OBJECT (src), "location");
227         gst_uri_handler_new_uri (GST_URI_HANDLER (src), src->uri);
228         return TRUE;
229 }
230 /**
231  * This function does the following:
232  *  1. Sets the location of the file.
233  *
234  * @param   object    [in]   GObject Structure
235  * @param   prop_id    [in]   id of the property
236  * @param   value    [in]   property value
237  * @param   pspec    [in]  GParamSpec Structure
238  *
239  * @return  void
240  */
241 static void gst_drm_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec)
242 {
243         GstDrmSrc *src;
244
245         g_return_if_fail (GST_IS_DRM_SRC (object));
246         src = GST_DRM_SRC (object);
247         switch (prop_id)
248         {
249                 //  1. Sets the location of the file.
250                 case ARG_LOCATION:
251                         gst_drm_src_set_location (src, g_value_get_string (value));
252                         break;
253                 default:
254                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
255                         break;
256         }
257 }
258 /**
259  * This function does the following:
260  *  1. Provides the location of the file.
261  *  2. Provides the file descriptor.
262  *
263  * @param   object    [in]   GObject Structure
264  * @param   prop_id    [in]   id of the property
265  * @param   value    [out]   property value
266  * @param   pspec    [in]  GParamSpec Structure
267  *
268  * @return  void
269  */
270 static void gst_drm_src_get_property (GObject * object, guint prop_id, GValue * value,GParamSpec * pspec)
271 {
272         GstDrmSrc *src;
273
274         g_return_if_fail (GST_IS_DRM_SRC (object));
275         src = GST_DRM_SRC (object);
276         switch (prop_id)
277         {
278                 //  1. Provides the location of the file.
279                 case ARG_LOCATION:
280                         g_value_set_string (value, src->filename);
281                         break;
282                 // 2. Provides the file descriptor.
283                 case ARG_FD:
284                         g_value_set_int (value, src->fd);
285                         break;
286                 case IS_DRM:
287                         g_value_set_boolean(value, src->drm_file);
288                         break;
289                 default:
290                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
291                         break;
292         }
293 }
294 /**
295  * This function does the following:
296  *  1. Seeks to the specified position for DRM file.
297  *  2. Allocates a buffer to push the data for DRM file.
298  *  3. Reads from the file and sets the related params for DRM file.
299  *
300  * @param   i_pDrmSrc    [in]   GstDrmSrc Structure
301  * @param   i_uiOffset    [in]   offset of the file to seek
302  * @param   length    [in]   size of the data in bytes
303  * @param   o_pBbuffer    [out]   GstBuffer to hold the contents
304  *
305  * @return  GstFlowReturn   Returns GST_FLOW_OK on success and ERROR on failure
306  */
307 static GstFlowReturn  gst_drm_src_create_read_drm_file (GstDrmSrc* i_pDrmSrc, guint64 i_uiOffset, guint length, GstBuffer ** o_pBbuffer)
308 {
309         GstBuffer *buf = NULL;
310         unsigned int readSize;
311         DRM_RESULT in_res = DRM_RESULT_SUCCESS;
312 PROFILE_FUNC_BEGIN;
313         // 1. Seeks to the specified position for DRM file.
314         if (G_UNLIKELY (i_pDrmSrc->read_position != i_uiOffset))
315         {
316                 in_res =drm_svc_seek_file(i_pDrmSrc->hfile, i_uiOffset, DRM_SEEK_SET);
317
318                 if(in_res  != DRM_RESULT_SUCCESS)
319                         goto FAILED;
320
321                 i_pDrmSrc->read_position = i_uiOffset;
322         }
323         // 2. Allocates a buffer to push the data for DRM file.
324         buf = gst_buffer_new_and_alloc (length);
325         if(buf == NULL)
326         {
327                 LOG_TRACE("Exit on error");
328                 return GST_FLOW_ERROR;
329         }
330         // 3. Reads from the file and sets the related params for DRM file.
331         in_res = drm_svc_read_file(i_pDrmSrc->hfile, GST_BUFFER_DATA(buf), length, &readSize);
332
333         if (in_res != DRM_RESULT_SUCCESS)
334                 goto FAILED;
335
336         if(readSize <= 0)
337         {
338                 LOG_TRACE("Exit on error");
339                 return GST_FLOW_ERROR;
340         }
341
342         #if 0 // Drm service can give lesser size block than requested thing.
343         if (G_UNLIKELY ((guint) readSize < length && i_pDrmSrc->seekable))
344         {
345                 GST_ELEMENT_ERROR (i_pDrmSrc, RESOURCE, READ, (NULL),("unexpected end of file."));
346                 gst_buffer_unref (buf);
347                 return GST_FLOW_ERROR;
348         }
349         #endif
350
351         if (G_UNLIKELY (readSize == 0 && length > 0))
352         {
353                 GST_DEBUG ("non-regular file hits EOS");
354                 gst_buffer_unref (buf);
355                 return GST_FLOW_UNEXPECTED;
356         }
357         length = readSize;
358         GST_BUFFER_SIZE (buf) = length;
359         GST_BUFFER_OFFSET (buf) = i_uiOffset;
360         GST_BUFFER_OFFSET_END (buf) = i_uiOffset + length;
361         *o_pBbuffer = buf;
362         i_pDrmSrc->read_position += length;
363 PROFILE_FUNC_END;
364
365         return GST_FLOW_OK;
366
367 FAILED:
368         {
369                 GST_ELEMENT_ERROR (i_pDrmSrc, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
370                 return GST_FLOW_ERROR;
371         }
372 }
373 /**
374  * This function does the following:
375  *  1. Seeks to the specified position.
376  *  2. Allocates a buffer to push the data
377  *  3. Reads from the file and sets the related params
378  *
379  * @param   src    [in]   GstDrmSrc Structure
380  * @param   offset    [in]   offset of the file to seek
381  * @param   length    [in]   size of the data in bytes
382  * @param   buffer    [out]   GstBuffer to hold the contents
383  *
384  * @return  GstFlowReturn   Returns GST_FLOW_OK on success and ERROR on failure
385  */
386 static GstFlowReturn gst_drm_src_create_read (GstDrmSrc * src, guint64 offset, guint length, GstBuffer ** buffer)
387 {
388         int ret;
389         GstBuffer *buf;
390         // 1. Seeks to the specified position.
391         if (G_UNLIKELY (src->read_position != offset))
392         {
393                 off_t res;
394                 res = lseek (src->fd, offset, SEEK_SET);
395                 if (G_UNLIKELY (res < 0 || res != offset))
396                 {
397                         GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
398                         return GST_FLOW_ERROR;
399                 }
400                 src->read_position = offset;
401         }
402         // 2. Allocates a buffer to push the data
403         buf = gst_buffer_new_and_alloc (length);
404         GST_LOG_OBJECT (src, "Reading %d bytes", length);
405         // 3. Reads from the file and sets the related params
406         ret = read (src->fd, GST_BUFFER_DATA (buf), length);
407         if (G_UNLIKELY (ret < 0))
408         {
409                 GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
410                 gst_buffer_unref (buf);
411                 return GST_FLOW_ERROR;
412         }
413         if (G_UNLIKELY ((guint) ret < length && src->seekable))
414         {
415                 GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),("unexpected end of file."));
416                 gst_buffer_unref (buf);
417                 return GST_FLOW_ERROR;
418         }
419         if (G_UNLIKELY (ret == 0 && length > 0))
420         {
421                 GST_DEBUG ("non-regular file hits EOS");
422                 gst_buffer_unref (buf);
423                 return GST_FLOW_UNEXPECTED;
424         }
425         length = ret;
426         GST_BUFFER_SIZE (buf) = length;
427         GST_BUFFER_OFFSET (buf) = offset;
428         GST_BUFFER_OFFSET_END (buf) = offset + length;
429         *buffer = buf;
430         src->read_position += length;
431         return GST_FLOW_OK;
432 }
433 /**
434  * This function does the following:
435  *  1. Calls DRM file read chain method for drm files.
436  *  2. Calls normal file read chain method for standard files.
437  *
438  * @param   basesrc    [in]   BaseSrc Structure
439  * @param   size    [out]   Size of the file
440  *
441  * @return  gboolean   Returns TRUE on success and FALSE on ERROR
442  */
443 static GstFlowReturn gst_drm_src_create (GstBaseSrc * basesrc, guint64 offset, guint length, GstBuffer ** buffer)
444 {
445         GstDrmSrc *src = GST_DRM_SRC (basesrc);
446
447         if (src->is_playready && src->event_posted == FALSE) {
448                 GstTagList *tags = NULL;
449                 GST_DEBUG_OBJECT (src, "posting playready tags");
450                 tags =  gst_tag_list_new_full (GST_TAG_PLAYREADY, src->filename, NULL);
451                 if (tags) {
452                         GstPad* src_pad = gst_element_get_static_pad (src, "src");
453                         if (src_pad) {
454                                 src->event_posted = gst_pad_push_event (src_pad, gst_event_new_tag (tags) );
455                                 GST_DEBUG_OBJECT (src, "posting tags returns [%d]", src->event_posted);
456                                 gst_object_unref (src_pad);
457                         }
458                 }
459         }
460
461         // 1. Calls DRM file read chain method for drm files.
462         if(src->drm_file == TRUE)
463                 return gst_drm_src_create_read_drm_file (src, offset, length, buffer);
464         // 2. Calls normal file read chain method for standard files.
465         return gst_drm_src_create_read (src, offset, length, buffer);
466 }
467 /**
468  *
469  * @param   basesrc    [in]   BaseSrc Structure
470  *
471  * @return  gboolean   Returns TRUE if the file is seekable and FALSE if the file is not seekable
472  */
473 static gboolean gst_drm_src_is_seekable (GstBaseSrc * basesrc)
474 {
475         GstDrmSrc *src = GST_DRM_SRC (basesrc);
476         return src->seekable;
477 }
478 /**
479  * This function does the following:
480  *  1. Gets the filesize for drm file by using seek oprations
481  *  2. Gets the file size for standard file by using statistics
482  *
483  * @param   basesrc    [in]   BaseSrc Structure
484  * @param   size    [in]   Size of the file
485  *
486  * @return  gboolean   Returns TRUE on success and FALSE on ERROR
487  */
488 static gboolean gst_drm_src_get_size (GstBaseSrc * basesrc, guint64 * size)
489 {
490         struct stat stat_results;
491         GstDrmSrc *src;
492         src = GST_DRM_SRC (basesrc);
493         //  1. Gets the filesize for drm file by using seek oprations
494         if(src->drm_file==TRUE)
495         {
496                 drm_svc_seek_file(src->hfile, 0, DRM_SEEK_END);
497                 *size = drm_svc_tell_file(src->hfile);
498                 drm_svc_seek_file(src->hfile, 0, DRM_SEEK_SET);
499                 src->read_position = 0;
500                 return TRUE;
501         }
502         if (!src->seekable)
503         {
504                 return FALSE;
505         }
506         // 2. Gets the file size for standard file by using statistics
507         if (fstat (src->fd, &stat_results) < 0)
508                 return FALSE;
509         *size = stat_results.st_size;
510         return TRUE;
511 }
512 /**
513  * This function does the following:
514  *  1. Checks the filename
515  *  2. Opens the file and check statistics of the file
516  *  3. Checks whether DRM file or not.
517  *  4. Checks the DRM file type (supports only for OMA) if it is DRM
518  *  5. Opens the DRM file if it is DRM
519  *  6. Gets the DRM_FILE_HANDLE and sets the drm, seekable and regular flag.
520  *  7. Checks the seeking for standard files
521  *
522  * @param   basesrc    [in]   BaseSrc Structure
523  *
524  * @return  gboolean   Returns TRUE on success and FALSE on ERROR
525  */
526 static gboolean gst_drm_src_start (GstBaseSrc * basesrc)
527 {
528         GstDrmSrc *src = GST_DRM_SRC (basesrc);
529         struct stat stat_results;
530         DRM_BOOL res = DRM_TRUE;
531         DRM_FILE_TYPE type = DRM_FILE_TYPE_NONE;
532         DRM_RESULT in_res = DRM_RESULT_SUCCESS;
533         off_t ret;
534 PROFILE_FUNC_BEGIN;
535         // 1. Checks the filename
536         if (src->filename == NULL || src->filename[0] == '\0')
537         {
538                 GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND,("No file name specified for reading."), (NULL));
539                 return FALSE;
540         }
541         // 2. Opens the file and check statistics of the file
542         GST_INFO_OBJECT (src, "opening file %s", src->filename);
543         src->fd = open (src->filename, O_RDONLY | O_BINARY);
544         if (src->fd < 0)
545         {
546                 if(errno == ENOENT)
547                 {
548                         GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL),("No such file \"%s\"", src->filename));
549                         return FALSE;
550                 }
551                 GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("Could not open file \"%s\" for reading.", src->filename), GST_ERROR_SYSTEM);
552                 return FALSE;
553         }
554         if (fstat (src->fd, &stat_results) < 0)
555         {
556                 GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("Could not get info on \"%s\".", src->filename), (NULL));
557                 close (src->fd);
558                 return FALSE;
559         }
560         if (S_ISDIR (stat_results.st_mode))
561         {
562                 GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("\"%s\" is a directory.", src->filename), (NULL));
563                 close (src->fd);
564                 return FALSE;
565         }
566         if (S_ISSOCK (stat_results.st_mode))
567         {
568                 GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("File \"%s\" is a socket.", src->filename), (NULL));
569                 close (src->fd);
570                 return FALSE;
571         }
572         src->read_position = 0;
573         /* DRM Related code */
574         // 3. Checks whether DRM file or not.
575 PROFILE_BLOCK_BEGIN("drmstart");
576         res = drm_svc_is_drm_file(src->filename);
577         if(res == DRM_TRUE)
578                 type = drm_svc_get_drm_type(src->filename);
579         GST_LOG_OBJECT (src, "is_drm=[%d], drm_type=[%d]", res, type);
580
581         /* We handles as DRM file if it is drm with OMA type */
582         if(res == DRM_TRUE && type == DRM_FILE_TYPE_OMA)
583         {
584 #if 0 // Do not check here.
585                 // 4. Checks the DRM file type (supports only for OMA) if it is DRM
586                 if(drm_svc_get_drm_type(src->filename) != DRM_FILE_TYPE_OMA)
587                 {
588                         GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("File \"%s\" is not OMA DRM.", src->filename), (NULL));
589                         return FALSE;
590                 }
591 #endif
592
593                 // 5. Opens the DRM file if it is DRM
594                 PROFILE_BLOCK_BEGIN("drmopen");
595                 in_res=drm_svc_open_file(src->filename, DRM_PERMISSION_PLAY, &(src->hfile));
596                 if(in_res != DRM_RESULT_SUCCESS)
597                 {
598                         GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("File \"%s\" open fail.", src->filename), (NULL));
599                         return FALSE;
600                 }
601                 PROFILE_BLOCK_END("drmopen");
602
603                 // 6. Gets the DRM_FILE_HANDLE and sets the drm, seekable and regular flags.
604                 res = drm_svc_is_drm_file_handle(src->hfile);
605                 if(res == DRM_TRUE)
606                 {
607                         drm_svc_seek_file(src->hfile, 0, DRM_SEEK_END);
608                         drm_svc_seek_file(src->hfile, 0, DRM_SEEK_SET);
609                 }
610                 src->seekable   = TRUE;
611                 src->is_regular = TRUE;
612                 src->drm_file   = TRUE;
613 PROFILE_BLOCK_END("drmstart");
614
615                 LOG_TRACE("Exit");
616                 return TRUE;
617         }
618
619         if(res == DRM_TRUE && type == DRM_FILE_TYPE_PLAYREADY) {
620                 src->is_playready = TRUE;
621                 src->event_posted = FALSE;
622         }
623
624         // 7. Checks the seeking for standard files
625         if (S_ISREG (stat_results.st_mode))
626                 src->is_regular = TRUE;
627         ret = lseek (src->fd, 0, SEEK_END);
628         if (res < 0)
629         {
630                 GST_LOG_OBJECT (src, "disabling seeking, not in mmap mode and lseek "
631                         "failed: %s", g_strerror (errno));
632                 src->seekable = FALSE;
633         }
634         else
635         {
636                 src->seekable = TRUE;
637         }
638         lseek (src->fd, 0, SEEK_SET);
639         src->seekable = src->seekable && src->is_regular;
640         PROFILE_FUNC_END;
641         return TRUE;
642 }
643 /**
644  * This function does the following:
645  *  1. Closes the file desciptor and resets the flags
646  *
647  * @param   basesrc    [in]   BaseSrc Structure
648  *
649  * @return  gboolean   Returns TRUE on success and FALSE on ERROR
650  */
651 static gboolean gst_drm_src_stop (GstBaseSrc * basesrc)
652 {
653         GstDrmSrc *src = GST_DRM_SRC (basesrc);
654
655         if (src->hfile) {
656                 drm_svc_close_file(src->hfile);
657                 src->hfile = NULL;
658         }
659         // 1. Closes the file desciptor and resets the flags
660         if(src->fd > 0)
661                 close (src->fd);
662         src->fd = 0;
663         src->is_regular = FALSE;
664         src->event_posted = FALSE;
665         src->is_playready = FALSE;
666 //      PROFILE_SHOW_RESULT;
667         return TRUE;
668 }
669 /**
670  *
671  * @param   void
672  *
673  * @return  GstURIType   Returns GST_URI_SRC
674  */
675
676 static GstURIType gst_drm_src_uri_get_type (void)
677 {
678         return GST_URI_SRC;
679 }
680
681 /**
682  * This function does the following:
683  *  1. Defines the list of protocols
684  *
685  * @param   void
686  *
687  * @return  gchar **   Returns the protocol list
688  */
689
690 static gchar ** gst_drm_src_uri_get_protocols (void)
691 {
692         static gchar *protocols[] = { "file", NULL };
693         return protocols;
694 }
695 /**
696  *
697  * @param   handler [in] GstURIHandler structure
698  *
699  * @return  gchar*   Returns the uri
700  */
701 static const gchar * gst_drm_src_uri_get_uri (GstURIHandler *handler)
702 {
703         GstDrmSrc *src = GST_DRM_SRC (handler);
704         return src->uri;
705 }
706 /**
707  * This function does the following:
708  *  1. Checks the protocol
709  *  2. Checks the whether it is absolute or not
710  *  3 sets the location
711  *
712  * @param   handler [in] GstURIHandler structure
713  * @param   uri [in] uri string
714  *
715  * @return  gboolean   Returns TRUE on success and FALSE on Error
716  */
717 static gboolean gst_drm_src_uri_set_uri (GstURIHandler *handler, const gchar * uri)
718 {
719         gchar *protocol, *location;
720         gboolean ret;
721         GstDrmSrc *src = GST_DRM_SRC (handler);
722         // 1. Checks the protocol
723         protocol = gst_uri_get_protocol (uri);
724         if (strcmp (protocol, "file") != 0)
725         {
726                 g_free (protocol);
727                 return FALSE;
728         }
729         g_free (protocol);
730         if (g_str_has_prefix (uri, "file://localhost/"))
731         {
732                 char *tmp;
733                 tmp = g_strconcat ("file://", uri + 16, NULL);
734                 location = gst_uri_get_location (tmp);
735                 g_free (tmp);
736         }
737         else if (strcmp (uri, "file://") == 0)
738         {
739                 gst_drm_src_set_location (src, NULL);
740                 return TRUE;
741         }
742         else
743         {
744                 location = gst_uri_get_location (uri);
745         }
746         if (!location)
747                 return FALSE;
748         // 2. Checks the whether it is absolute or not
749         if (!g_path_is_absolute (location))
750         {
751                 g_free (location);
752                 return FALSE;
753         }
754         // 3 sets the location
755         ret = gst_drm_src_set_location (src, location);
756         g_free (location);
757         return ret;
758 }
759 /**
760  * This function does the following:
761  *  1. Assignes the function pointer for URI related stuff
762  *
763  * @param   g_iface [in] an interface to URI handler
764  * @param   iface_data [in] a gpointer
765  *
766  * @return  void
767  */
768 static void gst_drm_src_uri_handler_init (gpointer g_iface, gpointer iface_data)
769 {
770         GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
771         // 1. Assigning the function pointer for URI related stuff
772         iface->get_type = gst_drm_src_uri_get_type;
773         iface->get_protocols = gst_drm_src_uri_get_protocols;
774         iface->get_uri = gst_drm_src_uri_get_uri;
775         iface->set_uri = gst_drm_src_uri_set_uri;
776 }
777 /**
778  * This function does the following:
779  *  1. Registers an element as drmsrc
780  *
781  * @param   i_pPlugin [in] a plug-in structure
782  *
783  * @return  gboolean TRUE on SUCCESS and FALSE on Error
784  */
785 static gboolean plugin_init(GstPlugin* i_pPlugin)
786 {
787         return gst_element_register(i_pPlugin, "drmsrc", GST_RANK_NONE, GST_TYPE_DRM_SRC);;
788 }
789 /**
790  * This function does the following:
791  *  1. plugin defination
792  *
793  */
794 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
795                                                  GST_VERSION_MINOR,
796                                                  "drmsrc",
797                                                  "Plugin to read data from standad/DRM File",
798                                                  plugin_init,
799                                                  VERSION,
800                                                  "LGPL",
801                                                  "Samsung Electronics Co",
802                                                  "http://www.samsung.com/")
803