/*---------------------------------------------------------------------------
| LOCAL FUNCTION PROTOTYPES: |
---------------------------------------------------------------------------*/
+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_subtitle_src(mm_player_t* player);
-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_text_sink_bin(mm_player_t* player);
static int __mmplayer_gst_element_link_bucket(GList* element_bucket);
static GstPadProbeReturn __mmplayer_gst_selector_blocked(GstPad* pad, GstPadProbeInfo *info, gpointer data);
if (player->pipeline->textbin == NULL) {
MMPlayerGstElement* mainbin = NULL;
- if (MM_ERROR_NONE != __mmplayer_gst_create_text_pipeline(player)) {
- LOGE("failed to create textbin. continuing without text\n");
+ if (MM_ERROR_NONE != __mmplayer_gst_create_text_sink_bin(player)) {
+ LOGE("failed to create text sink bin. continuing without text\n");
goto ERROR;
}
pad = gst_element_get_static_pad(GST_ELEMENT(textbin[MMPLAYER_T_QUEUE].gst), "sink");
if (!pad) {
- LOGE("failed to get video pad of textbin\n");
- return MM_ERROR_PLAYER_INTERNAL;
+ LOGE("failed to get sink pad of text queue");
+ goto ERROR;
}
ghostpad = gst_ghost_pad_new("text_sink", pad);
if (!gst_element_add_pad(textbin[MMPLAYER_T_BIN].gst, ghostpad)) {
LOGE("failed to add ghostpad to textbin\n");
+ gst_object_unref(ghostpad);
goto ERROR;
}
}
ERROR:
g_list_free(element_bucket);
+ if (!player->play_subtitle && textbin[MMPLAYER_T_FAKE_SINK].gst) {
+ LOGE("remove textbin sink from sink list");
+ __mmplayer_del_sink(player, textbin[MMPLAYER_T_FAKE_SINK].gst);
+ }
+
+ /* release element at __mmplayer_gst_create_text_sink_bin */
return MM_ERROR_PLAYER_INTERNAL;
}
-static int __mmplayer_gst_create_text_pipeline(mm_player_t* player)
+static int __mmplayer_gst_create_text_sink_bin(mm_player_t* player)
{
MMPlayerGstElement *textbin = NULL;
GList *element_bucket = NULL;
g_list_free(element_bucket);
+ /* release signal */
+ __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_TEXTBIN);
+
/* release element which are not added to bin */
for (i = 1; i < MMPLAYER_T_NUM; i++) {
/* NOTE : skip bin */
if (!parent) {
gst_object_unref(GST_OBJECT(textbin[i].gst));
textbin[i].gst = NULL;
- } else
+ } else {
gst_object_unref(GST_OBJECT(parent));
+ }
}
}
if (textbin[MMPLAYER_T_BIN].gst)
gst_object_unref(GST_OBJECT(textbin[MMPLAYER_T_BIN].gst));
- MMPLAYER_FREEIF(textbin);
-
+ MMPLAYER_FREEIF(player->pipeline->textbin);
player->pipeline->textbin = NULL;
return MM_ERROR_PLAYER_INTERNAL;
static int
-__mmplayer_gst_create_subtitle_src(mm_player_t* player)
+__mmplayer_gst_create_text_pipeline(mm_player_t* player)
{
MMPlayerGstElement* mainbin = NULL;
+ MMPlayerGstElement* textbin = NULL;
MMHandleType attrs = 0;
GstElement *subsrc = NULL;
GstElement *subparse = NULL;
MMPLAYER_FENTER();
/* get mainbin */
- MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
+ MMPLAYER_RETURN_VAL_IF_FAIL(player &&
+ player->pipeline &&
+ player->pipeline->mainbin, MM_ERROR_PLAYER_NOT_INITIALIZED);
mainbin = player->pipeline->mainbin;
if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), subsrc)) {
LOGW("failed to add queue\n");
+ gst_object_unref(mainbin[MMPLAYER_M_SUBSRC].gst);
+ mainbin[MMPLAYER_M_SUBSRC].gst = NULL;
+ mainbin[MMPLAYER_M_SUBSRC].id = MMPLAYER_M_NUM;
goto ERROR;
}
if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), subparse)) {
LOGW("failed to add subparse\n");
+ gst_object_unref(mainbin[MMPLAYER_M_SUBPARSE].gst);
+ mainbin[MMPLAYER_M_SUBPARSE].gst = NULL;
+ mainbin[MMPLAYER_M_SUBPARSE].id = MMPLAYER_M_NUM;
goto ERROR;
}
LOGD("play subtitle using subtitle file\n");
if (player->pipeline->textbin == NULL) {
- if (MM_ERROR_NONE != __mmplayer_gst_create_text_pipeline(player)) {
- LOGE("failed to create textbin. continuing without text\n");
+ if (MM_ERROR_NONE != __mmplayer_gst_create_text_sink_bin(player)) {
+ LOGE("failed to create text sink bin. continuing without text\n");
goto ERROR;
}
- if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), GST_ELEMENT(player->pipeline->textbin[MMPLAYER_T_BIN].gst))) {
+ textbin = player->pipeline->textbin;
+
+ if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), GST_ELEMENT(textbin[MMPLAYER_T_BIN].gst))) {
LOGW("failed to add textbin\n");
+
+ /* release signal */
+ __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_TEXTBIN);
+
+ /* release textbin with it's childs */
+ gst_object_unref(GST_OBJECT(textbin[MMPLAYER_T_BIN].gst));
+ MMPLAYER_FREEIF(player->pipeline->textbin);
+ player->pipeline->textbin = textbin = NULL;
goto ERROR;
}
player->external_text_idx = 0;
LOGI("player->textsink_linked set to 1\n");
} else {
+ textbin = player->pipeline->textbin;
LOGD("text bin has been created. reuse it.");
player->external_text_idx = 1;
}
- if (!gst_element_link_pads(subparse, "src", player->pipeline->textbin[MMPLAYER_T_BIN].gst, "text_sink")) {
+ if (!gst_element_link_pads(subparse, "src", textbin[MMPLAYER_T_BIN].gst, "text_sink")) {
LOGW("failed to link subparse and textbin\n");
goto ERROR;
}
- pad = gst_element_get_static_pad(player->pipeline->textbin[MMPLAYER_T_FAKE_SINK].gst, "sink");
-
+ pad = gst_element_get_static_pad(textbin[MMPLAYER_T_FAKE_SINK].gst, "sink");
if (!pad) {
LOGE("failed to get sink pad from textsink to probe data");
- return MM_ERROR_PLAYER_INTERNAL;
+ goto ERROR;
}
gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER,
return MM_ERROR_NONE;
ERROR:
+ /* release text pipeline resource */
player->textsink_linked = 0;
+
+ /* release signal */
+ __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_TEXTBIN);
+
+ if (player->pipeline->textbin) {
+ LOGE("remove textbin");
+
+ /* release textbin with it's childs */
+ MMPLAYER_RELEASE_ELEMENT(player, player->pipeline->textbin, MMPLAYER_T_BIN);
+ MMPLAYER_FREEIF(player->pipeline->textbin);
+ player->pipeline->textbin = NULL;
+
+ }
+
+ /* release subtitle elem */
+ MMPLAYER_RELEASE_ELEMENT(player, player->pipeline->mainbin, MMPLAYER_M_SUBSRC);
+ MMPLAYER_RELEASE_ELEMENT(player, player->pipeline->mainbin, MMPLAYER_M_SUBPARSE);
+
return MM_ERROR_PLAYER_INTERNAL;
}
/* Note : check whether subtitle atrribute uri is set. If uri is set, then try to play subtitle file */
if (__mmplayer_check_subtitle(player)) {
- if (MM_ERROR_NONE != __mmplayer_gst_create_subtitle_src(player))
- LOGE("fail to create subtitle src\n");
+ if (MM_ERROR_NONE != __mmplayer_gst_create_text_pipeline(player))
+ LOGE("fail to create text pipeline");
}
/* set sync handler to get tag synchronously */
MMPLAYER_FENTER();
/* check player handle */
- MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline , MM_ERROR_PLAYER_NOT_INITIALIZED);
-
- if (!(player->pipeline->mainbin) || !(player->pipeline->textbin)) {
- LOGE("Pipeline is not in proper state\n");
- result = MM_ERROR_PLAYER_NOT_INITIALIZED;
- goto EXIT;
- }
+ MMPLAYER_RETURN_VAL_IF_FAIL(player &&
+ player->pipeline &&
+ player->pipeline->mainbin &&
+ player->pipeline->textbin, MM_ERROR_PLAYER_NOT_INITIALIZED);
mainbin = player->pipeline->mainbin;
textbin = player->pipeline->textbin;
gst_element_set_state(mainbin[MMPLAYER_M_SUBSRC].gst, GST_STATE_PAUSED);
ret = gst_element_get_state(mainbin[MMPLAYER_M_SUBSRC].gst, &element_state, &element_pending_state, 5 * GST_SECOND);
- if (GST_STATE_CHANGE_FAILURE == ret)
+ if (GST_STATE_CHANGE_FAILURE == ret) {
LOGE("fail to state change.\n");
+ result = MM_ERROR_PLAYER_INTERNAL;
+ goto ERROR;
+ }
}
gst_element_set_base_time(textbin[MMPLAYER_T_BIN].gst, base_time);
if (!gst_element_query_position(mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &time)) {
result = MM_ERROR_PLAYER_INVALID_STATE;
LOGE("gst_element_query_position failed, invalid state\n");
- goto EXIT;
+ goto ERROR;
}
LOGD("seek time = %lld, rate = %f\n", time, player->playback_rate);
__gst_send_event_to_sink(player, event);
} else {
result = MM_ERROR_PLAYER_INTERNAL;
- LOGE("gst_event_new_seek failed\n");
- goto EXIT;
+ LOGE("gst_event_new_seek failed"); /* pipeline will got error and can not be recovered */
+ goto ERROR;
}
- // sync state with current pipeline
+ /* sync state with current pipeline */
gst_element_sync_state_with_parent(textbin[MMPLAYER_T_BIN].gst);
gst_element_sync_state_with_parent(mainbin[MMPLAYER_M_SUBPARSE].gst);
gst_element_sync_state_with_parent(mainbin[MMPLAYER_M_SUBSRC].gst);
-EXIT:
+ return MM_ERROR_NONE;
+
+ERROR:
+ /* release text pipeline resource */
+ player->textsink_linked = 0;
+
+ /* release signal */
+ __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_TEXTBIN);
+
+ /* release textbin with it's childs */
+ MMPLAYER_RELEASE_ELEMENT(player, player->pipeline->textbin, MMPLAYER_T_BIN);
+ MMPLAYER_FREEIF(player->pipeline->textbin);
+ player->pipeline->textbin = NULL;
+
+ /* release subtitle elem */
+ MMPLAYER_RELEASE_ELEMENT(player, player->pipeline->mainbin, MMPLAYER_M_SUBSRC);
+ MMPLAYER_RELEASE_ELEMENT(player, player->pipeline->mainbin, MMPLAYER_M_SUBPARSE);
+
return result;
}
MMPLAYER_FENTER();
/* check player handle */
- MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+ MMPLAYER_RETURN_VAL_IF_FAIL(player &&
+ player->pipeline &&
+ player->pipeline->mainbin &&
+ player->pipeline->textbin, MM_ERROR_PLAYER_NOT_INITIALIZED);
MMPLAYER_RETURN_VAL_IF_FAIL(filepath, MM_ERROR_COMMON_INVALID_ARGUMENT);
- if (!(player->pipeline) || !(player->pipeline->mainbin)) {
- result = MM_ERROR_PLAYER_INVALID_STATE;
- LOGE("Pipeline is not in proper state\n");
- goto EXIT;
- }
-
mainbin = player->pipeline->mainbin;
textbin = player->pipeline->textbin;
/* check player handle */
MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+ MMPLAYER_RETURN_VAL_IF_FAIL(filepath, MM_ERROR_COMMON_INVALID_ARGUMENT);
if (!player->pipeline) {
// IDLE state
mm_attrs_set_string_by_name(player->attrs, "subtitle_uri", filepath);
if (mmf_attrs_commit(player->attrs)) {
- LOGE("failed to commit.\n");
- result = MM_ERROR_PLAYER_INTERNAL;
+ LOGE("failed to commit"); /* subtitle path will not be created */
+ return MM_ERROR_PLAYER_INTERNAL;
}
} else {
// cur state <> IDLE(READY, PAUSE, PLAYING..)
- if (filepath == NULL)
- return MM_ERROR_COMMON_INVALID_ARGUMENT;
-
if (!__mmplayer_check_subtitle(player)) {
mm_attrs_set_string_by_name(player->attrs, "subtitle_uri", filepath);
if (mmf_attrs_commit(player->attrs)) {
- LOGE("failed to commit.\n");
- result = MM_ERROR_PLAYER_INTERNAL;
+ LOGE("failed to commit");
+ return MM_ERROR_PLAYER_INTERNAL;
}
- if (MM_ERROR_NONE != __mmplayer_gst_create_subtitle_src(player))
- LOGE("fail to create subtitle src\n");
+ if (MM_ERROR_NONE != __mmplayer_gst_create_text_pipeline(player)) {
+ LOGE("fail to create text pipeline");
+ return MM_ERROR_PLAYER_INTERNAL;
+ }
result = _mmplayer_sync_subtitle_pipeline(player);
- } else
+ } else {
result = __mmplayer_change_external_subtitle_language(player, filepath);
+ }
player->is_external_subtitle_added_now = TRUE;
}