diff options
author | Eunhye Choi <eunhae1.choi@samsung.com> | 2019-03-12 18:21:44 +0900 |
---|---|---|
committer | Eunhye Choi <eunhae1.choi@samsung.com> | 2019-03-12 19:59:09 +0900 |
commit | b9efa1481fd9a41b45832138bee5fa09fc4ef34f (patch) | |
tree | 97cc0e2ef65d1f0de4c8934d293a6c6c956430c1 | |
parent | 2480a2d4f950d190f3cbf799a441cb1094def53c (diff) | |
download | libmm-player-submit/tizen/20190313.054921.tar.gz libmm-player-submit/tizen/20190313.054921.tar.bz2 libmm-player-submit/tizen/20190313.054921.zip |
[0.6.172] add audio offload pathsubmit/tizen/20190313.054921accepted/tizen/unified/20190313.151523
Change-Id: Ia0323fe14818a050b6e08fb602c6ffc612f709ce
-rw-r--r-- | packaging/libmm-player.spec | 2 | ||||
-rw-r--r-- | src/include/mm_player.h | 4 | ||||
-rw-r--r-- | src/include/mm_player_ini.h | 2 | ||||
-rw-r--r-- | src/include/mm_player_priv.h | 4 | ||||
-rw-r--r-- | src/mm_player_attrs.c | 9 | ||||
-rw-r--r-- | src/mm_player_ini.c | 5 | ||||
-rw-r--r-- | src/mm_player_priv.c | 112 |
7 files changed, 110 insertions, 28 deletions
diff --git a/packaging/libmm-player.spec b/packaging/libmm-player.spec index f81460e..e80c2cc 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.171 +Version: 0.6.172 Release: 0 Group: Multimedia/Libraries License: Apache-2.0 diff --git a/src/include/mm_player.h b/src/include/mm_player.h index 2e0b8a6..e16c579 100644 --- a/src/include/mm_player.h +++ b/src/include/mm_player.h @@ -254,6 +254,10 @@ * rebuffer ms (int) */ #define MM_PLAYER_REBUFFER_MS "rebuffer_ms" +/** + * MM_PLAYER_AUDIO_OFFLOAD (int) + */ +#define MM_PLAYER_AUDIO_OFFLOAD "audio_offload" #define BUFFER_MAX_PLANE_NUM (4) diff --git a/src/include/mm_player_ini.h b/src/include/mm_player_ini.h index 3123828..1c682a7 100644 --- a/src/include/mm_player_ini.h +++ b/src/include/mm_player_ini.h @@ -70,6 +70,7 @@ typedef struct __mm_player_ini { gchar audiocodec_element_sw[PLAYER_INI_MAX_ELEMENT][PLAYER_INI_MAX_STRLEN]; gchar audioresampler_element[PLAYER_INI_MAX_STRLEN]; gchar audiosink_element[PLAYER_INI_MAX_STRLEN]; + gchar audio_offload_sink_element[PLAYER_INI_MAX_STRLEN]; gboolean skip_rescan; gboolean generate_dot; gboolean use_system_clock; @@ -159,6 +160,7 @@ typedef struct __mm_player_ini { #define DEFAULT_PCM_BUFFER_SIZE 51200 /* bytes */ #define DEFAULT_NUM_OF_VIDEO_BO 10 #define DEFAULT_TIMEOUT_OF_VIDEO_BO 10 /* sec */ +#define DEFAULT_AUDIO_OFFLOAD_SINK "" /* http streaming */ #define DEFAULT_HTTPSRC "souphttpsrc" diff --git a/src/include/mm_player_priv.h b/src/include/mm_player_priv.h index c0b05ee..35d8f4c 100644 --- a/src/include/mm_player_priv.h +++ b/src/include/mm_player_priv.h @@ -395,7 +395,6 @@ typedef struct { typedef struct { int uri_type; - int play_mode; MMPlayerInputBuffer input_mem; char uri[MM_MAX_URL_LEN]; char urgent[MM_MAX_FILENAME_LEN]; @@ -795,6 +794,9 @@ typedef struct { /* Video ROI area scale value */ MMPlayerVideoROI video_roi; + + /* build audio offload */ + gboolean build_audio_offload; } mm_player_t; typedef struct { diff --git a/src/mm_player_attrs.c b/src/mm_player_attrs.c index 42dfd2b..e8a1fea 100644 --- a/src/mm_player_attrs.c +++ b/src/mm_player_attrs.c @@ -736,6 +736,15 @@ _mmplayer_construct_attribute(MMHandleType handle) MIN_BUFFERING_TIME, MMPLAYER_MAX_INT }, + { + "audio_offload", /* MM_PLAYER_AUDIO_OFFLOAD */ + MM_ATTRS_TYPE_INT, + MM_ATTRS_FLAG_RW, + (void *)FALSE, + MM_ATTRS_VALID_TYPE_INT_RANGE, + FALSE, + TRUE + }, }; num_of_attrs = ARRAY_SIZE(player_attrs); diff --git a/src/mm_player_ini.c b/src/mm_player_ini.c index 89d9389..d8f022a 100644 --- a/src/mm_player_ini.c +++ b/src/mm_player_ini.c @@ -156,6 +156,7 @@ mm_player_ini_load(mm_player_ini_t *ini) MMPLAYER_INI_GET_STRING(dict, ini->audioresampler_element, "general:audio resampler element", DEFAULT_AUDIORESAMPLER); MMPLAYER_INI_GET_STRING(dict, ini->audiocodec_element_hw, "general:audio codec element hw", DEFAULT_CODEC_HW); MMPLAYER_INI_GET_STRING(dict, ini->audiosink_element, "general:audiosink element", DEFAULT_AUDIOSINK); + MMPLAYER_INI_GET_STRING(dict, ini->audio_offload_sink_element, "general:audio offload sink element", DEFAULT_AUDIO_OFFLOAD_SINK); MMPLAYER_INI_GET_STRING(dict, ini->videosink_element_overlay, "general:videosink element overlay", DEFAULT_VIDEOSINK_OVERLAY); MMPLAYER_INI_GET_STRING(dict, ini->videosink_element_fake, "general:videosink element fake", DEFAULT_VIDEOSINK_FAKE); @@ -213,6 +214,7 @@ mm_player_ini_load(mm_player_ini_t *ini) strncpy(ini->audioresampler_element, DEFAULT_AUDIORESAMPLER, PLAYER_INI_MAX_STRLEN - 1); strncpy(ini->audiosink_element, DEFAULT_AUDIOSINK, PLAYER_INI_MAX_STRLEN - 1); + strncpy(ini->audio_offload_sink_element, DEFAULT_AUDIO_OFFLOAD_SINK, PLAYER_INI_MAX_STRLEN - 1); strncpy(ini->audiocodec_element_hw, DEFAULT_CODEC_HW, PLAYER_INI_MAX_STRLEN - 1); strncpy(ini->videocodec_element_hw, DEFAULT_CODEC_HW, PLAYER_INI_MAX_STRLEN - 1); strncpy(ini->videoconverter_element, DEFAULT_VIDEO_CONVERTER, PLAYER_INI_MAX_STRLEN - 1); @@ -258,6 +260,7 @@ mm_player_ini_load(mm_player_ini_t *ini) LOGD("audio codec element(sw%d) %s", idx, ini->audiocodec_element_sw[idx]); LOGD("audio resampler element : %s", ini->audioresampler_element); LOGD("audiosink element : %s", ini->audiosink_element); + LOGD("audio offload sink element : %s", ini->audio_offload_sink_element); LOGD("generate dot : %d", ini->generate_dot); LOGD("use system clock(video only) : %d", ini->use_system_clock); LOGD("live state change timeout(sec) : %d", ini->live_state_change_timeout); @@ -461,7 +464,7 @@ __get_element_list(mm_player_ini_t *ini, gchar *str, int keyword_type) if (!list) { MMPLAYER_FREEIF(strtmp); - return; + return; } /* copy list */ diff --git a/src/mm_player_priv.c b/src/mm_player_priv.c index 21cf032..72b4c9c 100644 --- a/src/mm_player_priv.c +++ b/src/mm_player_priv.c @@ -110,6 +110,13 @@ /*--------------------------------------------------------------------------- | LOCAL DATA TYPE DEFINITIONS: | ---------------------------------------------------------------------------*/ +/* NOTE : GstAutoplugSelectResult is defined in gstplay-enum.h but not exposed + We are defining our own and will be removed when it actually exposed */ +typedef enum { + GST_AUTOPLUG_SELECT_TRY, + GST_AUTOPLUG_SELECT_EXPOSE, + GST_AUTOPLUG_SELECT_SKIP +} GstAutoplugSelectResult; /*--------------------------------------------------------------------------- | GLOBAL VARIABLE DEFINITIONS: | @@ -1120,14 +1127,16 @@ __mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data) gint samplerate = 0; gint channels = 0; - gst_structure_get_int(str, "rate", &samplerate); - gst_structure_get_int(str, "channels", &channels); - - if (MMPLAYER_IS_MS_BUFF_SRC(player)) { + if (MMPLAYER_IS_MS_BUFF_SRC(player) || player->build_audio_offload) { + if (player->build_audio_offload) + player->no_more_pad = TRUE; /* remove state holder */ __mmplayer_gst_create_sinkbin(elem, pad, player); goto DONE; } + gst_structure_get_int(str, "rate", &samplerate); + gst_structure_get_int(str, "channels", &channels); + if ((channels > 0 && samplerate == 0)) { /* exclude audio decoding */ __mmplayer_gst_make_fakesink(player, pad, name); goto DONE; @@ -1272,7 +1281,7 @@ __mmplayer_create_audio_sink_path(mm_player_t *player, GstElement *audio_selecto MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, FALSE); if (!audio_selector) { - LOGD("there is no audio track"); + LOGD("there is no audio track, num_dynamic_pad %d", player->num_dynamic_pad); /* in case the source is changed, output can be changed. */ if ((player->pipeline->audiobin) && (player->pipeline->audiobin[MMPLAYER_A_BIN].gst)) { @@ -1389,6 +1398,12 @@ __mmplayer_gst_decode_no_more_pads(GstElement *elem, gpointer data) audio_selector = player->pipeline->mainbin[MMPLAYER_M_A_INPUT_SELECTOR].gst; text_selector = player->pipeline->mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst; + if (!video_selector && !audio_selector && !text_selector) { + LOGW("there is no selector"); + player->no_more_pad = TRUE; + goto EXIT; + } + /* create video path followed by video-select */ if (video_selector && !audio_selector && !text_selector) player->no_more_pad = TRUE; @@ -2569,6 +2584,14 @@ __mmplayer_gst_fill_audio_bucket(mm_player_t *player, GList **bucket) audiobin = player->pipeline->audiobin; attrs = MMPLAYER_GET_ATTRS(player); + if (player->build_audio_offload) { /* skip all the audio filters */ + LOGD("create audio offload sink : %s", player->ini.audio_offload_sink_element); + MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, player->ini.audio_offload_sink_element, "audiosink", TRUE, player); + g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "sync", TRUE, NULL); + __mmplayer_add_sink(player, audiobin[MMPLAYER_A_SINK].gst); + goto DONE; + } + /* converter */ MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CONV, "audioconvert", "audio converter", TRUE, player); @@ -2715,6 +2738,7 @@ __mmplayer_gst_fill_audio_bucket(mm_player_t *player, GList **bucket) __mmplayer_add_sink(player, audiobin[MMPLAYER_A_SINK].gst); } +DONE: *bucket = element_bucket; MMPLAYER_FLEAVE(); @@ -6762,14 +6786,60 @@ __mmplayer_gst_decode_autoplug_continue(GstElement *bin, GstPad *pad, return ret; } -static int +static gboolean +__mmplayer_check_offload_path(mm_player_t *player) +{ + gboolean ret = FALSE; + GstElementFactory *factory = NULL; + + MMPLAYER_FENTER(); + MMPLAYER_RETURN_VAL_IF_FAIL(player && player->attrs, FALSE); + + if (strcmp(player->ini.audio_offload_sink_element, "")) { + /* FIXME : 1. need to consider the current audio output path and + player have to know whether it support offload or not. + 2. could be added new condition about content length */ + LOGD("current stream : %s, sink: %s", player->type, player->ini.audio_offload_sink_element); + if (!__mmplayer_is_only_mp3_type(player->type)) + goto DONE; + + factory = gst_element_factory_find(player->ini.audio_offload_sink_element); + if (!factory) + goto DONE; + + LOGD("can setup the audio offload path"); + gst_object_unref(factory); + ret = TRUE; + } + +DONE: + MMPLAYER_FLEAVE(); + return ret; +} + +static GstAutoplugSelectResult __mmplayer_check_codec_info(mm_player_t *player, const char *klass, GstCaps *caps, char *factory_name) { - int ret = MM_ERROR_NONE; + 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"))) { + mm_attrs_get_int_by_name(player->attrs, "audio_offload", &audio_offload); /* user setting */ + + if (audio_offload && __mmplayer_check_offload_path(player)) { + LOGD("expose audio path to build offload path"); + player->build_audio_offload = TRUE; + /* update codec info */ + player->not_supported_codec &= MISSING_PLUGIN_VIDEO; + player->can_support_codec |= FOUND_PLUGIN_AUDIO; + player->audiodec_linked = 1; + + ret = GST_AUTOPLUG_SELECT_EXPOSE; + goto DONE; + } + mm_attrs_get_int_by_name(player->attrs, "audio_codec_type", &codec_type); LOGD("audio codec type: %d", codec_type); @@ -6778,7 +6848,7 @@ __mmplayer_check_codec_info(mm_player_t *player, const char *klass, GstCaps *cap 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 = MM_ERROR_PLAYER_INTERNAL; + ret = GST_AUTOPLUG_SELECT_SKIP; goto DONE; } } @@ -6787,7 +6857,7 @@ __mmplayer_check_codec_info(mm_player_t *player, const char *klass, GstCaps *cap 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 = MM_ERROR_PLAYER_INTERNAL; + ret = GST_AUTOPLUG_SELECT_SKIP; goto DONE; } } @@ -6811,7 +6881,7 @@ __mmplayer_check_codec_info(mm_player_t *player, const char *klass, GstCaps *cap 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 = MM_ERROR_PLAYER_INTERNAL; + ret = GST_AUTOPLUG_SELECT_SKIP; goto DONE; } } @@ -6819,7 +6889,7 @@ __mmplayer_check_codec_info(mm_player_t *player, const char *klass, GstCaps *cap /* 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 = MM_ERROR_PLAYER_INTERNAL; + ret = GST_AUTOPLUG_SELECT_SKIP; goto DONE; } } @@ -6835,12 +6905,12 @@ __mmplayer_check_codec_info(mm_player_t *player, const char *klass, GstCaps *cap &player->video_decoder_resource) != MM_RESOURCE_MANAGER_ERROR_NONE) { LOGE("could not mark video_decoder resource for acquire"); - ret = MM_ERROR_PLAYER_INTERNAL; + ret = GST_AUTOPLUG_SELECT_SKIP; goto DONE; } } else { LOGW("video decoder resource is already acquired, skip it."); - ret = MM_ERROR_PLAYER_INTERNAL; + ret = GST_AUTOPLUG_SELECT_SKIP; goto DONE; } @@ -6849,7 +6919,7 @@ __mmplayer_check_codec_info(mm_player_t *player, const char *klass, GstCaps *cap if (mm_resource_manager_commit(player->resource_manager) != MM_RESOURCE_MANAGER_ERROR_NONE) { LOGE("could not acquire resources for video decoding"); - ret = MM_ERROR_PLAYER_INTERNAL; + ret = GST_AUTOPLUG_SELECT_SKIP; goto DONE; } } @@ -6868,14 +6938,6 @@ gint __mmplayer_gst_decode_autoplug_select(GstElement *bin, GstPad *pad, GstCaps *caps, GstElementFactory *factory, gpointer data) { - /* NOTE : GstAutoplugSelectResult is defined in gstplay-enum.h but not exposed - We are defining our own and will be removed when it actually exposed */ - typedef enum { - GST_AUTOPLUG_SELECT_TRY, - GST_AUTOPLUG_SELECT_EXPOSE, - GST_AUTOPLUG_SELECT_SKIP - } GstAutoplugSelectResult; - GstAutoplugSelectResult result = GST_AUTOPLUG_SELECT_TRY; mm_player_t *player = (mm_player_t *)data; @@ -6989,9 +7051,9 @@ __mmplayer_gst_decode_autoplug_select(GstElement *bin, GstPad *pad, } if (g_strrstr(klass, "Codec/Decoder")) { - if (__mmplayer_check_codec_info(player, klass, caps, factory_name) != MM_ERROR_NONE) { - LOGD("skipping %s codec", factory_name); - result = GST_AUTOPLUG_SELECT_SKIP; + result = __mmplayer_check_codec_info(player, klass, caps, factory_name); + if (result != GST_AUTOPLUG_SELECT_TRY) { + LOGW("skip add decoder"); goto DONE; } } |