From a7cb8b29bf599844d190191459024e3a31a65615 Mon Sep 17 00:00:00 2001 From: Zhao Cancan Date: Wed, 7 Dec 2016 22:11:17 -0500 Subject: [PATCH 01/16] 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 From d58337d0514858d9958f3255bf87d11f4b23ff36 Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Tue, 20 Dec 2016 16:49:15 +0900 Subject: [PATCH 02/16] ref/unref pad for unlink(unselected track) [Version] 0.1.13 [Profile] Common, Mobile, Wearable, TV [Issue Type] Fix bugs Change-Id: Ied7b7433f6fe875ab0ca3a250cf1301312b6f116 --- packaging/capi-mediademuxer.spec | 2 +- src/port_gst/mediademuxer_port_gst.c | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packaging/capi-mediademuxer.spec b/packaging/capi-mediademuxer.spec index 0ab08d5..2d0a380 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.12 +Version: 0.1.13 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 6f1dc88..bcd2a80 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -364,11 +364,11 @@ void __gst_free_stuct(track **head) track *temp = NULL; temp = *head; while (temp) { - /* + if (temp->pad) { MD_I("unref GST_PAD %p\n", temp->pad); gst_object_unref(temp->pad); - } */ + } if (temp->caps) { MD_I("unref GST_PAD caps %p\n", temp->caps); gst_caps_unref(temp->caps); @@ -419,7 +419,9 @@ int __gst_add_track_info(GstPad *pad, GstCaps *caps, track **head, } else { MD_I("allocate memory %p", temp); } - temp->pad = pad; + memset(temp, 0x00, sizeof(track)); + + temp->pad = gst_object_ref(pad); temp->caps = gst_caps_ref(caps); temp->caps_string = gst_caps_to_string(caps); temp->next = NULL; -- 2.7.4 From b2b60b75165d8a7ed0c6a653abade415279bce2b Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Thu, 22 Dec 2016 13:12:22 +0900 Subject: [PATCH 03/16] If the output buffer is keyframe, output media packet will set sync_frame flag There is a problem setting the gstbuffer frag in the media packet. [Version] 0.1.14 [Profile] Common(Mobile, Wearable, TV) [Issue Type] Fix bugs (Migration, Add features, Refactoring, Script etc.) Change-Id: Ifc2f85772614e3cf8010be84ef4eea078739eade --- packaging/capi-mediademuxer.spec | 2 +- src/port_gst/mediademuxer_port_gst.c | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packaging/capi-mediademuxer.spec b/packaging/capi-mediademuxer.spec index 2d0a380..92f18b4 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.13 +Version: 0.1.14 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 bcd2a80..38a3ac8 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -1425,10 +1425,12 @@ static int _gst_copy_buf_to_media_packet(media_packet_h out_pkt, ret = MD_ERROR_UNKNOWN; goto ERROR; } - if (media_packet_set_flags(out_pkt, GST_BUFFER_FLAGS(buffer))) { - MD_E("unable to set the buffer size\n"); - ret = MD_ERROR_UNKNOWN; - goto ERROR; + if (!GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT)) { + if (media_packet_set_flags(out_pkt, MEDIA_PACKET_SYNC_FRAME)) { + MD_E("unable to set the buffer flag\n"); + ret = MD_ERROR_UNKNOWN; + goto ERROR; + } } /* set codec data into media packet */ if (codec_data) { -- 2.7.4 From 0196ab2d12104c528a02bb0a5d1d7e910b0cf758 Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Mon, 26 Dec 2016 15:10:33 +0900 Subject: [PATCH 04/16] Add TIZEN_FEATURE_STREAMING define didn't support streaming [Version] 0.1.15 [Profile] Common, Mobile, Wearable, TV [Issue Type] Add feature Change-Id: I382d81788c784ebf9b863d0bc73dfc522abd41e0 --- packaging/capi-mediademuxer.spec | 2 +- src/mediademuxer_port.c | 14 +++++++++++++- src/port_gst/mediademuxer_port_gst.c | 9 +++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/packaging/capi-mediademuxer.spec b/packaging/capi-mediademuxer.spec index 92f18b4..c29c5c1 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.14 +Version: 0.1.15 Release: 1 Group: Multimedia/API License: Apache-2.0 diff --git a/src/mediademuxer_port.c b/src/mediademuxer_port.c index 2a503de..0d5dd63 100755 --- a/src/mediademuxer_port.c +++ b/src/mediademuxer_port.c @@ -177,8 +177,13 @@ mediademuxer_src_type __md_util_media_type(char **uri) file_stat = __md_util_exist_file_path(path + 7); if (file_stat == MD_ERROR_NONE) { if (__md_util_is_sdp_file(path)) { +#ifdef TIZEN_FEATURE_STREAMING MD_L("uri is actually a file but it's sdp file. giving it to rtspsrc\n"); return MEDIADEMUXER_SRC_RTSP; +#else + MD_L("uri is actually a file but it's sdp file. didn't support streaming uri"); + return MEDIADEMUXER_SRC_INVALID; +#endif } else { return MEDIADEMUXER_SRC_FILE; } @@ -187,6 +192,7 @@ mediademuxer_src_type __md_util_media_type(char **uri) MD_E("could not access %s.\n", path); goto ERROR; } +#ifdef TIZEN_FEATURE_STREAMING } else if ((path = strstr(*uri, "rtsp://"))) { if (strlen(path)) { if ((path = strstr(*uri, "/wfd1.0/"))) @@ -203,6 +209,7 @@ mediademuxer_src_type __md_util_media_type(char **uri) return (MEDIADEMUXER_SRC_HTTP); } } +#endif } else { int file_stat = MD_ERROR_NONE; file_stat = __md_util_exist_file_path(*uri); @@ -226,8 +233,13 @@ mediademuxer_src_type __md_util_media_type(char **uri) free(old_uristr); old_uristr = NULL; if (__md_util_is_sdp_file((char *)(*uri))) { +#ifdef TIZEN_FEATURE_STREAMING MD_L("uri is actually a file but it's sdp file. giving it to rtspsrc\n"); - return (MEDIADEMUXER_SRC_RTSP); + return MEDIADEMUXER_SRC_RTSP; +#else + MD_L("uri is actually a file but it's sdp file. didn't support streaming uri"); + return MEDIADEMUXER_SRC_INVALID; +#endif } else { return (MEDIADEMUXER_SRC_FILE); } diff --git a/src/port_gst/mediademuxer_port_gst.c b/src/port_gst/mediademuxer_port_gst.c index 38a3ac8..1cef964 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -875,7 +875,9 @@ static int _gst_create_pipeline(mdgst_handle_t *gst_handle, char *uri) int ret = MD_ERROR_NONE; GstBus *bus = NULL; char *path = NULL; +#ifdef TIZEN_FEATURE_STREAMING int remote_streaming = 0; +#endif /* Initialize GStreamer */ /* Note: Replace the arguments of gst_init to pass the command line args to GStreamer. */ gst_init(NULL, NULL); @@ -890,9 +892,14 @@ static int _gst_create_pipeline(mdgst_handle_t *gst_handle, char *uri) /* Create the elements */ if ((path = strstr(uri, "http://"))) { +#ifdef TIZEN_FEATURE_STREAMING gst_handle->filesrc = gst_element_factory_make("souphttpsrc", NULL); remote_streaming = 1; MD_I("Source is http stream. \n"); +#else + MD_I("Source is http stream. Didn't support streaming\n"); + goto ERROR; +#endif } else { gst_handle->filesrc = gst_element_factory_make("filesrc", NULL); MD_I("Source is file stream \n"); @@ -904,9 +911,11 @@ static int _gst_create_pipeline(mdgst_handle_t *gst_handle, char *uri) } /* Modify the source's properties */ +#ifdef TIZEN_FEATURE_STREAMING if (remote_streaming == 1) g_object_set(G_OBJECT(gst_handle->filesrc), "location", uri, NULL); else +#endif g_object_set(G_OBJECT(gst_handle->filesrc), "location", uri + 7, NULL); gst_handle->typefind = gst_element_factory_make("typefind", NULL); if (!gst_handle->typefind) { -- 2.7.4 From 76b5c53b98a170252cdc14f15252e99c269f9ce2 Mon Sep 17 00:00:00 2001 From: "juan82.liu" Date: Mon, 20 Feb 2017 09:05:22 +0800 Subject: [PATCH 05/16] not need codec_data when set caps as byte-stream format [Version] 0.1.16 [Profile] Common, Mobile, Wearable, TV [Issue Type] Fix bugs Change-Id: Ifb74bca33e89da826a94a769794636274848f8b1 --- packaging/capi-mediademuxer.spec | 2 +- src/port_gst/mediademuxer_port_gst.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packaging/capi-mediademuxer.spec b/packaging/capi-mediademuxer.spec index c29c5c1..4265b1d 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.15 +Version: 0.1.16 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 1cef964..54cc18a 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -517,6 +517,7 @@ int __gst_add_track_info(GstPad *pad, GstCaps *caps, track **head, outcaps = gst_caps_new_simple("video/x-h264", "stream-format", G_TYPE_STRING, "byte-stream", NULL); gst_element_link_filtered(parse_element, temp->appsink, outcaps); gst_caps_unref(outcaps); + temp->need_codec_data = FALSE; } else if (strstr(temp->caps_string, "mpeg")) { gst_element_link(parse_element, temp->appsink); } else { -- 2.7.4 From 7cfc885def87e5c0a8cfdcc7b27326778a92f927 Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Tue, 28 Feb 2017 14:28:42 +0900 Subject: [PATCH 06/16] Fixed for correct framerate setting [Version] 0.1.17 [Profile] Mobile, Wearable, TV [Issue Type] Fix bugs Change-Id: I25bbcd2e6b12dc2c41099d79b914d57f16c0faaf --- packaging/capi-mediademuxer.spec | 2 +- src/port_gst/mediademuxer_port_gst.c | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packaging/capi-mediademuxer.spec b/packaging/capi-mediademuxer.spec index 4265b1d..4f0c60e 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.16 +Version: 0.1.17 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 54cc18a..b695807 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -1161,6 +1162,7 @@ int _set_mime_video(media_format_h format, track *head) int src_height; int frame_rate_numerator = 0; int frame_rate_denominator = 0; + int frame_rate = 0; media_format_mimetype_e mime_type = MEDIA_FORMAT_MAX; struc = gst_caps_get_structure(head->caps, 0); if (!struc) { @@ -1192,7 +1194,13 @@ int _set_mime_video(media_format_h format, track *head) goto ERROR; } gst_structure_get_fraction(struc, "framerate", &frame_rate_numerator, &frame_rate_denominator); - if (media_format_set_video_frame_rate(format, frame_rate_numerator)) { + + /* Round off the framerate */ + if (frame_rate_denominator) + frame_rate = (int)floor((frame_rate_numerator / frame_rate_denominator) + 0.5); + + MD_I("set frame rate %d", frame_rate); + if (media_format_set_video_frame_rate(format, frame_rate)) { MD_E("Unable to set video frame rate\n"); goto ERROR; } -- 2.7.4 From ef1507ac86a5233ee18f106a3aa0b49f907395da Mon Sep 17 00:00:00 2001 From: "juan82.liu" Date: Fri, 3 Mar 2017 01:56:12 +0800 Subject: [PATCH 07/16] Fixed mediademuxer unprepare failed issue after eos [Version] 0.1.18 [Profile] Mobile, Wearable, TV [Issue Type] Fix bugs Change-Id: I7675199b5a63994280ab6d1a8eda617237f63de3 --- packaging/capi-mediademuxer.spec | 4 ++-- src/port_gst/mediademuxer_port_gst.c | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/packaging/capi-mediademuxer.spec b/packaging/capi-mediademuxer.spec index 4f0c60e..2ee5daf 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.17 +Version: 0.1.18 Release: 1 Group: Multimedia/API License: Apache-2.0 @@ -41,7 +41,7 @@ export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" %ifarch %{arm} export CFLAGS="$CFLAGS -DENABLE_FFMPEG_CODEC" %endif -export CFLAGS="$CFLAGS -DSYSCONFDIR=\\\"%{_sysconfdir}\\\" " +export CFLAGS="$CFLAGS -DSYSCONFDIR=\\\"%{_sysconfdir}\\\" -DTIZEN_FEATURE_GST_UPSTREAM" MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` %cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DFULLVER=%{version} -DMAJORVER=${MAJORVER} diff --git a/src/port_gst/mediademuxer_port_gst.c b/src/port_gst/mediademuxer_port_gst.c index b695807..2d0e2b7 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -459,6 +459,7 @@ int __gst_add_track_info(GstPad *pad, GstCaps *caps, track **head, MD_E("factory not able to make appsink"); goto ERROR; } + g_object_set(G_OBJECT(temp->appsink), "wait-on-eos", TRUE, NULL); if (!gst_bin_add(GST_BIN(pipeline), temp->appsink)) { gst_object_unref(temp->appsink); @@ -1020,6 +1021,7 @@ int _gst_set_appsink(track *temp, int index, int loop) } gst_app_sink_set_max_buffers((GstAppSink *)(temp->appsink), (guint) MAX_APP_BUFFER); gst_app_sink_set_drop((GstAppSink *)(temp->appsink), false); + gst_app_sink_set_wait_on_eos((GstAppSink *)(temp->appsink), true); MEDIADEMUXER_FLEAVE(); return ret; } @@ -1693,6 +1695,7 @@ int _gst_unset_appsink(track *temp, int index, int loop) } gst_app_sink_set_max_buffers((GstAppSink *)(temp->appsink), (guint)0); gst_app_sink_set_drop((GstAppSink *)(temp->appsink), true); + gst_app_sink_set_wait_on_eos((GstAppSink *)(temp->appsink), false); MEDIADEMUXER_FLEAVE(); return ret; } @@ -1778,6 +1781,25 @@ static int gst_demuxer_unprepare(MMHandleType pHandle) MEDIADEMUXER_CHECK_NULL(pHandle); mdgst_handle_t *gst_handle = (mdgst_handle_t *)pHandle; + /*Modification : Fix pipeline state change was block by appsink When EOS received and appsink also has many datas*/ + int indx = 0; + track *atrack = gst_handle->info.head; + while (atrack) { + if ((gst_handle->selected_tracks)[indx] == false) { + MD_I("Track [%d] Not selected\n", indx); + } else { + MD_I("Track [%d] to unset appsink...\n", indx); + gst_demuxer_unset_track(pHandle, indx); + } + if (atrack->next) { + track *next = atrack->next; + atrack = next; + } else { + break; + } + indx++; + } + _gst_clear_struct(gst_handle); if (gst_handle->bus_watch_id) { GSource *source = NULL; -- 2.7.4 From 82c9bf7ffd47ba3747f927f7c247283407526953 Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Wed, 22 Mar 2017 16:27:09 +0900 Subject: [PATCH 08/16] Use %license macro to copy license Change-Id: I2e554923002516bbf52ed7c007a60523f4e7f61d --- packaging/capi-mediademuxer.spec | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packaging/capi-mediademuxer.spec b/packaging/capi-mediademuxer.spec index 2ee5daf..5b420d8 100755 --- a/packaging/capi-mediademuxer.spec +++ b/packaging/capi-mediademuxer.spec @@ -51,10 +51,8 @@ make %{?jobs:-j%jobs} %install rm -rf %{buildroot} -mkdir -p %{buildroot}%{_datadir}/license -mkdir -p %{buildroot}/usr/bin -cp test/mediademuxer_test %{buildroot}/usr/bin -cp LICENSE.APLv2 %{buildroot}%{_datadir}/license/%{name} +mkdir -p %{buildroot}%{_bindir} +cp test/mediademuxer_test %{buildroot}%{_bindir} %make_install @@ -67,7 +65,7 @@ cp LICENSE.APLv2 %{buildroot}%{_datadir}/license/%{name} %files %manifest capi-mediademuxer.manifest %{_libdir}/libcapi-mediademuxer.so.* -%{_datadir}/license/%{name} +%license LICENSE.APLv2 %{_bindir}/* %files devel -- 2.7.4 From dbd653b6aaeee277ed3c6ffd6f940413c49a2489 Mon Sep 17 00:00:00 2001 From: "juan82.liu" Date: Tue, 28 Mar 2017 01:22:57 +0800 Subject: [PATCH 09/16] Patch to only send one seek event for the pipeline [Version] 0.1.19 [Profile] Mobile, Wearable, TV [Issue Type] Fix bugs Change-Id: I4fa0af2debcbeccc59cbb17e9a57c2e1e3ba08e8 --- packaging/capi-mediademuxer.spec | 2 +- src/port_gst/mediademuxer_port_gst.c | 25 +++++++++++++++---------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/packaging/capi-mediademuxer.spec b/packaging/capi-mediademuxer.spec index 2ee5daf..b39adf5 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.18 +Version: 0.1.19 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 2d0e2b7..61be3e3 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -1627,6 +1627,7 @@ static int gst_demuxer_seek(MMHandleType pHandle, gint64 pos1) track *temp = head_track->head; track *temp_track = head_track->head; int indx = 0; + bool is_seek = FALSE; /* Setting each appsink to paused state before seek */ while (temp_track) { @@ -1652,20 +1653,23 @@ static int gst_demuxer_seek(MMHandleType pHandle, gint64 pos1) indx = 0; while (temp) { - MD_I("Got one element %p\n", temp->appsink); + MD_I("Got one element %p {%s}\n", temp->appsink, GST_ELEMENT_NAME(temp->appsink)); if (gst_handle->selected_tracks[indx] == true) { temp->need_codec_data = TRUE; - if (!gst_element_seek(temp->appsink, rate, GST_FORMAT_TIME, - GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT | GST_SEEK_FLAG_SNAP_BEFORE, - GST_SEEK_TYPE_SET, pos, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) { - MD_E("Seek failed!\n"); - goto ERROR; - } else { - MD_I("Seek success...setting appsink to playing state\n"); - if (gst_element_set_state(temp->appsink, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { - MD_E("Failed to set into PLAYING state"); + + if (!is_seek) { + if (!gst_element_seek(temp->appsink, rate, GST_FORMAT_TIME, + GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT | GST_SEEK_FLAG_SNAP_BEFORE, + GST_SEEK_TYPE_SET, pos, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) { + MD_E("Seek failed!\n"); goto ERROR; } + is_seek = TRUE; + } + MD_I("Seek success...setting appsink to playing state\n"); + if (gst_element_set_state(temp->appsink, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { + MD_E("Failed to set into PLAYING state"); + goto ERROR; } } indx++; @@ -1676,6 +1680,7 @@ static int gst_demuxer_seek(MMHandleType pHandle, gint64 pos1) temp = NULL; } } + MEDIADEMUXER_FLEAVE(); return MD_ERROR_NONE; ERROR: -- 2.7.4 From 0bcadd24f28fae22ef764a365b89f152ebef054c Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Thu, 29 Jun 2017 20:36:25 +0900 Subject: [PATCH 10/16] Change the way to check mediademuxer prepared [Version] 0.1.20 [Profile] Mobile, Wearable, TV [Issue Type] Fix bugs Change-Id: I8238a4d19cf4a9b6fa49660e405b617875ecfc92 --- packaging/capi-mediademuxer.spec | 2 +- src/port_gst/mediademuxer_port_gst.c | 27 +++++++++++++++++---------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/packaging/capi-mediademuxer.spec b/packaging/capi-mediademuxer.spec index 1bafe37..add2edf 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.19 +Version: 0.1.20 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 61be3e3..4538aa4 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -881,6 +881,9 @@ static int _gst_create_pipeline(mdgst_handle_t *gst_handle, char *uri) #ifdef TIZEN_FEATURE_STREAMING int remote_streaming = 0; #endif + GstState element_state = GST_STATE_VOID_PENDING; + GstState element_pending_state = GST_STATE_VOID_PENDING; + /* Initialize GStreamer */ /* Note: Replace the arguments of gst_init to pass the command line args to GStreamer. */ gst_init(NULL, NULL); @@ -955,16 +958,20 @@ static int _gst_create_pipeline(mdgst_handle_t *gst_handle, char *uri) /* set pipeline state to PAUSED */ MEDIADEMUXER_SET_STATE(gst_handle->pipeline, GST_STATE_PAUSED, ERROR); - int count = 0; - while (gst_handle->is_prepared != true) { - count++; - usleep(POLLING_INTERVAL); - MD_I("Inside while loop\n"); - if (count > POLLING_INTERVAL) { - MD_E("Error occure\n"); - ret = MD_ERROR; - break; - } + if (gst_element_get_state(gst_handle->pipeline, &element_state, &element_pending_state, 1 * GST_SECOND) + == GST_STATE_CHANGE_FAILURE) { + MD_E(" [%s] state : %s pending : %s \n", + GST_ELEMENT_NAME(gst_handle->pipeline), + gst_element_state_get_name(element_state), + gst_element_state_get_name(element_pending_state)); + ret = MD_ERROR; + goto ERROR; + } + + if (gst_handle->is_prepared != true) { + MD_E("Error occure"); + ret = MD_ERROR; + goto ERROR; } MEDIADEMUXER_FLEAVE(); -- 2.7.4 From c2434e2ec1d1721035f63fda24a32c52bbe712c7 Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Fri, 21 Jul 2017 15:26:25 +0900 Subject: [PATCH 11/16] Fix cyclic build dependency remove capi-media-codec depency for test [Version] 0.1.21 [Profile] Mobile, Wearable, TV [Issue Type] Fix cyclic dependency Change-Id: I5fae29310ba9a8d56098a485deb890f6288186fe --- CMakeLists.txt | 3 +- packaging/capi-mediademuxer.spec | 5 +- test/mediademuxer_test.c | 190 +++++++++++++++++++++------------------ 3 files changed, 107 insertions(+), 91 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c7acfa..fa91135 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,8 @@ SET(INC_PORT_CUSTOM_DIR include/port_custom) SET(INC_PORT_FFMPEG_DIR include/port_ffmpeg) INCLUDE_DIRECTORIES(${INC_DIR} ${INC_PORT_GST_DIR} ${INC_PORT_CUSTOM_DIR} ${INC_PORT_FFMPEG_DIR}) -SET(dependents "dlog glib-2.0 mm-common capi-media-tool iniparser gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 capi-media-codec") +#SET(dependents "dlog glib-2.0 mm-common capi-media-tool iniparser gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 capi-media-codec") +SET(dependents "dlog glib-2.0 mm-common capi-media-tool iniparser gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0") SET(pc_dependents "capi-base-common capi-media-tool") INCLUDE(FindPkgConfig) diff --git a/packaging/capi-mediademuxer.spec b/packaging/capi-mediademuxer.spec index add2edf..4b07b67 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.20 +Version: 0.1.21 Release: 1 Group: Multimedia/API License: Apache-2.0 @@ -11,8 +11,7 @@ BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(mm-common) BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(capi-media-tool) -BuildRequires: pkgconfig(capi-media-codec) -BuildRequires: pkgconfig(libtbm) +#BuildRequires: pkgconfig(capi-media-codec) BuildRequires: pkgconfig(gstreamer-1.0) BuildRequires: pkgconfig(gstreamer-plugins-base-1.0) BuildRequires: pkgconfig(gstreamer-video-1.0) diff --git a/test/mediademuxer_test.c b/test/mediademuxer_test.c index b532d60..526c6b7 100755 --- a/test/mediademuxer_test.c +++ b/test/mediademuxer_test.c @@ -29,7 +29,9 @@ #include #include #include +#ifdef USE_MEDIA_CODEC #include +#endif /*----------------------------------------------------------------------- | GLOBAL CONSTANT DEFINITIONS: | @@ -131,10 +133,13 @@ int write_amrwb_header = 0; /* write magic number for AMR-WB Header at one time #endif bool validate_with_codec = false; -mediacodec_h g_media_codec = NULL; + FILE *fp_out_codec_audio = NULL; -mediacodec_h g_media_codec_1 = NULL; FILE *fp_out_codec_video = NULL; +#ifdef USE_MEDIA_CODEC +mediacodec_h g_media_codec = NULL; +mediacodec_h g_media_codec_1 = NULL; +#endif /*----------------------------------------------------------------------- | HELPER FUNCTION | @@ -305,6 +310,7 @@ int test_mediademuxer_get_track_info() return ret; } +#ifdef USE_MEDIA_CODEC static void mediacodec_finish(mediacodec_h handle, FILE *fp) { int err = 0; @@ -397,6 +403,86 @@ static void mediacodec_process_audio_pkt(media_packet_h in_buf) } } +static void _mediacodec_fill_video_buffer_cb(media_packet_h pkt, void *user_data) +{ + int err = 0; + uint64_t buf_size = 0; + void *data = NULL; + media_packet_h output_buf; + + if (pkt != NULL) { + err = mediacodec_get_output(g_media_codec_1, &output_buf, 0); + if (err == MEDIACODEC_ERROR_NONE) { + media_packet_get_buffer_size(output_buf, &buf_size); + /* g_print("%s - output_buf size = %lld\n", __func__, buf_size); */ + media_packet_get_buffer_data_ptr(output_buf, &data); + if (data != NULL) + fwrite(data, 1, buf_size, fp_out_codec_video); + else + g_print("Data is null inside _mediacodec_fill_video_buffer_cb\n"); + media_packet_destroy(output_buf); + } else { + g_print("mediacodec_get_output failed inside _mediacodec_fill_video_buffer_cb lerr = %d\n", err); + return; + } + } else { + g_print("video pkt from mediacodec is null\n"); + } + return; +} + +static void mediacodec_init_video(int codecid, int flag, int width, int height) +{ + /* This file will be used to dump the data */ + fp_out_codec_video = fopen("/opt/usr/codec_dump_video.out", "wb"); + g_print("Create dumped file as codec_dump_video.out\n"); + + if (g_media_codec_1 != NULL) { + mediacodec_unprepare(g_media_codec_1); + mediacodec_destroy(g_media_codec_1); + g_media_codec_1 = NULL; + } + if (mediacodec_create(&g_media_codec_1) != MEDIACODEC_ERROR_NONE) { + g_print("mediacodec_create is failed\n"); + return; + } + /* Now set the code info */ + if ((mediacodec_set_codec(g_media_codec_1, (mediacodec_codec_type_e)codecid, + (mediacodec_support_type_e)flag) != MEDIACODEC_ERROR_NONE)) { + g_print("mediacodec_set_codec is failed\n"); + return; + } + /* set the video dec info */ + if ((mediacodec_set_vdec_info(g_media_codec_1, width, height)) != MEDIACODEC_ERROR_NONE) { + g_print("mediacodec_set_vdec is failed\n"); + return; + } + /* Set the callback for output data, which will be used to write the data to file */ + mediacodec_set_output_buffer_available_cb(g_media_codec_1, + _mediacodec_fill_video_buffer_cb, + g_media_codec_1); + + if (MEDIACODEC_ERROR_NONE != mediacodec_prepare(g_media_codec_1)) { + g_print("mediacodec_prepare is failed\n"); + return; + } +} + +static void mediacodec_process_video_pkt(media_packet_h in_buf) +{ + if (g_media_codec_1 != NULL) { + /* process the media packet */ + if (MEDIACODEC_ERROR_NONE != mediacodec_process_input(g_media_codec_1, in_buf, 0)) { + g_print("mediacodec process input is failed inside mediacodec_process_video_pkt\n"); + return; + } + } else { + g_print("mediacodec handle is invalid inside mediacodec_process_video_pkt()\n"); + } +} + +#endif + void *_fetch_audio_data(void *ptr) { int ret = MEDIADEMUXER_ERROR_NONE; @@ -413,6 +499,7 @@ void *_fetch_audio_data(void *ptr) *status = -1; g_print("Audio Data function\n"); +#ifdef USE_MEDIA_CODEC if (validate_with_codec) { int flag = 0; if (a_mime == MEDIA_FORMAT_AAC_LC || a_mime == MEDIA_FORMAT_AAC_HE || @@ -445,7 +532,7 @@ void *_fetch_audio_data(void *ptr) return (void *)status; } } - +#endif while (1) { ret = mediademuxer_read_sample(demuxer, aud_track, &audbuf); if (ret != MEDIADEMUXER_ERROR_NONE) { @@ -484,97 +571,23 @@ void *_fetch_audio_data(void *ptr) } #endif +#ifdef USE_MEDIA_CODEC if (validate_with_codec) mediacodec_process_audio_pkt(audbuf); else +#endif media_packet_destroy(audbuf); } g_print("EOS return of mediademuxer_read_sample() for audio\n"); *status = 0; +#ifdef USE_MEDIA_CODEC if (validate_with_codec) mediacodec_finish(g_media_codec, fp_out_codec_audio); +#endif return (void *)status; } -static void _mediacodec_fill_video_buffer_cb(media_packet_h pkt, void *user_data) -{ - int err = 0; - uint64_t buf_size = 0; - void *data = NULL; - media_packet_h output_buf; - - if (pkt != NULL) { - err = mediacodec_get_output(g_media_codec_1, &output_buf, 0); - if (err == MEDIACODEC_ERROR_NONE) { - media_packet_get_buffer_size(output_buf, &buf_size); - /* g_print("%s - output_buf size = %lld\n", __func__, buf_size); */ - media_packet_get_buffer_data_ptr(output_buf, &data); - if (data != NULL) - fwrite(data, 1, buf_size, fp_out_codec_video); - else - g_print("Data is null inside _mediacodec_fill_video_buffer_cb\n"); - media_packet_destroy(output_buf); - } else { - g_print("mediacodec_get_output failed inside _mediacodec_fill_video_buffer_cb lerr = %d\n", err); - return; - } - } else { - g_print("video pkt from mediacodec is null\n"); - } - return; -} - -static void mediacodec_init_video(int codecid, int flag, int width, int height) -{ - /* This file will be used to dump the data */ - fp_out_codec_video = fopen("/opt/usr/codec_dump_video.out", "wb"); - g_print("Create dumped file as codec_dump_video.out\n"); - - if (g_media_codec_1 != NULL) { - mediacodec_unprepare(g_media_codec_1); - mediacodec_destroy(g_media_codec_1); - g_media_codec_1 = NULL; - } - if (mediacodec_create(&g_media_codec_1) != MEDIACODEC_ERROR_NONE) { - g_print("mediacodec_create is failed\n"); - return; - } - /* Now set the code info */ - if ((mediacodec_set_codec(g_media_codec_1, (mediacodec_codec_type_e)codecid, - (mediacodec_support_type_e)flag) != MEDIACODEC_ERROR_NONE)) { - g_print("mediacodec_set_codec is failed\n"); - return; - } - /* set the video dec info */ - if ((mediacodec_set_vdec_info(g_media_codec_1, width, height)) != MEDIACODEC_ERROR_NONE) { - g_print("mediacodec_set_vdec is failed\n"); - return; - } - /* Set the callback for output data, which will be used to write the data to file */ - mediacodec_set_output_buffer_available_cb(g_media_codec_1, - _mediacodec_fill_video_buffer_cb, - g_media_codec_1); - - if (MEDIACODEC_ERROR_NONE != mediacodec_prepare(g_media_codec_1)) { - g_print("mediacodec_prepare is failed\n"); - return; - } -} - -static void mediacodec_process_video_pkt(media_packet_h in_buf) -{ - if (g_media_codec_1 != NULL) { - /* process the media packet */ - if (MEDIACODEC_ERROR_NONE != mediacodec_process_input(g_media_codec_1, in_buf, 0)) { - g_print("mediacodec process input is failed inside mediacodec_process_video_pkt\n"); - return; - } - } else { - g_print("mediacodec handle is invalid inside mediacodec_process_video_pkt()\n"); - } -} - #if 0 static void _local_media_packet_get_codec_data(media_packet_h pkt) { @@ -610,6 +623,7 @@ void *_fetch_video_data(void *ptr) *status = -1; g_print("Video Data function\n"); +#ifdef USE_MEDIA_CODEC if (validate_with_codec) { int flag = 0; if (v_mime == MEDIA_FORMAT_H264_SP || v_mime == MEDIA_FORMAT_H264_MP || @@ -626,6 +640,7 @@ void *_fetch_video_data(void *ptr) return (void *)status; } } +#endif while (1) { ret = mediademuxer_read_sample(demuxer, vid_track, &vidbuf); if (ret != MEDIADEMUXER_ERROR_NONE) { @@ -651,16 +666,20 @@ void *_fetch_video_data(void *ptr) } #endif +#ifdef USE_MEDIA_CODEC if (validate_with_codec) mediacodec_process_video_pkt(vidbuf); else +#endif media_packet_destroy(vidbuf); } g_print("EOS return of mediademuxer_read_sample() for video\n"); *status = 0; + +#ifdef USE_MEDIA_CODEC if (validate_with_codec) mediacodec_finish(g_media_codec_1, fp_out_codec_video); - +#endif return (void *)status; } @@ -903,9 +922,11 @@ static void display_sub_basic() g_print("d. Destroy \t"); g_print("q. Quit \n"); g_print("---------------------------------------------------------------------------\n"); +#ifdef USE_MEDIA_CODEC if (validate_with_codec) g_print("[Validation with Media codec]\n"); else +#endif g_print("[validation as stand alone. To validate with media codec, run mediademuxertest with -c option]\n"); } @@ -1046,11 +1067,6 @@ static void interpret(char *cmd) test_mediademuxer_is_encrypted(); else g_print("UNKNOW COMMAND\n"); - } else if (len == 2) { - if (strncmp(cmd, "10", len) == 0) - g_print("UNKNOW COMMAND\n"); - else - g_print("UNKNOW COMMAND\n"); } else { g_print("UNKNOW COMMAND\n"); } -- 2.7.4 From 664b8e39ac81798d9033a0e300ea6181ac357016 Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Tue, 8 Aug 2017 15:11:27 +0900 Subject: [PATCH 12/16] Change fuction set_state to set_state_with_parent in have-type callback sometimes state hang during demux state shange [Version] 0.1.22 [Profile] Mobile, Wearable, TV [Issue Type] Fix bugs Change-Id: Ib5256c4d381dac72c34b1bba33ff02f7ced05941 --- include/port_gst/mediademuxer_port_gst.h | 9 +++++++++ packaging/capi-mediademuxer.spec | 2 +- src/port_gst/mediademuxer_port_gst.c | 26 +++++++++++++++++--------- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/include/port_gst/mediademuxer_port_gst.h b/include/port_gst/mediademuxer_port_gst.h index 9737be4..c784b81 100755 --- a/include/port_gst/mediademuxer_port_gst.h +++ b/include/port_gst/mediademuxer_port_gst.h @@ -42,6 +42,15 @@ extern "C" { } \ } while (0) +#define MEDIADEMUXER_SYNC_STATE_WITH_PARENT(x_element, error) \ + do { \ + MD_I("Sync state with parent [%s]\n", GST_ELEMENT_NAME(x_element)); \ + if (GST_STATE_CHANGE_FAILURE == gst_element_sync_state_with_parent(x_element)) { \ + MD_E("failed to sync %s state with parent\n", GST_ELEMENT_NAME(x_element)); \ + goto error; \ + } \ + } while (0) + #define MEDIADEMUXER_LINK_PAD(srcpad, sinkpad, error) \ do { \ if (GST_PAD_LINK_OK != gst_pad_link(srcpad, sinkpad)) { \ diff --git a/packaging/capi-mediademuxer.spec b/packaging/capi-mediademuxer.spec index 4b07b67..1d022c6 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.21 +Version: 0.1.22 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 4538aa4..3cc57aa 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -451,8 +451,8 @@ int __gst_add_track_info(GstPad *pad, GstCaps *caps, track **head, goto ERROR; } - MEDIADEMUXER_SET_STATE(temp->queue, GST_STATE_PAUSED, ERROR); MEDIADEMUXER_LINK_PAD(pad, queue_sink_pad, ERROR); + MEDIADEMUXER_SYNC_STATE_WITH_PARENT(temp->queue, ERROR); temp->appsink = gst_element_factory_make("appsink", NULL); if (!temp->appsink) { @@ -470,7 +470,6 @@ int __gst_add_track_info(GstPad *pad, GstCaps *caps, track **head, gst_app_sink_set_max_buffers((GstAppSink *) temp->appsink, (guint) 0); gst_app_sink_set_drop((GstAppSink *) temp->appsink, true); - MEDIADEMUXER_SET_STATE(temp->appsink, GST_STATE_PAUSED, ERROR); queue_src_pad = gst_element_get_static_pad(temp->queue, "src"); if (!queue_src_pad) { @@ -511,10 +510,11 @@ int __gst_add_track_info(GstPad *pad, GstCaps *caps, track **head, 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); /* Link demuxer pad with sink pad of parse element */ MEDIADEMUXER_LINK_PAD(queue_src_pad, parse_sink_pad, ERROR); + MEDIADEMUXER_SYNC_STATE_WITH_PARENT(parse_element, ERROR); + if (strstr(temp->caps_string, "h264")) { outcaps = gst_caps_new_simple("video/x-h264", "stream-format", G_TYPE_STRING, "byte-stream", NULL); gst_element_link_filtered(parse_element, temp->appsink, outcaps); @@ -564,7 +564,7 @@ int __gst_add_track_info(GstPad *pad, GstCaps *caps, track **head, goto ERROR; } MEDIADEMUXER_LINK_PAD(queue_src_pad, id3_sinkpad, ERROR); - MEDIADEMUXER_SET_STATE(id3tag, GST_STATE_PAUSED, ERROR); + MEDIADEMUXER_SYNC_STATE_WITH_PARENT(id3tag, ERROR); id3_srcpad = gst_element_get_static_pad(id3tag, "src"); if (!id3_srcpad) { MD_E("fail to get id3demux src pad.\n"); @@ -608,7 +608,6 @@ int __gst_add_track_info(GstPad *pad, GstCaps *caps, track **head, 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 */ if (id3tag) @@ -616,6 +615,8 @@ int __gst_add_track_info(GstPad *pad, GstCaps *caps, track **head, else MEDIADEMUXER_LINK_PAD(queue_src_pad, parse_sink_pad, ERROR); + MEDIADEMUXER_SYNC_STATE_WITH_PARENT(parse_element, ERROR); + /* Link src pad with appSink element */ gst_element_link(parse_element, temp->appsink); } else { @@ -624,6 +625,8 @@ int __gst_add_track_info(GstPad *pad, GstCaps *caps, track **head, } else { MEDIADEMUXER_LINK_PAD(queue_src_pad, apppad, ERROR); } + + MEDIADEMUXER_SYNC_STATE_WITH_PARENT(temp->appsink, ERROR); /* gst_pad_link(pad, fpad) */ if (*head == NULL) { *head = temp; @@ -797,8 +800,13 @@ static void __gst_cb_typefind(GstElement *tf, guint probability, G_CALLBACK(__gst_on_pad_added), gst_handle); g_signal_connect(gst_handle->demux, "no-more-pads", G_CALLBACK(__gst_no_more_pad), gst_handle); - gst_bin_add_many(GST_BIN(gst_handle->pipeline), - gst_handle->demux, NULL); + if (!gst_bin_add(GST_BIN(gst_handle->pipeline), gst_handle->demux)) { + gst_object_unref(gst_handle->demux); + MD_E("fail add demuxer(%s) in pipeline", + GST_ELEMENT_NAME(gst_handle->demux)); + goto ERROR; + } + pad = gst_element_get_static_pad(gst_handle->typefind, "src"); if (!pad) { MD_E("fail to get typefind src pad.\n"); @@ -816,8 +824,8 @@ static void __gst_cb_typefind(GstElement *tf, guint probability, } gst_pad_unlink(pad, fake_pad); MEDIADEMUXER_LINK_PAD(pad, demuxer_pad, ERROR); - MEDIADEMUXER_SET_STATE(gst_handle->demux, - GST_STATE_PAUSED, ERROR); + + MEDIADEMUXER_SYNC_STATE_WITH_PARENT(gst_handle->demux, ERROR); if (pad) gst_object_unref(pad); if (demuxer_pad) -- 2.7.4 From d3d5f40fbc8a5b1710e7e56a351c03d84ae3d93c Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Wed, 30 Aug 2017 16:14:30 +0900 Subject: [PATCH 13/16] Add element lock state for prevent deadlock Add handle NULL check [Version] 0.1.23 [Profile] Mobile, Wearable, TV [Issue Type] Fix bugs Change-Id: Id9ee77adba954eadee1d7a85633763403b8ff4f5 --- include/mediademuxer_util.h | 8 ++ packaging/capi-mediademuxer.spec | 2 +- src/port_gst/mediademuxer_port_gst.c | 185 +++++++++++++++++++---------------- 3 files changed, 110 insertions(+), 85 deletions(-) diff --git a/include/mediademuxer_util.h b/include/mediademuxer_util.h index 01c0670..93c7a58 100755 --- a/include/mediademuxer_util.h +++ b/include/mediademuxer_util.h @@ -84,6 +84,14 @@ extern "C" { } \ } while (0) +#define MEDIADEMUXER_CHECK_NULL_VOID(x_var) \ + do { \ + if (!x_var) { \ + MD_E("[%s] is NULL\n", #x_var); \ + return; \ + } \ + } while (0) + #define MEDIADEMUXER_CHECK_SET_AND_PRINT(x_var, x_cond, ret, ret_val, err_text) \ do { \ if (x_var != x_cond) { \ diff --git a/packaging/capi-mediademuxer.spec b/packaging/capi-mediademuxer.spec index 1d022c6..94b2671 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.22 +Version: 0.1.23 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 3cc57aa..4076551 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -333,6 +333,7 @@ static void __gst_no_more_pad(GstElement *element, gpointer data) int loop_track; track_info *head_track = &(gst_handle->info); track *head = head_track->head; + MEDIADEMUXER_CHECK_NULL_VOID(gst_handle); gst_handle->selected_tracks = (bool *) g_malloc(sizeof(bool) * (gst_handle->total_tracks)); MD_I("Allocating %p to core->selected_tracks \n", gst_handle->selected_tracks); @@ -677,7 +678,9 @@ 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); - GstCaps *caps = gst_pad_get_current_caps(pad); + GstCaps *caps = NULL; + MEDIADEMUXER_CHECK_NULL_VOID(gst_handle); + caps = gst_pad_get_current_caps(pad); if (!caps) { MD_E("caps is NULL"); return; @@ -775,101 +778,114 @@ static void __gst_cb_typefind(GstElement *tf, guint probability, GstPad *pad = NULL; GstPad *demuxer_pad = NULL; GstPad *fake_pad = NULL; - gchar *type; + gchar *type = NULL; + MEDIADEMUXER_CHECK_NULL_VOID(gst_handle); type = gst_caps_to_string(caps); - if (type) { - MD_I("Media type %s found, probability %d%%\n", type, probability); - if (strstr(type, "quicktime") || (strstr(type, "audio/x-m4a")) || strstr(type, "x-3gp") - || strstr(type, "ogg") || strstr(type, "flv") || strstr(type, "x-msvideo")) { - gst_handle->is_valid_container = true; - if (strstr(type, "ogg")) - gst_handle->demux = gst_element_factory_make("oggdemux", NULL); - else if (strstr(type, "flv")) - gst_handle->demux = gst_element_factory_make("flvdemux", NULL); - else if (strstr(type, "x-msvideo")) - gst_handle->demux = gst_element_factory_make("avidemux", NULL); - else - gst_handle->demux = gst_element_factory_make("qtdemux", NULL); - if (!gst_handle->demux) { - gst_handle->is_valid_container = false; - MD_E("factory not able to create qtdemux\n"); - goto ERROR; - } else { - g_signal_connect(gst_handle->demux, "pad-added", - G_CALLBACK(__gst_on_pad_added), gst_handle); - g_signal_connect(gst_handle->demux, "no-more-pads", - G_CALLBACK(__gst_no_more_pad), gst_handle); - if (!gst_bin_add(GST_BIN(gst_handle->pipeline), gst_handle->demux)) { - gst_object_unref(gst_handle->demux); - MD_E("fail add demuxer(%s) in pipeline", - GST_ELEMENT_NAME(gst_handle->demux)); - goto ERROR; - } + if (!type) { + MD_E("Fail to get caps string"); + goto ERROR; + } - pad = gst_element_get_static_pad(gst_handle->typefind, "src"); - if (!pad) { - MD_E("fail to get typefind src pad.\n"); - goto ERROR; - } - demuxer_pad = gst_element_get_static_pad(gst_handle->demux, "sink"); - if (!demuxer_pad) { - MD_E("fail to get qtdemuc sink 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); - MEDIADEMUXER_LINK_PAD(pad, demuxer_pad, ERROR); - - MEDIADEMUXER_SYNC_STATE_WITH_PARENT(gst_handle->demux, ERROR); - if (pad) - gst_object_unref(pad); - if (demuxer_pad) - gst_object_unref(demuxer_pad); - if (fake_pad) - gst_object_unref(fake_pad); - } - } else if ((strstr(type, "adts")) - || (strstr(type, "audio/mpeg")) - || (strstr(type, "audio/x-wav")) - || (strstr(type, "audio/x-flac")) - || (strstr(type, "application/x-id3")) - || (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); + MD_I("Media type %s found, probability %d%%\n", type, probability); + if (strstr(type, "quicktime") || strstr(type, "audio/x-m4a") || + strstr(type, "x-3gp") || strstr(type, "ogg") || + strstr(type, "flv") || strstr(type, "x-msvideo")) { + gst_handle->is_valid_container = true; + if (strstr(type, "ogg")) + gst_handle->demux = gst_element_factory_make("oggdemux", NULL); + else if (strstr(type, "flv")) + gst_handle->demux = gst_element_factory_make("flvdemux", NULL); + else if (strstr(type, "x-msvideo")) + gst_handle->demux = gst_element_factory_make("avidemux", NULL); + else + gst_handle->demux = gst_element_factory_make("qtdemux", NULL); - __gst_create_audio_only_pipeline(data, caps); - } else { + if (!gst_handle->demux) { gst_handle->is_valid_container = false; - MD_E("Not supported container %s\n", type); + MD_E("factory not able to create qtdemux\n"); + goto ERROR; } - g_free(type); + g_signal_connect(gst_handle->demux, "pad-added", + G_CALLBACK(__gst_on_pad_added), gst_handle); + g_signal_connect(gst_handle->demux, "no-more-pads", + G_CALLBACK(__gst_no_more_pad), gst_handle); + gst_element_set_locked_state(gst_handle->demux, TRUE); + if (!gst_bin_add(GST_BIN(gst_handle->pipeline), gst_handle->demux)) { + MD_E("fail add demuxer(%s) in pipeline", + GST_ELEMENT_NAME(gst_handle->demux)); + gst_object_unref(gst_handle->demux); + gst_handle->demux = NULL; + goto ERROR; + } + + pad = gst_element_get_static_pad(gst_handle->typefind, "src"); + if (!pad) { + MD_E("fail to get typefind src pad.\n"); + goto ERROR; + } + demuxer_pad = gst_element_get_static_pad(gst_handle->demux, "sink"); + if (!demuxer_pad) { + MD_E("fail to get qtdemuc sink 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); + MEDIADEMUXER_LINK_PAD(pad, demuxer_pad, ERROR); + + MEDIADEMUXER_SYNC_STATE_WITH_PARENT(gst_handle->demux, ERROR); + gst_element_set_locked_state(gst_handle->demux, FALSE); + if (pad) + gst_object_unref(pad); + if (demuxer_pad) + gst_object_unref(demuxer_pad); + if (fake_pad) + gst_object_unref(fake_pad); + + } else if ((strstr(type, "adts")) + || (strstr(type, "audio/mpeg")) + || (strstr(type, "audio/x-wav")) + || (strstr(type, "audio/x-flac")) + || (strstr(type, "application/x-id3")) + || (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; + MD_E("Not supported container %s\n", type); } + + g_free(type); MEDIADEMUXER_FLEAVE(); return; + ERROR: gst_handle->is_valid_container = false; if (type) g_free(type); + if (gst_handle->demux) + gst_element_set_locked_state(gst_handle->demux, FALSE); if (pad) gst_object_unref(pad); if (demuxer_pad) @@ -1214,7 +1230,7 @@ int _set_mime_video(media_format_h format, track *head) /* Round off the framerate */ if (frame_rate_denominator) - frame_rate = (int)floor((frame_rate_numerator / frame_rate_denominator) + 0.5); + frame_rate = (int)floor(((gdouble)frame_rate_numerator / frame_rate_denominator) + 0.5); MD_I("set frame rate %d", frame_rate); if (media_format_set_video_frame_rate(format, frame_rate)) { @@ -1766,6 +1782,7 @@ ERROR: void _gst_clear_struct(mdgst_handle_t *gst_handle) { MEDIADEMUXER_FENTER(); + MEDIADEMUXER_CHECK_NULL_VOID(gst_handle); if (gst_handle->selected_tracks) { MD_I("Deallocating gst_handle->selected_tracks %p\n", gst_handle->selected_tracks); -- 2.7.4 From 31903fd0e2de14a8a07a4c2894ad2d0c459e8a9e Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Fri, 29 Sep 2017 10:18:48 +0900 Subject: [PATCH 14/16] Fix coverity issues [Version] 0.1.24 [Profile] Mobile, Wearable, TV [Issue Type] Fix coverity issues Change-Id: I67cfb39f8904474b741e3a646274f71fb5fc8364 --- packaging/capi-mediademuxer.spec | 2 +- src/port_gst/mediademuxer_port_gst.c | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/packaging/capi-mediademuxer.spec b/packaging/capi-mediademuxer.spec index 94b2671..cdd1708 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.23 +Version: 0.1.24 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 4076551..ae1adb7 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -699,6 +699,13 @@ static void __gst_on_pad_added(GstElement *element, GstPad *pad, gpointer data) } gst_caps_unref(caps); tmp = head_track->head; + + if (!tmp) { + MD_I("trak is NULL\n"); + MEDIADEMUXER_FLEAVE(); + return; + } + while (tmp->next) tmp = tmp->next; if (!tmp || !tmp->caps_string) { @@ -1253,7 +1260,7 @@ int _set_mime_audio(media_format_h format, track *head) int bit = 0; int channels = 0; int id3_flag = 0; - const gchar *stream_format; + const gchar *stream_format = NULL; media_format_mimetype_e mime_type = MEDIA_FORMAT_MAX; struc = gst_caps_get_structure(head->caps, 0); @@ -1274,10 +1281,12 @@ int _set_mime_audio(media_format_h format, track *head) goto ERROR; stream_format = gst_structure_get_string(struc, "stream-format"); - if (strncmp(stream_format, "adts", 4) == 0) - media_format_set_audio_aac_type(format, 1); - else - media_format_set_audio_aac_type(format, 0); + if (stream_format) { + if (strncmp(stream_format, "adts", 4) == 0) + media_format_set_audio_aac_type(format, 1); + else + media_format_set_audio_aac_type(format, 0); + } } else if (mpegversion == 1 || id3_flag) { gst_structure_get_int(struc, "layer", &layer); -- 2.7.4 From 1703d65a71d369a16f3d699de8d89d2d52de8617 Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Mon, 16 Oct 2017 16:57:46 +0900 Subject: [PATCH 15/16] Fix coverity issues [Version] 0.1.25 [Profile] Mobile, Wearable, TV [Issue Type] Fix coverity issues Change-Id: I8f45adbfd1e966f01aed84b25c109c3c6579681a --- packaging/capi-mediademuxer.spec | 2 +- src/port_gst/mediademuxer_port_gst.c | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/packaging/capi-mediademuxer.spec b/packaging/capi-mediademuxer.spec index cdd1708..d9fbcf1 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.24 +Version: 0.1.25 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 ae1adb7..c0f1a3e 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -708,11 +708,19 @@ static void __gst_on_pad_added(GstElement *element, GstPad *pad, gpointer data) while (tmp->next) tmp = tmp->next; - if (!tmp || !tmp->caps_string) { - MD_I("trak or trak caps_string is NULL\n"); + + if (!tmp) { + MD_I("trak is NULL\n"); + MEDIADEMUXER_FLEAVE(); + return; + } + + if (!tmp->caps_string) { + MD_I("trak caps_string is NULL\n"); MEDIADEMUXER_FLEAVE(); return; } + if (tmp->caps_string[0] == 'v') { MD_I("found Video Pad\n"); (head_track->num_video_track)++; -- 2.7.4 From 41497313433fa2f928c4a1e5de13817e1408b261 Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Thu, 19 Oct 2017 17:18:56 +0900 Subject: [PATCH 16/16] Fix coverity issues [Version] 0.1.25 [Profile] Mobile, Wearable, TV [Issue Type] Fix coverity issues Change-Id: I732f1610e3c9a906d1c952770606d61686f11cef --- src/port_gst/mediademuxer_port_gst.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/port_gst/mediademuxer_port_gst.c b/src/port_gst/mediademuxer_port_gst.c index c0f1a3e..fb745d1 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -706,13 +706,13 @@ static void __gst_on_pad_added(GstElement *element, GstPad *pad, gpointer data) return; } - while (tmp->next) + while (tmp->next) { tmp = tmp->next; - - if (!tmp) { - MD_I("trak is NULL\n"); - MEDIADEMUXER_FLEAVE(); - return; + if (!tmp) { + MD_I("trak is NULL\n"); + MEDIADEMUXER_FLEAVE(); + return; + } } if (!tmp->caps_string) { -- 2.7.4