return TRUE;
}
+
+static mmplayer_track_type_e
+__mmplayer_convert_gst_stream_type_to_track_type (GstStreamType stype)
+{
+ switch (stype) {
+ case GST_STREAM_TYPE_AUDIO:
+ return MM_PLAYER_TRACK_TYPE_AUDIO;
+ case GST_STREAM_TYPE_VIDEO:
+ return MM_PLAYER_TRACK_TYPE_VIDEO;
+ case GST_STREAM_TYPE_TEXT:
+ return MM_PLAYER_TRACK_TYPE_TEXT;
+ default:
+ LOGD("not supported stream stype");
+ return MM_PLAYER_TRACK_TYPE_MAX;
+ }
+}
+
/* if retval is FALSE, it will be dropped for performance. */
static gboolean
__mmplayer_gst_check_useful_message(mmplayer_t *player, GstMessage *message)
gst_message_parse_streams_selected(msg, &collection);
if (collection) {
- guint i = 0, len = 0;
- len = gst_message_streams_selected_get_size(msg);
- for (i = 0; i < len; i++) {
+ guint len = gst_message_streams_selected_get_size(msg);
+ for (guint i = 0; i < len; i++) {
GstStream *stream = gst_message_streams_selected_get_stream(msg, i);
+ mmplayer_track_type_e type = __mmplayer_convert_gst_stream_type_to_track_type(
+ gst_stream_get_stream_type(stream));
LOGD (" Stream #%d : %s\n", i, gst_stream_get_stream_id(stream));
+ if (player->track[type].active_track_index == INVALID_TRACK_INDEX) {
+ int stream_index = INVALID_TRACK_INDEX;
+ if (_mmplayer_get_track_index(player, type, stream, &stream_index) == MM_ERROR_NONE) {
+ player->track[type].active_track_index = stream_index;
+ LOGD("selected this stream, update active idx : %d",
+ player->track[type].active_track_index);
+ }
+ }
gst_object_unref(stream);
}
gst_object_unref (collection);
MMPLAYER_FLEAVE();
}
-static gboolean
-__mmplayer_stream_equal(gconstpointer stream1, gconstpointer stream2)
-{
- const gchar *stream1_id = gst_stream_get_stream_id((GstStream *)stream1);
- const gchar *stream2_id = gst_stream_get_stream_id((GstStream *)stream2);
-
- return (g_strcmp0(stream1_id, stream2_id) == 0);
-}
-
-static gboolean
-__mmplayer_has_duplicated_stream(mmplayer_t *player, GstStreamType stype, GstStream *stream)
-{
- mmplayer_track_type_e type = MM_PLAYER_TRACK_TYPE_MAX;
- MMPLAYER_FENTER();
- MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
-
- switch (stype) {
- case GST_STREAM_TYPE_AUDIO:
- type = MM_PLAYER_TRACK_TYPE_AUDIO;
- break;
- case GST_STREAM_TYPE_VIDEO:
- type = MM_PLAYER_TRACK_TYPE_VIDEO;
- break;
- case GST_STREAM_TYPE_TEXT:
- type = MM_PLAYER_TRACK_TYPE_TEXT;
- break;
- default:
- LOGD("Skip not supported stream stype");
- return FALSE;
- }
-
- return g_ptr_array_find_with_equal_func(player->track[type].streams, stream, __mmplayer_stream_equal, NULL);
-}
-
static gint
__mmplayer_gst_select_stream (GstElement * uridecodebin, GstStreamCollection * collection,
GstStream * stream, gpointer data)
{
- gint ret = 0; /* 1: select, 0: skip, -1: depends on decodebin */
+#define RET_SELECT 1
+#define RET_SKIP 0
+#define RET_DEPENDS_ON_DECODEBIN -1
+
GstStreamType stype = gst_stream_get_stream_type(stream);
mmplayer_t *player = (mmplayer_t *)data;
mmplayer_track_type_e type = MM_PLAYER_TRACK_TYPE_MAX;
- GstCaps *caps = gst_stream_get_caps(stream);
+ g_autoptr(GstCaps) caps = gst_stream_get_caps(stream);
+ g_autofree gchar *caps_str = NULL;
GstStructure *caps_structure = NULL;
- gchar *caps_str = NULL;
+ int stream_index = INVALID_TRACK_INDEX;
+ int ret = MM_ERROR_NONE;
LOGD("Stream type %s flags 0x%x",
gst_stream_type_get_name(stype),
gst_stream_get_stream_flags(stream));
LOGD(" ID: %s", gst_stream_get_stream_id(stream));
- if (__mmplayer_has_duplicated_stream(player, stype, stream)) {
- LOGD("Already added stream, skip it");
- ret = 0;
- goto EXIT;
- }
+ type = __mmplayer_convert_gst_stream_type_to_track_type(stype);
if (caps) {
caps_str = gst_caps_to_string(caps);
mime, player->ini.unsupported_codec_keyword[idx]);
_mmplayer_update_not_supported_codec_info(player, NULL, mime);
- ret = 0;
- goto EXIT;
+ return RET_SKIP;
}
}
+ } else if (type == MM_PLAYER_TRACK_TYPE_AUDIO || type == MM_PLAYER_TRACK_TYPE_VIDEO) {
+ if (MMPLAYER_IS_HTTP_LIVE_STREAMING(player) || MMPLAYER_IS_DASH_STREAMING(player)) {
+ LOGD("No caps info, depends on decodebin");
+ _mmplayer_track_update_stream(player, type, stream);
+ return RET_DEPENDS_ON_DECODEBIN;
+ }
+
+ LOGD("No caps info, skip it");
+ return RET_SKIP;
}
switch (stype) {
case GST_STREAM_TYPE_AUDIO:
{
- gint samplerate = 0;
- gint channels = 0;
-
- type = MM_PLAYER_TRACK_TYPE_AUDIO;
-
if (caps_structure) {
+ gint samplerate = 0;
+ gint channels = 0;
+
gst_structure_get_int(caps_structure, "rate", &samplerate);
gst_structure_get_int(caps_structure, "channels", &channels);
-
- if (channels > 0 && samplerate == 0) {
+ if (samplerate == 0 && channels > 0) {
LOGW("Skip corrupted audio stream");
- goto EXIT;
+ return RET_SKIP;
}
if (g_strrstr(caps_str, "mobile-xmf"))
}
case GST_STREAM_TYPE_VIDEO:
{
- gint stype = 0;
- gint width = 0;
-
- type = MM_PLAYER_TRACK_TYPE_VIDEO;
-
- /* do not support multi track video */
- if (player->track[MM_PLAYER_TRACK_TYPE_VIDEO].total_track_num >= 1)
- goto EXIT;
+ if (player->track[MM_PLAYER_TRACK_TYPE_VIDEO].total_track_num >= 1) {
+ LOGD("do not support muti track video");
+ break;
+ }
// FIXME: it cause block during preparing
if ((!MMPLAYER_IS_HTTP_LIVE_STREAMING(player)) && (!MMPLAYER_IS_DASH_STREAMING(player))) {
- mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &stype);
+ gint stype = 0;
+ 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, skip video stream");
- goto EXIT;
+ return RET_SKIP;
}
}
if (caps_structure) {
- gst_structure_get_int(caps_structure, "width", &width);
+ gint width = 0;
+ gst_structure_get_int(caps_structure, "width", &width);
if (width != 0) {
if (player->v_stream_caps) {
gst_caps_unref(player->v_stream_caps);
break;
}
case GST_STREAM_TYPE_TEXT:
- type = MM_PLAYER_TRACK_TYPE_TEXT;
break;
default:
LOGW("Skip not supported stream type");
- goto EXIT;
+ return RET_SKIP;
}
_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, active idx : %d", player->track[type].active_track_index);
+ ret = _mmplayer_get_track_index(player, type, stream, &stream_index);
+
+ if ((player->track[type].active_track_index == INVALID_TRACK_INDEX) &&
+ (ret == MM_ERROR_NONE)) {
+ player->track[type].active_track_index = stream_index;
+ LOGD("select this stream, active track idx : %d", player->track[type].active_track_index);
if (type == MM_PLAYER_TRACK_TYPE_AUDIO)
_mmplayer_set_audio_attrs(player, caps);
- ret = 1;
+ return RET_SELECT;
}
-EXIT:
- g_free(caps_str);
- if (caps)
- gst_caps_unref(caps);
+ if (player->track[type].active_track_index == stream_index) {
+ LOGD("already activate track idx : %d", player->track[type].active_track_index);
+ return RET_SELECT;
+ }
- LOGD("ret %d", ret);
- return ret;
+ LOGD("Skip stream");
+ return RET_SKIP;
}
static gboolean
/* check player handle */
MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+ MMPLAYER_RETURN_VAL_IF_FAIL(type < MM_PLAYER_TRACK_TYPE_MAX, MM_ERROR_INVALID_ARGUMENT);
MMPLAYER_RETURN_VAL_IF_FAIL(count, MM_ERROR_INVALID_ARGUMENT);
MMPLAYER_RETURN_VAL_IF_FAIL((MMPLAYER_CURRENT_STATE(player) == MM_PLAYER_STATE_PAUSED)
|| (MMPLAYER_CURRENT_STATE(player) == MM_PLAYER_STATE_PLAYING),
MMPLAYER_FENTER();
MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+ MMPLAYER_RETURN_VAL_IF_FAIL(type < MM_PLAYER_TRACK_TYPE_MAX, MM_ERROR_INVALID_ARGUMENT);
LOGD("track type: %d, index: %d", type, index);
MMPLAYER_FENTER();
MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+ MMPLAYER_RETURN_VAL_IF_FAIL(type < MM_PLAYER_TRACK_TYPE_MAX, MM_ERROR_INVALID_ARGUMENT);
MMPLAYER_RETURN_VAL_IF_FAIL(index, MM_ERROR_INVALID_ARGUMENT);
attrs = MMPLAYER_GET_ATTRS(player);
MMPLAYER_FENTER();
MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+ MMPLAYER_RETURN_VAL_IF_FAIL(type < MM_PLAYER_TRACK_TYPE_MAX, MM_ERROR_INVALID_ARGUMENT);
MMPLAYER_RETURN_VAL_IF_FAIL(code, MM_ERROR_INVALID_ARGUMENT);
MMPLAYER_SUBTITLE_INFO_LOCK(player);
MMPLAYER_FENTER();
for (; type < MM_PLAYER_TRACK_TYPE_MAX ; type++) {
- /* 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->track[type].active_track_index = INVALID_TRACK_INDEX;
player->track[type].total_track_num = 0;
player->track[type].streams = g_ptr_array_new_with_free_func(gst_object_unref);
}
}
}
+int
+_mmplayer_get_track_index(mmplayer_t *player, mmplayer_track_type_e type, void* stream, int *index)
+{
+ guint found_index = 0;
+
+ MMPLAYER_FENTER();
+ MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+ MMPLAYER_RETURN_VAL_IF_FAIL(type < MM_PLAYER_TRACK_TYPE_MAX, MM_ERROR_INVALID_ARGUMENT);
+ MMPLAYER_RETURN_VAL_IF_FAIL(index, MM_ERROR_INVALID_ARGUMENT);
+
+ if (g_ptr_array_find(player->track[type].streams, stream, &found_index)) {
+ LOGD("Find same stream (%u)", found_index);
+ *index = (int)found_index;
+ return MM_ERROR_NONE;
+ }
+
+ *index = INVALID_TRACK_INDEX;
+ LOGD("Stream not found : type %d, stream %p", type, stream);
+ return MM_ERROR_PLAYER_INTERNAL;
+}
+
+static gboolean
+__mmplayer_stream_equal(gconstpointer stream1, gconstpointer stream2)
+{
+ return (g_strcmp0(gst_stream_get_stream_id((GstStream *)stream1),
+ gst_stream_get_stream_id((GstStream *)stream2)) == 0);
+}
+
void
_mmplayer_track_update_stream(mmplayer_t *player, mmplayer_track_type_e type, void *stream)
{
MMPLAYER_FENTER();
+ MMPLAYER_RETURN_IF_FAIL(player);
+ MMPLAYER_RETURN_IF_FAIL(type < MM_PLAYER_TRACK_TYPE_MAX);
+
+ if (g_ptr_array_find_with_equal_func(player->track[type].streams, stream, __mmplayer_stream_equal, NULL)) {
+ LOGD("Already added stream, not updated");
+ return;
+ }
player->track[type].total_track_num++;
g_ptr_array_add(player->track[type].streams, gst_object_ref(stream));
MMPLAYER_FENTER();
MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+ MMPLAYER_RETURN_VAL_IF_FAIL(type < MM_PLAYER_TRACK_TYPE_MAX, MM_ERROR_INVALID_ARGUMENT);
MMPLAYER_RETURN_VAL_IF_FAIL((code && (stream_index >= 0) &&
(stream_index < player->track[type].total_track_num)), MM_ERROR_INVALID_ARGUMENT);