[0.6.289] Fix not-linked error during prepare
[platform/core/multimedia/libmm-player.git] / src / mm_player_priv.c
index 6f88332..1004e50 100644 (file)
 #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")) {
@@ -1199,10 +1221,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 +1236,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 +1260,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 +1284,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 +1431,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 +1441,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));
 
@@ -4414,7 +4445,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 +4512,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 +5941,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 +6031,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 +6043,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 +6080,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 +6115,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 +6212,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 +6392,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 +6546,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 +6610,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 +6626,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 +7009,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 +7229,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 +7246,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 +7497,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 +7567,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 +7621,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 +7638,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 +7695,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 +7787,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 +7801,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;
@@ -8233,7 +8317,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 +8336,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;
                }
        }
@@ -8653,6 +8739,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 +9082,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 +9990,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";