Add TIZEN_FEATURE_STREAMING define
[platform/core/api/mediademuxer.git] / src / port_gst / mediademuxer_port_gst.c
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  * @file mediademuxer_port_gst.c
19  * @brief Handling for GStreamer Port, defined function and there implementation
20  */
21
22 #include <mm_debug.h>
23 #include <unistd.h>
24 #include <mediademuxer_error.h>
25 #include <mediademuxer_private.h>
26 #include <mediademuxer_port.h>
27 #include <mediademuxer_port_gst.h>
28 #include <media_packet_internal.h>
29
30 static int gst_demuxer_init(MMHandleType *pHandle);
31 static int gst_demuxer_prepare(MMHandleType pHandle, char *uri);
32 static int gst_demuxer_get_data_count(MMHandleType pHandle, int *count);
33 static int gst_demuxer_set_track(MMHandleType pHandle, int track);
34 static int gst_demuxer_start(MMHandleType pHandle);
35 static int gst_demuxer_read_sample(MMHandleType pHandle,
36                         media_packet_h *outbuf, int track_indx);
37 static int gst_demuxer_get_track_info(MMHandleType pHandle,
38                         media_format_h *format, int index);
39 static int gst_demuxer_seek(MMHandleType pHandle, gint64 pos1);
40 static int gst_demuxer_unset_track(MMHandleType pHandle, int track);
41 static int gst_demuxer_stop(MMHandleType pHandle);
42 static int gst_demuxer_unprepare(MMHandleType pHandle);
43 static int gst_demuxer_destroy(MMHandleType pHandle);
44 static int gst_set_error_cb(MMHandleType pHandle,
45                         gst_error_cb callback, void *user_data);
46 static int gst_set_eos_cb(MMHandleType pHandle,
47                         gst_eos_cb callback, void *user_data);
48 static int __gst_eos_callback(int track_num, void *user_data);
49
50 static gint __gst_handle_core_error(mdgst_handle_t *gst_handle, int code);
51 static gint __gst_handle_library_error(mdgst_handle_t *gst_handle, int code);
52 static gint __gst_handle_resource_error(mdgst_handle_t *gst_handle, int code);
53 static gint __gst_handle_stream_error(mdgst_handle_t *gst_handle, GError *error, GstMessage *message);
54 static gint __gst_transform_gsterror(mdgst_handle_t *gst_handle, GstMessage *message, GError *error);
55
56 /* Media Demuxer API common */
57 static media_port_demuxer_ops def_demux_ops = {
58         .n_size = 0,
59         .init = gst_demuxer_init,
60         .prepare = gst_demuxer_prepare,
61         .get_track_count = gst_demuxer_get_data_count,
62         .set_track = gst_demuxer_set_track,
63         .start = gst_demuxer_start,
64         .get_track_info = gst_demuxer_get_track_info,
65         .read_sample = gst_demuxer_read_sample,
66         .seek = gst_demuxer_seek,
67         .unset_track = gst_demuxer_unset_track,
68         .stop = gst_demuxer_stop,
69         .unprepare = gst_demuxer_unprepare,
70         .destroy = gst_demuxer_destroy,
71         .set_error_cb = gst_set_error_cb,
72         .set_eos_cb = gst_set_eos_cb,
73 };
74
75 static gint __gst_handle_core_error(mdgst_handle_t *gst_handle, int code)
76 {
77         gint trans_err = MEDIADEMUXER_ERROR_NONE;
78
79         MEDIADEMUXER_CHECK_NULL(gst_handle);
80
81         switch (code) {
82         case GST_CORE_ERROR_MISSING_PLUGIN:
83                 return MEDIADEMUXER_ERROR_NOT_SUPPORTED;
84         case GST_CORE_ERROR_STATE_CHANGE:
85         case GST_CORE_ERROR_SEEK:
86         case GST_CORE_ERROR_NOT_IMPLEMENTED:
87         case GST_CORE_ERROR_FAILED:
88         case GST_CORE_ERROR_TOO_LAZY:
89         case GST_CORE_ERROR_PAD:
90         case GST_CORE_ERROR_THREAD:
91         case GST_CORE_ERROR_NEGOTIATION:
92         case GST_CORE_ERROR_EVENT:
93         case GST_CORE_ERROR_CAPS:
94         case GST_CORE_ERROR_TAG:
95         case GST_CORE_ERROR_CLOCK:
96         case GST_CORE_ERROR_DISABLED:
97         default:
98                 trans_err =  MEDIADEMUXER_ERROR_INVALID_OPERATION;
99                 break;
100         }
101
102         return trans_err;
103 }
104
105 static gint __gst_handle_library_error(mdgst_handle_t *gst_handle, int code)
106 {
107         gint trans_err = MEDIADEMUXER_ERROR_NONE;
108
109         MEDIADEMUXER_CHECK_NULL(gst_handle);
110
111         switch (code) {
112         case GST_LIBRARY_ERROR_FAILED:
113         case GST_LIBRARY_ERROR_TOO_LAZY:
114         case GST_LIBRARY_ERROR_INIT:
115         case GST_LIBRARY_ERROR_SHUTDOWN:
116         case GST_LIBRARY_ERROR_SETTINGS:
117         case GST_LIBRARY_ERROR_ENCODE:
118         default:
119                 trans_err =  MEDIADEMUXER_ERROR_INVALID_OPERATION;
120                 break;
121         }
122
123         return trans_err;
124 }
125
126
127 static gint __gst_handle_resource_error(mdgst_handle_t *gst_handle, int code)
128 {
129         gint trans_err = MEDIADEMUXER_ERROR_NONE;
130
131         MEDIADEMUXER_CHECK_NULL(gst_handle);
132
133         switch (code) {
134         case GST_RESOURCE_ERROR_NO_SPACE_LEFT:
135                 trans_err = MEDIADEMUXER_ERROR_OUT_OF_MEMORY;
136                 break;
137         case GST_RESOURCE_ERROR_WRITE:
138         case GST_RESOURCE_ERROR_FAILED:
139         case GST_RESOURCE_ERROR_SEEK:
140         case GST_RESOURCE_ERROR_TOO_LAZY:
141         case GST_RESOURCE_ERROR_BUSY:
142         case GST_RESOURCE_ERROR_OPEN_WRITE:
143         case GST_RESOURCE_ERROR_OPEN_READ_WRITE:
144         case GST_RESOURCE_ERROR_CLOSE:
145         case GST_RESOURCE_ERROR_SYNC:
146         case GST_RESOURCE_ERROR_SETTINGS:
147         default:
148                 trans_err = MEDIADEMUXER_ERROR_RESOURCE_LIMIT;
149                 break;
150         }
151
152         return trans_err;
153 }
154
155 static gint __gst_handle_stream_error(mdgst_handle_t *gst_handle, GError *error, GstMessage *message)
156 {
157         gint trans_err = MEDIADEMUXER_ERROR_NONE;
158
159         MEDIADEMUXER_CHECK_NULL(gst_handle);
160         MEDIADEMUXER_CHECK_NULL(error);
161         MEDIADEMUXER_CHECK_NULL(message);
162
163         switch (error->code) {
164         case GST_STREAM_ERROR_FAILED:
165         case GST_STREAM_ERROR_TYPE_NOT_FOUND:
166         case GST_STREAM_ERROR_DECODE:
167         case GST_STREAM_ERROR_WRONG_TYPE:
168         case GST_STREAM_ERROR_DECRYPT:
169         case GST_STREAM_ERROR_DECRYPT_NOKEY:
170         case GST_STREAM_ERROR_CODEC_NOT_FOUND:
171                 trans_err = __gst_transform_gsterror(gst_handle, message, error);
172                 break;
173
174         case GST_STREAM_ERROR_NOT_IMPLEMENTED:
175         case GST_STREAM_ERROR_TOO_LAZY:
176         case GST_STREAM_ERROR_ENCODE:
177         case GST_STREAM_ERROR_DEMUX:
178         case GST_STREAM_ERROR_MUX:
179         case GST_STREAM_ERROR_FORMAT:
180         default:
181                 trans_err = MEDIADEMUXER_ERROR_INVALID_OPERATION;
182                 break;
183         }
184
185         return trans_err;
186 }
187
188 static gint __gst_transform_gsterror(mdgst_handle_t *gst_handle, GstMessage *message, GError *error)
189 {
190         gchar *src_element_name = NULL;
191         GstElement *src_element = NULL;
192         GstElementFactory *factory = NULL;
193         const gchar *klass = NULL;
194
195         MEDIADEMUXER_CHECK_NULL(gst_handle);
196
197         src_element = GST_ELEMENT_CAST(message->src);
198         if (!src_element)
199                 goto INTERNAL_ERROR;
200
201         src_element_name = GST_ELEMENT_NAME(src_element);
202         if (!src_element_name)
203                 goto INTERNAL_ERROR;
204
205         factory = gst_element_get_factory(src_element);
206         if (!factory)
207                 goto INTERNAL_ERROR;
208
209         klass = gst_element_factory_get_klass(factory);
210         if (!klass)
211                 goto INTERNAL_ERROR;
212
213         MD_I("error code=%d, msg=%s, src element=%s, class=%s\n",
214                         error->code, error->message, src_element_name, klass);
215
216         switch (error->code) {
217         case GST_STREAM_ERROR_DECODE:
218         case GST_STREAM_ERROR_FAILED:
219                 return MEDIADEMUXER_ERROR_INVALID_PARAMETER;
220                 break;
221
222         case GST_STREAM_ERROR_CODEC_NOT_FOUND:
223         case GST_STREAM_ERROR_TYPE_NOT_FOUND:
224         case GST_STREAM_ERROR_WRONG_TYPE:
225                 return MEDIADEMUXER_ERROR_NOT_SUPPORTED;
226                 break;
227
228         default:
229                 return MEDIADEMUXER_ERROR_INVALID_PARAMETER;
230                 break;
231         }
232
233         return MEDIADEMUXER_ERROR_INVALID_PARAMETER;
234
235 INTERNAL_ERROR:
236         return MEDIADEMUXER_ERROR_INVALID_PARAMETER;
237 }
238
239
240 int gst_mediademxer_port_register(media_port_demuxer_ops *pOps)
241 {
242         MEDIADEMUXER_FENTER();
243         int ret = MD_ERROR_NONE;
244         MEDIADEMUXER_CHECK_NULL(pOps);
245         def_demux_ops.n_size = sizeof(def_demux_ops);
246
247         memcpy((char *)pOps + sizeof(pOps->n_size),
248                (char *)&def_demux_ops + sizeof(def_demux_ops.n_size),
249                pOps->n_size - sizeof(pOps->n_size));
250
251         MEDIADEMUXER_FLEAVE();
252         return ret;
253 }
254
255 static int gst_demuxer_init(MMHandleType *pHandle)
256 {
257         MEDIADEMUXER_FENTER();
258         int ret = MD_ERROR_NONE;
259         mdgst_handle_t *new_mediademuxer = NULL;
260         new_mediademuxer = (mdgst_handle_t *)g_malloc(sizeof(mdgst_handle_t));
261         MD_I("gst_demuxer_init allocating new_mediademuxer:%p\n", new_mediademuxer);
262         if (!new_mediademuxer) {
263                 MD_E("Cannot allocate memory for demuxer\n");
264                 ret = MD_ERROR;
265                 goto ERROR;
266         }
267         memset(new_mediademuxer, 0, sizeof(mdgst_handle_t));
268         new_mediademuxer->is_prepared = false;
269         (new_mediademuxer->info).num_audio_track = 0;
270         (new_mediademuxer->info).num_video_track = 0;
271         (new_mediademuxer->info).num_subtitle_track = 0;
272         (new_mediademuxer->info).num_other_track = 0;
273         (new_mediademuxer->info).head = NULL;
274         *pHandle = (MMHandleType)new_mediademuxer;
275         new_mediademuxer->total_tracks = 0;
276         MEDIADEMUXER_FLEAVE();
277         return ret;
278 ERROR:
279         MEDIADEMUXER_FLEAVE();
280         return ret;
281 }
282
283 gboolean __gst_bus_call(GstBus *bus, GstMessage *msg, gpointer data)
284 {
285         mdgst_handle_t *gst_handle = (mdgst_handle_t *)data;
286         MEDIADEMUXER_FENTER();
287         int ret = MD_ERROR_NONE;
288         switch (GST_MESSAGE_TYPE(msg)) {
289         case GST_MESSAGE_EOS: {
290                         MD_I("EOS Reached");
291                 }
292                 break;
293         case GST_MESSAGE_ERROR: {
294                         GError *error = NULL;
295                         gst_message_parse_error(msg, &error, NULL);
296                         if (!error) {
297                                 MD_I("GST error message parsing failed");
298                                 break;
299                         }
300
301                         if (error->domain == GST_STREAM_ERROR)
302                                 ret = __gst_handle_stream_error(gst_handle, error, msg);
303                         else if (error->domain == GST_RESOURCE_ERROR)
304                                 ret = __gst_handle_resource_error(gst_handle, error->code);
305                         else if (error->domain == GST_LIBRARY_ERROR)
306                                 ret = __gst_handle_library_error(gst_handle, error->code);
307                         else if (error->domain == GST_CORE_ERROR)
308                                 ret = __gst_handle_core_error(gst_handle, error->code);
309                         else
310                                 MD_W("Unexpected error has occured");
311
312                         if (gst_handle->user_cb[_GST_EVENT_TYPE_ERROR]) {
313                                 ((mediademuxer_error_cb)gst_handle->user_cb[_GST_EVENT_TYPE_ERROR])
314                                         (ret, gst_handle->user_data[_GST_EVENT_TYPE_ERROR]);
315                                         MD_W("Error : (ox%08x)", ret);
316                         }
317                         MD_E("Error: %s\n", error->message);
318                         g_error_free(error);
319                 }
320                 break;
321         default:
322                 break;
323         }
324         MEDIADEMUXER_FLEAVE();
325         return ret;
326 }
327
328 static void __gst_no_more_pad(GstElement *element, gpointer data)
329 {
330         MEDIADEMUXER_FENTER();
331         mdgst_handle_t *gst_handle = (mdgst_handle_t *)data;
332         int loop_track;
333         track_info *head_track = &(gst_handle->info);
334         track *head = head_track->head;
335         gst_handle->selected_tracks =
336             (bool *) g_malloc(sizeof(bool) * (gst_handle->total_tracks));
337         MD_I("Allocating %p to core->selected_tracks \n", gst_handle->selected_tracks);
338         if (!gst_handle->selected_tracks) {
339                 MD_E("[%s]Memory allocation failed\n", __FUNCTION__);
340                 return;
341         } else {
342                 for (loop_track = 0; loop_track < gst_handle->total_tracks;
343                      loop_track++)
344                         gst_handle->selected_tracks[loop_track] = false;
345         }
346         MD_I("Number of video tracks are %d\n", head_track->num_video_track);
347         MD_I("Number of audio tracks are %d\n", head_track->num_audio_track);
348         MD_I("Number of subtitle tracks are %d\n",
349              head_track->num_subtitle_track);
350         MD_I("Number of other tracks are %d\n", head_track->num_other_track);
351         while (head) {
352                 MD_I("track caps[%s]\n", head->caps_string);
353                 head = head->next;
354         }
355         gst_handle->is_prepared = true;
356         MD_I("core->is_prepared: ");
357         gst_handle->is_prepared ? MD_I("true\n") : MD_I("false\n");
358         MEDIADEMUXER_FLEAVE();
359 }
360
361 void __gst_free_stuct(track **head)
362 {
363         MEDIADEMUXER_FENTER();
364         track *temp = NULL;
365         temp = *head;
366         while (temp) {
367
368                 if (temp->pad) {
369                         MD_I("unref GST_PAD %p\n", temp->pad);
370                         gst_object_unref(temp->pad);
371                 }
372                 if (temp->caps) {
373                         MD_I("unref GST_PAD caps %p\n", temp->caps);
374                         gst_caps_unref(temp->caps);
375                 }
376                 if (temp->caps_string) {
377                         MD_I("deallocate GST_PAD caps_string  %p\n",
378                              temp->caps_string);
379                         g_free(temp->caps_string);
380                 }
381                 if (temp->format) {
382                         MD_I("unref media_format  %p\n", temp->format);
383                         media_format_unref(temp->format);
384                 }
385                 if (temp->next) {
386                         track *next = temp->next;
387                         MD_I("deallocate memory %p\n", temp);
388                         free(temp);
389                         temp = next;
390                 } else {
391                         MD_I("deallocate memory %p\n", temp);
392                         free(temp);
393                         temp = NULL;
394                         *head = NULL;
395                 }
396         }
397         MEDIADEMUXER_FLEAVE();
398 }
399
400 int __gst_add_track_info(GstPad *pad, GstCaps *caps, track **head,
401                                                 GstElement *pipeline)
402 {
403         MEDIADEMUXER_FENTER();
404         GstPad *apppad = NULL;
405         GstPad *queue_sink_pad = NULL;
406         GstPad *queue_src_pad = NULL;
407         GstCaps *outcaps = NULL;
408         GstPad *parse_sink_pad = NULL;
409         GstElement *parse_element = NULL;
410         GstElement *id3tag = NULL;
411         GstPad *id3_sinkpad = NULL;
412         GstPad *id3_srcpad = NULL;
413         track *temp = NULL;
414
415         temp = (track *)(g_malloc(sizeof(track)));
416         if (!temp) {
417                 MD_E("Not able to allocate memory");
418                 return MD_ERROR;
419         } else {
420                 MD_I("allocate memory %p", temp);
421         }
422         memset(temp, 0x00, sizeof(track));
423
424         temp->pad = gst_object_ref(pad);
425         temp->caps = gst_caps_ref(caps);
426         temp->caps_string = gst_caps_to_string(caps);
427         temp->next = NULL;
428         temp->format = NULL;
429         temp->need_codec_data = TRUE;
430
431         MD_I("track caps(%s)", temp->caps_string ? temp->caps_string : "NULL");
432
433         /* Link demuxer - queue */
434         temp->queue = gst_element_factory_make("queue", NULL);
435         if (!temp->queue) {
436                 MD_E("factory not able to make queue");
437                 goto ERROR;
438         }
439
440         if (!gst_bin_add(GST_BIN(pipeline), temp->queue)) {
441                 gst_object_unref(temp->queue);
442                 MD_E("fail add queue in pipeline");
443                 goto ERROR;
444         }
445         MD_I("added queue element in pipeline.");
446
447         queue_sink_pad = gst_element_get_static_pad(temp->queue, "sink");
448         if (!queue_sink_pad) {
449                 MD_E("sink pad of queue not avaible");
450                 goto ERROR;
451         }
452
453         MEDIADEMUXER_SET_STATE(temp->queue, GST_STATE_PAUSED, ERROR);
454         MEDIADEMUXER_LINK_PAD(pad, queue_sink_pad, ERROR);
455
456         temp->appsink = gst_element_factory_make("appsink", NULL);
457         if (!temp->appsink) {
458                 MD_E("factory not able to make appsink");
459                 goto ERROR;
460         }
461
462         if (!gst_bin_add(GST_BIN(pipeline), temp->appsink)) {
463                 gst_object_unref(temp->appsink);
464                 MD_E("fail add appsink in pipeline");
465                 goto ERROR;
466         }
467         MD_I("added appsink element in pipeline.");
468
469         gst_app_sink_set_max_buffers((GstAppSink *) temp->appsink, (guint) 0);
470         gst_app_sink_set_drop((GstAppSink *) temp->appsink, true);
471         MEDIADEMUXER_SET_STATE(temp->appsink, GST_STATE_PAUSED, ERROR);
472
473         queue_src_pad = gst_element_get_static_pad(temp->queue, "src");
474         if (!queue_src_pad) {
475                 MD_E("src pad of queue not avaible");
476                 goto ERROR;
477         }
478         apppad = gst_element_get_static_pad(temp->appsink, "sink");
479         if (!apppad) {
480                 MD_E("sink pad of appsink not avaible");
481                 goto ERROR;
482         }
483         /* Check for type video and it should be h264 */
484         if (temp->caps_string && strstr(temp->caps_string, "video")) {
485                 if (strstr(temp->caps_string, "h264")) {
486                         parse_element = gst_element_factory_make("h264parse", NULL);
487                         if (!parse_element) {
488                                 MD_E("factory not able to make h264parse");
489                                 goto ERROR;
490                         }
491                 } else if (strstr(temp->caps_string, "mpeg")) {
492                         parse_element = gst_element_factory_make("mpeg4videoparse", NULL);
493                         if (!parse_element) {
494                                 MD_E("factory not able to make h264parse");
495                                 goto ERROR;
496                         }
497                         g_object_set(G_OBJECT(parse_element), "config-interval", 1, NULL);
498                 }
499
500                 if (parse_element) {
501                         MD_I("add video parse element(%s).", GST_ELEMENT_NAME(parse_element));
502                         if (!gst_bin_add(GST_BIN(pipeline), parse_element)) {
503                                 gst_object_unref(parse_element);
504                                 MD_E("fail add video parse(%s) in pipeline", GST_ELEMENT_NAME(parse_element));
505                                 goto ERROR;
506                         }
507                         parse_sink_pad = gst_element_get_static_pad(parse_element, "sink");
508                         if (!parse_sink_pad) {
509                                 MD_E("sink pad of video parse(%s) not available", GST_ELEMENT_NAME(parse_element));
510                                 goto ERROR;
511                         }
512                         MEDIADEMUXER_SET_STATE(parse_element, GST_STATE_PAUSED, ERROR);
513                         /* Link demuxer pad with sink pad of parse element */
514                         MEDIADEMUXER_LINK_PAD(queue_src_pad, parse_sink_pad, ERROR);
515
516                         if (strstr(temp->caps_string, "h264")) {
517                                 outcaps = gst_caps_new_simple("video/x-h264", "stream-format", G_TYPE_STRING, "byte-stream", NULL);
518                                 gst_element_link_filtered(parse_element, temp->appsink, outcaps);
519                                 gst_caps_unref(outcaps);
520                         } else if (strstr(temp->caps_string, "mpeg")) {
521                                 gst_element_link(parse_element, temp->appsink);
522                         } else {
523                                 MEDIADEMUXER_LINK_PAD(queue_src_pad, apppad, ERROR);
524                         }
525                 } else {
526                         MEDIADEMUXER_LINK_PAD(queue_src_pad, apppad, ERROR);
527                 }
528         } else if (temp->caps_string && (strstr(temp->caps_string, "audio") || strstr(temp->caps_string, "x-id3"))) {
529                 if (strstr(temp->caps_string, "audio/mpeg")) {
530                         int mpegversion = 0;
531                         GstStructure *structure = NULL;
532                         structure = gst_caps_get_structure(temp->caps, 0);
533                         gst_structure_get_int (structure, "mpegversion", &mpegversion);
534                         if (mpegversion == 2 || mpegversion == 4) {
535                                 parse_element = gst_element_factory_make("aacparse", NULL);
536                                 if (!parse_element) {
537                                         MD_E("factory not able to make aacparse");
538                                         goto ERROR;
539                                 }
540                         } else if (mpegversion == 1) {
541                                 parse_element = gst_element_factory_make("mpegaudioparse", NULL);
542                                 if (!parse_element) {
543                                         MD_E("factory not able to make mpegaudioparse");
544                                         goto ERROR;
545                                 }
546                         }
547                 } else if (strstr(temp->caps_string, "application/x-id3")) {
548                         id3tag = gst_element_factory_make("id3demux", NULL);
549                         if (!id3tag) {
550                                 MD_E("factory not able to make id3demux");
551                                 goto ERROR;
552                         }
553                         if (!gst_bin_add(GST_BIN(pipeline), id3tag)) {
554                                 gst_object_unref(id3tag);
555                                 MD_E("fail add id3tag element in pipeline");
556                                 goto ERROR;
557                         }
558                         id3_sinkpad = gst_element_get_static_pad(id3tag, "sink");
559                         if (!id3_sinkpad) {
560                                 MD_E("fail to get id3demux sink pad.\n");
561                                 goto ERROR;
562                         }
563                         MEDIADEMUXER_LINK_PAD(queue_src_pad, id3_sinkpad, ERROR);
564                         MEDIADEMUXER_SET_STATE(id3tag, GST_STATE_PAUSED, ERROR);
565                         id3_srcpad = gst_element_get_static_pad(id3tag, "src");
566                         if (!id3_srcpad) {
567                                 MD_E("fail to get id3demux src pad.\n");
568                                 goto ERROR;
569                         }
570                         parse_element = gst_element_factory_make("mpegaudioparse", NULL);
571                         if (!parse_element) {
572                                 MD_E("factory not able to make mpegaudioparse");
573                                 goto ERROR;
574                         }
575                 } else if (strstr(temp->caps_string, "audio/x-amr-nb-sh")
576                                 || strstr(temp->caps_string, "audio/x-amr-wb-sh")) {
577                         parse_element = gst_element_factory_make("amrparse", NULL);
578                         if (!parse_element) {
579                                 MD_E("factory not able to make amrparse");
580                                 goto ERROR;
581                         }
582                 } else if (strstr(temp->caps_string, "audio/x-wav")) {
583                         parse_element = gst_element_factory_make("wavparse", NULL);
584                         if (!parse_element) {
585                                 MD_E("factory not able to make wavparse");
586                                 goto ERROR;
587                         }
588                 } else if (strstr(temp->caps_string, "audio/x-flac")) {
589                         parse_element = gst_element_factory_make("flacparse", NULL);
590                         if (!parse_element) {
591                                 MD_E("factory not able to make flacparse");
592                                 goto ERROR;
593                         }
594                 }
595
596                 if (parse_element) {
597                         MD_I("add audio parse element(%s).", GST_ELEMENT_NAME(parse_element));
598                         if (!gst_bin_add(GST_BIN(pipeline), parse_element)) {
599                                 gst_object_unref(parse_element);
600                                 MD_E("fail add audio parse(%s) in pipeline", GST_ELEMENT_NAME(parse_element));
601                                 goto ERROR;
602                         }
603                         parse_sink_pad = gst_element_get_static_pad(parse_element, "sink");
604                         if (!parse_sink_pad) {
605                                 MD_E("sink pad of audio parse(%s) not available", GST_ELEMENT_NAME(parse_element));
606                                 goto ERROR;
607                         }
608                         MEDIADEMUXER_SET_STATE(parse_element, GST_STATE_PAUSED, ERROR);
609
610                         /* Link demuxer pad with sink pad of parse element */
611                         if (id3tag)
612                                 MEDIADEMUXER_LINK_PAD(id3_srcpad, parse_sink_pad, ERROR);
613                         else
614                                 MEDIADEMUXER_LINK_PAD(queue_src_pad, parse_sink_pad, ERROR);
615
616                         /* Link src pad with appSink element */
617                         gst_element_link(parse_element, temp->appsink);
618                 } else {
619                         MEDIADEMUXER_LINK_PAD(queue_src_pad, apppad, ERROR);
620                 }
621         } else {
622                 MEDIADEMUXER_LINK_PAD(queue_src_pad, apppad, ERROR);
623         }
624         /* gst_pad_link(pad, fpad) */
625         if (*head == NULL) {
626                 *head = temp;
627         } else {
628                 track *prev = *head;
629                 while (prev->next)
630                         prev = prev->next;
631                 prev->next = temp;
632         }
633         if (queue_sink_pad)
634                 gst_object_unref(queue_sink_pad);
635         if (queue_src_pad)
636                 gst_object_unref(queue_src_pad);
637         if (apppad)
638                 gst_object_unref(apppad);
639         if (parse_sink_pad)
640                 gst_object_unref(parse_sink_pad);
641         if (id3_sinkpad)
642                 gst_object_unref(id3_sinkpad);
643         if (id3_srcpad)
644                 gst_object_unref(id3_srcpad);
645         MEDIADEMUXER_FLEAVE();
646         return MD_ERROR_NONE;
647
648 ERROR:
649         __gst_free_stuct(&temp);
650         if (queue_sink_pad)
651                 gst_object_unref(queue_sink_pad);
652         if (queue_src_pad)
653                 gst_object_unref(queue_src_pad);
654         if (apppad)
655                 gst_object_unref(apppad);
656         if (parse_sink_pad)
657                 gst_object_unref(parse_sink_pad);
658         if (id3_sinkpad)
659                 gst_object_unref(id3_sinkpad);
660         if (id3_srcpad)
661                 gst_object_unref(id3_srcpad);
662         __gst_free_stuct(head);
663         MEDIADEMUXER_FLEAVE();
664         return MD_ERROR;
665 }
666
667 static void __gst_on_pad_added(GstElement *element, GstPad *pad, gpointer data)
668 {
669         MEDIADEMUXER_FENTER();
670         MD_I("Dynamic pad created, linking demuxer/decoder\n");
671         track *tmp = NULL;
672         mdgst_handle_t *gst_handle = (mdgst_handle_t *)data;
673         track_info *head_track = &(gst_handle->info);
674         GstCaps *caps = gst_pad_get_current_caps(pad);
675         if (!caps) {
676                 MD_E("caps is NULL");
677                 return;
678         }
679         gst_handle->total_tracks++;
680         if (__gst_add_track_info(pad, caps, &(head_track->head), gst_handle->pipeline)
681             != MD_ERROR_NONE) {
682                 MD_E("unable to added track info");
683                 head_track->num_audio_track = 0;
684                 head_track->num_video_track = 0;
685                 head_track->num_subtitle_track = 0;
686                 head_track->num_other_track = 0;
687                 gst_caps_unref(caps);
688                 __gst_free_stuct(&(head_track->head));
689                 return;
690         }
691         gst_caps_unref(caps);
692         tmp = head_track->head;
693         while (tmp->next)
694                 tmp = tmp->next;
695         if (!tmp || !tmp->caps_string) {
696                 MD_I("trak or trak caps_string is NULL\n");
697                 MEDIADEMUXER_FLEAVE();
698                 return;
699         }
700         if (tmp->caps_string[0] == 'v') {
701                 MD_I("found Video Pad\n");
702                 (head_track->num_video_track)++;
703         } else if (tmp->caps_string[0] == 'a') {
704                 MD_I("found Audio Pad\n");
705                 (head_track->num_audio_track)++;
706         } else if (tmp->caps_string[0] == 's') {
707                 MD_I("found subtitle(or Text) Pad\n");
708                 (head_track->num_subtitle_track)++;
709         } else {
710                 MD_W("found Pad, caps: %s\n", tmp->caps_string);
711                 (head_track->num_other_track)++;
712         }
713         MEDIADEMUXER_FLEAVE();
714 }
715
716 static int __gst_create_audio_only_pipeline(gpointer data,  GstCaps *caps)
717 {
718         MEDIADEMUXER_FENTER();
719         mdgst_handle_t *gst_handle = (mdgst_handle_t *)data;
720         GstPad *pad = NULL;
721         track_info *head_track = &(gst_handle->info);
722
723         gst_handle->is_valid_container = true;
724
725         pad = gst_element_get_static_pad(gst_handle->typefind, "src");
726         if (!pad) {
727                 MD_E("fail to get typefind src pad.\n");
728                 goto ERROR;
729         }
730
731         gst_handle->total_tracks++;
732         if (__gst_add_track_info(pad, caps, &(head_track->head), gst_handle->pipeline) != MD_ERROR_NONE) {
733                 MD_E("unable to added track info");
734                 head_track->num_audio_track = 0;
735                 head_track->num_video_track = 0;
736                 head_track->num_subtitle_track = 0;
737                 head_track->num_other_track = 0;
738                 __gst_free_stuct(&(head_track->head));
739                 goto ERROR;
740         }
741
742         (head_track->num_audio_track)++;
743
744         /* unref pads */
745         if (pad)
746                 gst_object_unref(pad);
747
748         /* In the case of audio only, there is no gst_handle->demux. So we pass NULL */
749         __gst_no_more_pad(NULL, data);
750
751         MEDIADEMUXER_FLEAVE();
752         return MD_ERROR_NONE;
753
754 ERROR:
755         gst_handle->is_valid_container = false;
756
757         if (pad)
758                 gst_object_unref(pad);
759
760         MEDIADEMUXER_FLEAVE();
761         return MD_ERROR;
762 }
763
764 static void __gst_cb_typefind(GstElement *tf, guint probability,
765                                         GstCaps *caps, gpointer data)
766 {
767         MEDIADEMUXER_FENTER();
768         mdgst_handle_t *gst_handle = (mdgst_handle_t *)data;
769         GstPad *pad = NULL;
770         GstPad *demuxer_pad = NULL;
771         GstPad *fake_pad = NULL;
772         gchar *type;
773         type = gst_caps_to_string(caps);
774         if (type) {
775                 MD_I("Media type %s found, probability %d%%\n", type, probability);
776                 if (strstr(type, "quicktime") || (strstr(type, "audio/x-m4a")) || strstr(type, "x-3gp")
777                                 || strstr(type, "ogg") || strstr(type, "flv") || strstr(type, "x-msvideo")) {
778                         gst_handle->is_valid_container = true;
779                         if (strstr(type, "ogg"))
780                                 gst_handle->demux = gst_element_factory_make("oggdemux", NULL);
781                         else if (strstr(type, "flv"))
782                                 gst_handle->demux = gst_element_factory_make("flvdemux", NULL);
783                         else if (strstr(type, "x-msvideo"))
784                                 gst_handle->demux = gst_element_factory_make("avidemux", NULL);
785                         else
786                                 gst_handle->demux = gst_element_factory_make("qtdemux", NULL);
787
788                         if (!gst_handle->demux) {
789                                 gst_handle->is_valid_container = false;
790                                 MD_E("factory not able to create qtdemux\n");
791                                 goto ERROR;
792                         } else {
793                                 g_signal_connect(gst_handle->demux, "pad-added",
794                                                                 G_CALLBACK(__gst_on_pad_added), gst_handle);
795                                 g_signal_connect(gst_handle->demux, "no-more-pads",
796                                                                 G_CALLBACK(__gst_no_more_pad), gst_handle);
797                                 gst_bin_add_many(GST_BIN(gst_handle->pipeline),
798                                                                 gst_handle->demux, NULL);
799                                 pad = gst_element_get_static_pad(gst_handle->typefind, "src");
800                                 if (!pad) {
801                                         MD_E("fail to get typefind src pad.\n");
802                                         goto ERROR;
803                                 }
804                                 demuxer_pad = gst_element_get_static_pad(gst_handle->demux, "sink");
805                                 if (!demuxer_pad) {
806                                         MD_E("fail to get qtdemuc sink pad.\n");
807                                         goto ERROR;
808                                 }
809                                 fake_pad = gst_element_get_static_pad(gst_handle->fakesink, "sink");
810                                 if (!fake_pad) {
811                                         MD_E("fail to get fakesink sink pad.\n");
812                                         goto ERROR;
813                                 }
814                                 gst_pad_unlink(pad, fake_pad);
815                                 MEDIADEMUXER_LINK_PAD(pad, demuxer_pad, ERROR);
816                                 MEDIADEMUXER_SET_STATE(gst_handle->demux,
817                                                                         GST_STATE_PAUSED, ERROR);
818                                 if (pad)
819                                         gst_object_unref(pad);
820                                 if (demuxer_pad)
821                                         gst_object_unref(demuxer_pad);
822                                 if (fake_pad)
823                                         gst_object_unref(fake_pad);
824                         }
825                 } else if ((strstr(type, "adts"))
826                            || (strstr(type, "audio/mpeg"))
827                            || (strstr(type, "audio/x-wav"))
828                            || (strstr(type, "audio/x-flac"))
829                            || (strstr(type, "application/x-id3"))
830                            || (strstr(type, "audio/x-amr-nb-sh"))
831                            || (strstr(type, "audio/x-amr-wb-sh"))) {
832                         MD_I("Audio only format is found\n");
833                         pad = gst_element_get_static_pad(gst_handle->typefind, "src");
834                         if (!pad) {
835                                 MD_E("fail to get typefind src pad.\n");
836                                 goto ERROR;
837                         }
838                         fake_pad = gst_element_get_static_pad(gst_handle->fakesink, "sink");
839                         if (!fake_pad) {
840                                 MD_E("fail to get fakesink sink pad.\n");
841                                 goto ERROR;
842                         }
843                         gst_pad_unlink(pad, fake_pad);
844                         if (pad)
845                                 gst_object_unref(pad);
846                         if (fake_pad)
847                                 gst_object_unref(fake_pad);
848
849                         __gst_create_audio_only_pipeline(data, caps);
850                 } else {
851                         gst_handle->is_valid_container = false;
852                         MD_E("Not supported container %s\n", type);
853                 }
854                 g_free(type);
855         }
856         MEDIADEMUXER_FLEAVE();
857         return;
858 ERROR:
859         gst_handle->is_valid_container = false;
860         if (type)
861                 g_free(type);
862         if (pad)
863                 gst_object_unref(pad);
864         if (demuxer_pad)
865                 gst_object_unref(demuxer_pad);
866         if (fake_pad)
867                 gst_object_unref(fake_pad);
868         MEDIADEMUXER_FLEAVE();
869         return;
870 }
871
872 static int _gst_create_pipeline(mdgst_handle_t *gst_handle, char *uri)
873 {
874         MEDIADEMUXER_FENTER();
875         int ret = MD_ERROR_NONE;
876         GstBus *bus = NULL;
877         char *path = NULL;
878 #ifdef TIZEN_FEATURE_STREAMING
879         int remote_streaming = 0;
880 #endif
881         /* Initialize GStreamer */
882         /* Note: Replace the arguments of gst_init to pass the command line args to GStreamer. */
883         gst_init(NULL, NULL);
884
885         /* Create the empty pipeline */
886         gst_handle->pipeline = gst_pipeline_new("Demuxer Gst pipeline");
887         if (!gst_handle->pipeline) {
888                 MD_E("pipeline create fail");
889                 ret = MD_ERROR;
890                 goto ERROR;
891         }
892
893         /* Create the elements */
894         if ((path = strstr(uri, "http://"))) {
895 #ifdef TIZEN_FEATURE_STREAMING
896                 gst_handle->filesrc  = gst_element_factory_make("souphttpsrc", NULL);
897                 remote_streaming = 1;
898                 MD_I("Source is http stream. \n");
899 #else
900                 MD_I("Source is http stream. Didn't support streaming\n");
901                 goto ERROR;
902 #endif
903         } else {
904                 gst_handle->filesrc = gst_element_factory_make("filesrc", NULL);
905                 MD_I("Source is file stream \n");
906         }
907         if (!gst_handle->filesrc) {
908                 MD_E("filesrc creation failed");
909                 ret = MD_ERROR;
910                 goto ERROR;
911         }
912
913         /* Modify the source's properties */
914 #ifdef TIZEN_FEATURE_STREAMING
915         if (remote_streaming == 1)
916                 g_object_set(G_OBJECT(gst_handle->filesrc), "location", uri, NULL);
917         else
918 #endif
919                 g_object_set(G_OBJECT(gst_handle->filesrc), "location", uri + 7, NULL);
920         gst_handle->typefind = gst_element_factory_make("typefind", NULL);
921         if (!gst_handle->typefind) {
922                 MD_E("typefind creation failed");
923                 ret = MD_ERROR;
924                 goto ERROR;
925         }
926         g_signal_connect(gst_handle->typefind, "have-type",
927                                         G_CALLBACK(__gst_cb_typefind), gst_handle);
928         gst_handle->fakesink = gst_element_factory_make("fakesink", NULL);
929         if (!gst_handle->fakesink) {
930                 MD_E("fakesink creation failed");
931                 ret = MD_ERROR;
932                 goto ERROR;
933         }
934
935         /* Build the pipeline */
936         gst_bin_add_many(GST_BIN(gst_handle->pipeline),
937                                                 gst_handle->filesrc,
938                                                 gst_handle->typefind,
939                                                 gst_handle->fakesink,
940                                                 NULL);
941         gst_element_link_many(gst_handle->filesrc,
942                                                         gst_handle->typefind,
943                                                         gst_handle->fakesink,
944                                                         NULL);
945
946         /* connect signals, bus watcher */
947         bus = gst_pipeline_get_bus(GST_PIPELINE(gst_handle->pipeline));
948         gst_handle->bus_watch_id = gst_bus_add_watch(bus, __gst_bus_call, gst_handle);
949         gst_handle->thread_default = g_main_context_get_thread_default();
950         gst_object_unref(GST_OBJECT(bus));
951
952         /* set pipeline state to PAUSED */
953         MEDIADEMUXER_SET_STATE(gst_handle->pipeline, GST_STATE_PAUSED, ERROR);
954
955         int count = 0;
956         while (gst_handle->is_prepared != true) {
957                 count++;
958                 usleep(POLLING_INTERVAL);
959                 MD_I("Inside while loop\n");
960                 if (count > POLLING_INTERVAL) {
961                         MD_E("Error occure\n");
962                         ret = MD_ERROR;
963                         break;
964                 }
965         }
966
967         MEDIADEMUXER_FLEAVE();
968         return ret;
969 ERROR:
970         MEDIADEMUXER_FLEAVE();
971         return ret;
972 }
973
974 static int gst_demuxer_prepare(MMHandleType pHandle, char *uri)
975 {
976         MEDIADEMUXER_FENTER();
977         int ret = MD_ERROR_NONE;
978         MEDIADEMUXER_CHECK_NULL(pHandle);
979         mdgst_handle_t *new_mediademuxer = (mdgst_handle_t *)pHandle;
980
981         MD_I("gst_demuxer_prepare Creating pipeline %p", new_mediademuxer);
982         ret = _gst_create_pipeline(new_mediademuxer, uri);
983         if (ret != MD_ERROR_NONE) {
984                 MD_E("_gst_create_pipeline() failed. returned %d\n", ret);
985                 goto ERROR;
986         }
987         MEDIADEMUXER_FLEAVE();
988         return ret;
989 ERROR:
990         MEDIADEMUXER_FLEAVE();
991         return ret;
992 }
993
994 static int gst_demuxer_get_data_count(MMHandleType pHandle, int *count)
995 {
996         MEDIADEMUXER_FENTER();
997         int ret = MD_ERROR_NONE;
998         MEDIADEMUXER_CHECK_NULL(pHandle);
999         mdgst_handle_t *new_mediademuxer = (mdgst_handle_t *)pHandle;
1000
1001         *count = (new_mediademuxer->info).num_video_track +
1002                         (new_mediademuxer->info).num_audio_track +
1003                         (new_mediademuxer->info).num_subtitle_track +
1004                         (new_mediademuxer->info).num_other_track;
1005         MEDIADEMUXER_FLEAVE();
1006         return ret;
1007 }
1008
1009 int _gst_set_appsink(track *temp, int index, int loop)
1010 {
1011         MEDIADEMUXER_FENTER();
1012         int ret = MD_ERROR_NONE;
1013         int count = 0;
1014
1015         while (count != index) {
1016                 temp = temp->next;
1017                 count++;
1018         }
1019         gst_app_sink_set_max_buffers((GstAppSink *)(temp->appsink), (guint) MAX_APP_BUFFER);
1020         gst_app_sink_set_drop((GstAppSink *)(temp->appsink), false);
1021         MEDIADEMUXER_FLEAVE();
1022         return ret;
1023 }
1024
1025 static int gst_demuxer_set_track(MMHandleType pHandle, int track)
1026 {
1027         MEDIADEMUXER_FENTER();
1028         int ret = MD_ERROR_NONE;
1029         MEDIADEMUXER_CHECK_NULL(pHandle);
1030         mdgst_handle_t *new_mediademuxer = (mdgst_handle_t *)pHandle;
1031
1032         MD_I("total_tracks (%d) :: selected  track (%d)", new_mediademuxer->total_tracks, track);
1033         if (track >= new_mediademuxer->total_tracks || track < 0) {
1034                 MD_E("total_tracks is less then selected track, So not support this track");
1035                 ret = MD_ERROR_INVALID_ARGUMENT;
1036                 goto ERROR;
1037         }
1038         new_mediademuxer->selected_tracks[track] = true;
1039         _gst_set_appsink((((mdgst_handle_t *)pHandle)->info).head, track,
1040                                         new_mediademuxer->total_tracks);
1041         MEDIADEMUXER_FLEAVE();
1042         return MD_ERROR_NONE;
1043 ERROR:
1044         MEDIADEMUXER_FLEAVE();
1045         return ret;
1046 }
1047
1048 static int _gst_unlink_unselected_track(track *temp, int index)
1049 {
1050         MEDIADEMUXER_FENTER();
1051         int ret = MD_ERROR_NONE;
1052         int count = 0;
1053         GstPad *queue_sink_pad = NULL;
1054         while (count != index) {
1055                 temp = temp->next;
1056                 count++;
1057         }
1058         queue_sink_pad = gst_element_get_static_pad(temp->queue, "sink");
1059         if (!queue_sink_pad) {
1060                 MD_E("queue_sink_pad of appsink not avaible\n");
1061                 return MD_ERROR;
1062         }
1063         if (gst_pad_unlink(temp->pad, queue_sink_pad) != TRUE)
1064                 MD_W("demuxer is already unlinked from queue for track %d\n", index);
1065
1066         gst_object_unref(queue_sink_pad);
1067         MEDIADEMUXER_FLEAVE();
1068         return ret;
1069 }
1070
1071 static int gst_demuxer_start(MMHandleType pHandle)
1072 {
1073         MEDIADEMUXER_FENTER();
1074         int ret = MD_ERROR_NONE;
1075         MEDIADEMUXER_CHECK_NULL(pHandle);
1076         mdgst_handle_t *gst_handle = (mdgst_handle_t *)pHandle;
1077
1078         int indx;
1079         for (indx = 0; indx < gst_handle->total_tracks; indx++) {
1080                 MD_I("track indx[%d] is marked as [%d]. (0- not selected, 1= selected)\n",
1081                         indx, gst_handle->selected_tracks[indx]);
1082                 /*
1083                 if (gst_handle->selected_tracks[indx] ==  false)
1084                         _gst_demuxer_unset(pHandle, indx);
1085                 */
1086                 if (gst_handle->selected_tracks[indx] != true) {
1087                         if (_gst_unlink_unselected_track((((mdgst_handle_t *)pHandle)->info).head, indx) != MD_ERROR_NONE) {
1088                                 MD_E("Failed to unlink unselected tracks\n");
1089                                 ret = MD_INTERNAL_ERROR;
1090                                 goto ERROR;
1091                         }
1092                 }
1093
1094         }
1095
1096         track_info *head_track = &(gst_handle->info);
1097         MD_I("Total Audio track=%d, Video track=%d, text track=%d\n",
1098                         head_track->num_audio_track, head_track->num_video_track,
1099                         head_track->num_subtitle_track);
1100
1101         track *temp = head_track->head;
1102         indx = 0;
1103         while (temp) {
1104                 MD_I("Got one element %p\n", temp->appsink);
1105                 if (gst_element_set_state(temp->appsink, GST_STATE_PLAYING) ==
1106                         GST_STATE_CHANGE_FAILURE) {
1107                         MD_E("Failed to set into PLAYING state");
1108                         ret = MD_INTERNAL_ERROR;
1109                         goto ERROR;
1110                 }
1111                 MD_I("set the state to playing\n");
1112                 indx++;
1113                 if (temp->next) {
1114                         track *next = temp->next;
1115                         temp = next;
1116                 } else {
1117                         temp = NULL;
1118                 }
1119         }
1120
1121         MD_I("gst_demuxer_start pipeine %p", gst_handle);
1122         MEDIADEMUXER_FLEAVE();
1123         return ret;
1124 ERROR:
1125         MEDIADEMUXER_FLEAVE();
1126         return ret;
1127 }
1128
1129 int _set_mime_text(media_format_h format, track *head)
1130 {
1131         MEDIADEMUXER_FENTER();
1132         int ret = MD_ERROR_NONE;
1133         GstStructure *struc = NULL;
1134         struc = gst_caps_get_structure(head->caps, 0);
1135         if (!struc) {
1136                 MD_E("cannot get structure from caps.\n");
1137                 goto ERROR;
1138         }
1139         if (gst_structure_has_name(struc, "text/x-raw")) {
1140                 if (media_format_set_text_mime(format, MEDIA_FORMAT_TEXT_MP4))
1141                         goto ERROR;
1142         } else {
1143                 MD_I("Text mime not supported so far\n");
1144                 goto ERROR;
1145         }
1146
1147         MEDIADEMUXER_FLEAVE();
1148         return ret;
1149 ERROR:
1150         MEDIADEMUXER_FLEAVE();
1151         return MD_ERROR;
1152 }
1153
1154 int _set_mime_video(media_format_h format, track *head)
1155 {
1156         MEDIADEMUXER_FENTER();
1157         int ret = MD_ERROR_NONE;
1158         GstStructure *struc = NULL;
1159         int src_width;
1160         int src_height;
1161         int frame_rate_numerator = 0;
1162         int frame_rate_denominator = 0;
1163         media_format_mimetype_e mime_type = MEDIA_FORMAT_MAX;
1164         struc = gst_caps_get_structure(head->caps, 0);
1165         if (!struc) {
1166                 MD_E("cannot get structure from caps.\n");
1167                 goto ERROR;
1168         }
1169         if (gst_structure_has_name(struc, "video/x-h264")) {
1170                 mime_type = MEDIA_FORMAT_H264_SP;
1171         } else if (gst_structure_has_name(struc, "video/x-h263")) {
1172                 mime_type = MEDIA_FORMAT_H263;
1173         } else if (gst_structure_has_name(struc, "video/mpeg")) {
1174                 mime_type = MEDIA_FORMAT_MPEG4_SP;
1175         } else {
1176                 MD_W("Video mime (%s) not supported so far\n", gst_structure_get_name(struc));
1177                 goto ERROR;
1178         }
1179         if (media_format_set_video_mime(format, mime_type)) {
1180                 MD_E("Unable to set video mime type (%x)\n", mime_type);
1181                 goto ERROR;
1182         }
1183         gst_structure_get_int(struc, "width", &src_width);
1184         gst_structure_get_int(struc, "height", &src_height);
1185         if (media_format_set_video_width(format, src_width)) {
1186                 MD_E("Unable to set video width\n");
1187                 goto ERROR;
1188         }
1189         if (media_format_set_video_height(format, src_height)) {
1190                 MD_E("Unable to set video height\n");
1191                 goto ERROR;
1192         }
1193         gst_structure_get_fraction(struc, "framerate",  &frame_rate_numerator, &frame_rate_denominator);
1194         if (media_format_set_video_frame_rate(format, frame_rate_numerator)) {
1195                 MD_E("Unable to set video frame rate\n");
1196                 goto ERROR;
1197         }
1198         MEDIADEMUXER_FLEAVE();
1199         return ret;
1200 ERROR:
1201         MEDIADEMUXER_FLEAVE();
1202         return MD_ERROR;
1203 }
1204
1205 int _set_mime_audio(media_format_h format, track *head)
1206 {
1207         MEDIADEMUXER_FENTER();
1208         int ret = MD_ERROR_NONE;
1209         GstStructure *struc = NULL;
1210         int rate = 0;
1211         int bit = 0;
1212         int channels = 0;
1213         int id3_flag = 0;
1214         const gchar *stream_format;
1215         media_format_mimetype_e mime_type = MEDIA_FORMAT_MAX;
1216
1217         struc = gst_caps_get_structure(head->caps, 0);
1218         if (!struc) {
1219                 MD_E("cannot get structure from caps.\n");
1220                 goto ERROR;
1221         }
1222
1223         if (gst_structure_has_name(struc, "application/x-id3"))
1224                 id3_flag = 1;
1225         if (gst_structure_has_name(struc, "audio/mpeg") || id3_flag) {
1226                 gint mpegversion;
1227                 int layer;
1228                 gst_structure_get_int(struc, "mpegversion", &mpegversion);
1229                 if (mpegversion == 4 || mpegversion == 2) {
1230                         mime_type = MEDIA_FORMAT_AAC_LC;
1231                         if (media_format_set_audio_mime(format, mime_type))
1232                                 goto ERROR;
1233                         stream_format = gst_structure_get_string(struc, "stream-format");
1234
1235                         if (strncmp(stream_format, "adts", 4) == 0)
1236                                 media_format_set_audio_aac_type(format, 1);
1237                         else
1238                                 media_format_set_audio_aac_type(format, 0);
1239
1240                 } else if (mpegversion == 1 || id3_flag) {
1241                         gst_structure_get_int(struc, "layer", &layer);
1242                         if ((layer == 3) || (id3_flag == 1)) {
1243                                 mime_type = MEDIA_FORMAT_MP3;
1244                         } else {
1245                                 MD_I("No Support for MPEG%d Layer %d media\n", mpegversion, layer);
1246                                 goto ERROR;
1247                         }
1248                 }
1249         } else if (gst_structure_has_name(struc, "audio/x-amr-nb-sh") ||
1250                 gst_structure_has_name(struc, "audio/x-amr-wb-sh")) {
1251                 if (gst_structure_has_name(struc, "audio/x-amr-nb-sh")) {
1252                         mime_type = MEDIA_FORMAT_AMR_NB;
1253                         rate = 8000;
1254                 } else {
1255                         mime_type = MEDIA_FORMAT_AMR_WB;
1256                         rate = 16000;
1257                 }
1258         } else if (gst_structure_has_name(struc, "audio/AMR")) {
1259                 mime_type = MEDIA_FORMAT_AMR_NB;
1260         } else if (gst_structure_has_name(struc, "audio/AMR-WB")) {
1261                 mime_type = MEDIA_FORMAT_AMR_WB;
1262         } else if (gst_structure_has_name(struc, "audio/x-wav")) {
1263                 mime_type = MEDIA_FORMAT_PCM;
1264         } else if (gst_structure_has_name(struc, "audio/x-flac")) {
1265                 mime_type = MEDIA_FORMAT_FLAC;
1266         } else if (gst_structure_has_name(struc, "audio/x-vorbis")) {
1267                 mime_type = MEDIA_FORMAT_VORBIS;
1268         } else {
1269                 MD_W("Audio mime (%s) not supported so far\n", gst_structure_get_name(struc));
1270                 goto ERROR;
1271         }
1272         if (media_format_set_audio_mime(format, mime_type))
1273                 goto ERROR;
1274         gst_structure_get_int(struc, "channels", &channels);
1275         if (channels == 0) {    /* default */
1276                 if (mime_type == MEDIA_FORMAT_AMR_NB || mime_type == MEDIA_FORMAT_AMR_WB)
1277                         channels = 1;
1278                 else
1279                         channels = 2;
1280         }
1281         if (media_format_set_audio_channel(format, channels))
1282                 goto ERROR;
1283         if (rate == 0)
1284                 gst_structure_get_int(struc, "rate", &rate);
1285         if (rate == 0)
1286                 rate = 44100;   /* default */
1287         if (media_format_set_audio_samplerate(format, rate))
1288                 goto ERROR;
1289         gst_structure_get_int(struc, "bit", &bit);
1290         if (bit == 0)
1291                 bit = 16;       /* default */
1292         if (media_format_set_audio_bit(format, bit))
1293                 goto ERROR;
1294         MEDIADEMUXER_FLEAVE();
1295         return ret;
1296 ERROR:
1297         MEDIADEMUXER_FLEAVE();
1298         return MD_ERROR;
1299 }
1300
1301 static int gst_demuxer_get_track_info(MMHandleType pHandle,
1302                                                         media_format_h *format, int index)
1303 {
1304         MEDIADEMUXER_FENTER();
1305         int ret = MD_ERROR_NONE;
1306         MEDIADEMUXER_CHECK_NULL(pHandle);
1307         mdgst_handle_t *new_mediademuxer = (mdgst_handle_t *)pHandle;
1308
1309         track *temp = NULL;
1310         int loop;
1311         int count = 0;
1312         temp = (new_mediademuxer->info).head;
1313         loop = (new_mediademuxer->info).num_video_track +
1314                         (new_mediademuxer->info).num_audio_track +
1315                         (new_mediademuxer->info).num_subtitle_track +
1316                         (new_mediademuxer->info).num_other_track;
1317         if (index >= loop || index < 0) {
1318                 MD_E("total tracks(loop) is less then selected track(index), So not support this track");
1319                 ret = MD_ERROR;
1320                 goto ERROR;
1321         }
1322
1323         while (count != index) {
1324                 temp = temp->next;
1325                 count++;
1326         }
1327         if (temp->format != NULL) {
1328                 ret = media_format_ref(temp->format);
1329                 if (ret != MEDIA_FORMAT_ERROR_NONE) {
1330                         MD_E("Mediaformat reference count increment failed. returned %d\n", ret);
1331                         ret = MD_INTERNAL_ERROR;
1332                         goto ERROR;
1333                 }
1334                 ret = media_format_make_writable(temp->format, format); /* copy the content */
1335                 if (ret != MEDIA_FORMAT_ERROR_NONE) {
1336                         MD_E("Mediaformat create copy failed. returned %d\n", ret);
1337                         media_format_unref(temp->format);
1338                         ret = MD_INTERNAL_ERROR;
1339                         goto ERROR;
1340                 }
1341                 MEDIADEMUXER_FLEAVE();
1342                 return ret;
1343         }
1344         ret = media_format_create(&(temp->format));
1345         if (ret != MEDIA_FORMAT_ERROR_NONE) {
1346                 MD_E("Mediaformat creation failed. returned %d\n", ret);
1347                 ret = MD_INTERNAL_ERROR;
1348                 goto ERROR;
1349         }
1350
1351         MD_I("CAPS for selected track [%d] is [%s]\n", index, temp->caps_string);
1352         MD_I("format ptr[%p]\n", temp->format);
1353         if (temp->caps_string[0] == 'a') {
1354                 MD_I("Setting for Audio \n");
1355                 _set_mime_audio(temp->format, temp);
1356         } else if (temp->caps_string[0] == 'v') {
1357                 MD_I("Setting for Video \n");
1358                 _set_mime_video(temp->format, temp);
1359         } else if (temp->caps_string[0] == 't') {
1360                 MD_I("Setting for Subtitle\n");
1361                 _set_mime_text(temp->format, temp);
1362         } else {
1363                 MD_W("Not supported so far (except audio, video and subtitle)\n");
1364         }
1365
1366         ret = media_format_ref(temp->format);   /* increment the ref to retain the original content */
1367         if (ret != MEDIA_FORMAT_ERROR_NONE) {
1368                 MD_E("Mediaformat reference count increment failed. returned %d\n", ret);
1369                 ret = MD_INTERNAL_ERROR;
1370                 goto ERROR;
1371         }
1372         ret = media_format_make_writable(temp->format, format); /* copy the content */
1373         if (ret != MEDIA_FORMAT_ERROR_NONE) {
1374                 MD_E("Mediaformat create copy failed. returned %d\n", ret);
1375                 media_format_unref(temp->format);
1376                 ret = MD_INTERNAL_ERROR;
1377                 goto ERROR;
1378         }
1379         MEDIADEMUXER_FLEAVE();
1380         return ret;
1381 ERROR:
1382         MEDIADEMUXER_FLEAVE();
1383         return ret;
1384 }
1385
1386 static int _gst_copy_buf_to_media_packet(media_packet_h out_pkt,
1387                                                         GstBuffer *buffer, GstBuffer *codec_data)
1388 {
1389         MEDIADEMUXER_FENTER();
1390         int ret = MD_ERROR_NONE;
1391         MEDIADEMUXER_CHECK_NULL(out_pkt);
1392         void *pkt_data;
1393         uint64_t size;
1394         GstMapInfo map;
1395
1396         if (!gst_buffer_map(buffer, &map, GST_MAP_READ)) {
1397                 MD_E("gst_buffer_map failed\n");
1398                 ret = MD_ERROR_UNKNOWN;
1399                 goto ERROR;
1400         }
1401         /* copy data */
1402         media_packet_get_buffer_size(out_pkt, &size);
1403         MD_I("Media packet Buffer capacity: %llu GST Buffer size = %d\n", size, map.size);
1404         if (size < (uint64_t)map.size) {
1405                 MD_W("Media packet Buffer capacity[%llu] is \
1406                         less than the GST Buffer size[%d]. Resizing...\n", size, map.size);
1407                 ret = media_packet_set_buffer_size(out_pkt, (uint64_t)map.size);
1408                 media_packet_get_buffer_size(out_pkt, &size);
1409                 MD_I("Media packet Buffer NEW  capacity: %llu \n", size);
1410         }
1411         if (media_packet_get_buffer_data_ptr(out_pkt, &pkt_data)) {
1412                 MD_E("unable to get the buffer pointer from media_packet_get_buffer_data_ptr\n");
1413                 ret = MD_ERROR_UNKNOWN;
1414                 goto ERROR;
1415         }
1416         memcpy((char *)pkt_data, map.data, map.size);
1417         if (media_packet_set_pts(out_pkt, GST_BUFFER_PTS(buffer))) {
1418                 MD_E("unable to set the pts\n");
1419                 ret = MD_ERROR_UNKNOWN;
1420                 goto ERROR;
1421         }
1422         if (media_packet_set_dts(out_pkt, GST_BUFFER_DTS(buffer))) {
1423                 MD_E("unable to set the dts\n");
1424                 ret = MD_ERROR_UNKNOWN;
1425                 goto ERROR;
1426         }
1427         if (media_packet_set_duration(out_pkt, GST_BUFFER_DURATION(buffer))) {
1428                 MD_E("unable to set the duration\n");
1429                 ret = MD_ERROR_UNKNOWN;
1430                 goto ERROR;
1431         }
1432         if (media_packet_set_buffer_size(out_pkt, gst_buffer_get_size(buffer))) {
1433                 MD_E("unable to set the buffer size\n");
1434                 ret = MD_ERROR_UNKNOWN;
1435                 goto ERROR;
1436         }
1437         if (!GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT)) {
1438                 if (media_packet_set_flags(out_pkt, MEDIA_PACKET_SYNC_FRAME)) {
1439                         MD_E("unable to set the buffer flag\n");
1440                         ret = MD_ERROR_UNKNOWN;
1441                         goto ERROR;
1442                 }
1443         }
1444         /* set codec data into media packet */
1445         if (codec_data) {
1446                 GstMapInfo codec_data_map;
1447                 if (!gst_buffer_map(codec_data, &codec_data_map, GST_MAP_READ)) {
1448                         MD_E("codec data buffer map failed\n");
1449                         ret = MD_ERROR_UNKNOWN;
1450                         goto ERROR;
1451                 }
1452                 if (media_packet_set_codec_data(out_pkt, (void *)codec_data_map.data,
1453                         (unsigned int)codec_data_map.size)) {
1454                         MD_E("unable to set the codec data\n");
1455                         ret = MD_ERROR_UNKNOWN;
1456                         gst_buffer_unmap(codec_data, &codec_data_map);
1457                         goto ERROR;
1458                 }
1459                 gst_buffer_unmap(codec_data, &codec_data_map);
1460
1461                 media_buffer_flags_e flags;
1462                 media_packet_get_flags(out_pkt, &flags);
1463                 media_packet_set_flags(out_pkt, flags | MEDIA_PACKET_CODEC_CONFIG);
1464         }
1465 ERROR:
1466         gst_buffer_unmap(buffer, &map);
1467         MEDIADEMUXER_FLEAVE();
1468         return ret;
1469 }
1470
1471 static int _gst_demuxer_create_eos_packet(media_format_h fmt, media_packet_h *outbuf)
1472 {
1473         media_packet_h mediabuf = NULL;
1474         int ret = MD_ERROR_NONE;
1475
1476         MEDIADEMUXER_FENTER();
1477         if (media_packet_create_alloc(fmt, NULL, NULL, &mediabuf)) {
1478                 MD_E("media_packet_create_alloc failed\n");
1479                 ret = MD_ERROR;
1480                 goto ERROR;
1481         }
1482
1483         if (media_packet_set_flags(mediabuf, MEDIA_PACKET_END_OF_STREAM)) {
1484                 MD_E("unable to set EOS flag\n");
1485                 ret = MD_ERROR_UNKNOWN;
1486                 goto ERROR;
1487         }
1488
1489         *outbuf = mediabuf;
1490         MEDIADEMUXER_FLEAVE();
1491
1492         return ret;
1493 ERROR:
1494         if (mediabuf)
1495                 media_packet_destroy(mediabuf);
1496         *outbuf = NULL;
1497         MEDIADEMUXER_FLEAVE();
1498         return ret;
1499 }
1500
1501 static int gst_demuxer_read_sample(MMHandleType pHandle,
1502                                                 media_packet_h *outbuf, int track_indx)
1503 {
1504         MEDIADEMUXER_FENTER();
1505         int ret = MD_ERROR_NONE;
1506         MEDIADEMUXER_CHECK_NULL(pHandle);
1507         mdgst_handle_t *demuxer = (mdgst_handle_t *)pHandle;
1508
1509         media_packet_h mediabuf = NULL;
1510         int indx = 0;
1511
1512         track *atrack = demuxer->info.head;
1513         if ((demuxer->selected_tracks)[track_indx] == false) {
1514                 MD_E("Track Not selected\n");
1515                 ret = MD_ERROR;
1516                 goto ERROR;
1517         }
1518         while (atrack) {
1519                 if (indx == track_indx)  /* Got the requird track details */
1520                         break;
1521                 if (atrack->next) {
1522                         track *next = atrack->next;
1523                         atrack = next;
1524                 } else {
1525                         MD_E("Invalid track Index\n");
1526                         ret = MD_ERROR_INVALID_ARGUMENT;
1527                         goto ERROR;
1528                 }
1529                 indx++;
1530         }
1531
1532         if (!atrack) {
1533                 MD_E("atrack is NULL\n");
1534                 goto ERROR;
1535         }
1536
1537         if (indx != track_indx) {
1538                 MD_E("Invalid track Index\n");
1539                 ret = MD_ERROR_INVALID_ARGUMENT;
1540                 goto ERROR;
1541         }
1542         GstElement *sink = atrack->appsink;
1543         GstSample *sample = NULL;
1544
1545         sample = gst_app_sink_pull_sample((GstAppSink *) sink);
1546         if (sample == NULL) {
1547                 if (gst_app_sink_is_eos((GstAppSink *) sink)) {
1548                         MD_W("End of stream (EOS) reached, triggering the eos callback\n");
1549                         ret = MD_ERROR_NONE;
1550                         *outbuf = NULL;
1551                         __gst_eos_callback(track_indx, demuxer);
1552
1553                         //Make EOS packet
1554                         _gst_demuxer_create_eos_packet(atrack->format, outbuf);
1555                         return ret;
1556                 } else {
1557                         MD_E("gst_demuxer_read_sample failed\n");
1558                         *outbuf = NULL;
1559                         ret = MD_ERROR_UNKNOWN;
1560                         return ret;
1561                 }
1562         }
1563
1564         if (media_packet_create_alloc(atrack->format, NULL, NULL, &mediabuf)) {
1565                 MD_E("media_packet_create_alloc failed\n");
1566                 ret = MD_ERROR;
1567                 goto ERROR;
1568         }
1569
1570         GstBuffer *buffer = gst_sample_get_buffer(sample);
1571         if (buffer == NULL) {
1572                 MD_E("gst_sample_get_buffer returned NULL pointer\n");
1573                 ret = MD_ERROR_UNKNOWN;
1574                 goto ERROR;
1575         }
1576
1577         GstBuffer *codec_data_buffer = NULL;
1578         /* Need to Check : Only the first frame need set codec_data, what about Resolution changed instance ...*/
1579         if (atrack->need_codec_data) {
1580                 atrack->need_codec_data = FALSE;
1581                 /* Create the codec data and pass to _gst_copy_buf_to_media_packet() to add into the media packet */
1582                 GstStructure *structure = NULL;
1583                 const GValue *value = NULL;
1584
1585                 structure = gst_caps_get_structure(atrack->caps, 0);
1586                 /* get codec data from caps*/
1587                 value = gst_structure_get_value(structure, "codec_data");
1588                 if (value)
1589                         codec_data_buffer = gst_value_get_buffer(value);
1590         }
1591
1592         /* Fill the media_packet with proper information */
1593         ret = _gst_copy_buf_to_media_packet(mediabuf, buffer, codec_data_buffer);
1594         gst_sample_unref(sample);
1595         *outbuf = mediabuf;
1596
1597         MEDIADEMUXER_FLEAVE();
1598         return ret;
1599 ERROR:
1600         if (mediabuf)
1601                 media_packet_destroy(mediabuf);
1602         *outbuf = NULL;
1603         MEDIADEMUXER_FLEAVE();
1604         return ret;
1605 }
1606
1607 static int gst_demuxer_seek(MMHandleType pHandle, gint64 pos1)
1608 {
1609         MEDIADEMUXER_FENTER();
1610         MEDIADEMUXER_CHECK_NULL(pHandle);
1611         mdgst_handle_t *gst_handle = (mdgst_handle_t *)pHandle;
1612
1613         gint64 pos = 0;
1614         gdouble rate = 1;
1615         track_info *head_track = &(gst_handle->info);
1616         track *temp = head_track->head;
1617         track *temp_track = head_track->head;
1618         int indx = 0;
1619
1620         /* Setting each appsink to paused state before seek */
1621         while (temp_track) {
1622                 if (gst_handle->selected_tracks[indx] == true) {
1623                         if (gst_element_set_state(temp_track->appsink, GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE) {
1624                                 MD_E("Failed to set into PAUSED state");
1625                                 goto ERROR;
1626                         }
1627                         MD_I("set the state to paused\n");
1628                 }
1629                 indx++;
1630                 if (temp_track->next) {
1631                         track *next = temp_track->next;
1632                         temp_track = next;
1633                 } else {
1634                         temp_track = NULL;
1635                 }
1636         }
1637
1638         pos = pos1 * GST_MSECOND;
1639
1640         MD_I("NEW Time: %" GST_TIME_FORMAT, GST_TIME_ARGS(pos));
1641
1642         indx = 0;
1643         while (temp) {
1644                 MD_I("Got one element %p\n", temp->appsink);
1645                 if (gst_handle->selected_tracks[indx] == true) {
1646                         temp->need_codec_data = TRUE;
1647                         if (!gst_element_seek(temp->appsink, rate, GST_FORMAT_TIME,
1648                              GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT | GST_SEEK_FLAG_SNAP_BEFORE,
1649                              GST_SEEK_TYPE_SET, pos, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) {
1650                                 MD_E("Seek failed!\n");
1651                                 goto ERROR;
1652                         } else {
1653                                 MD_I("Seek success...setting appsink to playing state\n");
1654                                 if (gst_element_set_state(temp->appsink, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
1655                                         MD_E("Failed to set into PLAYING state");
1656                                         goto ERROR;
1657                                 }
1658                         }
1659                 }
1660                 indx++;
1661                 if (temp->next) {
1662                         track *next = temp->next;
1663                         temp = next;
1664                 } else {
1665                         temp = NULL;
1666                 }
1667         }
1668         MEDIADEMUXER_FLEAVE();
1669         return MD_ERROR_NONE;
1670 ERROR:
1671         MEDIADEMUXER_FLEAVE();
1672         return MD_ERROR;
1673 }
1674
1675 int _gst_unset_appsink(track *temp, int index, int loop)
1676 {
1677         MEDIADEMUXER_FENTER();
1678         int ret = MD_ERROR_NONE;
1679         int count = 0;
1680
1681         while (count != index) {
1682                 temp = temp->next;
1683                 count++;
1684         }
1685         gst_app_sink_set_max_buffers((GstAppSink *)(temp->appsink), (guint)0);
1686         gst_app_sink_set_drop((GstAppSink *)(temp->appsink), true);
1687         MEDIADEMUXER_FLEAVE();
1688         return ret;
1689 }
1690
1691 static int gst_demuxer_unset_track(MMHandleType pHandle, int track)
1692 {
1693         MEDIADEMUXER_FENTER();
1694         int ret = MD_ERROR_NONE;
1695         MEDIADEMUXER_CHECK_NULL(pHandle);
1696         mdgst_handle_t *new_mediademuxer = (mdgst_handle_t *)pHandle;
1697
1698         if (track >= new_mediademuxer->total_tracks || track < 0) {
1699                 MD_E("total tracks is less then unselected track, So not support this track");
1700                 ret = MD_ERROR_INVALID_ARGUMENT;
1701                 goto ERROR;
1702         }
1703         new_mediademuxer->selected_tracks[track] = false;
1704         _gst_unset_appsink((((mdgst_handle_t *)pHandle)->info).head, track,
1705                                         new_mediademuxer->total_tracks);
1706         MEDIADEMUXER_FLEAVE();
1707         return ret;
1708 ERROR:
1709         MEDIADEMUXER_FLEAVE();
1710         return ret;
1711 }
1712
1713 static int gst_demuxer_stop(MMHandleType pHandle)
1714 {
1715         MEDIADEMUXER_FENTER();
1716         int ret = MD_ERROR_NONE;
1717         MEDIADEMUXER_CHECK_NULL(pHandle);
1718         mdgst_handle_t *gst_handle = (mdgst_handle_t *)pHandle;
1719
1720         MD_I("gst_demuxer_stop pipeine %p", gst_handle);
1721         if (gst_element_set_state(gst_handle->pipeline, GST_STATE_PAUSED) ==
1722             GST_STATE_CHANGE_FAILURE) {
1723                 MD_E("Failed to set into PAUSE state");
1724                 ret = MD_INTERNAL_ERROR;
1725                 goto ERROR;
1726         }
1727         MEDIADEMUXER_FLEAVE();
1728         return ret;
1729 ERROR:
1730         MEDIADEMUXER_FLEAVE();
1731         return ret;
1732 }
1733
1734 void  _gst_clear_struct(mdgst_handle_t *gst_handle)
1735 {
1736         MEDIADEMUXER_FENTER();
1737         if (gst_handle->selected_tracks) {
1738                 MD_I("Deallocating gst_handle->selected_tracks %p\n",
1739                      gst_handle->selected_tracks);
1740                 g_free(gst_handle->selected_tracks);
1741                 gst_handle->selected_tracks = NULL;
1742         }
1743         if ((gst_handle->info).head)
1744                 __gst_free_stuct(&(gst_handle->info).head);
1745         MEDIADEMUXER_FLEAVE();
1746 }
1747
1748 int _md_gst_destroy_pipeline(GstElement *pipeline)
1749 {
1750         MEDIADEMUXER_FENTER();
1751         int ret = MD_ERROR_NONE;
1752         if (pipeline)
1753                 MEDIADEMUXER_SET_STATE(pipeline, GST_STATE_NULL, ERROR);
1754         if (pipeline)
1755                 gst_object_unref(GST_OBJECT(pipeline));
1756         MEDIADEMUXER_FLEAVE();
1757         return ret;
1758 ERROR:
1759         if (pipeline)
1760                 gst_object_unref(GST_OBJECT(pipeline));
1761         MEDIADEMUXER_FLEAVE();
1762         return MD_ERROR;
1763 }
1764
1765 static int gst_demuxer_unprepare(MMHandleType pHandle)
1766 {
1767         MEDIADEMUXER_FENTER();
1768         int ret = MD_ERROR_NONE;
1769         MEDIADEMUXER_CHECK_NULL(pHandle);
1770         mdgst_handle_t *gst_handle = (mdgst_handle_t *)pHandle;
1771
1772         _gst_clear_struct(gst_handle);
1773         if (gst_handle->bus_watch_id) {
1774                 GSource *source = NULL;
1775                 source = g_main_context_find_source_by_id(gst_handle->thread_default, gst_handle->bus_watch_id);
1776                 if (source) {
1777                         g_source_destroy(source);
1778                         LOGD("Deallocation bus watch id");
1779                 }
1780         }
1781
1782         MD_I("gst_demuxer_stop pipeine %p\n", gst_handle->pipeline);
1783         if (_md_gst_destroy_pipeline(gst_handle->pipeline) != MD_ERROR_NONE) {
1784                 ret = MD_ERROR;
1785                 goto ERROR;
1786         }
1787         MEDIADEMUXER_FLEAVE();
1788         return ret;
1789 ERROR:
1790         MEDIADEMUXER_FLEAVE();
1791         return ret;
1792 }
1793
1794 static int gst_demuxer_destroy(MMHandleType pHandle)
1795 {
1796         MEDIADEMUXER_FENTER();
1797         int ret = MD_ERROR_NONE;
1798         MEDIADEMUXER_CHECK_NULL(pHandle);
1799         mdgst_handle_t *new_mediademuxer = (mdgst_handle_t *)pHandle;
1800
1801         MD_I("gst_demuxer_destroy deallocating new_mediademuxer:%p\n",
1802              new_mediademuxer);
1803         g_free(new_mediademuxer);
1804         MEDIADEMUXER_FLEAVE();
1805         return ret;
1806 }
1807
1808 int gst_set_error_cb(MMHandleType pHandle,
1809                         gst_error_cb callback, void *user_data)
1810 {
1811         MEDIADEMUXER_FENTER();
1812         int ret = MD_ERROR_NONE;
1813         MEDIADEMUXER_CHECK_NULL(pHandle);
1814         mdgst_handle_t *gst_handle = (mdgst_handle_t *)pHandle;
1815
1816         if (gst_handle->user_cb[_GST_EVENT_TYPE_ERROR]) {
1817                 MD_E("Already set mediademuxer_error_cb\n");
1818                 ret = MD_ERROR_INVALID_ARGUMENT;
1819                 goto ERROR;
1820         } else {
1821                 if (!callback) {
1822                         MD_E("fail invaild argument (callback)\n");
1823                         ret = MD_ERROR_INVALID_ARGUMENT;
1824                         goto ERROR;
1825                 }
1826         }
1827
1828         MD_I("Set event handler callback(cb = %p, data = %p)\n", callback, user_data);
1829
1830         gst_handle->user_cb[_GST_EVENT_TYPE_ERROR] = (gst_error_cb)callback;
1831         gst_handle->user_data[_GST_EVENT_TYPE_ERROR] = user_data;
1832         MEDIADEMUXER_FLEAVE();
1833         return MD_ERROR_NONE;
1834 ERROR:
1835         MEDIADEMUXER_FLEAVE();
1836         return ret;
1837 }
1838
1839 int gst_set_eos_cb(MMHandleType pHandle, gst_eos_cb callback, void *user_data)
1840 {
1841         MEDIADEMUXER_FENTER();
1842         int ret = MD_ERROR_NONE;
1843         MEDIADEMUXER_CHECK_NULL(pHandle);
1844         mdgst_handle_t *gst_handle = (mdgst_handle_t *)pHandle;
1845
1846         if (gst_handle->user_cb[_GST_EVENT_TYPE_EOS]) {
1847                 MD_E("Already set mediademuxer_eos_cb\n");
1848                 ret = MD_ERROR_INVALID_ARGUMENT;
1849                 goto ERROR;
1850         } else {
1851                 if (!callback) {
1852                         MD_E("fail invaild argument (callback)\n");
1853                         ret = MD_ERROR_INVALID_ARGUMENT;
1854                         goto ERROR;
1855                 }
1856         }
1857
1858         MD_I("Set event handler callback(cb = %p, data = %p)\n", callback, user_data);
1859         gst_handle->user_cb[_GST_EVENT_TYPE_EOS] = (gst_eos_cb)callback;
1860         gst_handle->user_data[_GST_EVENT_TYPE_EOS] = user_data;
1861         MEDIADEMUXER_FLEAVE();
1862         return MD_ERROR_NONE;
1863 ERROR:
1864         MEDIADEMUXER_FLEAVE();
1865         return ret;
1866 }
1867
1868 static int __gst_eos_callback(int track_num, void* user_data)
1869 {
1870         if (user_data == NULL) {
1871                 MD_E("Invalid argument");
1872                 return MD_ERROR;
1873         }
1874         mdgst_handle_t *gst_handle = (mdgst_handle_t *)user_data;
1875         if (gst_handle->user_cb[_GST_EVENT_TYPE_EOS])
1876                 ((gst_eos_cb)gst_handle->user_cb[_GST_EVENT_TYPE_EOS])(track_num,
1877                                         gst_handle->user_data[_GST_EVENT_TYPE_EOS]);
1878         else
1879                 MD_E("EOS received, but callback is not set!!!");
1880         return MD_ERROR_NONE;
1881 }