From 202effe0ecca168973ef34f9049075d8ba9f51a2 Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Mon, 17 Jul 2023 15:06:16 +0900 Subject: [PATCH] [0.6.287] Fix HLS prepare issue - Invalid argument check for mmplayer_track-type_e Change-Id: I9a703d74bfdd5f6676c58f43b0f83e594de81bc5 --- packaging/libmm-player.spec | 2 +- src/include/mm_player_tracks.h | 2 + src/mm_player_gst.c | 153 ++++++++++++++++++++--------------------- src/mm_player_priv.c | 1 + src/mm_player_tracks.c | 44 +++++++++++- 5 files changed, 121 insertions(+), 81 deletions(-) diff --git a/packaging/libmm-player.spec b/packaging/libmm-player.spec index c68189a..2c6bdaf 100644 --- a/packaging/libmm-player.spec +++ b/packaging/libmm-player.spec @@ -1,6 +1,6 @@ Name: libmm-player Summary: Multimedia Framework Player Library -Version: 0.6.286 +Version: 0.6.287 Release: 0 Group: Multimedia/Libraries License: Apache-2.0 diff --git a/src/include/mm_player_tracks.h b/src/include/mm_player_tracks.h index 4a64b90..a9987ee 100644 --- a/src/include/mm_player_tracks.h +++ b/src/include/mm_player_tracks.h @@ -40,6 +40,8 @@ void _mmplayer_track_update_stream(mmplayer_t *player, mmplayer_track_type_e typ void _mmplayer_track_update_text_attr_info(mmplayer_t *player, GstMessage *msg); +int _mmplayer_get_track_index(mmplayer_t *player, mmplayer_track_type_e type, void* stream, int *index); + int _mmplayer_get_track_count(MMHandleType hplayer, mmplayer_track_type_e type, int *count); int _mmplayer_select_track(MMHandleType hplayer, mmplayer_track_type_e type, int index); diff --git a/src/mm_player_gst.c b/src/mm_player_gst.c index 27498b7..8924690 100644 --- a/src/mm_player_gst.c +++ b/src/mm_player_gst.c @@ -872,6 +872,23 @@ __mmplayer_gst_extract_tag_from_msg(mmplayer_t *player, GstMessage *msg) 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) @@ -2076,11 +2093,20 @@ __mmplayer_gst_bus_msg_callback(GstMessage *msg, gpointer data) 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); @@ -2881,62 +2907,29 @@ __mmplayer_gst_found_source(GObject *object, GObject *orig, GParamSpec *pspec, g 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); @@ -2951,27 +2944,32 @@ __mmplayer_gst_select_stream (GstElement * uridecodebin, GstStreamCollection * c 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")) @@ -2982,30 +2980,28 @@ __mmplayer_gst_select_stream (GstElement * uridecodebin, GstStreamCollection * c } 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); @@ -3019,29 +3015,32 @@ __mmplayer_gst_select_stream (GstElement * uridecodebin, GstStreamCollection * c 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 diff --git a/src/mm_player_priv.c b/src/mm_player_priv.c index f335587..1925e54 100644 --- a/src/mm_player_priv.c +++ b/src/mm_player_priv.c @@ -8732,6 +8732,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); diff --git a/src/mm_player_tracks.c b/src/mm_player_tracks.c index 0c51db7..6104d09 100644 --- a/src/mm_player_tracks.c +++ b/src/mm_player_tracks.c @@ -47,6 +47,7 @@ _mmplayer_get_track_count(MMHandleType hplayer, mmplayer_track_type_e type, int /* 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), @@ -88,6 +89,7 @@ _mmplayer_select_track(MMHandleType hplayer, mmplayer_track_type_e type, int ind 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); @@ -157,6 +159,7 @@ _mmplayer_get_current_track(MMHandleType hplayer, mmplayer_track_type_e type, in 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); @@ -217,6 +220,7 @@ _mmplayer_get_track_language_code(MMHandleType hplayer, mmplayer_track_type_e ty 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); @@ -267,9 +271,7 @@ _mmplayer_track_initialize(mmplayer_t *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); } @@ -295,10 +297,45 @@ _mmplayer_track_destroy(mmplayer_t *player) } } +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)); @@ -380,6 +417,7 @@ __mmplayer_track_get_language(mmplayer_t *player, mmplayer_track_type_e type, gi 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); -- 2.7.4