support multi-track 04/230004/4
authorEunhye Choi <eunhae1.choi@samsung.com>
Tue, 7 Apr 2020 06:09:04 +0000 (15:09 +0900)
committerEunhye Choi <eunhae1.choi@samsung.com>
Tue, 7 Apr 2020 08:02:37 +0000 (17:02 +0900)
- support multi track with uridecodebin3

Change-Id: Ieb6db9de1d285d9f95cf45f7e1c333c7b8d81375

src/include/mm_player_priv.h
src/include/mm_player_tracks.h
src/mm_player_gst.c
src/mm_player_priv.c
src/mm_player_tracks.c

index d883934..e31299a 100644 (file)
@@ -450,12 +450,12 @@ typedef struct {
 } mmplayer_video_roi_t;
 
 typedef struct {
-       gint active_pad_index;
+       gint active_track_index;
        gint total_track_num;
-       GPtrArray *channels;
-       gulong block_id;
-       gulong event_probe_id;
-} mmplayer_selector_t;
+       GPtrArray *streams;
+       gulong block_id;                /* FIXME: will be removed */
+       gulong event_probe_id;  /* FIXME: will be removed */
+} mmplayer_track_t;
 
 typedef struct {
        gboolean running;
@@ -740,7 +740,7 @@ typedef struct {
        GstStreamCollection *collection;
        guint stream_notify_id;
 
-       mmplayer_selector_t selector[MM_PLAYER_TRACK_TYPE_MAX];
+       mmplayer_track_t track[MM_PLAYER_TRACK_TYPE_MAX];
 
        guint internal_text_idx;
        guint external_text_idx;
index ae29a07..9bdb259 100644 (file)
@@ -35,7 +35,7 @@ void _mmplayer_track_initialize(mmplayer_t *player);
 
 void _mmplayer_track_destroy(mmplayer_t *player);
 
-void _mmplayer_track_update_selector_info(mmplayer_t *player, mmplayer_track_type_e type, GstPad *sinkpad);
+void _mmplayer_track_update_stream(mmplayer_t *player, mmplayer_track_type_e type, void *stream);
 
 void _mmplayer_track_update_text_attr_info(mmplayer_t *player, GstMessage *msg);
 
index 56e9500..246e0ba 100644 (file)
 ========================================================================================== */
 
 /*---------------------------------------------------------------------------
-|    GLOBAL CONSTANT DEFINITIONS:                                                                                      |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-|    IMPORTED VARIABLE DECLARATIONS:                                                                           |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-|    IMPORTED FUNCTION DECLARATIONS:                                                                           |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-|    LOCAL #defines:                                                                                                           |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
 |    LOCAL CONSTANT DEFINITIONS:                                                                                       |
 ---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-|    LOCAL DATA TYPE DEFINITIONS:                                                                                      |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-|    GLOBAL VARIABLE DEFINITIONS:                                                                                      |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-|    LOCAL VARIABLE DEFINITIONS:                                                                                       |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-|    LOCAL FUNCTION PROTOTYPES:                                                                                                |
----------------------------------------------------------------------------*/
+#define MMPLAYER_TAG_INDENT 3
 
 /*===========================================================================================
 |                                                                                                                                                                                      |
@@ -117,12 +86,12 @@ __mmplayer_check_error_posted_from_activated_track(mmplayer_t *player, gchar *sr
 {
        /* check whether the error is posted from not-activated track or not */
        int msg_src_pos = 0;
-       gint active_pad_index = 0;
+       gint active_index = 0;
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->mainbin[MMPLAYER_M_A_INPUT_SELECTOR].gst, TRUE);
 
-       active_pad_index = player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].active_pad_index;
-       LOGD("current  active pad index  -%d", active_pad_index);
+       active_index = player->track[MM_PLAYER_TRACK_TYPE_AUDIO].active_track_index;
+       LOGD("current  active pad index  -%d", active_index);
 
        if  (src_element_name) {
                int idx = 0;
@@ -140,10 +109,10 @@ __mmplayer_check_error_posted_from_activated_track(mmplayer_t *player, gchar *sr
                                idx++;
                        }
                }
