summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEunhye Choi <eunhae1.choi@samsung.com>2019-10-02 14:35:47 +0900
committerEunhye Choi <eunhae1.choi@samsung.com>2019-10-02 17:37:46 +0900
commit869197c68f07bb925fd3eed18ead2d296f174846 (patch)
tree153f8ac50f51546692a067d4b713e3fad7cebb7e
parent62487d23412e2b9a248f0bb0c61d813636c3a99a (diff)
downloadlibmm-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.spec2
-rw-r--r--src/include/mm_player_priv.h3
-rw-r--r--src/mm_player_gst.c4
-rw-r--r--src/mm_player_priv.c186
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)