diff options
author | Eunhye Choi <eunhae1.choi@samsung.com> | 2019-10-02 14:35:47 +0900 |
---|---|---|
committer | Eunhye Choi <eunhae1.choi@samsung.com> | 2019-10-02 17:37:46 +0900 |
commit | 869197c68f07bb925fd3eed18ead2d296f174846 (patch) | |
tree | 153f8ac50f51546692a067d4b713e3fad7cebb7e | |
parent | 62487d23412e2b9a248f0bb0c61d813636c3a99a (diff) | |
download | libmm-player-869197c68f07bb925fd3eed18ead2d296f174846.tar.gz libmm-player-869197c68f07bb925fd3eed18ead2d296f174846.tar.bz2 libmm-player-869197c68f07bb925fd3eed18ead2d296f174846.zip |
[0.6.205] sort codec factory by user requestsubmit/tizen/20191004.024448accepted/tizen/unified/20191006.223651
- sort codec elements instead of skip it during auto-plugging.
- to handle the unsupported media format with default type decoder
the other type decoder should be added.
Change-Id: I80aea47412e6230f8677bc8ffc66874d325d5e05
-rw-r--r-- | packaging/libmm-player.spec | 2 | ||||
-rw-r--r-- | src/include/mm_player_priv.h | 3 | ||||
-rw-r--r-- | src/mm_player_gst.c | 4 | ||||
-rw-r--r-- | src/mm_player_priv.c | 186 |
4 files changed, 147 insertions, 48 deletions
diff --git a/packaging/libmm-player.spec b/packaging/libmm-player.spec index 94c15dc..4b0d878 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.204 +Version: 0.6.205 Release: 0 Group: Multimedia/Libraries License: Apache-2.0 diff --git a/src/include/mm_player_priv.h b/src/include/mm_player_priv.h index c74063f..5431dfd 100644 --- a/src/include/mm_player_priv.h +++ b/src/include/mm_player_priv.h @@ -635,6 +635,8 @@ typedef struct { gboolean no_more_pad; gint num_dynamic_pad; gboolean has_many_types; + gboolean need_audio_dec_sorting; + gboolean need_video_dec_sorting; /* progress callback timer */ /* FIXIT : since duplicated functionality with get_position @@ -878,6 +880,7 @@ gboolean _mmplayer_gst_remove_fakesink(mmplayer_t *player, mmplayer_gst_element_ void _mmplayer_add_signal_connection(mmplayer_t *player, GObject *object, mmplayer_signal_type_e type, const gchar *signal, GCallback cb_funct, gpointer u_data); void _mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data); gint _mmplayer_gst_decode_autoplug_select(GstElement *bin, GstPad *pad, GstCaps *caps, GstElementFactory *factory, gpointer data); +GValueArray *_mmplayer_gst_decode_autoplug_sort(GstElement *bin, GstPad *pad, GstCaps *caps, GValueArray *factories, gpointer data); gboolean _mmplayer_gst_create_decoder(mmplayer_t *player, GstPad *srcpad, const GstCaps *caps); void _mmplayer_gst_element_added(GstElement *bin, GstElement *element, gpointer data); GstElement *_mmplayer_gst_make_decodebin(mmplayer_t *player); diff --git a/src/mm_player_gst.c b/src/mm_player_gst.c index b2dd971..79af3f2 100644 --- a/src/mm_player_gst.c +++ b/src/mm_player_gst.c @@ -2295,6 +2295,10 @@ __mmplayer_gst_create_es_decoder(mmplayer_t *player, mmplayer_stream_type_e type _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-select", G_CALLBACK(_mmplayer_gst_decode_autoplug_select), (gpointer)player); + if (player->need_video_dec_sorting || player->need_audio_dec_sorting) + _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-sort", + G_CALLBACK(_mmplayer_gst_decode_autoplug_sort), (gpointer)player); + /* This signal is emitted when a element is added to the bin.*/ _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "element-added", G_CALLBACK(_mmplayer_gst_element_added), (gpointer)player); diff --git a/src/mm_player_priv.c b/src/mm_player_priv.c index 08c11fb..6f1a7d6 100644 --- a/src/mm_player_priv.c +++ b/src/mm_player_priv.c @@ -4947,11 +4947,13 @@ int _mmplayer_realize(MMHandleType hplayer) { mmplayer_t *player = (mmplayer_t *)hplayer; + int ret = MM_ERROR_NONE; char *uri = NULL; void *param = NULL; MMHandleType attrs = 0; - int ret = MM_ERROR_NONE; - + int video_codec_type = 0; + int audio_codec_type = 0; + int default_codec_type = 0; MMPLAYER_FENTER(); /* check player handle */ @@ -5035,6 +5037,23 @@ _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) @@ -5937,6 +5956,10 @@ _mmplayer_gst_make_decodebin(mmplayer_t *player) _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-continue", G_CALLBACK(__mmplayer_gst_decode_autoplug_continue), (gpointer)player); + if (player->need_video_dec_sorting || player->need_audio_dec_sorting) + _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-sort", + G_CALLBACK(_mmplayer_gst_decode_autoplug_sort), (gpointer)player); + /* This signal is emitted whenever decodebin finds a new stream. It is emitted before looking for any elements that can handle that stream.*/ _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-select", @@ -6941,8 +6964,6 @@ static GstAutoplugSelectResult __mmplayer_check_codec_info(mmplayer_t *player, const char *klass, GstCaps *caps, char *factory_name) { GstAutoplugSelectResult ret = GST_AUTOPLUG_SELECT_TRY; - int idx = 0; - int codec_type = MM_PLAYER_CODEC_TYPE_DEFAULT; int audio_offload = 0; if ((g_strrstr(klass, "Codec/Decoder/Audio"))) { @@ -6964,28 +6985,6 @@ __mmplayer_check_codec_info(mmplayer_t *player, const char *klass, GstCaps *caps And need to consider the multi-track audio content. There is no HW audio decoder in public. */ - mm_attrs_get_int_by_name(player->attrs, "audio_codec_type", &codec_type); - - LOGD("audio codec type: %d", codec_type); - if (codec_type == MM_PLAYER_CODEC_TYPE_HW) { - /* sw codec will be skipped */ - for (idx = 0; player->ini.audiocodec_element_sw[idx][0] != '\0'; idx++) { - if (strstr(factory_name, player->ini.audiocodec_element_sw[idx])) { - LOGW("skipping sw acodec:[%s] by codec type", factory_name); - ret = GST_AUTOPLUG_SELECT_SKIP; - goto DONE; - } - } - } else if (codec_type == MM_PLAYER_CODEC_TYPE_SW) { - /* hw codec will be skipped */ - if (strcmp(player->ini.audiocodec_element_hw, "") && - g_strrstr(factory_name, player->ini.audiocodec_element_hw)) { - LOGW("skipping hw acodec:[%s] by codec type", factory_name); - ret = GST_AUTOPLUG_SELECT_SKIP; - goto DONE; - } - } - /* set stream information */ if (!player->audiodec_linked) __mmplayer_set_audio_attrs(player, caps); @@ -6997,27 +6996,6 @@ __mmplayer_check_codec_info(mmplayer_t *player, const char *klass, GstCaps *caps } else if (g_strrstr(klass, "Codec/Decoder/Video")) { - mm_attrs_get_int_by_name(player->attrs, "video_codec_type", &codec_type); - - LOGD("video codec type: %d", codec_type); - if (codec_type == MM_PLAYER_CODEC_TYPE_HW) { - /* sw codec is skipped */ - for (idx = 0; player->ini.videocodec_element_sw[idx][0] != '\0'; idx++) { - if (strstr(factory_name, player->ini.videocodec_element_sw[idx])) { - LOGW("skipping sw vcodec:[%s] by codec type", factory_name); - ret = GST_AUTOPLUG_SELECT_SKIP; - goto DONE; - } - } - } else if (codec_type == MM_PLAYER_CODEC_TYPE_SW) { - /* hw codec is skipped */ - if (g_strrstr(factory_name, player->ini.videocodec_element_hw)) { - LOGW("skipping hw vcodec:[%s] by codec type", factory_name); - ret = GST_AUTOPLUG_SELECT_SKIP; - goto DONE; - } - } - if ((strlen(player->ini.videocodec_element_hw) > 0) && (g_strrstr(factory_name, player->ini.videocodec_element_hw))) { @@ -7046,6 +7024,120 @@ DONE: return ret; } +GValueArray * +_mmplayer_gst_decode_autoplug_sort(GstElement *bin, + GstPad *pad, GstCaps *caps, GValueArray *factories, gpointer data) +{ +#define DEFAULT_IDX 0xFFFF +#define MIN_FACTORY_NUM 2 + mmplayer_t *player = (mmplayer_t *)data; + GValueArray *new_factories = NULL; + GValue val = { 0, }; + GstElementFactory *factory = NULL; + const gchar *klass = NULL; + gchar *factory_name = NULL; + guint hw_dec_idx = DEFAULT_IDX; + guint first_sw_dec_idx = DEFAULT_IDX; + guint last_sw_dec_idx = DEFAULT_IDX; + guint new_pos = DEFAULT_IDX; + guint rm_pos = DEFAULT_IDX; + int audio_codec_type; + int video_codec_type; + mmplayer_codec_type_e codec_type = MM_PLAYER_CODEC_TYPE_DEFAULT; + + if (factories->n_values < MIN_FACTORY_NUM) + return NULL; + + mm_attrs_get_int_by_name(player->attrs, MM_PLAYER_VIDEO_CODEC_TYPE, &video_codec_type); + mm_attrs_get_int_by_name(player->attrs, MM_PLAYER_AUDIO_CODEC_TYPE, &audio_codec_type); + +#ifdef __DEBUG__ + LOGD("num of factory : %d, codec type %d, %d", factories->n_values, video_codec_type, audio_codec_type); +#endif + for (int i = 0 ; i < factories->n_values ; i++) { + gchar *hw_dec_info = NULL; + gchar (*sw_dec_info)[PLAYER_INI_MAX_STRLEN] = {NULL, }; + + factory = g_value_get_object(g_value_array_get_nth(factories, i)); + klass = gst_element_factory_get_klass(factory); + factory_name = GST_OBJECT_NAME(factory); + +#ifdef __DEBUG__ + LOGD("Klass [%s] Factory [%s]", klass, factory_name); +#endif + if (g_strrstr(klass, "Codec/Decoder/Audio")) { + if (!player->need_audio_dec_sorting) { + LOGD("sorting is not required"); + return NULL; + } + codec_type = audio_codec_type; + hw_dec_info = player->ini.audiocodec_element_hw; + sw_dec_info = player->ini.audiocodec_element_sw; + } else if (g_strrstr(klass, "Codec/Decoder/Video")) { + if (!player->need_video_dec_sorting) { + LOGD("sorting is not required"); + return NULL; + } + codec_type = video_codec_type; + hw_dec_info = player->ini.videocodec_element_hw; + sw_dec_info = player->ini.videocodec_element_sw; + } else { + continue; + } + + if (g_strrstr(factory_name, hw_dec_info)) { + hw_dec_idx = i; + } else { + for (int j = 0; sw_dec_info[j][0] != '\0'; j++) { + if (strstr(factory_name, sw_dec_info[j])) { + last_sw_dec_idx = i; + if (first_sw_dec_idx == DEFAULT_IDX) { + first_sw_dec_idx = i; + } + } + } + + if (first_sw_dec_idx == DEFAULT_IDX) + LOGW("unknown codec %s", factory_name); + } + } + + if (hw_dec_idx == DEFAULT_IDX || first_sw_dec_idx == DEFAULT_IDX) + return NULL; + + if (codec_type == MM_PLAYER_CODEC_TYPE_HW) { + if (hw_dec_idx < first_sw_dec_idx) + return NULL; + new_pos = first_sw_dec_idx - 1; + rm_pos = hw_dec_idx + 1; + } else if (codec_type == MM_PLAYER_CODEC_TYPE_SW) { + if (last_sw_dec_idx < hw_dec_idx) + return NULL; + new_pos = last_sw_dec_idx + 1; + rm_pos = hw_dec_idx; + } else { + return NULL; + } + + /* change position - insert H/W decoder according to the new position */ + new_factories = g_value_array_copy(factories); + factory = g_value_get_object(g_value_array_get_nth(factories, hw_dec_idx)); + g_value_init (&val, G_TYPE_OBJECT); + g_value_set_object (&val, factory); + g_value_array_insert(new_factories, new_pos, &val); + g_value_unset (&val); + g_value_array_remove(new_factories, rm_pos); /* remove previous H/W element */ + + for (int i = 0 ; i < new_factories->n_values ; i++) { + factory = g_value_get_object(g_value_array_get_nth(new_factories, i)); + + LOGD("[Re-arranged] Klass [%s] Factory [%s]", + gst_element_factory_get_klass(factory), GST_OBJECT_NAME (factory)); + } + + return new_factories; +} + gint _mmplayer_gst_decode_autoplug_select(GstElement *bin, GstPad *pad, GstCaps *caps, GstElementFactory *factory, gpointer data) |