---------------------------------------------------------------------------*/
static int __mmplayer_gst_create_pipeline(mm_player_t* player);
static int __mmplayer_gst_destroy_pipeline(mm_player_t* player);
-static int __mmplayer_gst_create_video_pipeline(mm_player_t* player, GstCaps *caps, MMDisplaySurfaceType surface_type);
-static int __mmplayer_gst_create_audio_pipeline(mm_player_t* player);
static int __mmplayer_gst_create_text_pipeline(mm_player_t* player);
+static int __mmplayer_gst_create_video_sink_bin(mm_player_t* player, GstCaps *caps, MMDisplaySurfaceType surface_type);
+static int __mmplayer_gst_create_audio_sink_bin(mm_player_t* player);
static int __mmplayer_gst_create_text_sink_bin(mm_player_t* player);
static GstPadProbeReturn __mmplayer_gst_selector_blocked(GstPad* pad, GstPadProbeInfo *info, gpointer data);
static void __mmplayer_gst_decode_no_more_pads(GstElement* elem, gpointer data);
-static void __mmplayer_gst_decode_callback(GstElement *decodebin, GstPad *pad, gpointer data);
+static void __mmplayer_gst_create_sinkbin(GstElement *decodebin, GstPad *pad, gpointer data);
static void __mmplayer_gst_decode_unknown_type(GstElement *elem, GstPad* pad, GstCaps *caps, gpointer data);
static gboolean __mmplayer_gst_decode_autoplug_continue(GstElement *bin, GstPad* pad, GstCaps * caps, gpointer data);
static void __mmplayer_gst_decode_pad_removed(GstElement *elem, GstPad* new_pad, gpointer data);
LOGD("surface type : %d", stype);
if (MMPLAYER_IS_MS_BUFF_SRC(player)) {
- __mmplayer_gst_decode_callback(elem, pad, player);
+ __mmplayer_gst_create_sinkbin(elem, pad, player);
goto DONE;
}
gst_structure_get_int(str, "channels", &channels);
if (MMPLAYER_IS_MS_BUFF_SRC(player)) {
- __mmplayer_gst_decode_callback(elem, pad, player);
+ __mmplayer_gst_create_sinkbin(elem, pad, player);
goto DONE;
}
return;
}
-static gboolean __mmplayer_create_decode_path(mm_player_t* player, GstElement* selector, MMPlayerTrackType type)
+static gboolean __mmplayer_create_sink_path(mm_player_t* player, GstElement* selector, MMPlayerTrackType type)
{
GstPad* srcpad = NULL;
LOGD("got pad %s:%s from selector", GST_DEBUG_PAD_NAME(srcpad));
- __mmplayer_gst_decode_callback(selector, srcpad, player);
+ __mmplayer_gst_create_sinkbin(selector, srcpad, player);
LOGD("unblocking %s:%s", GST_DEBUG_PAD_NAME(srcpad));
if (player->selector[type].block_id) {
return;
}
-static gboolean __mmplayer_create_audio_decode_path(mm_player_t* player, GstElement* audio_selector)
+static gboolean __mmplayer_create_audio_sink_path(mm_player_t* player, GstElement* audio_selector)
{
MMPLAYER_FENTER();
MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, FALSE);
/* apply the audio track information */
__mmplayer_set_decode_track_info(player, MM_PLAYER_TRACK_TYPE_AUDIO);
- /* create audio decode path */
- if (!__mmplayer_create_decode_path(player, audio_selector, MM_PLAYER_TRACK_TYPE_AUDIO)) {
- LOGE("failed to create audio decode path");
+ /* create audio sink path */
+ if (!__mmplayer_create_sink_path(player, audio_selector, MM_PLAYER_TRACK_TYPE_AUDIO)) {
+ LOGE("failed to create audio sink path");
return FALSE;
}
return TRUE;
}
-static gboolean __mmplayer_create_text_decode_path(mm_player_t* player, GstElement* text_selector)
+static gboolean __mmplayer_create_text_sink_path(mm_player_t* player, GstElement* text_selector)
{
MMPLAYER_FENTER();
MMPLAYER_RETURN_VAL_IF_FAIL(player && text_selector, FALSE);
/* 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");
+ if (!__mmplayer_create_sink_path(player, text_selector, MM_PLAYER_TRACK_TYPE_TEXT)) {
+ LOGE("failed to create text sink path");
return FALSE;
}
if (video_selector && !audio_selector && !text_selector)
player->no_more_pad = TRUE;
- if (!__mmplayer_create_decode_path(player, video_selector, MM_PLAYER_TRACK_TYPE_VIDEO))
+ if (!__mmplayer_create_sink_path(player, video_selector, MM_PLAYER_TRACK_TYPE_VIDEO))
goto EXIT;
/* create audio path followed by audio-select */
if (audio_selector && !text_selector)
player->no_more_pad = TRUE;
- if (!__mmplayer_create_audio_decode_path(player, audio_selector))
+ if (!__mmplayer_create_audio_sink_path(player, audio_selector))
goto EXIT;
/* create text path followed by text-select */
- __mmplayer_create_text_decode_path(player, text_selector);
+ __mmplayer_create_text_sink_path(player, text_selector);
EXIT:
if (player->gapless.reconfigure) {
MMPLAYER_PLAYBACK_UNLOCK(player);
}
- MMPLAYER_FENTER();
+ MMPLAYER_FLEAVE();
}
+static gboolean
+__mmplayer_gst_add_sinkbin_to_pipeline(mm_player_t *player, GstElement *sinkbin, GstPad *pad, gboolean reusing, gchar *sink_pad_name)
+{
+ gboolean ret = FALSE;
+ GstElement *pipeline = NULL;
+ GstPad *sinkpad = NULL;
+
+ MMPLAYER_FENTER();
+ MMPLAYER_RETURN_VAL_IF_FAIL(sinkbin && pad, FALSE);
+ MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->mainbin, FALSE);
+
+ pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
+
+ sinkpad = gst_element_get_static_pad(GST_ELEMENT(sinkbin), sink_pad_name);
+ if (!sinkpad) {
+ LOGE("failed to get pad from sinkbin");
+ goto EXIT;
+ }
+
+ if (reusing) {
+ /* link only */
+ if (gst_pad_link(pad, sinkpad) != GST_PAD_LINK_OK) {
+ LOGE("failed to link sinkbin for reusing");
+ goto EXIT; /* exit either pass or fail */
+ }
+ } else {
+ /* warm up */
+ if (gst_element_set_state(sinkbin, GST_STATE_READY) == GST_STATE_CHANGE_FAILURE) {
+ LOGE("failed to set state(READY) to sinkbin");
+ goto EXIT;
+ }
+
+ /* add */
+ if (!gst_bin_add(GST_BIN(pipeline), sinkbin)) {
+ LOGE("failed to add sinkbin to pipeline");
+ goto EXIT;
+ }
+
+ /* link */
+ if (gst_pad_link(pad, sinkpad) != GST_PAD_LINK_OK) {
+ LOGE("failed to link %s:%s - %s:%s", GST_DEBUG_PAD_NAME(pad), GST_DEBUG_PAD_NAME(sinkpad));
+ goto EXIT;
+ }
+
+ /* run */
+ if (gst_element_set_state(sinkbin, GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE) {
+ LOGE("failed to set state(PAUSED) to sinkbin");
+ goto EXIT;
+ }
+ }
+
+ ret = TRUE;
+
+EXIT:
+ if (sinkpad)
+ gst_object_unref(GST_OBJECT(sinkpad));
+ sinkpad = NULL;
+
+ MMPLAYER_FLEAVE();
+ return ret;
+}
static void
-__mmplayer_gst_decode_callback(GstElement *elem, GstPad *pad, gpointer data)
+__mmplayer_gst_create_sinkbin(GstElement *elem, GstPad *pad, gpointer data)
{
mm_player_t *player = NULL;
MMHandleType attrs = 0;
- GstElement *pipeline = NULL;
GstCaps *caps = NULL;
gchar *caps_str = NULL;
GstStructure *str = NULL;
const gchar *name = NULL;
- GstPad *sinkpad = NULL;
GstElement *sinkbin = NULL;
gboolean reusing = FALSE;
- GstElement *text_selector = NULL;
gboolean caps_ret = TRUE;
+ gchar *sink_pad_name = "sink";
/* check handles */
player = (mm_player_t*) data;
+ MMPLAYER_FENTER();
MMPLAYER_RETURN_IF_FAIL(elem && pad);
- MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->mainbin);
-
- pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
-
- attrs = MMPLAYER_GET_ATTRS(player);
- if (!attrs) {
- LOGE("cannot get content attribute\n");
- goto ERROR;
- }
+ MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && MMPLAYER_GET_ATTRS(player));
MMPLAYER_GST_GET_CAPS_INFO(pad, caps, str, name, caps_ret);
if (!caps_ret)
/* LOGD("detected mimetype : %s", name); */
if (strstr(name, "audio")) {
if (player->pipeline->audiobin == NULL) {
- if (__mmplayer_gst_create_audio_pipeline(player) != MM_ERROR_NONE) {
- LOGE("failed to create audiobin. continuing without audio\n");
+ if (__mmplayer_gst_create_audio_sink_bin(player) != MM_ERROR_NONE) {
+ LOGE("failed to create audiobin. continuing without audio");
goto ERROR;
}
sinkbin = player->pipeline->audiobin[MMPLAYER_A_BIN].gst;
- LOGD("creating audiosink bin success");
+ LOGD("creating audiobin success");
} else {
reusing = TRUE;
sinkbin = player->pipeline->audiobin[MMPLAYER_A_BIN].gst;
- LOGD("reusing audiobin\n");
+ LOGD("reusing audiobin");
__mmplayer_update_content_attrs(player, ATTR_AUDIO);
}
-
- if (player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].total_track_num <= 0) // should not update if content have multi audio tracks
- mm_attrs_set_int_by_name(attrs, "content_audio_track_num", 1);
-
- player->audiosink_linked = 1;
-
- sinkpad = gst_element_get_static_pad(GST_ELEMENT(sinkbin), "sink");
- if (!sinkpad) {
- LOGE("failed to get pad from sinkbin\n");
- goto ERROR;
- }
} else if (strstr(name, "video")) {
- if (caps_str && (strstr(caps_str, "ST12") || strstr(caps_str, "SN12") ||
- strstr(caps_str, "SN21") || strstr(caps_str, "S420") || strstr(caps_str, "SR32")))
- player->set_mode.video_zc = TRUE;
-
+ /* 1. zero copy is updated at _decode_pad_added()
+ * 2. NULL surface type is handled in _decode_pad_added() */
+ LOGD("zero copy %d", player->set_mode.video_zc);
if (player->pipeline->videobin == NULL) {
- /* NOTE : not make videobin because application dose not want to play it even though file has video stream. */
- /* get video surface type */
int surface_type = 0;
mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &surface_type);
LOGD("display_surface_type (%d)", surface_type);
- if (surface_type == MM_DISPLAY_SURFACE_NULL) {
- LOGD("surface_type is NULL");
- goto ERROR;
- }
-
- if (surface_type == MM_DISPLAY_SURFACE_OVERLAY) {
- /* mark video overlay for acquire */
- if (player->video_overlay_resource == NULL) {
- if (mm_resource_manager_mark_for_acquire(player->resource_manager,
- MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_OVERLAY,
- MM_RESOURCE_MANAGER_RES_VOLUME_FULL,
- &player->video_overlay_resource)
- != MM_RESOURCE_MANAGER_ERROR_NONE) {
- LOGE("could not mark video_overlay resource for acquire\n");
- goto ERROR;
- }
+ if (surface_type == MM_DISPLAY_SURFACE_OVERLAY && player->video_overlay_resource == NULL) {
+ LOGD("mark video overlay for acquire");
+ if (mm_resource_manager_mark_for_acquire(player->resource_manager,
+ MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_OVERLAY,
+ MM_RESOURCE_MANAGER_RES_VOLUME_FULL,
+ &player->video_overlay_resource)
+ != MM_RESOURCE_MANAGER_ERROR_NONE) {
+ LOGE("could not mark video_overlay resource for acquire");
+ goto ERROR;
}
}
player->interrupted_by_resource = FALSE;
- /* acquire resources for video overlay */
+
if (mm_resource_manager_commit(player->resource_manager) !=
MM_RESOURCE_MANAGER_ERROR_NONE) {
- LOGE("could not acquire resources for video playing\n");
+ LOGE("could not acquire resources for video playing");
goto ERROR;
}
- if (MM_ERROR_NONE != __mmplayer_gst_create_video_pipeline(player, caps, surface_type)) {
- LOGE("failed to create videobin. continuing without video\n");
+ if (__mmplayer_gst_create_video_sink_bin(player, caps, surface_type) != MM_ERROR_NONE) {
+ LOGE("failed to create videobin. continuing without video");
goto ERROR;
}
sinkbin = player->pipeline->videobin[MMPLAYER_V_BIN].gst;
- LOGD("creating videosink bin success\n");
+ LOGD("creating videosink bin success");
} else {
reusing = TRUE;
sinkbin = player->pipeline->videobin[MMPLAYER_V_BIN].gst;
- LOGD("re-using videobin\n");
+ LOGD("re-using videobin");
__mmplayer_update_content_attrs(player, ATTR_VIDEO);
}
-
- player->videosink_linked = 1;
-
- sinkpad = gst_element_get_static_pad(GST_ELEMENT(sinkbin), "sink");
- if (!sinkpad) {
- LOGE("failed to get pad from sinkbin\n");
- goto ERROR;
- }
} else if (strstr(name, "text")) {
if (player->pipeline->textbin == NULL) {
- MMPlayerGstElement* mainbin = NULL;
-
- if (MM_ERROR_NONE != __mmplayer_gst_create_text_sink_bin(player)) {
- LOGE("failed to create text sink bin. continuing without text\n");
+ if (__mmplayer_gst_create_text_sink_bin(player) != MM_ERROR_NONE) {
+ LOGE("failed to create text sink bin. continuing without text");
goto ERROR;
}
sinkbin = player->pipeline->textbin[MMPLAYER_T_BIN].gst;
- LOGD("creating textsink bin success\n");
+ LOGD("creating textsink bin success");
- /* FIXIT : track number shouldn't be hardcoded */
mm_attrs_set_int_by_name(attrs, "content_text_track_num", 1);
-
player->textsink_linked = 1;
- LOGI("player->textsink_linked set to 1\n");
-
- sinkpad = gst_element_get_static_pad(GST_ELEMENT(sinkbin), "text_sink");
- if (!sinkpad) {
- LOGE("failed to get pad from sinkbin\n");
- goto ERROR;
- }
-
- mainbin = player->pipeline->mainbin;
-
- if (!mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst) {
- /* input selector */
- text_selector = gst_element_factory_make("input-selector", "subtitle_inselector");
- if (!text_selector) {
- LOGE("failed to create subtitle input selector element\n");
- goto ERROR;
- }
- g_object_set(text_selector, "sync-streams", TRUE, NULL);
- mainbin[MMPLAYER_M_T_INPUT_SELECTOR].id = MMPLAYER_M_T_INPUT_SELECTOR;
- mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst = text_selector;
-
- /* warm up */
- if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(text_selector, GST_STATE_READY)) {
- LOGE("failed to set state(READY) to sinkbin\n");
- goto ERROR;
- }
-
- if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), text_selector)) {
- LOGW("failed to add subtitle input selector\n");
- goto ERROR;
- }
-
- LOGD("created element input-selector");
-
- } else {
- LOGD("already having subtitle input selector");
- text_selector = mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst;
- }
} else {
if (!player->textsink_linked) {
- LOGD("re-using textbin\n");
-
+ LOGD("re-using textbin");
reusing = TRUE;
sinkbin = player->pipeline->textbin[MMPLAYER_T_BIN].gst;
-
player->textsink_linked = 1;
- LOGI("player->textsink_linked set to 1\n");
- } else
- LOGD("ignoring internal subtutle since external subtitle is available");
+ } else {
+ /* linked textbin exist which means that the external subtitle path exist already */
+ LOGW("ignoring internal subtutle since external subtitle is available");
+ }
}
+ sink_pad_name = "text_sink";
} else {
- LOGW("unknown type of elementary stream!ignoring it...\n");
+ LOGW("unknown mime type %s, ignoring it", name);
goto ERROR;
}
- if (sinkbin) {
- if (!reusing) {
- /* warm up */
- if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(sinkbin, GST_STATE_READY)) {
- LOGE("failed to set state(READY) to sinkbin\n");
- goto ERROR;
- }
-
- /* Added for multi audio support to avoid adding audio bin again*/
- /* add */
- if (FALSE == gst_bin_add(GST_BIN(pipeline), sinkbin)) {
- LOGE("failed to add sinkbin to pipeline\n");
- goto ERROR;
- }
- }
-
- /* link */
- if (GST_PAD_LINK_OK != gst_pad_link(pad, sinkpad)) {
- LOGE("failed to get pad from sinkbin\n");
- goto ERROR;
- }
-
- if (!reusing) {
- /* run */
- if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(sinkbin, GST_STATE_PAUSED)) {
- LOGE("failed to set state(PAUSED) to sinkbin\n");
- goto ERROR;
- }
-
- if (text_selector) {
- if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(text_selector, GST_STATE_PAUSED)) {
- LOGE("failed to set state(PAUSED) to sinkbin\n");
- goto ERROR;
- }
- }
- }
-
- gst_object_unref(sinkpad);
- sinkpad = NULL;
- }
+ if (!__mmplayer_gst_add_sinkbin_to_pipeline(player, sinkbin, pad, reusing, sink_pad_name))
+ goto ERROR;
- LOGD("[handle: %p] linking sink bin success", player);
+ LOGD("[handle: %p] success to create and link sink bin", player);
/* FIXIT : we cannot hold callback for 'no-more-pad' signal because signal was emitted in
* streaming task. if the task blocked, then buffer will not flow to the next element
if (player->num_dynamic_pad)
player->num_dynamic_pad--;
- LOGD("no more pads: %d stream count dec : %d(num of dynamic pad)\n", player->no_more_pad, player->num_dynamic_pad);
+ LOGD("no more pads: %d, stream count dec : %d(num of dynamic pad)", player->no_more_pad, player->num_dynamic_pad);
if ((player->no_more_pad) && (player->num_dynamic_pad == 0))
__mmplayer_pipeline_complete(NULL, player);
if (caps)
gst_caps_unref(caps);
- if (sinkpad)
- gst_object_unref(GST_OBJECT(sinkpad));
-
/* flusing out new attributes */
if (mmf_attrs_commit(attrs))
- LOGE("failed to comit attributes\n");
+ LOGE("failed to comit attributes");
return;
}
*
* @return This function returns zero on success.
* @remark
- * @see __mmplayer_gst_create_midi_pipeline, __mmplayer_gst_create_video_pipeline
+ * @see __mmplayer_gst_create_midi_pipeline, __mmplayer_gst_create_video_sink_bin
*/
/* macro for code readability. just for sinkbin-creation functions */
#define MMPLAYER_CREATE_ELEMENT(x_bin, x_id, x_factory, x_name, x_add_bucket, x_player) \
}
static int
-__mmplayer_gst_create_audio_pipeline(mm_player_t* player)
+__mmplayer_gst_create_audio_sink_bin(mm_player_t* player)
{
MMPlayerGstElement *first_element = NULL;
MMPlayerGstElement *audiobin = NULL;
if (strlen(player->ini.videosink_element_overlay) > 0)
factory_name = player->ini.videosink_element_overlay;
break;
- case MM_DISPLAY_SURFACE_NULL:
- if (strlen(player->ini.videosink_element_fake) > 0)
- factory_name = player->ini.videosink_element_fake;
- break;
case MM_DISPLAY_SURFACE_REMOTE:
if (strlen(player->ini.videosink_element_fake) > 0)
factory_name = player->ini.videosink_element_fake;
break;
+ case MM_DISPLAY_SURFACE_NULL:
+ LOGE("null surface type have to be handled in _decode_pad_added()");
+ break;
default:
LOGE("unidentified surface type");
break;
}
/**
- * VIDEO PIPELINE
+ * VIDEO BIN
* - video overlay surface(arm/x86) : tizenwlsink
*/
static int
-__mmplayer_gst_create_video_pipeline(mm_player_t* player, GstCaps* caps, MMDisplaySurfaceType surface_type)
+__mmplayer_gst_create_video_sink_bin(mm_player_t* player, GstCaps* caps, MMDisplaySurfaceType surface_type)
{
GstPad *pad = NULL;
GList *element_bucket = NULL;
player->smooth_streaming = FALSE;
player->videodec_linked = 0;
- player->videosink_linked = 0;
player->audiodec_linked = 0;
- player->audiosink_linked = 0;
player->textsink_linked = 0;
player->is_external_subtitle_present = FALSE;
player->is_external_subtitle_added_now = FALSE;
player->smooth_streaming = FALSE;
player->videodec_linked = 0;
player->audiodec_linked = 0;
- player->videosink_linked = 0;
- player->audiosink_linked = 0;
player->textsink_linked = 0;
player->is_external_subtitle_present = FALSE;
player->is_external_subtitle_added_now = FALSE;
dump_s = NULL;
LOGE("failed to get %s sink pad added", factory_name);
}
-
-
}
}
return FALSE;