From: Eunhye Choi Date: Tue, 21 May 2019 08:58:54 +0000 (+0900) Subject: [0.6.194] add new player path with uridecodebin3 X-Git-Tag: submit/tizen/20200413.123659~1^2~11 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ef0181bf72a3c92fb39b74170f6f2b0791df0df4;p=platform%2Fcore%2Fmultimedia%2Flibmm-player.git [0.6.194] add new player path with uridecodebin3 - add new player path with uridecodebin3 which use one audio/video decoder at a time even if there are many tracks - this is experimental feature and it is applied only for http streaming at the moment - ini file need to be modified to enable uridecodebin3 path Change-Id: I667ea0ae87930901308623e3ffcfd687c294795e --- diff --git a/packaging/libmm-player.spec b/packaging/libmm-player.spec index bcac4db..7b1eda9 100644 --- a/packaging/libmm-player.spec +++ b/packaging/libmm-player.spec @@ -1,6 +1,6 @@ Name: libmm-player Summary: Multimedia Framework Player Library -Version: 0.6.193 +Version: 0.6.194 Release: 0 Group: Multimedia/Libraries License: Apache-2.0 diff --git a/src/include/mm_player_ini.h b/src/include/mm_player_ini.h index f682052..a4e967e 100644 --- a/src/include/mm_player_ini.h +++ b/src/include/mm_player_ini.h @@ -81,6 +81,7 @@ typedef struct { gint delay_before_repeat; gint eos_delay; gboolean video_playback_supported; + gboolean use_uridecodebin3; /* experimental feature */ gchar gst_param[5][PLAYER_INI_MAX_PARAM_STRLEN]; gchar exclude_element_keyword[PLAYER_INI_MAX_ELEMENT][PLAYER_INI_MAX_STRLEN]; @@ -164,6 +165,7 @@ typedef struct { #define DEFAULT_NUM_OF_VIDEO_BO 10 #define DEFAULT_TIMEOUT_OF_VIDEO_BO 10 /* sec */ #define DEFAULT_AUDIO_OFFLOAD_SINK "" +#define DEFAULT_USE_URIDECODEBIN3 FALSE /* http streaming */ #define DEFAULT_HTTPSRC "souphttpsrc" diff --git a/src/include/mm_player_priv.h b/src/include/mm_player_priv.h index 82bfc47..c2e4443 100644 --- a/src/include/mm_player_priv.h +++ b/src/include/mm_player_priv.h @@ -164,6 +164,7 @@ typedef enum { /* it could be a decodebin or could be a typefind. depends on player ini */ MMPLAYER_M_TYPEFIND, MMPLAYER_M_AUTOPLUG, + MMPLAYER_M_AUTOPLUG_PARSEBIN, MMPLAYER_M_AUTOPLUG_V_DEC, MMPLAYER_M_AUTOPLUG_A_DEC, @@ -631,9 +632,9 @@ typedef struct { /* autoplugging */ GList *factories; - GList *audio_decoders; // list of linked audio name + GList *audio_decoders; /* list of linked audio name */ gboolean no_more_pad; - gint num_dynamic_pad; + gint num_dynamic_pad; /* only for rtsp */ gboolean has_many_types; /* progress callback timer */ @@ -872,6 +873,7 @@ int _mmplayer_set_replaygain_enabled(MMHandleType hplayer, bool enabled); int _mmplayer_is_replaygain_enabled(MMHandleType hplayer, bool *enabled); int _mmplayer_set_video_roi_area(MMHandleType hplayer, double scale_x, double scale_y, double scale_width, double scale_height); int _mmplayer_get_video_roi_area(MMHandleType hplayer, double *scale_x, double *scale_y, double *scale_width, double *scale_height); +int _mmplayer_set_client_pid(MMHandleType hplayer, int pid); /* internal */ void _mmplayer_bus_msg_thread_destroy(MMHandleType hplayer); @@ -893,7 +895,13 @@ int _mmplayer_gst_element_add_bucket_to_bin(GstBin *bin, GList *element_bucket); int _mmplayer_gst_element_link_bucket(GList *element_bucket); void _mmplayer_typefind_have_type(GstElement *tf, guint probability, GstCaps *caps, gpointer data); int _mmplayer_parse_profile(const char *uri, void *param, mmplayer_parse_profile_t *data); -int _mmplayer_set_client_pid(MMHandleType hplayer, int pid); + +void _mmplayer_gst_decode_pad_removed(GstElement *elem, GstPad *new_pad, gpointer data); +void _mmplayer_gst_decode_no_more_pads(GstElement *elem, gpointer data); +void _mmplayer_gst_decode_drained(GstElement *bin, gpointer data); +void _mmplayer_gst_decode_unknown_type(GstElement *elem, GstPad *pad, GstCaps *caps, gpointer data); +gboolean _mmplayer_gst_decode_autoplug_continue(GstElement *bin, GstPad *pad, GstCaps *caps, gpointer data); +void _mmplayer_pipeline_complete(GstElement *decodebin, gpointer data); #ifdef __cplusplus } diff --git a/src/include/mm_player_utils.h b/src/include/mm_player_utils.h index e0ffbc5..0255e94 100644 --- a/src/include/mm_player_utils.h +++ b/src/include/mm_player_utils.h @@ -282,6 +282,8 @@ #define MMPLAYER_STREAM_TYPE_GET_NAME(type) _mmplayer_get_stream_type_name(type) +#define MMPLAYER_USE_URIDECODEBIN3(x_player) _mmplayer_use_uridecodebin3(x_player) + /*=========================================================================================== | | | GLOBAL FUNCTION PROTOTYPES | @@ -300,6 +302,7 @@ gboolean _mmplayer_is_dash_streaming(mmplayer_t *player); gboolean _mmplayer_is_smooth_streaming(mmplayer_t *player); gboolean _mmplayer_is_ms_buff_src(mmplayer_t *player); gboolean _mmplayer_has_suffix(mmplayer_t *player, const gchar *suffix); +gboolean _mmplayer_use_uridecodebin3(mmplayer_t *player); gboolean _mmplayer_post_message(mmplayer_t *player, enum MMMessageType msgtype, MMMessageParamType *param); gboolean _mmplayer_dump_pipeline_state(mmplayer_t *player); diff --git a/src/mm_player_gst.c b/src/mm_player_gst.c index 4ec53c7..4eb339f 100644 --- a/src/mm_player_gst.c +++ b/src/mm_player_gst.c @@ -993,6 +993,7 @@ __mmplayer_gst_check_useful_message(mmplayer_t *player, GstMessage *message) case GST_MESSAGE_ELEMENT: case GST_MESSAGE_DURATION_CHANGED: case GST_MESSAGE_ASYNC_START: + case GST_MESSAGE_STREAM_COLLECTION: retval = TRUE; break; case GST_MESSAGE_ASYNC_DONE: @@ -1000,8 +1001,6 @@ __mmplayer_gst_check_useful_message(mmplayer_t *player, GstMessage *message) /* we only handle messages from pipeline */ if ((message->src == (GstObject *)player->pipeline->mainbin[MMPLAYER_M_PIPE].gst) && (!player->gapless.reconfigure)) retval = TRUE; - else - retval = FALSE; break; case GST_MESSAGE_BUFFERING: { @@ -1028,8 +1027,18 @@ __mmplayer_gst_check_useful_message(mmplayer_t *player, GstMessage *message) break; } + case GST_MESSAGE_STREAMS_SELECTED: + { + if (!MMPLAYER_USE_URIDECODEBIN3(player)) + break; /* drop msg */ + + LOGD("GST_MESSAGE_STREAMS_SELECTED"); + player->no_more_pad = TRUE; + _mmplayer_pipeline_complete(NULL, player); + retval = TRUE; + break; + } default: - retval = FALSE; break; } @@ -2033,6 +2042,12 @@ __mmplayer_gst_bus_msg_callback(GstMessage *msg, gpointer data) case GST_MESSAGE_ASYNC_DONE: __mmplayer_gst_handle_async_done_message(player, msg); break; + case GST_MESSAGE_STREAM_COLLECTION: + LOGD("GST_MESSAGE_STREAM_COLLECTION : %s", GST_ELEMENT_NAME(GST_MESSAGE_SRC(msg))); + break; + case GST_MESSAGE_STREAMS_SELECTED: + LOGD("GST_MESSAGE_STREAMS_SELECTED : %s", GST_ELEMENT_NAME(GST_MESSAGE_SRC(msg))); + break; #if 0 /* delete unnecessary logs */ case GST_MESSAGE_REQUEST_STATE: LOGD("GST_MESSAGE_REQUEST_STATE"); break; @@ -2645,7 +2660,7 @@ __mmplayer_gst_rtp_no_more_pads(GstElement *element, gpointer data) if (!_mmplayer_gst_remove_fakesink(player, &player->pipeline->mainbin[MMPLAYER_M_SRC_FAKESINK])) - /* NOTE : __mmplayer_pipeline_complete() can be called several time. because + /* NOTE : _mmplayer_pipeline_complete() can be called several time. because * signaling mechanism(pad-added, no-more-pad, new-decoded-pad) from various * source element are not same. To overcome this situation, this function will called * several places and several times. Therefore, this is not an error case. @@ -2703,6 +2718,187 @@ __mmplayer_gst_make_rtsp_src(mmplayer_t *player) return element; } +void __mmplayer_http_src_setup(GstElement *element, GstElement *source, gpointer data) +{ +#define HTTP_SOURCE_BLOCK_SIZE (64 * 1024) + + mmplayer_t *player = (mmplayer_t *)data; + MMHandleType attrs = 0; + gchar *user_agent, *cookies, **cookie_list; + gint http_timeout = DEFAULT_HTTP_TIMEOUT; + user_agent = cookies = NULL; + cookie_list = NULL; + + MMPLAYER_FENTER(); + MMPLAYER_RETURN_IF_FAIL(player); + + LOGD("source element %s", GST_ELEMENT_NAME(source)); + + /* get profile attribute */ + attrs = MMPLAYER_GET_ATTRS(player); + if (!attrs) { + LOGE("failed to get content attribute"); + return; + } + + player->pipeline->mainbin[MMPLAYER_M_SRC].id = MMPLAYER_M_SRC; + player->pipeline->mainbin[MMPLAYER_M_SRC].gst = source; + + /* get attribute */ + mm_attrs_get_string_by_name(attrs, "streaming_cookie", &cookies); + mm_attrs_get_string_by_name(attrs, "streaming_user_agent", &user_agent); + + if (player->ini.http_timeout != DEFAULT_HTTP_TIMEOUT) + http_timeout = player->ini.http_timeout; + + /* get attribute */ + SECURE_LOGD("cookies : %s", cookies); + SECURE_LOGD("user_agent : %s", user_agent); + LOGD("timeout : %d", http_timeout); + + /* setting property to streaming source */ + g_object_set(G_OBJECT(source), "timeout", http_timeout, "blocksize", (unsigned long)(HTTP_SOURCE_BLOCK_SIZE), NULL); + + /* parsing cookies */ + if ((cookie_list = _mmplayer_get_cookie_list((const char *)cookies))) { + g_object_set(G_OBJECT(source), "cookies", cookie_list, NULL); + g_strfreev(cookie_list); + } + + if (user_agent) + g_object_set(G_OBJECT(source), "user-agent", user_agent, NULL); + + MMPLAYER_FLEAVE(); + return; +} + +gint __mmplayer_gst_select_stream (GstElement * uridecodebin, GstStreamCollection * collection, + GstStream * stream, gpointer data) +{ + GstStreamType stype = gst_stream_get_stream_type (stream); + + if (stype & GST_STREAM_TYPE_AUDIO) + LOGW("AUDIO type 0x%X", stype); + else if (stype & GST_STREAM_TYPE_VIDEO) + LOGW("VIDEO type 0x%X", stype); + else if (stype & GST_STREAM_TYPE_TEXT) + LOGW("TEXT type 0x%X", stype); + + return 1; +} + +void +__mmplayer_gst_deep_element_added(GstElement *bin, GstBin *child, GstElement *element, gpointer data) +{ + gchar *factory_name = NULL; + mmplayer_t *player = (mmplayer_t *)data; + + factory_name = GST_OBJECT_NAME(gst_element_get_factory(element)); + + LOGD("%s > %s > %s : %s", GST_ELEMENT_NAME(bin), GST_ELEMENT_NAME(child), + factory_name, GST_ELEMENT_NAME(element)); + + /* keep the first typefind reference only */ + if (!player->pipeline->mainbin[MMPLAYER_M_TYPEFIND].gst && g_strrstr(factory_name, "typefind")) { + player->pipeline->mainbin[MMPLAYER_M_TYPEFIND].id = MMPLAYER_M_TYPEFIND; + player->pipeline->mainbin[MMPLAYER_M_TYPEFIND].gst = element; + + _mmplayer_add_signal_connection(player, G_OBJECT(element), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "have-type", G_CALLBACK(_mmplayer_typefind_have_type), (gpointer)player); + } else if (g_strrstr(factory_name, "parsebin")) { + player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG_PARSEBIN].id = MMPLAYER_M_AUTOPLUG_PARSEBIN; + player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG_PARSEBIN].gst = element; + _mmplayer_add_signal_connection(player, G_OBJECT(element), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "unknown-type", G_CALLBACK(_mmplayer_gst_decode_unknown_type), (gpointer)player); + + _mmplayer_add_signal_connection(player, G_OBJECT(element), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-continue", G_CALLBACK(_mmplayer_gst_decode_autoplug_continue), (gpointer)player); + + _mmplayer_add_signal_connection(player, G_OBJECT(element), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-select", G_CALLBACK(_mmplayer_gst_decode_autoplug_select), (gpointer)player); + } else { + _mmplayer_gst_element_added((GstElement *)child, element, data); + } + + return; +} + +void +__mmplayer_gst_deep_element_removed(GstElement *bin, GstBin *child, GstElement *element, gpointer data) +{ + LOGD("%s > %s > %s", GST_ELEMENT_NAME(bin), GST_ELEMENT_NAME(child), GST_ELEMENT_NAME(element)); + return; +} + +static GstElement * +__mmplayer_gst_make_uridecodebin(mmplayer_t *player) +{ + GstElement *uridecodebin3 = NULL; + GstElement *decodebin3 = NULL, *multiqueue = NULL; + + MMPLAYER_FENTER(); + MMPLAYER_RETURN_VAL_IF_FAIL(player, NULL); + + uridecodebin3 = gst_element_factory_make("uridecodebin3", "uridecodebin3"); + if (!uridecodebin3) { + LOGE("failed to create uridecodebin3"); + return NULL; + } + + /* get attribute */ + SECURE_LOGD("uri : %s", player->profile.uri); + + decodebin3 = gst_bin_get_by_name((GstBin *)uridecodebin3, "decodebin3-0"); + + if (decodebin3) { + g_object_set(G_OBJECT(decodebin3), "message-forward", TRUE, NULL); + multiqueue = gst_bin_get_by_name((GstBin *)decodebin3, "multiqueue0"); + } + + if (multiqueue) { + player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].id = MMPLAYER_M_DEMUXED_S_BUFFER; + player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst = multiqueue; + + /* in case of multiqueue, max bytes size is defined with fixed value in mm_player_streaming.h */ + _mm_player_streaming_set_multiqueue(player->streamer, multiqueue); + } + + /* setting property to streaming source */ + g_object_set(G_OBJECT(uridecodebin3), "uri", player->profile.uri, "message-forward", TRUE, NULL); + + _mmplayer_add_signal_connection(player, G_OBJECT(uridecodebin3), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "source-setup", G_CALLBACK(__mmplayer_http_src_setup), (gpointer)player); + + _mmplayer_add_signal_connection(player, G_OBJECT(uridecodebin3), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added", G_CALLBACK(_mmplayer_gst_decode_pad_added), (gpointer)player); + + _mmplayer_add_signal_connection(player, G_OBJECT(uridecodebin3), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-removed", G_CALLBACK(_mmplayer_gst_decode_pad_removed), (gpointer)player); + + _mmplayer_add_signal_connection(player, G_OBJECT(uridecodebin3), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "no-more-pads", G_CALLBACK(_mmplayer_gst_decode_no_more_pads), (gpointer)player); + + _mmplayer_add_signal_connection(player, G_OBJECT(uridecodebin3), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "select-stream", G_CALLBACK(__mmplayer_gst_select_stream), (gpointer)player); + +/* FIXME: need to be added for gapless playback + _mmplayer_add_signal_connection(player, G_OBJECT(element), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "about-to-finish", G_CALLBACK(_mmplayer_gst_decode_drained), (gpointer)player); +*/ + + _mmplayer_add_signal_connection(player, G_OBJECT(uridecodebin3), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "deep-element-added", G_CALLBACK(__mmplayer_gst_deep_element_added), (gpointer)player); + + _mmplayer_add_signal_connection(player, G_OBJECT(uridecodebin3), + MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "deep-element-removed", G_CALLBACK(__mmplayer_gst_deep_element_removed), (gpointer)player); + + if (MMPLAYER_URL_HAS_DASH_SUFFIX(player)) + LOGW("[DASH] this is still experimental feature"); + + MMPLAYER_FLEAVE(); + return uridecodebin3; +} + static GstElement * __mmplayer_gst_make_http_src(mmplayer_t *player) { @@ -3197,9 +3393,11 @@ _mmplayer_gst_pause(mmplayer_t *player, gboolean async) return ret; } - if ((!MMPLAYER_IS_RTSP_STREAMING(player)) && (!player->video_decoded_cb) && - (!player->pipeline->videobin) && (!player->pipeline->audiobin)) - return MM_ERROR_PLAYER_CODEC_NOT_FOUND; + if (!MMPLAYER_USE_URIDECODEBIN3(player)) { + if ((!MMPLAYER_IS_RTSP_STREAMING(player)) && (!player->video_decoded_cb) && + (!player->pipeline->videobin) && (!player->pipeline->audiobin)) + return MM_ERROR_PLAYER_CODEC_NOT_FOUND; + } MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_PAUSED); @@ -3741,6 +3939,8 @@ _mmplayer_gst_build_pipeline(mmplayer_t *player) MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->mainbin, MM_ERROR_PLAYER_NOT_INITIALIZED); + mainbin = player->pipeline->mainbin; + /* get profile attribute */ attrs = MMPLAYER_GET_ATTRS(player); if (!attrs) { @@ -3756,6 +3956,10 @@ _mmplayer_gst_build_pipeline(mmplayer_t *player) src_elem = __mmplayer_gst_make_rtsp_src(player); break; case MM_PLAYER_URI_TYPE_URL_HTTP: + if (player->ini.use_uridecodebin3) { /* or MMPLAYER_USE_URIDECODEBIN3(player) */ + LOGD("uridecodebin include src element."); + goto ADD_DECODEBIN; + } src_elem = __mmplayer_gst_make_http_src(player); break; case MM_PLAYER_URI_TYPE_FILE: @@ -3808,8 +4012,6 @@ _mmplayer_gst_build_pipeline(mmplayer_t *player) return MM_ERROR_PLAYER_INTERNAL; } - mainbin = player->pipeline->mainbin; - /* take source element */ LOGD("source elem is created %s", GST_ELEMENT_NAME(src_elem)); @@ -3817,17 +4019,25 @@ _mmplayer_gst_build_pipeline(mmplayer_t *player) mainbin[MMPLAYER_M_SRC].gst = src_elem; element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_SRC]); - /* create next element for auto-plugging */ +ADD_DECODEBIN: /* create next element for auto-plugging */ if (MMPLAYER_IS_HTTP_STREAMING(player)) { - autoplug_elem_id = MMPLAYER_M_TYPEFIND; - autoplug_elem = gst_element_factory_make("typefind", "typefinder"); - if (!autoplug_elem) { - LOGE("failed to create typefind element"); - goto ERROR; + if (!src_elem) { /* make uridecodebin3 which include src element */ + autoplug_elem_id = MMPLAYER_M_AUTOPLUG; + autoplug_elem = __mmplayer_gst_make_uridecodebin(player); + if (!autoplug_elem) { + LOGE("failed to create uridecodebin3 element"); + goto ERROR; + } + } else { + autoplug_elem_id = MMPLAYER_M_TYPEFIND; + autoplug_elem = gst_element_factory_make("typefind", "typefinder"); + if (!autoplug_elem) { + LOGE("failed to create typefind element"); + goto ERROR; + } + _mmplayer_add_signal_connection(player, G_OBJECT(autoplug_elem), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "have-type", + G_CALLBACK(_mmplayer_typefind_have_type), (gpointer)player); } - - _mmplayer_add_signal_connection(player, G_OBJECT(autoplug_elem), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "have-type", - G_CALLBACK(_mmplayer_typefind_have_type), (gpointer)player); } else if (!MMPLAYER_IS_RTSP_STREAMING(player)) { autoplug_elem_id = MMPLAYER_M_AUTOPLUG; autoplug_elem = _mmplayer_gst_make_decodebin(player); @@ -3861,7 +4071,6 @@ _mmplayer_gst_build_pipeline(mmplayer_t *player) goto ERROR; } - /* FIXME: need to check whether this is required or not. */ if (MMPLAYER_IS_HTTP_STREAMING(player) || MMPLAYER_IS_RTSP_STREAMING(player)) { /* create fakesink element for keeping the pipeline state PAUSED. if needed */ mainbin[MMPLAYER_M_SRC_FAKESINK].id = MMPLAYER_M_SRC_FAKESINK; diff --git a/src/mm_player_ini.c b/src/mm_player_ini.c index 34a9dd6..b995465 100644 --- a/src/mm_player_ini.c +++ b/src/mm_player_ini.c @@ -152,6 +152,7 @@ mm_player_ini_load(mmplayer_ini_t *ini) ini->pcm_buffer_size = iniparser_getint(dict, "general:pcm buffer size", DEFAULT_PCM_BUFFER_SIZE); ini->num_of_video_bo = iniparser_getint(dict, "general:video bo max", DEFAULT_NUM_OF_VIDEO_BO); ini->video_bo_timeout = iniparser_getint(dict, "general:video bo timeout", DEFAULT_TIMEOUT_OF_VIDEO_BO); + ini->use_uridecodebin3 = iniparser_getboolean(dict, "general:use uridecodebin3", DEFAULT_USE_URIDECODEBIN3); MMPLAYER_INI_GET_STRING(dict, ini->audioresampler_element, "general:audio resampler element", DEFAULT_AUDIORESAMPLER); MMPLAYER_INI_GET_STRING(dict, ini->audiocodec_element_hw, "general:audio codec element hw", DEFAULT_CODEC_HW); @@ -214,6 +215,7 @@ mm_player_ini_load(mmplayer_ini_t *ini) ini->pcm_buffer_size = DEFAULT_PCM_BUFFER_SIZE; ini->num_of_video_bo = DEFAULT_NUM_OF_VIDEO_BO; ini->video_bo_timeout = DEFAULT_TIMEOUT_OF_VIDEO_BO; + ini->use_uridecodebin3 = DEFAULT_USE_URIDECODEBIN3; strncpy(ini->audioresampler_element, DEFAULT_AUDIORESAMPLER, PLAYER_INI_MAX_STRLEN - 1); strncpy(ini->audiosink_element, DEFAULT_AUDIOSINK, PLAYER_INI_MAX_STRLEN - 1); @@ -283,6 +285,7 @@ mm_player_ini_load(mmplayer_ini_t *ini) LOGD("gst param3 : %s", ini->gst_param[2]); LOGD("gst param4 : %s", ini->gst_param[3]); LOGD("gst param5 : %s", ini->gst_param[4]); + LOGD("use uridecodebin3 : %d", ini->use_uridecodebin3); for (idx = 0; ini->exclude_element_keyword[idx][0] != '\0'; idx++) LOGD("exclude_element_keyword [%d] : %s", idx, ini->exclude_element_keyword[idx]); diff --git a/src/mm_player_priv.c b/src/mm_player_priv.c index ce103ae..0cc1ecc 100644 --- a/src/mm_player_priv.c +++ b/src/mm_player_priv.c @@ -142,16 +142,10 @@ static int __mmplayer_gst_create_video_sink_bin(mmplayer_t *player, GstCaps *ca static int __mmplayer_gst_create_audio_sink_bin(mmplayer_t *player); static int __mmplayer_gst_create_text_sink_bin(mmplayer_t *player); -static void __mmplayer_gst_decode_no_more_pads(GstElement *elem, gpointer data); static void __mmplayer_gst_create_sinkbin(GstElement *decodebin, GstPad *pad, gpointer data); -static void __mmplayer_gst_decode_unknown_type(GstElement *elem, GstPad *pad, GstCaps *caps, gpointer data); -static gboolean __mmplayer_gst_decode_autoplug_continue(GstElement *bin, GstPad *pad, GstCaps *caps, gpointer data); -static void __mmplayer_gst_decode_pad_removed(GstElement *elem, GstPad *new_pad, gpointer data); -static void __mmplayer_gst_decode_drained(GstElement *bin, gpointer data); -static void __mmplayer_pipeline_complete(GstElement *decodebin, gpointer data); static gboolean __mmplayer_is_midi_type(gchar *str_caps); static gboolean __mmplayer_is_only_mp3_type(gchar *str_caps); -static void __mmplayer_set_audio_attrs(mmplayer_t *player, GstCaps *caps); +static void __mmplayer_set_audio_attrs(mmplayer_t *player, GstCaps *caps); static gboolean __mmplayer_update_subtitle(GstElement *object, GstBuffer *buffer, GstPad *pad, gpointer data); static void __mmplayer_release_misc(mmplayer_t *player); @@ -1239,7 +1233,7 @@ _mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data) LOGD("surface type : %d", stype); - if (MMPLAYER_IS_MS_BUFF_SRC(player)) { + if (MMPLAYER_IS_MS_BUFF_SRC(player) || MMPLAYER_USE_URIDECODEBIN3(player)) { __mmplayer_gst_create_sinkbin(elem, pad, player); goto DONE; } @@ -1258,7 +1252,7 @@ _mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data) gint samplerate = 0; gint channels = 0; - if (MMPLAYER_IS_MS_BUFF_SRC(player) || player->build_audio_offload) { + if (MMPLAYER_IS_MS_BUFF_SRC(player) || MMPLAYER_USE_URIDECODEBIN3(player) || player->build_audio_offload) { if (player->build_audio_offload) player->no_more_pad = TRUE; /* remove state holder */ __mmplayer_gst_create_sinkbin(elem, pad, player); @@ -1426,7 +1420,7 @@ __mmplayer_create_audio_sink_path(mmplayer_t *player, GstElement *audio_selector } if (player->num_dynamic_pad == 0) /* FIXME: num_dynamic_pad is only for rtsp? */ - __mmplayer_pipeline_complete(NULL, player); + _mmplayer_pipeline_complete(NULL, player); return TRUE; } @@ -1497,8 +1491,8 @@ __mmplayer_gst_set_queue2_buffering(mmplayer_t *player) return TRUE; } -static void -__mmplayer_gst_decode_no_more_pads(GstElement *elem, gpointer data) +void +_mmplayer_gst_decode_no_more_pads(GstElement *elem, gpointer data) { mmplayer_t *player = NULL; GstElement *video_selector = NULL; @@ -1744,7 +1738,7 @@ __mmplayer_gst_create_sinkbin(GstElement *elem, GstPad *pad, gpointer data) LOGD("no more pads: %d, stream count dec : %d(num of dynamic pad)", player->no_more_pad, player->num_dynamic_pad); if ((player->no_more_pad) && (player->num_dynamic_pad == 0)) - __mmplayer_pipeline_complete(NULL, player); + _mmplayer_pipeline_complete(NULL, player); ERROR: @@ -5953,21 +5947,20 @@ _mmplayer_typefind_have_type(GstElement *tf, guint probability, return; } - if (!_mmplayer_gst_create_decoder(player, pad, caps)) { - gboolean async = FALSE; - LOGE("failed to autoplug %s", player->type); + if (!player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst) { + if (!_mmplayer_gst_create_decoder(player, pad, caps)) { + gboolean async = FALSE; + LOGE("failed to autoplug %s", player->type); - mm_attrs_get_int_by_name(player->attrs, "profile_prepare_async", &async); - - if (async && player->msg_posted == FALSE) - __mmplayer_handle_missed_plugin(player); + mm_attrs_get_int_by_name(player->attrs, "profile_prepare_async", &async); + if (async && player->msg_posted == FALSE) + __mmplayer_handle_missed_plugin(player); + } } gst_object_unref(GST_OBJECT(pad)); - MMPLAYER_FLEAVE(); - return; } @@ -5992,20 +5985,20 @@ _mmplayer_gst_make_decodebin(mmplayer_t *player) /* no-more-pad pad handling signal */ _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "no-more-pads", - G_CALLBACK(__mmplayer_gst_decode_no_more_pads), (gpointer)player); + G_CALLBACK(_mmplayer_gst_decode_no_more_pads), (gpointer)player); _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-removed", - G_CALLBACK(__mmplayer_gst_decode_pad_removed), (gpointer)player); + G_CALLBACK(_mmplayer_gst_decode_pad_removed), (gpointer)player); /* This signal is emitted when a pad for which there is no further possible decoding is added to the decodebin.*/ _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "unknown-type", - G_CALLBACK(__mmplayer_gst_decode_unknown_type), (gpointer)player); + G_CALLBACK(_mmplayer_gst_decode_unknown_type), (gpointer)player); /* This signal is emitted whenever decodebin finds a new stream. It is emitted before looking for any elements that can handle that stream.*/ _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-continue", - G_CALLBACK(__mmplayer_gst_decode_autoplug_continue), (gpointer)player); + G_CALLBACK(_mmplayer_gst_decode_autoplug_continue), (gpointer)player); /* This signal is emitted whenever decodebin finds a new stream. It is emitted before looking for any elements that can handle that stream.*/ @@ -6014,7 +6007,7 @@ _mmplayer_gst_make_decodebin(mmplayer_t *player) /* This signal is emitted once decodebin has finished decoding all the data.*/ _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "drained", - G_CALLBACK(__mmplayer_gst_decode_drained), (gpointer)player); + G_CALLBACK(_mmplayer_gst_decode_drained), (gpointer)player); /* This signal is emitted when a element is added to the bin.*/ _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "element-added", @@ -6282,8 +6275,8 @@ DONE: return MM_ERROR_NONE; } -static void -__mmplayer_pipeline_complete(GstElement *decodebin, gpointer data) +void +_mmplayer_pipeline_complete(GstElement *decodebin, gpointer data) { mmplayer_t *player = (mmplayer_t *)data; @@ -6294,7 +6287,7 @@ __mmplayer_pipeline_complete(GstElement *decodebin, gpointer data) /* remove fakesink. */ if (!_mmplayer_gst_remove_fakesink(player, &player->pipeline->mainbin[MMPLAYER_M_SRC_FAKESINK])) { - /* NOTE : __mmplayer_pipeline_complete() can be called several time. because + /* NOTE : _mmplayer_pipeline_complete() can be called several time. because * signaling mechanism(pad-added, no-more-pad, new-decoded-pad) from various * source element are not same. To overcome this situation, this function will called * several places and several times. Therefore, this is not an error case. @@ -6715,8 +6708,8 @@ _mmplayer_get_next_uri(MMHandleType hplayer, char **uri) return MM_ERROR_NONE; } -static void -__mmplayer_gst_decode_unknown_type(GstElement *elem, GstPad *pad, +void +_mmplayer_gst_decode_unknown_type(GstElement *elem, GstPad *pad, GstCaps *caps, gpointer data) { mmplayer_t *player = (mmplayer_t *)data; @@ -6737,9 +6730,9 @@ __mmplayer_gst_decode_unknown_type(GstElement *elem, GstPad *pad, __mmplayer_check_not_supported_codec(player, klass, mime); } -static gboolean -__mmplayer_gst_decode_autoplug_continue(GstElement *bin, GstPad *pad, - GstCaps *caps, gpointer data) +gboolean +_mmplayer_gst_decode_autoplug_continue(GstElement *bin, GstPad *pad, + GstCaps *caps, gpointer data) { mmplayer_t *player = (mmplayer_t *)data; const char *mime = NULL; @@ -7216,8 +7209,8 @@ DONE: return result; } -static void -__mmplayer_gst_decode_pad_removed(GstElement *elem, GstPad *new_pad, +void +_mmplayer_gst_decode_pad_removed(GstElement *elem, GstPad *new_pad, gpointer data) { //mmplayer_t *player = (mmplayer_t *)data; @@ -7240,8 +7233,8 @@ __mmplayer_gst_decode_pad_removed(GstElement *elem, GstPad *new_pad, gst_caps_unref(caps); } -static void -__mmplayer_gst_decode_drained(GstElement *bin, gpointer data) +void +_mmplayer_gst_decode_drained(GstElement *bin, gpointer data) { mmplayer_t *player = (mmplayer_t *)data; GstIterator *iter = NULL; @@ -7253,7 +7246,7 @@ __mmplayer_gst_decode_drained(GstElement *bin, gpointer data) MMPLAYER_FENTER(); MMPLAYER_RETURN_IF_FAIL(player); - LOGD("__mmplayer_gst_decode_drained"); + LOGD("got drained signal"); if (!MMPLAYER_CMD_TRYLOCK(player)) { LOGW("Fail to get cmd lock"); diff --git a/src/mm_player_utils.c b/src/mm_player_utils.c index a88ca2d..ec9f954 100644 --- a/src/mm_player_utils.c +++ b/src/mm_player_utils.c @@ -608,3 +608,18 @@ media_format_mimetype_e _mmplayer_convert_audio_pcm_str_to_media_format_mime(con return MEDIA_FORMAT_MAX; } } + +gboolean _mmplayer_use_uridecodebin3(mmplayer_t *player) /* MMPLAYER_USE_URIDECODEBIN3(player) */ +{ + MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE); + + if (!player->ini.use_uridecodebin3) + return FALSE; + + if (MMPLAYER_IS_HTTP_STREAMING(player) || + MMPLAYER_IS_HTTP_LIVE_STREAMING(player) || + MMPLAYER_IS_DASH_STREAMING(player)) + return TRUE; + + return FALSE; +}