[0.6.222] support codec type setting with u3
[platform/core/multimedia/libmm-player.git] / src / mm_player_priv.c
index 78ae23a..a15b493 100644 (file)
@@ -140,8 +140,8 @@ static int          __mmplayer_gst_create_text_pipeline(mmplayer_t *player);
 static int             __mmplayer_gst_create_video_sink_bin(mmplayer_t *player, GstCaps *caps, MMDisplaySurfaceType surface_type);
 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_create_sinkbin(GstElement *decodebin, GstPad *pad, gpointer data);
+static void            __mmplayer_gst_create_sink_bin(GstElement *decodebin, GstPad *pad, GstCaps *ref_caps, gpointer data);
+static gboolean __mmplayer_create_sink_path(mmplayer_t *player, GstElement *combiner, mmplayer_track_type_e type, GstCaps *caps);
 static gboolean __mmplayer_is_midi_type(gchar *str_caps);
 static gboolean __mmplayer_is_only_mp3_type(gchar *str_caps);
 
@@ -173,6 +173,7 @@ static int          __mmplayer_gst_set_message_callback(mmplayer_t *player, MMMessageCal
 static gboolean __mmplayer_verify_gapless_play_path(mmplayer_t *player);
 static void __mmplayer_check_pipeline_reconfigure_state(mmplayer_t *player);
 static gboolean __mmplayer_deactivate_selector(mmplayer_t *player, mmplayer_track_type_e type);
+static gboolean __mmplayer_deactivate_combiner(mmplayer_t *player, mmplayer_track_type_e type);
 static void __mmplayer_deactivate_old_path(mmplayer_t *player);
 static int __mmplayer_gst_create_plain_text_elements(mmplayer_t *player);
 static guint32 _mmplayer_convert_fourcc_string_to_value(const gchar *format_name);
@@ -962,7 +963,7 @@ __mmplayer_gst_selector_event_probe(GstPad *pad, GstPadProbeInfo *info, gpointer
                GST_EVENT_TYPE(event) != GST_EVENT_QOS)
                return ret;
 
-       MMPLAYER_GST_GET_CAPS_INFO(pad, caps, str, name, caps_ret);
+       MMPLAYER_GST_GET_CAPS_INFO_FROM_PAD(pad, caps, str, name, caps_ret);
        if (!caps_ret)
                goto ERROR;
 
@@ -1146,6 +1147,35 @@ EXIT:
 }
 
 static GstElement *
