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