summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEunhye Choi <eunhae1.choi@samsung.com>2019-03-12 18:21:44 +0900
committerEunhye Choi <eunhae1.choi@samsung.com>2019-03-12 19:59:09 +0900
commitb9efa1481fd9a41b45832138bee5fa09fc4ef34f (patch)
tree97cc0e2ef65d1f0de4c8934d293a6c6c956430c1
parent2480a2d4f950d190f3cbf799a441cb1094def53c (diff)
downloadlibmm-player-submit/tizen/20190313.054921.tar.gz
libmm-player-submit/tizen/20190313.054921.tar.bz2
libmm-player-submit/tizen/20190313.054921.zip
Change-Id: Ia0323fe14818a050b6e08fb602c6ffc612f709ce
-rw-r--r--packaging/libmm-player.spec2
-rw-r--r--src/include/mm_player.h4
-rw-r--r--src/include/mm_player_ini.h2
-rw-r--r--src/include/mm_player_priv.h4
-rw-r--r--src/mm_player_attrs.c9
-rw-r--r--src/mm_player_ini.c5
-rw-r--r--src/mm_player_priv.c112
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;
}
}