From a7cb8b29bf599844d190191459024e3a31a65615 Mon Sep 17 00:00:00 2001 From: Zhao Cancan Date: Wed, 7 Dec 2016 22:11:17 -0500 Subject: [PATCH] Fix to unify add track info function for audio only case Change-Id: I6aa20bce9db2e152fd3f65390c1f4cd31cba54be --- include/port_gst/mediademuxer_port_gst.h | 1 - packaging/capi-mediademuxer.spec | 2 +- src/port_gst/mediademuxer_port_gst.c | 283 ++++++++++++++----------------- 3 files changed, 131 insertions(+), 155 deletions(-) diff --git a/include/port_gst/mediademuxer_port_gst.h b/include/port_gst/mediademuxer_port_gst.h index 80865ff..9737be4 100755 --- a/include/port_gst/mediademuxer_port_gst.h +++ b/include/port_gst/mediademuxer_port_gst.h @@ -61,7 +61,6 @@ typedef struct track { GstPad *pad; GstCaps *caps; bool need_codec_data; - gchar *name; gchar *caps_string; GstElement *appsink; GstElement *fakesink; diff --git a/packaging/capi-mediademuxer.spec b/packaging/capi-mediademuxer.spec index e0ed499..0ab08d5 100755 --- a/packaging/capi-mediademuxer.spec +++ b/packaging/capi-mediademuxer.spec @@ -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 diff --git a/src/port_gst/mediademuxer_port_gst.c b/src/port_gst/mediademuxer_port_gst.c index b0ac330..6f1dc88 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -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) -- 2.7.4