-               LOGD("active pad = %d, error src index = %d", active_pad_index,  msg_src_pos);
+               LOGD("active pad = %d, error src index = %d", active_index,  msg_src_pos);
        }
 
-       if (active_pad_index != msg_src_pos) {
+       if (active_index != msg_src_pos) {
                LOGD("skip error because error is posted from no activated track");
                return FALSE;
        }
@@ -258,7 +227,8 @@ __mmplayer_gst_transform_gsterror(mmplayer_t *player, GstMessage *message, GErro
        LOGD("error code=%d, msg=%s, src element=%s, class=%s",
                        error->code, error->message, src_element_name, klass);
 
-       if (!__mmplayer_check_error_posted_from_activated_track(player, src_element_name))
+       if (!MMPLAYER_USE_URIDECODEBIN3(player) &&
+               !__mmplayer_check_error_posted_from_activated_track(player, src_element_name))
                return MM_ERROR_NONE;
 
        switch (error->code) {
@@ -1929,7 +1899,7 @@ __mmplayer_print_tag_foreach(const GstTagList *tags, const gchar *tag, gpointer
 {
        GValue val = { 0, };
        gchar *str = NULL;
-       gint depth = GPOINTER_TO_INT(user_data);
+       guint indent = GPOINTER_TO_UINT(user_data);
 
        if (!gst_tag_list_copy_value(&val, tags, tag))
                return;
@@ -1939,7 +1909,7 @@ __mmplayer_print_tag_foreach(const GstTagList *tags, const gchar *tag, gpointer
        else
                str = gst_value_serialize(&val);
 
-       LOGD("%*s%s: %s\n", 2 * depth, " ", gst_tag_get_nick(tag), str);
+       LOGD("%*s%s: %s\n", 2 * indent, " ", gst_tag_get_nick(tag), str);
        g_free(str);
        g_value_unset(&val);
 }
@@ -1969,7 +1939,7 @@ __mmplayer_dump_collection(GstStreamCollection * collection)
                tags = gst_stream_get_tags(stream);
                if (tags) {
                        LOGD ("  tags:\n");
-                       gst_tag_list_foreach(tags, __mmplayer_print_tag_foreach, GUINT_TO_POINTER(3));
+                       gst_tag_list_foreach(tags, __mmplayer_print_tag_foreach, GUINT_TO_POINTER(MMPLAYER_TAG_INDENT));
                        gst_tag_list_unref(tags);
                }
        }
@@ -1979,9 +1949,8 @@ static void
 __mmplayer_stream_notify_cb(GstStreamCollection *collection,
                        GstStream *stream, GParamSpec *pspec, gpointer data)
 {
-
        LOGD ("Got stream-notify from stream %s for %s (collection %p)\n",
-                               stream->stream_id, pspec->name, collection);
+                               gst_stream_get_stream_id(stream), pspec->name, collection);
        if (g_str_equal(pspec->name, "caps")) {
                GstCaps *caps = gst_stream_get_caps(stream);
                gchar *caps_str = gst_caps_to_string(caps);
@@ -1989,6 +1958,15 @@ __mmplayer_stream_notify_cb(GstStreamCollection *collection,
                g_free(caps_str);
                gst_caps_unref(caps);
        }
+
+       if (g_str_equal (pspec->name, "tags")) {
+               GstTagList *tags = gst_stream_get_tags(stream);
+               if (tags) {
+                       LOGD ("  tags:\n");
+                       gst_tag_list_foreach(tags, __mmplayer_print_tag_foreach, GUINT_TO_POINTER(MMPLAYER_TAG_INDENT));
+                       gst_tag_list_unref(tags);
+               }
+       }
 }
 
 static void
@@ -2893,15 +2871,40 @@ gint __mmplayer_gst_select_stream (GstElement * uridecodebin, GstStreamCollectio
     GstStream * stream, gpointer data)
 {
        GstStreamType stype = gst_stream_get_stream_type (stream);
+       mmplayer_t *player = (mmplayer_t *)data;
+       mmplayer_track_type_e type = MM_PLAYER_TRACK_TYPE_MAX;
 
-       if (stype & GST_STREAM_TYPE_AUDIO)
+       if (stype & GST_STREAM_TYPE_AUDIO) {
                LOGW("AUDIO type 0x%X", stype);
-       else if (stype & GST_STREAM_TYPE_VIDEO)
+               type = MM_PLAYER_TRACK_TYPE_AUDIO;
+       }
+
+       if (stype & GST_STREAM_TYPE_VIDEO) {
                LOGW("VIDEO type 0x%X", stype);
-       else if (stype & GST_STREAM_TYPE_TEXT)
+               if (type != MM_PLAYER_TRACK_TYPE_MAX) {
+                       LOGE("Multi Stream 0x%X", type);
+                       return -1;
+               }
+               type = MM_PLAYER_TRACK_TYPE_VIDEO;
+       }
+
+       if (stype & GST_STREAM_TYPE_TEXT) {
                LOGW("TEXT type 0x%X", stype);
+               if (type != MM_PLAYER_TRACK_TYPE_MAX) {
+                       LOGE("Multi Stream 0x%X", type);
+                       return -1;
+               }
+               type = MM_PLAYER_TRACK_TYPE_TEXT;
+       }
+
+       _mmplayer_track_update_stream(player, type, stream);
+
+       if (player->track[type].active_track_index == (player->track[type].total_track_num - 1)) {
+               LOGD("select this stream, type : %d, idx : %d", type, player->track[type].active_track_index);
+               return 1;
+       }
 
-       return 1;
+       return -1;
 }
 
 void
index 00e8afb..db6036c 100644 (file)
@@ -866,7 +866,7 @@ __mmplayer_gst_selector_update_start_time(mmplayer_t *player, mmplayer_track_typ
 
        for (idx = MM_PLAYER_TRACK_TYPE_AUDIO; idx < MM_PLAYER_TRACK_TYPE_TEXT; idx++) {
                if ((player->gapless.update_segment[idx] == TRUE) ||
-                       !(player->selector[idx].event_probe_id)) {
+                       !(player->track[idx].event_probe_id)) {
 #ifdef __DEBUG__
                        LOGW("[%d] skip", idx);
 #endif
@@ -1140,14 +1140,14 @@ __mmplayer_gst_make_selector(mmplayer_t *player, main_element_id_e elem_idx, mmp
        player->pipeline->mainbin[elem_idx].id = elem_idx;
        player->pipeline->mainbin[elem_idx].gst = selector;
 
-       /* player->selector[stream_type].active_pad_index = DEFAULT_TRACK; */
+       /* player->track[stream_type].active_track_index = DEFAULT_TRACK; */
 
        srcpad = gst_element_get_static_pad(selector, "src");
 
        LOGD("blocking %s:%s", GST_DEBUG_PAD_NAME(srcpad));
-       player->selector[stream_type].block_id = gst_pad_add_probe(srcpad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
+       player->track[stream_type].block_id = gst_pad_add_probe(srcpad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
                __mmplayer_gst_selector_blocked, NULL, NULL);
-       player->selector[stream_type].event_probe_id = gst_pad_add_probe(srcpad, GST_PAD_PROBE_TYPE_EVENT_BOTH|GST_PAD_PROBE_TYPE_EVENT_FLUSH,
+       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);
 
        gst_element_set_state(selector, GST_STATE_PAUSED);
@@ -1281,7 +1281,8 @@ _mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
                g_object_set(selector, "active-pad", sinkpad, NULL);
        }
 
-       _mmplayer_track_update_selector_info(player, stream_type, sinkpad);
+       if (!MMPLAYER_USE_URIDECODEBIN3(player))
+               _mmplayer_track_update_stream(player, stream_type, sinkpad);
 
 DONE:
 ERROR:
@@ -1323,9 +1324,9 @@ __mmplayer_create_sink_path(mmplayer_t *player, GstElement *selector, mmplayer_t
        __mmplayer_gst_create_sinkbin(selector, srcpad, player);
 
        LOGD("unblocking %s:%s", GST_DEBUG_PAD_NAME(srcpad));
-       if (player->selector[type].block_id) {
-               gst_pad_remove_probe(srcpad, player->selector[type].block_id);
-               player->selector[type].block_id = 0;
+       if (player->track[type].block_id) {
+               gst_pad_remove_probe(srcpad, player->track[type].block_id);
+               player->track[type].block_id = 0;
        }
 
        if (srcpad) {
@@ -1345,21 +1346,21 @@ __mmplayer_set_decode_track_info(mmplayer_t *player, mmplayer_track_type_e type)
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_IF_FAIL(player);
 
-       LOGD("type: %d, the num of track: %d", type, player->selector[type].total_track_num);
+       LOGD("type: %d, the num of track: %d", type, player->track[type].total_track_num);
 
        /* change track to active pad */
-       active_index = player->selector[type].active_pad_index;
+       active_index = player->track[type].active_track_index;
        if ((active_index != DEFAULT_TRACK) &&
                (__mmplayer_change_selector_pad(player, type, active_index) != MM_ERROR_NONE)) {
                LOGW("failed to change %d type track to %d", type, active_index);
-               player->selector[type].active_pad_index = DEFAULT_TRACK;
+               player->track[type].active_track_index = DEFAULT_TRACK;
                return;
        }
 
        if (type == MM_PLAYER_TRACK_TYPE_TEXT)
                mm_player_set_attribute((MMHandleType)player, NULL,
-                               "content_text_track_num", player->selector[type].total_track_num,
-                               "current_text_track_index", player->selector[type].active_pad_index, NULL);
+                               "content_text_track_num", player->track[type].total_track_num,
+                               "current_text_track_index", player->track[type].active_track_index, NULL);
 
        MMPLAYER_FLEAVE();
        return;
@@ -1392,7 +1393,8 @@ __mmplayer_create_audio_sink_path(mmplayer_t *player, GstElement *audio_selector
        }
 
        /* apply the audio track information */
-       __mmplayer_set_decode_track_info(player, MM_PLAYER_TRACK_TYPE_AUDIO);
+       if (!MMPLAYER_USE_URIDECODEBIN3(player))
+               __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)) {
@@ -1418,7 +1420,7 @@ __mmplayer_create_text_sink_path(mmplayer_t *player, GstElement *text_selector)
        /* apply the text track information */
        __mmplayer_set_decode_track_info(player, MM_PLAYER_TRACK_TYPE_TEXT);
 
-       if (player->selector[MM_PLAYER_TRACK_TYPE_TEXT].total_track_num > 0)
+       if (player->track[MM_PLAYER_TRACK_TYPE_TEXT].total_track_num > 0)
                player->has_closed_caption = TRUE;
 
        /* create text decode path */
@@ -6447,7 +6449,7 @@ ERROR:
 static gboolean
 __mmplayer_deactivate_selector(mmplayer_t *player, mmplayer_track_type_e type)
 {
-       mmplayer_selector_t *selector = &player->selector[type];
+       mmplayer_track_t *selector = &player->track[type];
        mmplayer_gst_element_t *sinkbin = NULL;
        main_element_id_e selectorId = MMPLAYER_M_NUM;
        main_element_id_e sinkId = MMPLAYER_M_NUM;
@@ -6518,11 +6520,12 @@ __mmplayer_deactivate_selector(mmplayer_t *player, mmplayer_track_type_e type)
                LOGD("selector release");
 
                /* release and unref requests pad from the selector */
-               for (n = 0; n < selector->channels->len; n++) {
-                       GstPad *sinkpad = g_ptr_array_index(selector->channels, n);
+               for (n = 0; n < selector->streams->len; n++) {
+                       GstPad *sinkpad = g_ptr_array_index(selector->streams, n);
                        gst_element_release_request_pad((player->pipeline->mainbin[selectorId].gst), sinkpad);
                }
-               g_ptr_array_set_size(selector->channels, 0);
+
+               g_ptr_array_set_size(selector->streams, 0);
 
                gst_element_set_state(player->pipeline->mainbin[selectorId].gst, GST_STATE_NULL);
                gst_bin_remove(GST_BIN_CAST(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst), player->pipeline->mainbin[selectorId].gst);
@@ -8139,6 +8142,35 @@ _mmplayer_set_external_subtitle_path(MMHandleType hplayer, const char *filepath)
 }
 
 static int
+__mmplayer_switch_stream(mmplayer_t *player, mmplayer_track_type_e type, int index)
+{
+       guint active_idx = 0;
+       GstStream *stream = NULL;
+       GList *streams = NULL;
+       GstEvent *ev = NULL;
+
+       LOGD("Switching Streams... type: %d, index: %d", type, index);
+
+       player->track[type].active_track_index = index;
+
+       for (int i = 0; i < MM_PLAYER_TRACK_TYPE_MAX; i++) {
+               /* FIXME: need to consider the non display type or audio only in case of MM_PLAYER_TRACK_TYPE_VIDEO */
+               if (player->track[i].total_track_num > 0) {
+                       active_idx = player->track[i].active_track_index;
+                       stream = g_ptr_array_index(player->track[i].streams, active_idx);
+                       streams = g_list_append (streams, (gchar *)gst_stream_get_stream_id(stream));
+                       LOGD("Selecting %d type stream : %s\n", i, gst_stream_get_stream_id(stream));
+               }
+       }
+
+       ev = gst_event_new_select_streams(streams);
+       gst_element_send_event(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, ev);
+       g_list_free(streams);
+
+       return MM_ERROR_NONE;
+}
+
+static int
 __mmplayer_change_selector_pad(mmplayer_t *player, mmplayer_track_type_e type, int index)
 {
        int result = MM_ERROR_NONE;
@@ -8174,7 +8206,7 @@ __mmplayer_change_selector_pad(mmplayer_t *player, mmplayer_track_type_e type, i
                goto EXIT;
        }
 
-       total_track_num = player->selector[type].total_track_num;
+       total_track_num = player->track[type].total_track_num;
        if (total_track_num <= 0) {
                result = MM_ERROR_PLAYER_NO_OP;
                LOGD("Language list is not available");
@@ -8231,7 +8263,6 @@ _mmplayer_change_track_language(MMHandleType hplayer, mmplayer_track_type_e type
        gint current_active_index = 0;
 
        GstState current_state = GST_STATE_VOID_PENDING;
-       GstEvent *event = NULL;
        gint64 time = 0;
 
        MMPLAYER_FENTER();
@@ -8242,13 +8273,13 @@ _mmplayer_change_track_language(MMHandleType hplayer, mmplayer_track_type_e type
        if (!player->pipeline) {
                LOGE("Track %d pre setting -> %d", type, index);
 
-               player->selector[type].active_pad_index = index;
+               player->track[type].active_track_index = index;
                goto EXIT;
        }
 
        mainbin = player->pipeline->mainbin;
 
-       current_active_index = player->selector[type].active_pad_index;
+       current_active_index = player->track[type].active_track_index;
 
        /*If index is same as running index no need to change the pad*/
        if (current_active_index == index)
@@ -8266,23 +8297,30 @@ _mmplayer_change_track_language(MMHandleType hplayer, mmplayer_track_type_e type
                goto EXIT;
        }
 
-       result = __mmplayer_change_selector_pad(player, type, index);
+       if (MMPLAYER_USE_URIDECODEBIN3(player)) {
+               result = __mmplayer_switch_stream(player, type, index);
+       } else {
+               result = __mmplayer_change_selector_pad(player, type, index);
+       }
        if (result != MM_ERROR_NONE) {
-               LOGE("change selector pad error");
+               LOGE("failed to change track");
                goto EXIT;
        }
 
-       player->selector[type].active_pad_index = index;
+       player->track[type].active_track_index = index;
 
-       if (current_state == GST_STATE_PLAYING) {
-               event = gst_event_new_seek(player->playback_rate, GST_FORMAT_TIME,
-                       (GstSeekFlags)(GST_SEEK_FLAG_SEGMENT | GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SKIP),
-                       GST_SEEK_TYPE_SET, time, GST_SEEK_TYPE_NONE, -1);
-               if (event) {
-                       _mmplayer_gst_send_event_to_sink(player, event);
-               } else {
-                       result = MM_ERROR_PLAYER_INTERNAL;
-                       goto EXIT;
+       if (!MMPLAYER_USE_URIDECODEBIN3(player)) {
+               GstEvent *event = NULL;
+               if (current_state == GST_STATE_PLAYING) {
+                       event = gst_event_new_seek(player->playback_rate, GST_FORMAT_TIME,
+                               (GstSeekFlags)(GST_SEEK_FLAG_SEGMENT | GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SKIP),
+                               GST_SEEK_TYPE_SET, time, GST_SEEK_TYPE_NONE, -1);
+                       if (event) {
+                               _mmplayer_gst_send_event_to_sink(player, event);
+                       } else {
+                               result = MM_ERROR_PLAYER_INTERNAL;
+                               goto EXIT;
+                       }
                }
        }
 
index e76b8a4..effb483 100644 (file)
@@ -63,8 +63,8 @@ _mmplayer_get_track_count(MMHandleType hplayer,  mmplayer_track_type_e type, int
 
        switch (type) {
        case MM_PLAYER_TRACK_TYPE_AUDIO:
-               if (player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].total_track_num > 0)
-                       *count = player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].total_track_num;
+               if (player->track[MM_PLAYER_TRACK_TYPE_AUDIO].total_track_num > 0)
+                       *count = player->track[MM_PLAYER_TRACK_TYPE_AUDIO].total_track_num;
                break;
        case MM_PLAYER_TRACK_TYPE_TEXT: /* internal or external */
                ret = mm_attrs_get_int_by_name(attrs, "content_text_track_num", count);
@@ -171,13 +171,13 @@ _mmplayer_get_current_track(MMHandleType hplayer, mmplayer_track_type_e type, in
 
        switch (type) {
        case MM_PLAYER_TRACK_TYPE_AUDIO:
-               if (player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].total_track_num <= 0) {
+               if (player->track[MM_PLAYER_TRACK_TYPE_AUDIO].total_track_num <= 0) {
                        LOGW("there is no audio track");
                        ret = MM_ERROR_PLAYER_NO_OP;
                        goto EXIT;
                }
 
-               *index = player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].active_pad_index;
+               *index = player->track[MM_PLAYER_TRACK_TYPE_AUDIO].active_track_index;
                break;
        case MM_PLAYER_TRACK_TYPE_TEXT: /* internal or external */
                mm_attrs_get_int_by_name(attrs, "content_text_track_num", &count);
@@ -235,7 +235,7 @@ _mmplayer_get_track_language_code(MMHandleType hplayer, mmplayer_track_type_e ty
                }
                g_strlcpy(lang_code, language_list->language_code, LANGUAGE_CODE_SIZE);
        } else { /* audio or internal subtitle */
-               if (player->selector[type].total_track_num <= 0) {
+               if (player->track[type].total_track_num <= 0) {
                        LOGW("language list is not available. [type:%d]", type);
                        ret = MM_ERROR_PLAYER_NO_OP;
                        goto EXIT;
@@ -268,11 +268,11 @@ _mmplayer_track_initialize(mmplayer_t *player)
        MMPLAYER_FENTER();
 
        for (; type < MM_PLAYER_TRACK_TYPE_MAX ; type++) {
-               /* active_pad_index is initialized when player is created or destroyed.
+               /* active_track_index is initialized when player is created or destroyed.
                   and the value can be set by calling _mmplayer_change_track_language()
                   before pipeline is created.*/
-               player->selector[type].total_track_num = 0;
-               player->selector[type].channels = g_ptr_array_new();
+               player->track[type].total_track_num = 0;
+               player->track[type].streams = g_ptr_array_new();
        }
 }
 
@@ -287,24 +287,24 @@ _mmplayer_track_destroy(mmplayer_t *player)
                LOGE("failed to reset track attr");
 
        for (; type < MM_PLAYER_TRACK_TYPE_MAX ; type++) {
-               player->selector[type].active_pad_index = 0;
-               player->selector[type].total_track_num = 0;
+               player->track[type].active_track_index = 0;
+               player->track[type].total_track_num = 0;
 
-               if (player->selector[type].channels)
-                       g_ptr_array_free(player->selector[type].channels, TRUE);
-               player->selector[type].channels = NULL;
+               if (player->track[type].streams)
+                       g_ptr_array_free(player->track[type].streams, TRUE);
+               player->track[type].streams = NULL;
        }
 }
 
 void
-_mmplayer_track_update_selector_info(mmplayer_t *player, mmplayer_track_type_e type, GstPad *sinkpad)
+_mmplayer_track_update_stream(mmplayer_t *player, mmplayer_track_type_e type, void *stream)
 {
        MMPLAYER_FENTER();
 
-       player->selector[type].total_track_num++;
-       g_ptr_array_add(player->selector[type].channels, sinkpad);
+       player->track[type].total_track_num++;
+       g_ptr_array_add(player->track[type].streams, stream);
 
-       LOGD("type: %d, track cnt: %d", type, player->selector[type].total_track_num);
+       LOGD("type: %d, track cnt: %d", type, player->track[type].total_track_num);
 }
 
 void
@@ -378,20 +378,24 @@ __mmplayer_track_get_language(mmplayer_t *player, mmplayer_track_type_e type, gi
 {
        GstTagList *tag_list = NULL;
        gchar *tag = NULL;
-       GstPad *sinkpad = NULL;
 
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
        MMPLAYER_RETURN_VAL_IF_FAIL((code && (stream_index >= 0) &&
-               (stream_index < player->selector[type].total_track_num)), MM_ERROR_INVALID_ARGUMENT);
+               (stream_index < player->track[type].total_track_num)), MM_ERROR_INVALID_ARGUMENT);
 
-       LOGD("type: %d, track count: %d, intput idx: %d", type, player->selector[type].total_track_num, stream_index);
+       LOGD("type: %d, track count: %d, intput idx: %d", type, player->track[type].total_track_num, stream_index);
 
        *code = (gchar *)g_malloc0(LANGUAGE_CODE_SIZE * sizeof(char));
 
-       sinkpad = g_ptr_array_index(player->selector[type].channels, stream_index);
+       if (MMPLAYER_USE_URIDECODEBIN3(player)) {
+               GstStream *stream = g_ptr_array_index(player->track[type].streams, stream_index);
+               tag_list = gst_stream_get_tags (stream);
+       } else {
+               GstPad *sinkpad = g_ptr_array_index(player->track[type].streams, stream_index);
+               g_object_get(sinkpad, "tags", &tag_list, NULL);
+       }
 
-       g_object_get(sinkpad, "tags", &tag_list, NULL);
        if (tag_list)
                gst_tag_list_get_string(tag_list, GST_TAG_LANGUAGE_CODE, &tag);