Fix to unify add track info function for audio only case 92/103292/2
authorZhao Cancan <cancan.zhao@samsung.com>
Thu, 8 Dec 2016 03:11:17 +0000 (22:11 -0500)
committerZhao Cancan <cancan.zhao@samsung.com>
Tue, 13 Dec 2016 01:28:20 +0000 (20:28 -0500)
Change-Id: I6aa20bce9db2e152fd3f65390c1f4cd31cba54be

include/port_gst/mediademuxer_port_gst.h
packaging/capi-mediademuxer.spec
src/port_gst/mediademuxer_port_gst.c

index 80865ff..9737be4 100755 (executable)
@@ -61,7 +61,6 @@ typedef struct track {
        GstPad *pad;
        GstCaps *caps;
        bool need_codec_data;
-       gchar *name;
        gchar *caps_string;
        GstElement *appsink;
        GstElement *fakesink;
index e0ed499..0ab08d5 100755 (executable)
@@ -1,6 +1,6 @@
 Name:       capi-mediademuxer
 Summary:    A Media Demuxer library in Tizen Native API
-Version:    0.1.11
+Version:    0.1.12
 Release:    1
 Group:      Multimedia/API
 License:    Apache-2.0
index b0ac330..6f1dc88 100755 (executable)
@@ -366,17 +366,13 @@ void __gst_free_stuct(track **head)
        while (temp) {
                /*
                if (temp->pad) {
-                       MD_I("deallocate GST_PAD %p\n", temp->pad);
+                       MD_I("unref GST_PAD %p\n", temp->pad);
                        gst_object_unref(temp->pad);
                } */
                if (temp->caps) {
-                       MD_I("deallocate GST_PAD caps_  %p\n", temp->caps);
+                       MD_I("unref GST_PAD caps %p\n", temp->caps);
                        gst_caps_unref(temp->caps);
                }
-               if (temp->name) {
-                       MD_I("deallocate GST_PAD name  %p\n", temp->name);
-                       g_free(temp->name);
-               }
                if (temp->caps_string) {
                        MD_I("deallocate GST_PAD caps_string  %p\n",
                             temp->caps_string);
@@ -401,7 +397,7 @@ void __gst_free_stuct(track **head)
        MEDIADEMUXER_FLEAVE();
 }
 
-int __gst_add_track_info(GstPad *pad, gchar *name, track **head,
+int __gst_add_track_info(GstPad *pad, GstCaps *caps, track **head,
                                                GstElement *pipeline)
 {
        MEDIADEMUXER_FENTER();
@@ -411,6 +407,9 @@ int __gst_add_track_info(GstPad *pad, gchar *name, track **head,
        GstCaps *outcaps = NULL;
        GstPad *parse_sink_pad = NULL;
        GstElement *parse_element = NULL;
+       GstElement *id3tag = NULL;
+       GstPad *id3_sinkpad = NULL;
+       GstPad *id3_srcpad = NULL;
        track *temp = NULL;
 
        temp = (track *)(g_malloc(sizeof(track)));
@@ -421,16 +420,14 @@ int __gst_add_track_info(GstPad *pad, gchar *name, track **head,
                MD_I("allocate memory %p", temp);
        }
        temp->pad = pad;
-       temp->caps = gst_pad_get_current_caps(pad);
-       if (name)
-               temp->name = g_strndup(name, strlen(name));
-       else
-               temp->name = NULL;
-       temp->caps_string = gst_caps_to_string(temp->caps);
+       temp->caps = gst_caps_ref(caps);
+       temp->caps_string = gst_caps_to_string(caps);
        temp->next = NULL;
        temp->format = NULL;
        temp->need_codec_data = TRUE;
 
+       MD_I("track caps(%s)", temp->caps_string ? temp->caps_string : "NULL");
+
        /* Link demuxer - queue */
        temp->queue = gst_element_factory_make("queue", NULL);
        if (!temp->queue) {
@@ -439,13 +436,15 @@ int __gst_add_track_info(GstPad *pad, gchar *name, track **head,
        }
 
        if (!gst_bin_add(GST_BIN(pipeline), temp->queue)) {
+               gst_object_unref(temp->queue);
                MD_E("fail add queue in pipeline");
                goto ERROR;
        }
+       MD_I("added queue element in pipeline.");
 
        queue_sink_pad = gst_element_get_static_pad(temp->queue, "sink");
        if (!queue_sink_pad) {
-               MD_E("queue_sink_pad of appsink not avaible");
+               MD_E("sink pad of queue not avaible");
                goto ERROR;
        }
 
@@ -459,9 +458,11 @@ int __gst_add_track_info(GstPad *pad, gchar *name, track **head,
        }
 
        if (!gst_bin_add(GST_BIN(pipeline), temp->appsink)) {
-               MD_E("fail add queue in pipeline");
+               gst_object_unref(temp->appsink);
+               MD_E("fail add appsink in pipeline");
                goto ERROR;
        }
+       MD_I("added appsink element in pipeline.");
 
        gst_app_sink_set_max_buffers((GstAppSink *) temp->appsink, (guint) 0);
        gst_app_sink_set_drop((GstAppSink *) temp->appsink, true);
@@ -469,7 +470,7 @@ int __gst_add_track_info(GstPad *pad, gchar *name, track **head,
 
        queue_src_pad = gst_element_get_static_pad(temp->queue, "src");
        if (!queue_src_pad) {
-               MD_E("queue_src_pad of appsink not avaible");
+               MD_E("src pad of queue not avaible");
                goto ERROR;
        }
        apppad = gst_element_get_static_pad(temp->appsink, "sink");
@@ -478,7 +479,7 @@ int __gst_add_track_info(GstPad *pad, gchar *name, track **head,
                goto ERROR;
        }
        /* Check for type video and it should be h264 */
-       if (temp->name && strstr(temp->name, "video")) {
+       if (temp->caps_string && strstr(temp->caps_string, "video")) {
                if (strstr(temp->caps_string, "h264")) {
                        parse_element = gst_element_factory_make("h264parse", NULL);
                        if (!parse_element) {
@@ -495,11 +496,15 @@ int __gst_add_track_info(GstPad *pad, gchar *name, track **head,
                }
 
                if (parse_element) {
-                       gst_bin_add(GST_BIN(pipeline), parse_element);
+                       MD_I("add video parse element(%s).", GST_ELEMENT_NAME(parse_element));
+                       if (!gst_bin_add(GST_BIN(pipeline), parse_element)) {
+                               gst_object_unref(parse_element);
+                               MD_E("fail add video parse(%s) in pipeline", GST_ELEMENT_NAME(parse_element));
+                               goto ERROR;
+                       }
                        parse_sink_pad = gst_element_get_static_pad(parse_element, "sink");
                        if (!parse_sink_pad) {
-                               gst_object_unref(parse_element);
-                               MD_E("sink pad of h264parse not available");
+                               MD_E("sink pad of video parse(%s) not available", GST_ELEMENT_NAME(parse_element));
                                goto ERROR;
                        }
                        MEDIADEMUXER_SET_STATE(parse_element, GST_STATE_PAUSED, ERROR);
@@ -518,40 +523,93 @@ int __gst_add_track_info(GstPad *pad, gchar *name, track **head,
                } else {
                        MEDIADEMUXER_LINK_PAD(queue_src_pad, apppad, ERROR);
                }
-       } else if (temp->name && strstr(temp->name, "audio")) {
-               //Create Parse
+       } else if (temp->caps_string && (strstr(temp->caps_string, "audio") || strstr(temp->caps_string, "x-id3"))) {
                if (strstr(temp->caps_string, "audio/mpeg")) {
                        int mpegversion = 0;
                        GstStructure *structure = NULL;
                        structure = gst_caps_get_structure(temp->caps, 0);
                        gst_structure_get_int (structure, "mpegversion", &mpegversion);
-                       if (mpegversion == 2 || mpegversion == 4)
+                       if (mpegversion == 2 || mpegversion == 4) {
                                parse_element = gst_element_factory_make("aacparse", NULL);
-                       else if (mpegversion == 1)
+                               if (!parse_element) {
+                                       MD_E("factory not able to make aacparse");
+                                       goto ERROR;
+                               }
+                       } else if (mpegversion == 1) {
                                parse_element = gst_element_factory_make("mpegaudioparse", NULL);
+                               if (!parse_element) {
+                                       MD_E("factory not able to make mpegaudioparse");
+                                       goto ERROR;
+                               }
+                       }
                } else if (strstr(temp->caps_string, "application/x-id3")) {
+                       id3tag = gst_element_factory_make("id3demux", NULL);
+                       if (!id3tag) {
+                               MD_E("factory not able to make id3demux");
+                               goto ERROR;
+                       }
+                       if (!gst_bin_add(GST_BIN(pipeline), id3tag)) {
+                               gst_object_unref(id3tag);
+                               MD_E("fail add id3tag element in pipeline");
+                               goto ERROR;
+                       }
+                       id3_sinkpad = gst_element_get_static_pad(id3tag, "sink");
+                       if (!id3_sinkpad) {
+                               MD_E("fail to get id3demux sink pad.\n");
+                               goto ERROR;
+                       }
+                       MEDIADEMUXER_LINK_PAD(queue_src_pad, id3_sinkpad, ERROR);
+                       MEDIADEMUXER_SET_STATE(id3tag, GST_STATE_PAUSED, ERROR);
+                       id3_srcpad = gst_element_get_static_pad(id3tag, "src");
+                       if (!id3_srcpad) {
+                               MD_E("fail to get id3demux src pad.\n");
+                               goto ERROR;
+                       }
                        parse_element = gst_element_factory_make("mpegaudioparse", NULL);
+                       if (!parse_element) {
+                               MD_E("factory not able to make mpegaudioparse");
+                               goto ERROR;
+                       }
                } else if (strstr(temp->caps_string, "audio/x-amr-nb-sh")
                                || strstr(temp->caps_string, "audio/x-amr-wb-sh")) {
                        parse_element = gst_element_factory_make("amrparse", NULL);
+                       if (!parse_element) {
+                               MD_E("factory not able to make amrparse");
+                               goto ERROR;
+                       }
                } else if (strstr(temp->caps_string, "audio/x-wav")) {
                        parse_element = gst_element_factory_make("wavparse", NULL);
+                       if (!parse_element) {
+                               MD_E("factory not able to make wavparse");
+                               goto ERROR;
+                       }
                } else if (strstr(temp->caps_string, "audio/x-flac")) {
                        parse_element = gst_element_factory_make("flacparse", NULL);
+                       if (!parse_element) {
+                               MD_E("factory not able to make flacparse");
+                               goto ERROR;
+                       }
                }
 
                if (parse_element) {
-                       gst_bin_add(GST_BIN(pipeline), parse_element);
+                       MD_I("add audio parse element(%s).", GST_ELEMENT_NAME(parse_element));
+                       if (!gst_bin_add(GST_BIN(pipeline), parse_element)) {
+                               gst_object_unref(parse_element);
+                               MD_E("fail add audio parse(%s) in pipeline", GST_ELEMENT_NAME(parse_element));
+                               goto ERROR;
+                       }
                        parse_sink_pad = gst_element_get_static_pad(parse_element, "sink");
                        if (!parse_sink_pad) {
-                               gst_object_unref(parse_element);
-                               MD_E("sink pad of h264parse not available");
+                               MD_E("sink pad of audio parse(%s) not available", GST_ELEMENT_NAME(parse_element));
                                goto ERROR;
                        }
                        MEDIADEMUXER_SET_STATE(parse_element, GST_STATE_PAUSED, ERROR);
 
                        /* Link demuxer pad with sink pad of parse element */
-                       MEDIADEMUXER_LINK_PAD(queue_src_pad, parse_sink_pad, ERROR);
+                       if (id3tag)
+                               MEDIADEMUXER_LINK_PAD(id3_srcpad, parse_sink_pad, ERROR);
+                       else
+                               MEDIADEMUXER_LINK_PAD(queue_src_pad, parse_sink_pad, ERROR);
 
                        /* Link src pad with appSink element */
                        gst_element_link(parse_element, temp->appsink);
@@ -578,20 +636,15 @@ int __gst_add_track_info(GstPad *pad, gchar *name, track **head,
                gst_object_unref(apppad);
        if (parse_sink_pad)
                gst_object_unref(parse_sink_pad);
+       if (id3_sinkpad)
+               gst_object_unref(id3_sinkpad);
+       if (id3_srcpad)
+               gst_object_unref(id3_srcpad);
        MEDIADEMUXER_FLEAVE();
        return MD_ERROR_NONE;
 
 ERROR:
-       if (parse_element)
-               gst_object_unref(parse_element);
-       if (temp->caps)
-               gst_object_unref(temp->caps);
-       if (temp->caps_string)
-               g_free(temp->caps_string);
-       if (temp->queue)
-               gst_object_unref(temp->queue);
-       if (temp->appsink)
-               gst_object_unref(temp->appsink);
+       __gst_free_stuct(&temp);
        if (queue_sink_pad)
                gst_object_unref(queue_sink_pad);
        if (queue_src_pad)
@@ -600,6 +653,10 @@ ERROR:
                gst_object_unref(apppad);
        if (parse_sink_pad)
                gst_object_unref(parse_sink_pad);
+       if (id3_sinkpad)
+               gst_object_unref(id3_sinkpad);
+       if (id3_srcpad)
+               gst_object_unref(id3_srcpad);
        __gst_free_stuct(head);
        MEDIADEMUXER_FLEAVE();
        return MD_ERROR;
@@ -612,18 +669,24 @@ static void __gst_on_pad_added(GstElement *element, GstPad *pad, gpointer data)
        track *tmp = NULL;
        mdgst_handle_t *gst_handle = (mdgst_handle_t *)data;
        track_info *head_track = &(gst_handle->info);
-       gchar *name = gst_pad_get_name(pad);
+       GstCaps *caps = gst_pad_get_current_caps(pad);
+       if (!caps) {
+               MD_E("caps is NULL");
+               return;
+       }
        gst_handle->total_tracks++;
-       if (__gst_add_track_info(pad, name, &(head_track->head), gst_handle->pipeline)
+       if (__gst_add_track_info(pad, caps, &(head_track->head), gst_handle->pipeline)
            != MD_ERROR_NONE) {
                MD_E("unable to added track info");
                head_track->num_audio_track = 0;
                head_track->num_video_track = 0;
                head_track->num_subtitle_track = 0;
                head_track->num_other_track = 0;
+               gst_caps_unref(caps);
                __gst_free_stuct(&(head_track->head));
                return;
        }
+       gst_caps_unref(caps);
        tmp = head_track->head;
        while (tmp->next)
                tmp = tmp->next;
@@ -642,7 +705,7 @@ static void __gst_on_pad_added(GstElement *element, GstPad *pad, gpointer data)
                MD_I("found subtitle(or Text) Pad\n");
                (head_track->num_subtitle_track)++;
        } else {
-               MD_W("found Pad %s\n", name);
+               MD_W("found Pad, caps: %s\n", tmp->caps_string);
                (head_track->num_other_track)++;
        }
        MEDIADEMUXER_FLEAVE();
@@ -653,92 +716,18 @@ static int __gst_create_audio_only_pipeline(gpointer data,  GstCaps *caps)
        MEDIADEMUXER_FENTER();
        mdgst_handle_t *gst_handle = (mdgst_handle_t *)data;
        GstPad *pad = NULL;
-       GstPad *aud_pad = NULL;
-       GstPad *aud_srcpad = NULL;
-       GstPad *fake_pad = NULL;
-       GstElement *id3tag = NULL;
-       gchar *name = NULL;
-       gchar *type = NULL;
        track_info *head_track = &(gst_handle->info);
-       track *tmp_track = NULL;
 
        gst_handle->is_valid_container = true;
 
-       type = gst_caps_to_string(caps);
-
-       if (strstr(type, "adts") || strstr(type, "adif")) {
-               gst_handle->demux = gst_element_factory_make("aacparse", NULL);
-       } else if (strstr(type, "audio/mpeg")) {
-               gst_handle->demux = gst_element_factory_make("mpegaudioparse", NULL);
-       } else if (strstr(type, "application/x-id3")) {
-               id3tag = gst_element_factory_make("id3demux", NULL);
-               gst_handle->demux = gst_element_factory_make("mpegaudioparse", NULL);
-       } else if (strstr(type, "audio/x-amr-nb-sh")
-                  || strstr(type, "audio/x-amr-wb-sh")) {
-               gst_handle->demux = gst_element_factory_make("amrparse", NULL);
-       } else if (strstr(type, "audio/x-wav")) {
-               gst_handle->demux = gst_element_factory_make("wavparse", NULL);
-       } else if (strstr(type, "audio/x-flac")) {
-               gst_handle->demux = gst_element_factory_make("flacparse", NULL);
-       }
-
-       if (!gst_handle->demux) {
-               gst_handle->is_valid_container = false;
-               MD_E("factory not able to create audio parse element\n");
+       pad = gst_element_get_static_pad(gst_handle->typefind, "src");
+       if (!pad) {
+               MD_E("fail to get typefind src pad.\n");
                goto ERROR;
-       } else {
-               gst_bin_add_many(GST_BIN(gst_handle->pipeline),
-                                gst_handle->demux, id3tag, NULL);
-               pad = gst_element_get_static_pad(gst_handle->typefind, "src");
-               if (!pad) {
-                       MD_E("fail to get typefind src pad.\n");
-                       goto ERROR;
-               }
-
-               fake_pad = gst_element_get_static_pad(gst_handle->fakesink, "sink");
-               if (!fake_pad) {
-                       MD_E("fail to get fakesink sink pad.\n");
-                       goto ERROR;
-               }
-               gst_pad_unlink(pad, fake_pad);
-
-               if (fake_pad)
-                       gst_object_unref(fake_pad);
-
-               if (!id3tag)
-                       aud_pad = gst_element_get_static_pad(gst_handle->demux, "sink");
-               else
-                       aud_pad = gst_element_get_static_pad(id3tag, "sink");
-               if (!aud_pad) {
-                       MD_E("fail to get audio parse sink pad.\n");
-                       goto ERROR;
-               }
-
-               MEDIADEMUXER_LINK_PAD(pad, aud_pad, ERROR);
-               if (pad)
-                       gst_object_unref(pad);
-               if (aud_pad)
-                       gst_object_unref(aud_pad);
-
-               if (!id3tag) {
-                       MEDIADEMUXER_SET_STATE(gst_handle->demux, GST_STATE_PAUSED, ERROR);
-               } else {
-                       MEDIADEMUXER_SET_STATE(id3tag, GST_STATE_PAUSED, ERROR);
-                       MEDIADEMUXER_SET_STATE(gst_handle->demux, GST_STATE_PAUSED, ERROR);
-                       gst_element_link(id3tag, gst_handle->demux);
-               }
        }
 
        gst_handle->total_tracks++;
-
-       aud_srcpad = gst_element_get_static_pad(gst_handle->demux, "src");
-       if (!aud_srcpad) {
-               MD_E("fail to get audioparse source pad.\n");
-               goto ERROR;
-       }
-
-       name = gst_pad_get_name(aud_srcpad);
-       if (__gst_add_track_info(aud_srcpad, name, &(head_track->head), gst_handle->pipeline) != MD_ERROR_NONE) {
+       if (__gst_add_track_info(pad, caps, &(head_track->head), gst_handle->pipeline) != MD_ERROR_NONE) {
                MD_E("unable to added track info");
                head_track->num_audio_track = 0;
                head_track->num_video_track = 0;
@@ -748,50 +737,24 @@ static int __gst_create_audio_only_pipeline(gpointer data,  GstCaps *caps)
                goto ERROR;
        }
 
-       tmp_track = head_track->head;
-       while (tmp_track != NULL && aud_srcpad != tmp_track->pad)
-               tmp_track = tmp_track->next;
-
-       if (tmp_track != NULL) {
-               if (tmp_track->caps)
-                       gst_caps_unref(tmp_track->caps);
-               tmp_track->caps = gst_caps_copy(caps);
-               if (tmp_track->caps_string)
-                       g_free(tmp_track->caps_string);
-               tmp_track->caps_string = gst_caps_to_string(tmp_track->caps);
-               MD_I("caps set to %s\n", tmp_track->caps_string);
-               if (tmp_track->name)
-                       g_free(tmp_track->name);
-               tmp_track->name = g_strndup("audio", strlen("audio"));
-       }
-
        (head_track->num_audio_track)++;
 
        /* unref pads */
-       if (aud_srcpad)
-               gst_object_unref(aud_srcpad);
+       if (pad)
+               gst_object_unref(pad);
+
+       /* In the case of audio only, there is no gst_handle->demux. So we pass NULL */
+       __gst_no_more_pad(NULL, data);
 
-       __gst_no_more_pad(gst_handle->demux, data);
-       g_free(type);
-       g_free(name);
        MEDIADEMUXER_FLEAVE();
        return MD_ERROR_NONE;
 
 ERROR:
        gst_handle->is_valid_container = false;
-       if (gst_handle->demux)
-               gst_object_unref(gst_handle->demux);
+
        if (pad)
                gst_object_unref(pad);
-       if (aud_pad)
-               gst_object_unref(aud_pad);
-       if (fake_pad)
-               gst_object_unref(fake_pad);
-       if (aud_srcpad)
-               gst_object_unref(aud_srcpad);
 
-       g_free(type);
-       g_free(name);
        MEDIADEMUXER_FLEAVE();
        return MD_ERROR;
 }
@@ -865,6 +828,22 @@ static void __gst_cb_typefind(GstElement *tf, guint probability,
                           || (strstr(type, "audio/x-amr-nb-sh"))
                           || (strstr(type, "audio/x-amr-wb-sh"))) {
                        MD_I("Audio only format is found\n");
+                       pad = gst_element_get_static_pad(gst_handle->typefind, "src");
+                       if (!pad) {
+                               MD_E("fail to get typefind src pad.\n");
+                               goto ERROR;
+                       }
+                       fake_pad = gst_element_get_static_pad(gst_handle->fakesink, "sink");
+                       if (!fake_pad) {
+                               MD_E("fail to get fakesink sink pad.\n");
+                               goto ERROR;
+                       }
+                       gst_pad_unlink(pad, fake_pad);
+                       if (pad)
+                               gst_object_unref(pad);
+                       if (fake_pad)
+                               gst_object_unref(fake_pad);
+
                        __gst_create_audio_only_pipeline(data, caps);
                } else {
                        gst_handle->is_valid_container = false;
@@ -876,8 +855,6 @@ static void __gst_cb_typefind(GstElement *tf, guint probability,
        return;
 ERROR:
        gst_handle->is_valid_container = false;
-       if (gst_handle->demux)
-               gst_object_unref(gst_handle->demux);
        if (type)
                g_free(type);
        if (pad)