X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fmm_player_priv.c;h=3689bed668f0c5bdf13a2435a038623deeee1eff;hb=refs%2Ftags%2Faccepted%2Ftizen%2Funified%2F20240219.160358;hp=6f88332d1a2ed99d5500129ce9a8ad08f99dc278;hpb=da579a79154e8f83e1465ea0c2b30a40c0451d61;p=platform%2Fcore%2Fmultimedia%2Flibmm-player.git diff --git a/src/mm_player_priv.c b/src/mm_player_priv.c index 6f88332..3689bed 100644 --- a/src/mm_player_priv.c +++ b/src/mm_player_priv.c @@ -107,6 +107,8 @@ #define DEFAULT_PCM_OUT_SAMPLERATE 44100 #define DEFAULT_PCM_OUT_CHANNEL 2 +#define MQ_UNLINKED_CACHE_TIME (500 * GST_MSECOND) + /*--------------------------------------------------------------------------- | LOCAL CONSTANT DEFINITIONS: | ---------------------------------------------------------------------------*/ @@ -156,7 +158,6 @@ static int __mmplayer_change_selector_pad(mmplayer_t *player, mmplayer_track_typ static gboolean __mmplayer_check_subtitle(mmplayer_t *player); static int __mmplayer_handle_missed_plugin(mmplayer_t *player); -static int __mmplayer_check_not_supported_codec(mmplayer_t *player, const gchar *factory_class, const gchar *mime); static void __mmplayer_add_sink(mmplayer_t *player, GstElement *sink, gboolean first); static void __mmplayer_del_sink(mmplayer_t *player, GstElement *sink); static void __mmplayer_release_signal_connection(mmplayer_t *player, mmplayer_signal_type_e type); @@ -745,11 +746,16 @@ __mmplayer_gapless_play_thread(gpointer data) mainbin = player->pipeline->mainbin; - MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_MUXED_S_BUFFER); - MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_ID3DEMUX); - MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_AUTOPLUG); - MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_TYPEFIND); - MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_SRC); + if (MMPLAYER_USE_DECODEBIN(player)) { + MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_MUXED_S_BUFFER); + MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_AUTOPLUG); /* decodebin */ + MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_TYPEFIND); + MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_SRC); + } else { + MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_AUTOPLUG); /* uridecodebin */ + mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst = NULL; + mainbin[MMPLAYER_M_SRC].gst = NULL; + } /* Initialize Player values */ __mmplayer_initialize_gapless_play(player); @@ -913,7 +919,7 @@ ERROR: } static GstPadProbeReturn -__mmplayer_gst_selector_blocked(GstPad *pad, GstPadProbeInfo *info, gpointer data) +__mmplayer_gst_combiner_blocked(GstPad *pad, GstPadProbeInfo *info, gpointer data) { LOGD("pad(%s:%s) is blocked", GST_DEBUG_PAD_NAME(pad)); return GST_PAD_PROBE_OK; @@ -982,7 +988,7 @@ __mmplayer_gst_selector_update_start_time(mmplayer_t *player, mmplayer_track_typ } static GstPadProbeReturn -__mmplayer_gst_selector_event_probe(GstPad *pad, GstPadProbeInfo *info, gpointer data) +__mmplayer_gst_combiner_event_probe(GstPad *pad, GstPadProbeInfo *info, gpointer data) { GstPadProbeReturn ret = GST_PAD_PROBE_OK; GstEvent *event = GST_PAD_PROBE_INFO_DATA(info); @@ -1001,7 +1007,23 @@ __mmplayer_gst_selector_event_probe(GstPad *pad, GstPadProbeInfo *info, gpointer return ret; MMPLAYER_GST_GET_CAPS_INFO_FROM_PAD(pad, caps, str, name, caps_ret); - if (!caps_ret) + if (!caps_ret) { + GstStream *stream = NULL; + + if (GST_EVENT_TYPE(event) != GST_EVENT_STREAM_START) + goto ERROR; + + gst_event_parse_stream (event, &stream); + if (stream == NULL) { + LOGW ("Got a STREAM_START event without a GstStream"); + goto ERROR; + } + + name = gst_stream_type_get_name(gst_stream_get_stream_type(stream)); + gst_object_unref (stream); + } + + if (!name) goto ERROR; if (strstr(name, "audio")) { @@ -1018,10 +1040,12 @@ __mmplayer_gst_selector_event_probe(GstPad *pad, GstPadProbeInfo *info, gpointer case GST_EVENT_EOS: { /* in case of gapless, drop eos event not to send it to sink */ + MMPLAYER_RECONFIGURE_LOCK(player); if (player->gapless.reconfigure && !player->msg_posted) { LOGD("[%d] %s:%s EOS received but will be drop", stream_type, GST_DEBUG_PAD_NAME(pad)); ret = GST_PAD_PROBE_DROP; } + MMPLAYER_RECONFIGURE_UNLOCK(player); break; } case GST_EVENT_STREAM_START: @@ -1199,10 +1223,11 @@ ERROR: } static GstElement * -__mmplayer_gst_make_concat(mmplayer_t *player, main_element_id_e elem_idx) +__mmplayer_gst_make_concat(mmplayer_t *player, main_element_id_e elem_idx, mmplayer_track_type_e stream_type) { GstElement *pipeline = NULL; - GstElement *concat = NULL; + g_autoptr(GstElement) concat = NULL; + g_autoptr(GstPad) srcpad = NULL; MMPLAYER_FENTER(); MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->mainbin, NULL); @@ -1213,13 +1238,21 @@ __mmplayer_gst_make_concat(mmplayer_t *player, main_element_id_e elem_idx) return NULL; } + srcpad = gst_element_get_static_pad(concat, "src"); + + LOGD("blocking %s:%s", GST_DEBUG_PAD_NAME(srcpad)); + player->track[stream_type].block_id = gst_pad_add_probe(srcpad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, + __mmplayer_gst_combiner_blocked, NULL, NULL); + player->track[stream_type].event_probe_id = gst_pad_add_probe(srcpad, GST_PAD_PROBE_TYPE_EVENT_BOTH|GST_PAD_PROBE_TYPE_EVENT_FLUSH, + __mmplayer_gst_combiner_event_probe, player, NULL); + + gst_element_set_state(concat, GST_STATE_PAUSED); pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst; if (!gst_bin_add(GST_BIN(pipeline), concat)) { LOGE("failed to add concat to pipeline"); gst_element_set_state(concat, GST_STATE_NULL); - gst_object_unref(GST_OBJECT(concat)); return NULL; } @@ -1229,7 +1262,7 @@ __mmplayer_gst_make_concat(mmplayer_t *player, main_element_id_e elem_idx) player->pipeline->mainbin[elem_idx].gst = concat; MMPLAYER_FLEAVE(); - return concat; + return g_steal_pointer(&concat); } static GstElement * @@ -1253,9 +1286,9 @@ __mmplayer_gst_make_selector(mmplayer_t *player, main_element_id_e elem_idx, mmp LOGD("blocking %s:%s", GST_DEBUG_PAD_NAME(srcpad)); player->track[stream_type].block_id = gst_pad_add_probe(srcpad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, - __mmplayer_gst_selector_blocked, NULL, NULL); + __mmplayer_gst_combiner_blocked, NULL, NULL); player->track[stream_type].event_probe_id = gst_pad_add_probe(srcpad, GST_PAD_PROBE_TYPE_EVENT_BOTH|GST_PAD_PROBE_TYPE_EVENT_FLUSH, - __mmplayer_gst_selector_event_probe, player, NULL); + __mmplayer_gst_combiner_event_probe, player, NULL); gst_element_set_state(selector, GST_STATE_PAUSED); @@ -1400,7 +1433,7 @@ _mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data) if (MMPLAYER_USE_DECODEBIN(player)) combiner = __mmplayer_gst_make_selector(player, elem_idx, stream_type); else - combiner = __mmplayer_gst_make_concat(player, elem_idx); + combiner = __mmplayer_gst_make_concat(player, elem_idx, stream_type); if (!combiner) goto ERROR; @@ -1410,7 +1443,7 @@ _mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data) } /* link */ - sinkpad = gst_element_get_request_pad(combiner, "sink_%u"); + sinkpad = gst_element_request_pad_simple(combiner, "sink_%u"); LOGD("pad link: %s:%s - %s:%s", GST_DEBUG_PAD_NAME(pad), GST_DEBUG_PAD_NAME(sinkpad)); @@ -4228,9 +4261,9 @@ __mmplayer_update_subtitle(GstElement *object, GstBuffer *buffer, GstPad *pad, g LOGI("subtitle duration is invalid, subtitle duration change " "GST_CLOCK_TIME_NONE -> %" GST_TIME_FORMAT, GST_TIME_ARGS(duration)); } - msg.subtitle.duration = GST_TIME_AS_MSECONDS(duration); + msg.subtitle.duration = (unsigned long)GST_TIME_AS_MSECONDS(duration); - LOGD("update subtitle : [%ld msec] %s", msg.subtitle.duration, (char *)msg.data); + LOGD("update subtitle : [%lu msec] %s", msg.subtitle.duration, (char *)msg.data); MMPLAYER_POST_MSG(player, MM_MESSAGE_UPDATE_SUBTITLE, &msg); gst_buffer_unmap(buffer, &mapinfo); @@ -4248,17 +4281,13 @@ __mmplayer_subtitle_adjust_position_probe(GstPad *pad, GstPadProbeInfo *info, gp gint64 adjusted_timestamp = 0; GstBuffer *buffer = gst_pad_probe_info_get_buffer(info); - MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE); + MMPLAYER_RETURN_VAL_IF_FAIL(player, GST_PAD_PROBE_DROP); - if (player->set_mode.subtitle_off) { - LOGD("subtitle is OFF."); - return TRUE; - } + if (player->set_mode.subtitle_off) + return GST_PAD_PROBE_OK; - if (player->adjust_subtitle_pos == 0) { - LOGD("nothing to do"); - return TRUE; - } + if (player->adjust_subtitle_pos == 0) + return GST_PAD_PROBE_OK; cur_timestamp = GST_BUFFER_TIMESTAMP(buffer); adjusted_timestamp = (gint64)cur_timestamp + ((gint64)player->adjust_subtitle_pos * G_GINT64_CONSTANT(1000000)); @@ -4266,7 +4295,7 @@ __mmplayer_subtitle_adjust_position_probe(GstPad *pad, GstPadProbeInfo *info, gp if (adjusted_timestamp < 0) { LOGD("adjusted_timestamp under zero"); MMPLAYER_FLEAVE(); - return FALSE; + return GST_PAD_PROBE_DROP; } GST_BUFFER_TIMESTAMP(buffer) = (GstClockTime) adjusted_timestamp; @@ -4414,7 +4443,7 @@ __mmplayer_gst_destroy_pipeline(mmplayer_t *player) MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_INVALID_HANDLE); /* cleanup stuffs */ - MMPLAYER_FREEIF(player->type); + MMPLAYER_FREEIF(player->type_caps_str); player->no_more_pad = FALSE; player->num_dynamic_pad = 0; @@ -4481,11 +4510,6 @@ __mmplayer_gst_destroy_pipeline(mmplayer_t *player) } MMPLAYER_FREEIF(player->album_art); - if (player->type_caps) { - gst_caps_unref(player->type_caps); - player->type_caps = NULL; - } - if (player->v_stream_caps) { gst_caps_unref(player->v_stream_caps); player->v_stream_caps = NULL; @@ -5915,7 +5939,7 @@ _mmplayer_get_duration(MMHandleType hplayer, gint64 *duration) MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED); MMPLAYER_RETURN_VAL_IF_FAIL(duration, MM_ERROR_COMMON_INVALID_ARGUMENT); - if (g_strrstr(player->type, "video/mpegts")) + if (g_strrstr(player->type_caps_str, "video/mpegts")) __mmplayer_update_duration_value(player); *duration = player->duration; @@ -6005,9 +6029,9 @@ static void __mmplayer_update_content_type_info(mmplayer_t *player) { MMPLAYER_FENTER(); - MMPLAYER_RETURN_IF_FAIL(player && player->type); + MMPLAYER_RETURN_IF_FAIL(player && player->type_caps_str); - if (__mmplayer_is_midi_type(player->type)) { + if (__mmplayer_is_midi_type(player->type_caps_str)) { player->bypass_audio_effect = TRUE; return; } @@ -6017,19 +6041,19 @@ __mmplayer_update_content_type_info(mmplayer_t *player) return; } - if (g_strrstr(player->type, "application/x-hls")) { + if (g_strrstr(player->type_caps_str, "application/x-hls")) { /* If it can't know exact type when it parses uri because of redirection case, * it will be fixed by typefinder or when doing autoplugging. */ player->profile.uri_type = MM_PLAYER_URI_TYPE_HLS; player->streamer->is_adaptive_streaming = TRUE; - } else if (g_strrstr(player->type, "application/dash+xml")) { + } else if (g_strrstr(player->type_caps_str, "application/dash+xml")) { player->profile.uri_type = MM_PLAYER_URI_TYPE_DASH; player->streamer->is_adaptive_streaming = TRUE; } /* in case of TS, fixed buffering mode should be used because player can not get exact duration time */ - if ((player->streamer->is_adaptive_streaming) || (g_strrstr(player->type, "video/mpegts"))) { + if ((player->streamer->is_adaptive_streaming) || (g_strrstr(player->type_caps_str, "video/mpegts"))) { player->streamer->buffering_req.mode = MM_PLAYER_BUFFERING_MODE_FIXED; if (player->streamer->buffering_req.rebuffer_time <= MIN_BUFFERING_TIME) { /* if user did not set the rebuffer value */ @@ -6054,23 +6078,13 @@ _mmplayer_typefind_have_type(GstElement *tf, guint probability, MMPLAYER_RETURN_IF_FAIL(player && tf && caps); - /* store type string */ - if (player->type_caps) { - gst_caps_unref(player->type_caps); - player->type_caps = NULL; - } - - player->type_caps = gst_caps_copy(caps); - MMPLAYER_LOG_GST_CAPS_TYPE(player->type_caps); - - MMPLAYER_FREEIF(player->type); - player->type = gst_caps_to_string(caps); - if (player->type) - LOGD("[handle: %p] media type %s found, probability %d%% / %d", - player, player->type, probability, gst_caps_get_size(caps)); + MMPLAYER_FREEIF(player->type_caps_str); + player->type_caps_str = gst_caps_to_string(caps); + LOGD("[handle: %p] media type %s found, probability %d%% / %d", + player, player->type_caps_str, probability, gst_caps_get_size(caps)); if ((!MMPLAYER_IS_RTSP_STREAMING(player)) && - (g_strrstr(player->type, "audio/x-raw-int"))) { + (g_strrstr(player->type_caps_str, "audio/x-raw-int"))) { LOGE("not support media format"); if (player->msg_posted == FALSE) { @@ -6099,7 +6113,7 @@ _mmplayer_typefind_have_type(GstElement *tf, guint probability, if (!_mmplayer_gst_create_decoder(player, pad, caps)) { gboolean async = FALSE; - LOGE("failed to autoplug %s", player->type); + LOGE("failed to autoplug %s", player->type_caps_str); mm_attrs_get_int_by_name(player->attrs, "profile_prepare_async", &async); @@ -6196,7 +6210,7 @@ __mmplayer_gst_make_queue2(mmplayer_t *player) /* NOTE : in case of ts streaming, player could not get the correct duration info * * skip the pull mode(file or ring buffering) setting. */ if (dur_bytes > 0) { - if (!g_strrstr(player->type, "video/mpegts")) { + if (!g_strrstr(player->type_caps_str, "video/mpegts")) { type = MUXED_BUFFER_TYPE_MEM_RING_BUFFER; player->streamer->ring_buffer_size = player->ini.http_ring_buffer_size; } @@ -6376,8 +6390,8 @@ ERROR: return FALSE; } -static int -__mmplayer_check_not_supported_codec(mmplayer_t *player, const gchar *factory_class, const gchar *mime) +int +_mmplayer_update_not_supported_codec_info(mmplayer_t *player, const gchar *factory_class, const gchar *mime) { MMPLAYER_FENTER(); @@ -6530,6 +6544,12 @@ __mmplayer_get_next_uri(mmplayer_t *player) return FALSE; } + if (!MMPLAYER_USE_DECODEBIN(player)) { + if (player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst) + g_object_set(G_OBJECT(player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst), + "uri", profile.uri, NULL); + } + SECURE_LOGD("next playback uri: %s", uri); return TRUE; } @@ -6588,6 +6608,8 @@ __mmplayer_verify_gapless_play_path(mmplayer_t *player) } num_of_uri = g_list_length(player->uri_info.uri_list); + if (!MMPLAYER_USE_DECODEBIN(player)) + player->gapless.running = TRUE; LOGD("repeat count = %d, num_of_list = %d", count, num_of_uri); @@ -6602,6 +6624,13 @@ __mmplayer_verify_gapless_play_path(mmplayer_t *player) LOGD("there is no next uri and no repeat"); goto ERROR; } + + if (!MMPLAYER_USE_DECODEBIN(player)) { + if (player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst) + g_object_set(G_OBJECT(player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst), + "uri", player->profile.uri, NULL); + } + LOGD("looping cnt %d", count); } else { /* gapless playback path */ @@ -6978,7 +7007,7 @@ _mmplayer_gst_decode_unknown_type(GstElement *elem, GstPad *pad, MMPLAYER_FREEIF(caps_str); /* There is no available codec. */ - __mmplayer_check_not_supported_codec(player, klass, mime); + _mmplayer_update_not_supported_codec_info(player, klass, mime); } gboolean @@ -7198,7 +7227,7 @@ __mmplayer_is_offload_supported_type(mmplayer_t *player) this function need to be updated according to the supported media format @see player->ini.audio_offload_media_format */ - if (__mmplayer_is_only_mp3_type(player->type)) { + if (__mmplayer_is_only_mp3_type(player->type_caps_str)) { LOGD("offload supportable media format type"); return TRUE; } @@ -7215,7 +7244,7 @@ __mmplayer_can_build_audio_offload_path(mmplayer_t *player) MMPLAYER_FENTER(); MMPLAYER_RETURN_VAL_IF_FAIL(player && player->attrs, FALSE); - LOGD("current stream : %s, sink: %s", player->type, player->ini.audio_offload_sink_element); + LOGD("current stream : %s, sink: %s", player->type_caps_str, player->ini.audio_offload_sink_element); if (!__mmplayer_is_offload_supported_type(player)) goto DONE; @@ -7466,8 +7495,8 @@ _mmplayer_gst_decode_autoplug_select(GstElement *bin, GstPad *pad, LOGD("[handle: %p] found new element [%s] to link", player, factory_name); /* store type string */ - if (player->type == NULL) { - player->type = gst_caps_to_string(caps); + if (player->type_caps_str == NULL) { + player->type_caps_str = gst_caps_to_string(caps); __mmplayer_update_content_type_info(player); } @@ -7536,14 +7565,19 @@ _mmplayer_gst_decode_autoplug_select(GstElement *bin, GstPad *pad, gint stype = 0; gint width = 0; GstStructure *str = NULL; - mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &stype); - /* don't make video because of not required */ - if ((stype == MM_DISPLAY_SURFACE_NULL) && - (!player->set_mode.video_export)) { - LOGD("no need video decoding, expose pad"); - result = GST_AUTOPLUG_SELECT_EXPOSE; - goto DONE; + /* parsebin in adaptivedemux get error if there is no parser */ + if ((!g_strrstr(GST_ELEMENT_NAME(bin), "parsebin")) || + ((!MMPLAYER_IS_HTTP_LIVE_STREAMING(player)) && (!MMPLAYER_IS_DASH_STREAMING(player)))) { + mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &stype); + + /* don't make video because of not required */ + if ((stype == MM_DISPLAY_SURFACE_NULL) && + (!player->set_mode.video_export)) { + LOGD("no need video decoding, expose pad"); + result = GST_AUTOPLUG_SELECT_EXPOSE; + goto DONE; + } } /* get w/h for omx state-tune */ @@ -7585,6 +7619,7 @@ _mmplayer_gst_decode_pad_removed(GstElement *elem, GstPad *pad, mmplayer_t *player = (mmplayer_t *)data; mmplayer_gst_element_t *mainbin = player->pipeline->mainbin; mmplayer_gst_element_t *videobin = player->pipeline->videobin; + gint timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player); MMPLAYER_FENTER(); MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && mainbin); @@ -7601,11 +7636,27 @@ _mmplayer_gst_decode_pad_removed(GstElement *elem, GstPad *pad, __mmplayer_del_sink(player, videobin[MMPLAYER_V_SINK].gst); + LOGD("remove videobin"); + ret = _mmplayer_gst_set_state(player, videobin[MMPLAYER_V_BIN].gst, + GST_STATE_NULL, FALSE, timeout); + if (ret != MM_ERROR_NONE) { + LOGE("fail to change state of videobin to NULL"); + return; + } + if (!gst_bin_remove(GST_BIN_CAST(mainbin[MMPLAYER_M_PIPE].gst), videobin[MMPLAYER_V_BIN].gst)) { LOGE("failed to remove videobin"); gst_object_unref(GST_OBJECT(videobin[MMPLAYER_V_BIN].gst)); } + LOGD("remove concat"); + ret = _mmplayer_gst_set_state(player, mainbin[MMPLAYER_M_V_CONCAT].gst, + GST_STATE_NULL, FALSE, timeout); + if (ret != MM_ERROR_NONE) { + LOGE("fail to change state of concat to NULL"); + return; + } + if (!gst_bin_remove(GST_BIN_CAST(mainbin[MMPLAYER_M_PIPE].gst), mainbin[MMPLAYER_M_V_CONCAT].gst)) { LOGE("failed to remove video concat"); gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_V_CONCAT].gst)); @@ -7642,15 +7693,22 @@ _mmplayer_gst_about_to_finish(GstElement *bin, gpointer data) if (!__mmplayer_verify_gapless_play_path(player)) { LOGD("decoding is finished."); - MMPLAYER_CMD_UNLOCK(player); - return; + if (MMPLAYER_USE_DECODEBIN(player)) { + MMPLAYER_CMD_UNLOCK(player); + return; + } } - _mmplayer_set_reconfigure_state(player, TRUE); - MMPLAYER_CMD_UNLOCK(player); - - MMPLAYER_POST_MSG(player, MM_MESSAGE_FLUSH_BUFFER, NULL); - __mmplayer_deactivate_old_path(player); + if (MMPLAYER_USE_DECODEBIN(player)) { + _mmplayer_set_reconfigure_state(player, TRUE); + MMPLAYER_CMD_UNLOCK(player); + MMPLAYER_POST_MSG(player, MM_MESSAGE_FLUSH_BUFFER, NULL); + __mmplayer_deactivate_old_path(player); + } else { + player->gapless.update_segment[MM_PLAYER_TRACK_TYPE_AUDIO] = FALSE; + player->gapless.update_segment[MM_PLAYER_TRACK_TYPE_VIDEO] = FALSE; + MMPLAYER_CMD_UNLOCK(player); + } MMPLAYER_FLEAVE(); } @@ -7727,7 +7785,7 @@ _mmplayer_gst_decode_drained(GstElement *bin, gpointer data) } void -_mmplayer_gst_element_added(GstElement *bin, GstElement *element, gpointer data) +_mmplayer_gst_element_added(GstBin *bin, GstElement *element, gpointer data) { mmplayer_t *player = (mmplayer_t *)data; const gchar *klass = NULL; @@ -7741,91 +7799,115 @@ _mmplayer_gst_element_added(GstElement *bin, GstElement *element, gpointer data) if (__mmplayer_add_dump_buffer_probe(player, element)) LOGD("add buffer probe"); - if (g_strrstr(klass, "Codec/Decoder/Audio")) { - gchar *selected = NULL; - selected = g_strdup(GST_ELEMENT_NAME(element)); - player->audio_decoders = g_list_append(player->audio_decoders, selected); - - /* update codec info */ - player->not_supported_codec &= MISSING_PLUGIN_VIDEO; - player->can_support_codec |= FOUND_PLUGIN_AUDIO; - player->audiodec_linked = 1; - } else if (g_strrstr(klass, "Codec/Decoder/Video")) { - /* update codec info */ - player->not_supported_codec &= MISSING_PLUGIN_AUDIO; - player->can_support_codec |= FOUND_PLUGIN_VIDEO; - player->videodec_linked = 1; - } - - if (g_strrstr(klass, "Demuxer/Adaptive")) { - player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].id = MMPLAYER_M_ADAPTIVE_DEMUX; - player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst = element; - - LOGD("set max variant limit: %d, %d %d", player->adaptive_info.limit.bandwidth, - player->adaptive_info.limit.width, player->adaptive_info.limit.height); - - g_object_set(player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst, - "max-bandwidth", player->adaptive_info.limit.bandwidth, - "max-video-width", player->adaptive_info.limit.width, - "max-video-height", player->adaptive_info.limit.height, NULL); + if (g_strrstr(klass, "Decoder")) { + if (g_strrstr(klass, "Audio")) { + player->audio_decoders = g_list_append(player->audio_decoders, + g_strdup(GST_ELEMENT_NAME(element))); + /* update codec info */ + player->not_supported_codec &= MISSING_PLUGIN_VIDEO; + player->can_support_codec |= FOUND_PLUGIN_AUDIO; + player->audiodec_linked = 1; + } else if (g_strrstr(klass, "Video")) { + GstElement *video_parse = player->pipeline->mainbin[MMPLAYER_M_V_PARSE].gst; + /* update codec info */ + player->not_supported_codec &= MISSING_PLUGIN_AUDIO; + player->can_support_codec |= FOUND_PLUGIN_VIDEO; + player->videodec_linked = 1; + + if (video_parse) { + GstPad *srcpad = gst_element_get_static_pad (video_parse, "src"); + if (srcpad) { + GstCaps *caps = NULL; + GstStructure *str = NULL; + const gchar *name = NULL; + gboolean caps_ret = TRUE; + + MMPLAYER_GST_GET_CAPS_INFO_FROM_PAD (srcpad, caps, str, name, caps_ret); + if (caps_ret && str) { + const gchar *stream_format = gst_structure_get_string (str, "stream-format"); + if (stream_format && g_strrstr(stream_format, "byte-stream")) { + if ((g_object_class_find_property(G_OBJECT_GET_CLASS(video_parse), "config-interval"))) { + g_object_set(G_OBJECT(video_parse), "config-interval", -1, NULL); + LOGD("Send SPS and PPS Insertion every IDR frame"); + } + } + } + gst_object_unref(GST_OBJECT(srcpad)); + } + } + } } else if (g_strrstr(klass, "Demuxer")) { + if (g_strrstr(klass, "Adaptive")) { + player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].id = MMPLAYER_M_ADAPTIVE_DEMUX; + player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst = element; + + MMPLAYER_FREEIF(player->type_caps_str); + + if (g_strrstr(factory_name, "hlsdemux")) { + player->type_caps_str = g_strdup("application/x-hls"); + player->profile.uri_type = MM_PLAYER_URI_TYPE_HLS; + } else if (g_strrstr(factory_name, "dashdemux")) { + player->type_caps_str = g_strdup("application/dash+xml"); + player->profile.uri_type = MM_PLAYER_URI_TYPE_DASH; + } else { + LOGE("not supported type"); + return; + } + player->streamer->is_adaptive_streaming = TRUE; + + if (player->streamer->buffering_req.prebuffer_time <= MIN_BUFFERING_TIME) + player->streamer->buffering_req.prebuffer_time = DEFAULT_PREBUFFERING_TIME; + + LOGD("max variant limit: %d, %d, %d, prebuffer time: %d ms", + player->adaptive_info.limit.bandwidth, + player->adaptive_info.limit.width, + player->adaptive_info.limit.height, + player->streamer->buffering_req.prebuffer_time); + + g_object_set(player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst, + "max-bitrate", player->adaptive_info.limit.bandwidth, + "max-video-width", player->adaptive_info.limit.width, + "max-video-height", player->adaptive_info.limit.height, + "low-watermark-time", (guint64)(player->streamer->buffering_req.prebuffer_time * GST_MSECOND), + NULL); + } else { #ifdef __DEBUG__ - LOGD("plugged element is demuxer. take it"); + LOGD("plugged element is demuxer. take it"); #endif - player->pipeline->mainbin[MMPLAYER_M_DEMUX].id = MMPLAYER_M_DEMUX; - player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst = element; + player->pipeline->mainbin[MMPLAYER_M_DEMUX].id = MMPLAYER_M_DEMUX; + player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst = element; + } } else if (g_strrstr(klass, "Parser") && (g_strrstr(klass, "Video"))) { player->pipeline->mainbin[MMPLAYER_M_V_PARSE].id = MMPLAYER_M_V_PARSE; player->pipeline->mainbin[MMPLAYER_M_V_PARSE].gst = element; } - if (g_strrstr(factory_name, "asfdemux") || g_strrstr(factory_name, "qtdemux") || g_strrstr(factory_name, "avidemux")) { - int surface_type = 0; - - mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &surface_type); - } - - // to support trust-zone only - if (g_strrstr(factory_name, "asfdemux")) { - LOGD("set file-location %s", player->profile.uri); - g_object_set(G_OBJECT(element), "file-location", player->profile.uri, NULL); - } else if (g_strrstr(factory_name, "legacyh264parse")) { - LOGD("[%s] output-format to legacyh264parse", "mssdemux"); - g_object_set(G_OBJECT(element), "output-format", 1, NULL); /* NALU/Byte Stream format */ - } else if (g_strrstr(factory_name, "mpegaudioparse")) { + if (g_strrstr(factory_name, "mpegaudioparse")) { if ((MMPLAYER_IS_HTTP_STREAMING(player)) && - (__mmplayer_is_only_mp3_type(player->type))) { + (__mmplayer_is_only_mp3_type(player->type_caps_str))) { LOGD("[mpegaudioparse] set streaming pull mode."); g_object_set(G_OBJECT(element), "http-pull-mp3dec", TRUE, NULL); } - } else if (g_strrstr(factory_name, player->ini.videocodec_element_hw)) { - player->pipeline->mainbin[MMPLAYER_M_DEC1].gst = element; - } - - if (g_strrstr(factory_name, "omxdec_h264") || g_strrstr(factory_name, "v4l2h264dec")) { - GstElement *video_parse = player->pipeline->mainbin[MMPLAYER_M_V_PARSE].gst; - if (video_parse && (g_object_class_find_property(G_OBJECT_GET_CLASS(video_parse), "config-interval"))) { - g_object_set(G_OBJECT(video_parse), "config-interval", -1, NULL); - LOGD("Send SPS and PPS Insertion every IDR frame"); - } - } - - if ((player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst) && + } else if ((player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst) && (g_strrstr(GST_ELEMENT_NAME(element), "multiqueue"))) { + LOGD("plugged element is multiqueue. take it %s", GST_ELEMENT_NAME(element)); + /* set mq unlinked cache size to avoid not-linked error */ + gboolean sync_by_running_time = FALSE; + g_object_get(G_OBJECT(element), "sync-by-running-time", &sync_by_running_time, NULL); + if (sync_by_running_time) + g_object_set(G_OBJECT(element), "unlinked-cache-time", MQ_UNLINKED_CACHE_TIME, NULL); + player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].id = MMPLAYER_M_DEMUXED_S_BUFFER; player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst = element; - if ((MMPLAYER_IS_HTTP_STREAMING(player)) || - (MMPLAYER_IS_HTTP_LIVE_STREAMING(player)) || - (MMPLAYER_IS_DASH_STREAMING(player))) { + if (MMPLAYER_IS_HTTP_STREAMING(player)) { /* in case of multiqueue, max bytes size is defined with fixed value in mm_player_streaming.h*/ _mm_player_streaming_set_multiqueue(player->streamer, element); _mm_player_streaming_sync_property(player->streamer, player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst); } - } return; @@ -7987,15 +8069,15 @@ __mmplayer_check_subtitle(mmplayer_t *player) /* get subtitle attribute */ attrs = MMPLAYER_GET_ATTRS(player); - if (!attrs) - return FALSE; + MMPLAYER_RETURN_VAL_IF_FAIL(attrs, FALSE); mm_attrs_get_string_by_name(attrs, "subtitle_uri", &subtitle_uri); - if (!subtitle_uri || !strlen(subtitle_uri)) + if (!subtitle_uri || (strlen(subtitle_uri) == 0)) { + MMPLAYER_FLEAVE(); return FALSE; + } SECURE_LOGD("subtitle uri is %s[%zu]", subtitle_uri, strlen(subtitle_uri)); - player->is_external_subtitle_present = TRUE; MMPLAYER_FLEAVE(); @@ -8233,7 +8315,7 @@ _mmplayer_sync_subtitle_pipeline(mmplayer_t *player) current_state = GST_STATE(mainbin[MMPLAYER_M_PIPE].gst); // sync clock with current pipeline - curr_clock = GST_ELEMENT_CLOCK(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst); + curr_clock = gst_element_get_clock(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst); curr_time = gst_clock_get_time(curr_clock); base_time = gst_element_get_base_time(GST_ELEMENT_CAST(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst)); @@ -8252,6 +8334,8 @@ _mmplayer_sync_subtitle_pipeline(mmplayer_t *player) if (GST_STATE_CHANGE_FAILURE == ret) { LOGE("fail to state change."); result = MM_ERROR_PLAYER_INTERNAL; + if (curr_clock) + gst_object_unref(curr_clock); goto ERROR; } } @@ -8272,14 +8356,26 @@ _mmplayer_sync_subtitle_pipeline(mmplayer_t *player) LOGD("seek time = %"G_GINT64_FORMAT", rate = %f", time, player->playback_rate); event = gst_event_new_seek(player->playback_rate, GST_FORMAT_TIME, (GstSeekFlags)(GST_SEEK_FLAG_FLUSH), GST_SEEK_TYPE_SET, time, GST_SEEK_TYPE_NONE, -1); - if (event) { - _mmplayer_gst_send_event_to_sink(player, event); - } else { + if (!event) { result = MM_ERROR_PLAYER_INTERNAL; LOGE("gst_event_new_seek failed"); /* pipeline will got error and can not be recovered */ goto ERROR; } + if (player->seek_state == MMPLAYER_SEEK_IN_PROGRESS) { + GstElement *text_sink = GST_ELEMENT_CAST(player->pipeline->textbin[MMPLAYER_T_FAKE_SINK].gst); + if (GST_IS_ELEMENT(text_sink)) { + if (gst_element_send_event(text_sink, event)) + LOGD("sending event[%s] to subtitle sink element [%s] success!", + GST_EVENT_TYPE_NAME(event), GST_ELEMENT_NAME(text_sink)); + else + LOGE("sending event[%s] to subtitle sink element [%s] failed!", + GST_EVENT_TYPE_NAME(event), GST_ELEMENT_NAME(text_sink)); + } + } else { + _mmplayer_gst_send_event_to_sink(player, event); + } + /* sync state with current pipeline */ gst_element_sync_state_with_parent(textbin[MMPLAYER_T_BIN].gst); gst_element_sync_state_with_parent(mainbin[MMPLAYER_M_SUBPARSE].gst); @@ -8483,6 +8579,7 @@ _mmplayer_set_external_subtitle_path(MMHandleType hplayer, const char *filepath) } MMPLAYER_SUBTITLE_INFO_UNLOCK(player); } + player->is_external_subtitle_present = TRUE; MMPLAYER_FLEAVE(); return result; @@ -8653,6 +8750,7 @@ _mmplayer_change_track_language(MMHandleType hplayer, mmplayer_track_type_e type player = (mmplayer_t *)hplayer; MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED); + MMPLAYER_RETURN_VAL_IF_FAIL(type < MM_PLAYER_TRACK_TYPE_MAX, MM_ERROR_PLAYER_NOT_INITIALIZED); if (!player->pipeline) { LOGE("Track %d pre setting -> %d", type, index); @@ -8995,7 +9093,7 @@ _mmplayer_set_max_adaptive_variant_limit(MMHandleType hplayer, int bandwidth, in if (player->pipeline && player->pipeline->mainbin && player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst) { LOGD("update max limit of %s", GST_ELEMENT_NAME(player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst)); g_object_set(player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst, - "max-bandwidth", bandwidth, "max-video-width", width, "max-video-height", height, NULL); + "max-bitrate", bandwidth, "max-video-width", width, "max-video-height", height, NULL); /* FIXME: seek to current position for applying new variant limitation */ } @@ -9903,12 +10001,12 @@ __mmplayer_set_playing_state(mmplayer_t *player) * So, if it's not set yet, fill it with found data. */ if (!audio_codec) { - if (g_strrstr(player->type, "audio/midi")) + if (g_strrstr(player->type_caps_str, "audio/midi")) audio_codec = "MIDI"; - else if (g_strrstr(player->type, "audio/x-amr")) + else if (g_strrstr(player->type_caps_str, "audio/x-amr")) audio_codec = "AMR"; - else if (g_strrstr(player->type, "audio/mpeg") - && !g_strrstr(player->type, "mpegversion=(int)1")) + else if (g_strrstr(player->type_caps_str, "audio/mpeg") + && !g_strrstr(player->type_caps_str, "mpegversion=(int)1")) audio_codec = "AAC"; else audio_codec = "unknown";