+__mmplayer_gst_make_concat(mmplayer_t *player, main_element_id_e elem_idx)
+{
+       GstElement *pipeline = NULL;
+       GstElement *concat = NULL;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->mainbin, NULL);
+
+       concat = gst_element_factory_make("concat", NULL);
+       if (!concat) {
+               LOGE("failed to create concat");
+               return NULL;
+       }
+
+       LOGD("Create concat [%d] element", elem_idx);
+
+       player->pipeline->mainbin[elem_idx].id = elem_idx;
+       player->pipeline->mainbin[elem_idx].gst = concat;
+
+       gst_element_set_state(concat, GST_STATE_PAUSED);
+
+       pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
+       gst_bin_add(GST_BIN(pipeline), concat);
+
+       MMPLAYER_FLEAVE();
+       return concat;
+}
+
+static GstElement *
 __mmplayer_gst_make_selector(mmplayer_t *player, main_element_id_e elem_idx, mmplayer_track_type_e stream_type)
 {
        GstElement *pipeline = NULL;
@@ -1190,7 +1220,7 @@ void
 _mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
 {
        mmplayer_t *player = (mmplayer_t *)data;
-       GstElement *selector = NULL;
+       GstElement *combiner = NULL;
        GstCaps *caps = NULL;
        GstStructure *str = NULL;
        const gchar *name = NULL;
@@ -1208,7 +1238,7 @@ _mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
        LOGD("pad-added signal handling");
 
        /* get mimetype from caps */
-       MMPLAYER_GST_GET_CAPS_INFO(pad, caps, str, name, caps_ret);
+       MMPLAYER_GST_GET_CAPS_INFO_FROM_PAD(pad, caps, str, name, caps_ret);
        if (!caps_ret)
                goto ERROR;
 
@@ -1233,8 +1263,8 @@ _mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
 
                LOGD("surface type : %d", stype);
 
-               if (MMPLAYER_IS_MS_BUFF_SRC(player) || !MMPLAYER_USE_DECODEBIN(player)) {
-                       __mmplayer_gst_create_sinkbin(elem, pad, player);
+               if (MMPLAYER_IS_MS_BUFF_SRC(player)) {
+                       __mmplayer_gst_create_sink_bin(elem, pad, caps, player);
                        goto DONE;
                }
 
@@ -1245,17 +1275,22 @@ _mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
                        goto DONE;
                }
 
-               LOGD("video selector is required");
-               elem_idx = MMPLAYER_M_V_INPUT_SELECTOR;
+               if (MMPLAYER_USE_DECODEBIN(player)) {
+                       LOGD("video selector is required");
+                       elem_idx = MMPLAYER_M_V_INPUT_SELECTOR;
+               } else {
+                       LOGD("video concat is required");
+                       elem_idx = MMPLAYER_M_V_CONCAT;
+               }
                stream_type = MM_PLAYER_TRACK_TYPE_VIDEO;
        } else if (strstr(name, "audio")) {
                gint samplerate = 0;
                gint channels = 0;
 
-               if (MMPLAYER_IS_MS_BUFF_SRC(player) || !MMPLAYER_USE_DECODEBIN(player) || player->build_audio_offload) {
+               if (MMPLAYER_IS_MS_BUFF_SRC(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);
+                       __mmplayer_gst_create_sink_bin(elem, pad, caps, player);
                        goto DONE;
                }
 
@@ -1266,14 +1301,23 @@ _mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
                        __mmplayer_gst_make_fakesink(player, pad, name);
                        goto DONE;
                }
-
-               LOGD("audio selector is required");
-               elem_idx = MMPLAYER_M_A_INPUT_SELECTOR;
+               if (MMPLAYER_USE_DECODEBIN(player)) {
+                       LOGD("audio selector is required");
+                       elem_idx = MMPLAYER_M_A_INPUT_SELECTOR;
+               } else {
+                       LOGD("audio concat is required");
+                       elem_idx = MMPLAYER_M_A_CONCAT;
+               }
                stream_type = MM_PLAYER_TRACK_TYPE_AUDIO;
 
        } else if (strstr(name, "text")) {
-               LOGD("text selector is required");
-               elem_idx = MMPLAYER_M_T_INPUT_SELECTOR;
+               if (MMPLAYER_USE_DECODEBIN(player)) {
+                       LOGD("text selector is required");
+                       elem_idx = MMPLAYER_M_T_INPUT_SELECTOR;
+               } else {
+                       LOGD("text concat is required");
+                       elem_idx = MMPLAYER_M_T_CONCAT;
+               }
                stream_type = MM_PLAYER_TRACK_TYPE_TEXT;
        } else {
                LOGE("invalid caps info");
@@ -1281,33 +1325,41 @@ _mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
        }
 
        /* check selector and create it */
-       if (!(selector = player->pipeline->mainbin[elem_idx].gst)) {
-               selector = __mmplayer_gst_make_selector(player, elem_idx, stream_type);
-               if (!selector)
+       if (!(combiner = player->pipeline->mainbin[elem_idx].gst)) {
+               if (MMPLAYER_USE_DECODEBIN(player))
+                       combiner = __mmplayer_gst_make_selector(player, elem_idx, stream_type);
+               else
+                       combiner = __mmplayer_gst_make_concat(player, elem_idx);
+
+               if (!combiner)
                        goto ERROR;
                first_track = TRUE;
        } else {
-               LOGD("input-selector is already created.");
+               LOGD("Combiner element is already created.");
        }
 
        /* link */
-       sinkpad = gst_element_get_request_pad(selector, "sink_%u");
+       sinkpad = gst_element_get_request_pad(combiner, "sink_%u");
 
        LOGD("pad link: %s:%s - %s:%s", GST_DEBUG_PAD_NAME(pad), GST_DEBUG_PAD_NAME(sinkpad));
 
        if (gst_pad_link(pad, sinkpad) != GST_PAD_LINK_OK) {
-               LOGE("failed to link selector");
-               gst_object_unref(GST_OBJECT(selector));
+               LOGE("failed to link combiner");
+               gst_object_unref(GST_OBJECT(combiner));
                goto ERROR;
        }
 
        if (first_track) {
-               LOGD("this track will be activated");
-               g_object_set(selector, "active-pad", sinkpad, NULL);
+               if (MMPLAYER_USE_DECODEBIN(player)) {
+                       LOGD("this track will be activated");
+                       g_object_set(combiner, "active-pad", sinkpad, NULL);
+               }
        }
 
        if (MMPLAYER_USE_DECODEBIN(player))
                _mmplayer_track_update_stream(player, stream_type, sinkpad);
+       else
+               __mmplayer_create_sink_path(player, combiner, stream_type, caps);
 
 DONE:
 ERROR:
@@ -1324,7 +1376,7 @@ ERROR:
 }
 
 static gboolean
-__mmplayer_create_sink_path(mmplayer_t *player, GstElement *selector, mmplayer_track_type_e type)
+__mmplayer_create_sink_path(mmplayer_t *player, GstElement *combiner, mmplayer_track_type_e type, GstCaps *caps)
 {
        GstPad *srcpad = NULL;
 
@@ -1333,20 +1385,20 @@ __mmplayer_create_sink_path(mmplayer_t *player, GstElement *selector, mmplayer_t
 
        LOGD("type %d", type);
 
-       if (!selector) {
+       if (!combiner) {
                LOGD("there is no %d track", type);
                return TRUE;
        }
 
-       srcpad = gst_element_get_static_pad(selector, "src");
+       srcpad = gst_element_get_static_pad(combiner, "src");
        if (!srcpad) {
-               LOGE("failed to get srcpad from selector");
+               LOGE("failed to get srcpad from combiner");
                return FALSE;
        }
 
-       LOGD("got pad %s:%s from selector", GST_DEBUG_PAD_NAME(srcpad));
+       LOGD("got pad %s:%s from combiner", GST_DEBUG_PAD_NAME(srcpad));
 
-       __mmplayer_gst_create_sinkbin(selector, srcpad, player);
+       __mmplayer_gst_create_sink_bin(combiner, srcpad, caps, player);
 
        LOGD("unblocking %s:%s", GST_DEBUG_PAD_NAME(srcpad));
        if (player->track[type].block_id) {
@@ -1422,7 +1474,7 @@ __mmplayer_create_audio_sink_path(mmplayer_t *player, GstElement *audio_selector
                __mmplayer_set_decode_track_info(player, MM_PLAYER_TRACK_TYPE_AUDIO);
 
        /* create audio sink path */
-       if (!__mmplayer_create_sink_path(player, audio_selector, MM_PLAYER_TRACK_TYPE_AUDIO)) {
+       if (!__mmplayer_create_sink_path(player, audio_selector, MM_PLAYER_TRACK_TYPE_AUDIO, NULL)) {
                LOGE("failed to create audio sink path");
                return FALSE;
        }
@@ -1451,7 +1503,7 @@ __mmplayer_create_text_sink_path(mmplayer_t *player, GstElement *text_selector)
        /* create text decode path */
        player->no_more_pad = TRUE;
 
-       if (!__mmplayer_create_sink_path(player, text_selector, MM_PLAYER_TRACK_TYPE_TEXT)) {
+       if (!__mmplayer_create_sink_path(player, text_selector, MM_PLAYER_TRACK_TYPE_TEXT, NULL)) {
                LOGE("failed to create text sink path");
                return FALSE;
        }
@@ -1526,7 +1578,7 @@ _mmplayer_gst_decode_no_more_pads(GstElement *elem, gpointer data)
        if (video_selector && !audio_selector && !text_selector)
                player->no_more_pad = TRUE;
 
-       if (!__mmplayer_create_sink_path(player, video_selector, MM_PLAYER_TRACK_TYPE_VIDEO))
+       if (!__mmplayer_create_sink_path(player, video_selector, MM_PLAYER_TRACK_TYPE_VIDEO, NULL))
                goto EXIT;
 
        /* create audio path followed by audio-select */
@@ -1607,7 +1659,7 @@ EXIT:
 }
 
 static void
-__mmplayer_gst_create_sinkbin(GstElement *elem, GstPad *pad, gpointer data)
+__mmplayer_gst_create_sink_bin(GstElement *elem, GstPad *pad, GstCaps *ref_caps, gpointer data)
 {
        mmplayer_t *player = NULL;
        GstCaps *caps = NULL;
@@ -1625,10 +1677,14 @@ __mmplayer_gst_create_sinkbin(GstElement *elem, GstPad *pad, gpointer data)
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_IF_FAIL(elem && pad);
        MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && MMPLAYER_GET_ATTRS(player));
+       MMPLAYER_GST_GET_CAPS_INFO_FROM_PAD(pad, caps, str, name, caps_ret);
+       if (!caps_ret) {
+               MMPLAYER_GST_GET_CAPS_INFO(ref_caps, str, name, caps_ret);
+               if (!caps_ret)
+                       goto ERROR;
 
-       MMPLAYER_GST_GET_CAPS_INFO(pad, caps, str, name, caps_ret);
-       if (!caps_ret)
-               goto ERROR;
+               caps = gst_caps_ref(ref_caps);
+       }
 
        caps_str = gst_caps_to_string(caps);
 #ifdef __DEBUG__
@@ -2219,7 +2275,7 @@ __mmplayer_gst_caps_notify_cb(GstPad *pad, GParamSpec *unused, gpointer data)
        if (!caps)
                return;
 
-       MMPLAYER_GST_GET_CAPS_INFO(pad, caps, str, name, caps_ret);
+       MMPLAYER_GST_GET_CAPS_INFO_FROM_PAD(pad, caps, str, name, caps_ret);
        if (!caps_ret)
                goto ERROR;
 
@@ -4997,9 +5053,7 @@ _mmplayer_realize(MMHandleType hplayer)
        char *uri = NULL;
        void *param = NULL;
        MMHandleType attrs = 0;
-       int video_codec_type = 0;
-       int audio_codec_type = 0;
-       int default_codec_type = 0;
+
        MMPLAYER_FENTER();
 
        /* check player handle */
@@ -5082,23 +5136,6 @@ _mmplayer_realize(MMHandleType hplayer)
                                                                player->streamer->buffering_req.rebuffer_time);
        }
 
-       mm_attrs_get_int_by_name(player->attrs, MM_PLAYER_AUDIO_CODEC_TYPE, &audio_codec_type);
-       if (!strcmp(player->ini.audiocodec_default_type, "hw"))
-               default_codec_type = MM_PLAYER_CODEC_TYPE_HW;
-       else
-               default_codec_type = MM_PLAYER_CODEC_TYPE_SW;
-
-       if (audio_codec_type != default_codec_type) {
-               LOGD("audio dec sorting is required");
-               player->need_audio_dec_sorting = TRUE;
-       }
-
-       mm_attrs_get_int_by_name(player->attrs, MM_PLAYER_VIDEO_CODEC_TYPE, &video_codec_type);
-       if (video_codec_type != MM_PLAYER_CODEC_TYPE_DEFAULT) {
-               LOGD("video dec sorting is required");
-               player->need_video_dec_sorting = TRUE;
-       }
-
        /* realize pipeline */
        ret = __mmplayer_gst_realize(player);
        if (ret != MM_ERROR_NONE)
@@ -6472,6 +6509,87 @@ ERROR:
        return FALSE;
 }
 
+static void
+__mmplayer_remove_sinkpad (const GValue *item, gpointer user_data)
+{
+       GstPad *sinkpad = g_value_get_object (item);
+       GstElement *element = GST_ELEMENT(user_data);
+       LOGD("(%s)element release request pad(%s)", GST_ELEMENT_NAME(element), GST_PAD_NAME(sinkpad));
+       gst_element_release_request_pad(element, GST_PAD(sinkpad));
+}
+
+static gboolean
+__mmplayer_deactivate_combiner(mmplayer_t *player, mmplayer_track_type_e type)
+{
+       mmplayer_gst_element_t *sinkbin = NULL;
+       main_element_id_e concatId = MMPLAYER_M_NUM;
+       main_element_id_e sinkId = MMPLAYER_M_NUM;
+       gboolean send_notice = FALSE;
+       GstElement *element;
+       GstIterator *iter;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
+
+       LOGD("type %d", type);
+
+       switch (type) {
+       case MM_PLAYER_TRACK_TYPE_AUDIO:
+               concatId = MMPLAYER_M_A_CONCAT;
+               sinkId = MMPLAYER_A_BIN;
+               sinkbin = player->pipeline->audiobin;
+               break;
+       case MM_PLAYER_TRACK_TYPE_VIDEO:
+               concatId = MMPLAYER_M_V_CONCAT;
+               sinkId = MMPLAYER_V_BIN;
+               sinkbin = player->pipeline->videobin;
+               send_notice = TRUE;
+               break;
+       case MM_PLAYER_TRACK_TYPE_TEXT:
+               concatId = MMPLAYER_M_T_CONCAT;
+               sinkId = MMPLAYER_T_BIN;
+               sinkbin = player->pipeline->textbin;
+               break;
+       default:
+               LOGE("requested type is not supportable");
+               return FALSE;
+               break;
+       }
+
+       element = player->pipeline->mainbin[concatId].gst;
+       if (!element)
+               return TRUE;
+
+       if ((sinkbin) && (sinkbin[sinkId].gst)) {
+               GstPad *srcpad = gst_element_get_static_pad(element, "src");
+               GstPad *sinkpad = gst_element_get_static_pad(sinkbin[sinkId].gst, "sink");
+               if (srcpad && sinkpad) {
+                       /* after getting drained signal there is no data flows, so no need to do pad_block */
+                       LOGD("unlink %s:%s, %s:%s", GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
+                       gst_pad_unlink(srcpad, sinkpad);
+
+                       /* send custom event to sink pad to handle it at video sink */
+                       if (send_notice) {
+                               LOGD("send custom event to sinkpad");
+                               GstStructure *s = gst_structure_new_empty("tizen/flush-buffer");
+                               GstEvent *event = gst_event_new_custom(GST_EVENT_CUSTOM_DOWNSTREAM, s);
+                               gst_pad_send_event(sinkpad, event);
+                       }
+               }
+               gst_object_unref(srcpad);
+               gst_object_unref(sinkpad);
+       }
+
+       LOGD("release concat request pad");
+       /* release and unref requests pad from the selector */
+       iter = gst_element_iterate_sink_pads(element);
+       while (gst_iterator_foreach(iter, __mmplayer_remove_sinkpad, element) == GST_ITERATOR_RESYNC)
+               gst_iterator_resync(iter);
+       gst_iterator_free(iter);
+
+       return TRUE;
+}
+
 static gboolean
 __mmplayer_deactivate_selector(mmplayer_t *player, mmplayer_track_type_e type)
 {
@@ -6569,11 +6687,20 @@ __mmplayer_deactivate_old_path(mmplayer_t *player)
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_IF_FAIL(player);
 
-       if ((!__mmplayer_deactivate_selector(player, MM_PLAYER_TRACK_TYPE_AUDIO)) ||
-               (!__mmplayer_deactivate_selector(player, MM_PLAYER_TRACK_TYPE_VIDEO)) ||
-               (!__mmplayer_deactivate_selector(player, MM_PLAYER_TRACK_TYPE_TEXT))) {
-               LOGE("deactivate selector error");
-               goto ERROR;
+       if (MMPLAYER_USE_DECODEBIN(player)) {
+               if ((!__mmplayer_deactivate_selector(player, MM_PLAYER_TRACK_TYPE_AUDIO)) ||
+                       (!__mmplayer_deactivate_selector(player, MM_PLAYER_TRACK_TYPE_VIDEO)) ||
+                       (!__mmplayer_deactivate_selector(player, MM_PLAYER_TRACK_TYPE_TEXT))) {
+                       LOGE("deactivate selector error");
+                       goto ERROR;
+               }
+       } else {
+               if ((!__mmplayer_deactivate_combiner(player, MM_PLAYER_TRACK_TYPE_AUDIO)) ||
+                       (!__mmplayer_deactivate_combiner(player, MM_PLAYER_TRACK_TYPE_VIDEO)) ||
+                       (!__mmplayer_deactivate_combiner(player, MM_PLAYER_TRACK_TYPE_TEXT))) {
+                       LOGE("deactivate concat error");
+                       goto ERROR;
+               }
        }
 
        _mmplayer_track_destroy(player);
@@ -6700,7 +6827,7 @@ _mmplayer_get_next_uri(MMHandleType hplayer, char **uri)
        if (num_of_list > 0) {
                gint uri_idx = player->uri_info.uri_idx;
 
-               if (uri_idx < num_of_list-1)
+               if (uri_idx < num_of_list - 1)
                        uri_idx++;
                else
                        uri_idx = 0;
@@ -7353,6 +7480,36 @@ _mmplayer_gst_decode_pad_removed(GstElement *elem, GstPad *new_pad,
 }
 
 void
+_mmplayer_gst_about_to_finish(GstElement *bin, gpointer data)
+{
+       mmplayer_t *player = (mmplayer_t *)data;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player);
+
+       LOGD("got about to finish signal");
+
+       if (!MMPLAYER_CMD_TRYLOCK(player)) {
+               LOGW("Fail to get cmd lock");
+               return;
+       }
+
+       if (!__mmplayer_verify_gapless_play_path(player)) {
+               LOGD("decoding is finished.");
+               MMPLAYER_CMD_UNLOCK(player);
+               return;
+       }
+
+       _mmplayer_set_reconfigure_state(player, TRUE);
+       MMPLAYER_CMD_UNLOCK(player);
+
+       MMPLAYER_POST_MSG(player, MM_MESSAGE_GAPLESS_CONSTRUCTION, NULL);
+       __mmplayer_deactivate_old_path(player);
+
+       MMPLAYER_FLEAVE();
+}
+
+void
 _mmplayer_gst_decode_drained(GstElement *bin, gpointer data)
 {
        mmplayer_t *player = (mmplayer_t *)data;
@@ -8338,11 +8495,11 @@ _mmplayer_change_track_language(MMHandleType hplayer, mmplayer_track_type_e type
                goto EXIT;
        }
 
-       if (MMPLAYER_USE_DECODEBIN(player)) {
+       if (MMPLAYER_USE_DECODEBIN(player))
                result = __mmplayer_change_selector_pad(player, type, index);
-       } else {
+       else
                result = __mmplayer_switch_stream(player, type, index);
-       }
+
        if (result != MM_ERROR_NONE) {
                LOGE("failed to change track");
                goto EXIT;
@@ -8711,47 +8868,62 @@ _mmplayer_set_codec_type(MMHandleType hplayer, mmplayer_stream_type_e stream_typ
 {
 #define IDX_FIRST_SW_CODEC 0
        mmplayer_t *player = (mmplayer_t *)hplayer;
-       const char *attr_name = (stream_type == MM_PLAYER_STREAM_TYPE_AUDIO) ? (MM_PLAYER_AUDIO_CODEC_TYPE) : (MM_PLAYER_VIDEO_CODEC_TYPE);
+       int default_codec_type = MM_PLAYER_CODEC_TYPE_DEFAULT;
+       const char *attr_name = NULL;
+       const char *default_type = NULL;
+       const char *element_hw = NULL;
+       const char *element_sw = NULL;
 
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       LOGD("ini setting : [a][h:%s][s:%s] / [v][h:%s][s:%s]",
-               player->ini.audiocodec_element_hw, player->ini.audiocodec_element_sw[IDX_FIRST_SW_CODEC],
-               player->ini.videocodec_element_hw, player->ini.videocodec_element_sw[IDX_FIRST_SW_CODEC]);
+       LOGD("stream type: %d, codec_type: %d", stream_type, codec_type);
 
+       /* FIXME: player need to know whether the decoder exist or not about required codec type since 6.0*/
        switch (stream_type) {
        case MM_PLAYER_STREAM_TYPE_AUDIO:
-       /* to support audio codec selection, codec info have to be added in ini file as below.
-          audio codec element hw = xxxx
-          audio codec element sw = avdec
-          and in case of audio hw codec is supported and selected,
-          audio filter elements should be applied depending on the hw capabilities.
-        */
-               if (((codec_type == MM_PLAYER_CODEC_TYPE_HW) &&
-                        (!strcmp(player->ini.audiocodec_element_hw, ""))) ||
-                       ((codec_type == MM_PLAYER_CODEC_TYPE_SW) &&
-                        (!strcmp(player->ini.audiocodec_element_sw[IDX_FIRST_SW_CODEC], "")))) {
-                       LOGE("There is no audio codec info for codec_type %d", codec_type);
-                       return MM_ERROR_PLAYER_NO_OP;
-               }
-       break;
+               attr_name = MM_PLAYER_AUDIO_CODEC_TYPE;
+               default_type = player->ini.audiocodec_default_type;
+               element_hw = player->ini.audiocodec_element_hw;
+               element_sw = player->ini.audiocodec_element_sw[IDX_FIRST_SW_CODEC];
+               break;
        case MM_PLAYER_STREAM_TYPE_VIDEO:
-       /* to support video codec selection, codec info have to be added in ini file as below.
-          video codec element hw = omx
-          video codec element sw = avdec */
-               if (((codec_type == MM_PLAYER_CODEC_TYPE_HW) &&
-                        (!strcmp(player->ini.videocodec_element_hw, ""))) ||
-                       ((codec_type == MM_PLAYER_CODEC_TYPE_SW) &&
-                        (!strcmp(player->ini.videocodec_element_sw[IDX_FIRST_SW_CODEC], "")))) {
-                       LOGE("There is no video codec info for codec_type %d", codec_type);
-                       return MM_ERROR_PLAYER_NO_OP;
-               }
-       break;
+               attr_name = MM_PLAYER_VIDEO_CODEC_TYPE;
+               default_type = player->ini.videocodec_default_type;
+               element_hw = player->ini.videocodec_element_hw;
+               element_sw = player->ini.videocodec_element_sw[IDX_FIRST_SW_CODEC];
+               break;
        default:
                LOGE("Invalid stream type %s", MMPLAYER_STREAM_TYPE_GET_NAME(stream_type));
                return MM_ERROR_COMMON_INVALID_ARGUMENT;
-       break;
+               break;
+       }
+
+       LOGD("default setting: [%s][%s][h:%s][s:%s]", attr_name, default_type, element_hw, element_sw);
+
+       if (!strcmp(default_type, "sw"))
+               default_codec_type = MM_PLAYER_CODEC_TYPE_SW;
+       else
+               default_codec_type = MM_PLAYER_CODEC_TYPE_HW;
+
+       if (codec_type == MM_PLAYER_CODEC_TYPE_DEFAULT)
+               codec_type = default_codec_type;
+
+       /* to support codec selection, codec info have to be added in ini file.
+          in case of hw codec is selected, filter elements should be applied
+          depending on the hw capabilities. */
+       if (codec_type != default_codec_type) {
+               if (((codec_type == MM_PLAYER_CODEC_TYPE_HW) && (!strcmp(element_hw, ""))) ||
+                       ((codec_type == MM_PLAYER_CODEC_TYPE_SW) && (!strcmp(element_sw, "")))) {
+                       LOGE("There is no codec for type %d", codec_type);
+                       return MM_ERROR_PLAYER_NO_OP;
+               }
+
+               LOGD("sorting is required");
+               if (stream_type == MM_PLAYER_STREAM_TYPE_AUDIO)
+                       player->need_audio_dec_sorting = TRUE;
+               else
+                       player->need_video_dec_sorting = TRUE;
        }
 
        LOGD("update %s codec_type to %d", attr_name, codec_type);