static int __mmplayer_gst_unrealize(mm_player_t* player);
static int __mmplayer_gst_adjust_subtitle_position(mm_player_t* player, int format, int position);
static int __mmplayer_gst_set_message_callback(mm_player_t* player, MMMessageCallback callback, gpointer user_param);
+static void __mmplayer_gst_build_deinterleave_path(GstElement *elem, GstPad *pad, gpointer data);
/* util */
static int __mmplayer_realize_streaming_ext(mm_player_t* player);
MMPLAYER_RETURN_IF_FAIL(elem && pad);
MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->mainbin);
+ LOGD("pad-added signal handling");
+
/* get mimetype from caps */
MMPLAYER_GST_GET_CAPS_INFO(pad, caps, str, name, caps_ret);
if (!caps_ret)
return;
}
-static void __mmplayer_handle_text_decode_path(mm_player_t* player, GstElement* text_selector)
+static gboolean __mmplayer_create_decode_path(mm_player_t* player, GstElement* selector, MMPlayerTrackType type)
{
GstPad* srcpad = NULL;
- MMHandleType attrs = 0;
- gint active_index = 0;
- // [link] input-selector :: textbin
- srcpad = gst_element_get_static_pad(text_selector, "src");
+ MMPLAYER_FENTER();
+ MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, FALSE);
+
+ LOGD("type %d", type);
+
+ if (!selector) {
+ LOGD("there is no %d track", type);
+ return TRUE;
+ }
+
+ srcpad = gst_element_get_static_pad(selector, "src");
if (!srcpad) {
- LOGE("failed to get srcpad from selector\n");
- return;
+ LOGE("failed to get srcpad from selector");
+ return FALSE;
}
- LOGD("got pad %s:%s from text selector\n", GST_DEBUG_PAD_NAME(srcpad));
+ LOGD("got pad %s:%s from selector", GST_DEBUG_PAD_NAME(srcpad));
- active_index = player->selector[MM_PLAYER_TRACK_TYPE_TEXT].active_pad_index;
- if ((active_index != DEFAULT_TRACK) &&
- (__mmplayer_change_selector_pad(player, MM_PLAYER_TRACK_TYPE_TEXT, active_index) != MM_ERROR_NONE)) {
- LOGW("failed to change text track\n");
- player->selector[MM_PLAYER_TRACK_TYPE_TEXT].active_pad_index = DEFAULT_TRACK;
+ __mmplayer_gst_decode_callback(selector, srcpad, player);
+
+ LOGD("unblocking %s:%s", GST_DEBUG_PAD_NAME(srcpad));
+ if (player->selector[type].block_id) {
+ gst_pad_remove_probe(srcpad, player->selector[type].block_id);
+ player->selector[type].block_id = 0;
}
- player->no_more_pad = TRUE;
- __mmplayer_gst_decode_callback(text_selector, srcpad, player);
+ if (srcpad) {
+ gst_object_unref(GST_OBJECT(srcpad));
+ srcpad = NULL;
+ }
- LOGD("unblocking %s:%s", GST_DEBUG_PAD_NAME(srcpad));
- if (player->selector[MM_PLAYER_TRACK_TYPE_TEXT].block_id) {
- gst_pad_remove_probe(srcpad, player->selector[MM_PLAYER_TRACK_TYPE_TEXT].block_id);
- player->selector[MM_PLAYER_TRACK_TYPE_TEXT].block_id = 0;
+ MMPLAYER_FLEAVE();
+ return TRUE;
+}
+
+static void __mmplayer_set_decode_track_info(mm_player_t* player, MMPlayerTrackType type)
+{
+ MMHandleType attrs = 0;
+ gint active_index = 0;
+ gchar *attr_name = NULL;
+
+ MMPLAYER_FENTER();
+ MMPLAYER_RETURN_IF_FAIL(player);
+
+ LOGD("type %d", type);
+
+ /* change track to active pad */
+ active_index = player->selector[type].active_pad_index;
+ if ((active_index != DEFAULT_TRACK) &&
+ (__mmplayer_change_selector_pad(player, type, active_index) != MM_ERROR_NONE)) {
+ LOGW("failed to change %d type track to %d", type, active_index);
+ player->selector[type].active_pad_index = DEFAULT_TRACK;
}
- LOGD("Total text tracks = %d \n", player->selector[MM_PLAYER_TRACK_TYPE_TEXT].total_track_num);
+ LOGD("Total num of tracks = %d", player->selector[type].total_track_num);
- if (player->selector[MM_PLAYER_TRACK_TYPE_TEXT].total_track_num > 0)
- player->has_closed_caption = TRUE;
+ if (type == MM_PLAYER_TRACK_TYPE_AUDIO) {
+ attr_name = "content_audio_track_num";
+ } else if (type == MM_PLAYER_TRACK_TYPE_TEXT) {
+ attr_name = "content_text_track_num";
+ } else {
+ LOGE("invalid type info %d", type);
+ return;
+ }
attrs = MMPLAYER_GET_ATTRS(player);
if (attrs) {
- mm_attrs_set_int_by_name(attrs, "content_text_track_num", (gint)player->selector[MM_PLAYER_TRACK_TYPE_TEXT].total_track_num);
+ mm_attrs_set_int_by_name(attrs, attr_name, (gint)player->selector[type].total_track_num);
if (mmf_attrs_commit(attrs))
- LOGE("failed to commit.\n");
- } else
- LOGE("cannot get content attribute");
+ LOGW("failed to commit attrs.");
+ } else {
+ LOGW("cannot get content attribute");
+ }
+
+ MMPLAYER_FLEAVE();
+ return;
+}
+
+static gboolean __mmplayer_create_audio_decode_path(mm_player_t* player, GstElement* audio_selector)
+{
+ GstPad* srcpad = NULL;
+
+ MMPLAYER_FENTER();
+ MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, FALSE);
+
+ if (!audio_selector) {
+ LOGD("there is no audio track");
+
+ /* in case the source is changed, output can be changed. */
+ if ((player->pipeline->audiobin) && (player->pipeline->audiobin[MMPLAYER_A_BIN].gst)) {
+ LOGD("remove previous audiobin if it exist");
+
+ __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_AUDIOBIN);
+ __mmplayer_del_sink(player, player->pipeline->audiobin[MMPLAYER_A_SINK].gst);
+
+ MMPLAYER_RELEASE_ELEMENT(player, player->pipeline->audiobin, MMPLAYER_A_BIN);
+ MMPLAYER_FREEIF(player->pipeline->audiobin);
+ }
+
+ if (player->num_dynamic_pad == 0) /* FIXME: num_dynamic_pad is only for rtsp? */
+ __mmplayer_pipeline_complete(NULL, player);
+
+ return TRUE;
+ }
+
+ /* apply the audio track information */
+ __mmplayer_set_decode_track_info(player, MM_PLAYER_TRACK_TYPE_AUDIO);
+
+ /* create audio decode path */
+ if ((player->use_deinterleave) && (player->max_audio_channels >= 2)) {
+ srcpad = gst_element_get_static_pad(audio_selector, "src");
+ if (!srcpad) {
+ LOGE("failed to get srcpad from selector");
+ return FALSE;
+ }
+
+ LOGD("unblocking %s:%s", GST_DEBUG_PAD_NAME(srcpad));
+ if (player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].block_id) {
+ gst_pad_remove_probe(srcpad, player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].block_id);
+ player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].block_id = 0;
+ }
+
+ __mmplayer_gst_build_deinterleave_path(audio_selector, srcpad, player);
- if (srcpad) {
gst_object_unref(GST_OBJECT(srcpad));
- srcpad = NULL;
+
+ } else {
+ if (!__mmplayer_create_decode_path(player, audio_selector, MM_PLAYER_TRACK_TYPE_AUDIO)) {
+ LOGE("failed to create audio decode path");
+ return FALSE;
+ }
+ }
+
+ MMPLAYER_FLEAVE();
+ return TRUE;
+}
+
+static gboolean __mmplayer_create_text_decode_path(mm_player_t* player, GstElement* text_selector)
+{
+ MMPLAYER_FENTER();
+ MMPLAYER_RETURN_VAL_IF_FAIL(player && text_selector, FALSE);
+
+ if (MMPLAYER_IS_MS_BUFF_SRC(player)) {
+ LOGD("text path is not supproted");
+ return TRUE;
}
+
+ /* apply the text track information */
+ __mmplayer_set_decode_track_info(player, MM_PLAYER_TRACK_TYPE_TEXT);
+
+ if (player->selector[MM_PLAYER_TRACK_TYPE_TEXT].total_track_num > 0)
+ player->has_closed_caption = TRUE;
+
+ /* create text decode path */
+ player->no_more_pad = TRUE;
+
+ if (!__mmplayer_create_decode_path(player, text_selector, MM_PLAYER_TRACK_TYPE_TEXT)) {
+ LOGE("failed to create text decode path");
+ return FALSE;
+ }
+
+ MMPLAYER_FLEAVE();
+ return TRUE;
}
static void
return;
}
+static gboolean
+__mmplayer_gst_set_queue2_buffering(mm_player_t *player)
+{
+#define ESTIMATED_BUFFER_UNIT (1*1024*1024)
+
+ gint init_buffering_time = 0;
+ guint buffer_bytes = 0;
+ gint64 dur_bytes = 0L;
+
+ MMPLAYER_FENTER();
+ MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline &&
+ player->pipeline->mainbin && player->streamer, FALSE);
+
+ init_buffering_time = player->streamer->buffering_req.prebuffer_time;
+ buffer_bytes = (guint)(init_buffering_time/1000) * ESTIMATED_BUFFER_UNIT;
+
+ buffer_bytes = MAX(buffer_bytes, player->streamer->buffer_handle[BUFFER_TYPE_MUXED].buffering_bytes);
+ LOGD("pre buffer time: %d ms, buffer size : %d", init_buffering_time, buffer_bytes);
+
+ init_buffering_time = (init_buffering_time != 0) ? (init_buffering_time) : (player->ini.http_buffering_time);
+
+ if (!gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, GST_FORMAT_BYTES, &dur_bytes))
+ LOGE("fail to get duration.");
+
+ /* there is no mq, enable use-buffering on queue2 (ex) wav streaming
+ * use file information was already set on Q2 when it was created. */
+ __mm_player_streaming_set_queue2(player->streamer,
+ player->pipeline->mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst,
+ TRUE, /* use_buffering */
+ buffer_bytes,
+ init_buffering_time,
+ 1.0, /* low percent */
+ player->ini.http_buffering_limit, /* high percent */
+ MUXED_BUFFER_TYPE_MAX, /* use previous buffer type setting */
+ NULL,
+ ((dur_bytes > 0) ? ((guint64)dur_bytes) : 0));
+
+ MMPLAYER_FLEAVE();
+ return TRUE;
+}
+
static void
__mmplayer_gst_decode_no_more_pads(GstElement *elem, gpointer data)
{
- mm_player_t* player = NULL;
- GstPad* srcpad = NULL;
- GstElement* video_selector = NULL;
- GstElement* audio_selector = NULL;
- GstElement* text_selector = NULL;
- MMHandleType attrs = 0;
- gint active_index = 0;
- gint64 dur_bytes = 0L;
+ mm_player_t *player = NULL;
+ GstElement *video_selector = NULL;
+ GstElement *audio_selector = NULL;
+ GstElement *text_selector = NULL;
+ MMPLAYER_FENTER();
player = (mm_player_t*) data;
- LOGD("no-more-pad signal handling\n");
+ LOGD("no-more-pad signal handling");
if ((player->cmd == MMPLAYER_COMMAND_DESTROY) ||
(player->cmd == MMPLAYER_COMMAND_UNREALIZE)) {
- LOGW("no need to go more");
-
- if (player->gapless.reconfigure) {
- player->gapless.reconfigure = FALSE;
- MMPLAYER_PLAYBACK_UNLOCK(player);
- }
-
- return;
+ LOGW("player is shutting down");
+ goto EXIT;
}
if ((!MMPLAYER_IS_HTTP_PD(player)) &&
(MMPLAYER_IS_HTTP_STREAMING(player)) &&
(!player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst) &&
(player->pipeline->mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst)) {
- #define ESTIMATED_BUFFER_UNIT (1*1024*1024)
-
- if (NULL == player->streamer) {
- LOGW("invalid state for buffering");
- goto ERROR;
+ if (!__mmplayer_gst_set_queue2_buffering(player)) {
+ LOGE("failed to set queue2 buffering");
+ goto EXIT;
}
-
- gint init_buffering_time = player->streamer->buffering_req.prebuffer_time;
- guint buffer_bytes = (guint)(init_buffering_time/1000) * ESTIMATED_BUFFER_UNIT;
-
- buffer_bytes = MAX(buffer_bytes, player->streamer->buffer_handle[BUFFER_TYPE_MUXED].buffering_bytes);
- LOGD("[Decodebin2] set use-buffering on Q2(pre buffer time: %d ms, buffer size : %d)\n", init_buffering_time, buffer_bytes);
-
- init_buffering_time = (init_buffering_time != 0) ? (init_buffering_time) : (player->ini.http_buffering_time);
-
- if (!gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, GST_FORMAT_BYTES, &dur_bytes))
- LOGE("fail to get duration.\n");
-
- /* there is no mq, enable use-buffering on queue2 (ex) wav streaming
- * use file information was already set on Q2 when it was created. */
- __mm_player_streaming_set_queue2(player->streamer,
- player->pipeline->mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst,
- TRUE, /* use_buffering */
- buffer_bytes,
- init_buffering_time,
- 1.0, /* low percent */
- player->ini.http_buffering_limit, /* high percent */
- MUXED_BUFFER_TYPE_MAX, /* use previous buffer type setting */
- NULL,
- ((dur_bytes > 0) ? ((guint64)dur_bytes) : 0));
}
video_selector = player->pipeline->mainbin[MMPLAYER_M_V_INPUT_SELECTOR].gst;
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) {
- // [link] input-selector :: videobin
- srcpad = gst_element_get_static_pad(video_selector, "src");
- if (!srcpad) {
- LOGE("failed to get srcpad from video selector\n");
- goto ERROR;
- }
-
- LOGD("got pad %s:%s from video selector\n", GST_DEBUG_PAD_NAME(srcpad));
- if (!text_selector && !audio_selector)
- player->no_more_pad = TRUE;
-
- __mmplayer_gst_decode_callback(video_selector, srcpad, player);
-
- LOGD("unblocking %s:%s", GST_DEBUG_PAD_NAME(srcpad));
- if (player->selector[MM_PLAYER_TRACK_TYPE_VIDEO].block_id) {
- gst_pad_remove_probe(srcpad, player->selector[MM_PLAYER_TRACK_TYPE_VIDEO].block_id);
- player->selector[MM_PLAYER_TRACK_TYPE_VIDEO].block_id = 0;
- }
- }
-
- if (audio_selector) {
- active_index = player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].active_pad_index;
- if ((active_index != DEFAULT_TRACK) &&
- (__mmplayer_change_selector_pad(player, MM_PLAYER_TRACK_TYPE_AUDIO, active_index) != MM_ERROR_NONE)) {
- LOGW("failed to change audio track\n");
- player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].active_pad_index = DEFAULT_TRACK;
- }
-
- // [link] input-selector :: audiobin
- srcpad = gst_element_get_static_pad(audio_selector, "src");
- if (!srcpad) {
- LOGE("failed to get srcpad from selector\n");
- goto ERROR;
- }
- LOGD("got pad %s:%s from selector\n", GST_DEBUG_PAD_NAME(srcpad));
- if (!text_selector)
- player->no_more_pad = TRUE;
+ /* create video path followed by video-select */
+ if (video_selector && !audio_selector && !text_selector)
+ player->no_more_pad = TRUE;
- if ((player->use_deinterleave == TRUE) && (player->max_audio_channels >= 2)) {
- LOGD("unblocking %s:%s", GST_DEBUG_PAD_NAME(srcpad));
- if (player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].block_id) {
- gst_pad_remove_probe(srcpad, player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].block_id);
- player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].block_id = 0;
- }
-
- __mmplayer_gst_build_deinterleave_path(audio_selector, srcpad, player);
- } else {
- __mmplayer_gst_decode_callback(audio_selector, srcpad, player);
-
- LOGD("unblocking %s:%s", GST_DEBUG_PAD_NAME(srcpad));
- if (player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].block_id) {
- gst_pad_remove_probe(srcpad, player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].block_id);
- player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].block_id = 0;
- }
- }
-
- LOGD("Total audio tracks = %d \n", player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].total_track_num);
-
- attrs = MMPLAYER_GET_ATTRS(player);
- if (attrs) {
- mm_attrs_set_int_by_name(attrs, "content_audio_track_num", (gint)player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].total_track_num);
- if (mmf_attrs_commit(attrs))
- LOGE("failed to commit.\n");
- } else
- LOGE("cannot get content attribute");
- } else {
- if ((player->pipeline->audiobin) && (player->pipeline->audiobin[MMPLAYER_A_BIN].gst)) {
- LOGD("There is no audio track : remove audiobin");
-
- __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_AUDIOBIN);
- __mmplayer_del_sink(player, player->pipeline->audiobin[MMPLAYER_A_SINK].gst);
+ if (!__mmplayer_create_decode_path(player, video_selector, MM_PLAYER_TRACK_TYPE_VIDEO))
+ goto EXIT;
- MMPLAYER_RELEASE_ELEMENT(player, player->pipeline->audiobin, MMPLAYER_A_BIN);
- MMPLAYER_FREEIF(player->pipeline->audiobin);
- }
+ /* create audio path followed by audio-select */
+ if (audio_selector && !text_selector)
+ player->no_more_pad = TRUE;
- if (player->num_dynamic_pad == 0)
- __mmplayer_pipeline_complete(NULL, player);
- }
-
- if (!MMPLAYER_IS_MS_BUFF_SRC(player)) {
- if (text_selector)
- __mmplayer_handle_text_decode_path(player, text_selector);
- }
+ if (!__mmplayer_create_audio_decode_path(player, audio_selector))
+ goto EXIT;
- MMPLAYER_FLEAVE();
-ERROR:
- if (srcpad) {
- gst_object_unref(GST_OBJECT(srcpad));
- srcpad = NULL;
- }
+ /* create text path followed by text-select */
+ __mmplayer_create_text_decode_path(player, text_selector);
+EXIT:
if (player->gapless.reconfigure) {
player->gapless.reconfigure = FALSE;
MMPLAYER_PLAYBACK_UNLOCK(player);
}
+
+ MMPLAYER_FENTER();
}
static void