static void __mmplayer_set_pause_state(mmplayer_t *player);
static void __mmplayer_set_playing_state(mmplayer_t *player);
+static int __mmplayer_switch_stream(mmplayer_t *player, mmplayer_track_type_e type, int index);
/*===========================================================================================
| |
| FUNCTION DEFINITIONS |
__mmplayer_remove_g_source_from_context(player->context.thread_default, player->bus_watcher);
MMPLAYER_BUS_WATCHER_LOCK(player);
end_time = g_get_monotonic_time () + 2 * G_TIME_SPAN_SECOND;
- while (player->bus_watcher > 0)
- MMPLAYER_BUS_WATCHER_WAIT_UNTIL(player, end_time);
+ while (player->bus_watcher > 0) {
+ if (!MMPLAYER_BUS_WATCHER_WAIT_UNTIL(player, end_time)) {
+ LOGW("MMPLAYER_BUS_WATCHER_WAIT_UNTIL() timeout has passed - bus_watcher (%d)",
+ player->bus_watcher);
+ break;
+ }
+ }
MMPLAYER_BUS_WATCHER_UNLOCK(player);
-
g_mutex_clear(&player->bus_watcher_mutex);
g_cond_clear(&player->bus_watcher_cond);
}
/* change track to active pad */
active_index = player->track[type].active_track_index;
- if ((active_index != DEFAULT_TRACK) &&
+ if ((active_index != DEFAULT_TRACK_INDEX) &&
(__mmplayer_change_selector_pad(player, type, active_index) != MM_ERROR_NONE)) {
LOGW("failed to change %d type track to %d", type, active_index);
- player->track[type].active_track_index = DEFAULT_TRACK;
+ player->track[type].active_track_index = DEFAULT_TRACK_INDEX;
return;
}
MMPLAYER_GST_GET_CAPS_INFO(ref_caps, str, name, caps_ret);
if (!caps_ret)
goto ERROR;
-
+ if (caps)
+ gst_caps_unref(caps);
caps = gst_caps_ref(ref_caps);
}
return MM_ERROR_NONE;
}
-int
-_mmplayer_set_audio_only(MMHandleType hplayer, bool audio_only)
+static int __mmplayer_set_disable_overlay_option(mmplayer_t *player, bool disable)
{
gboolean disable_overlay = FALSE;
- mmplayer_t *player = (mmplayer_t *)hplayer;
MMPLAYER_FENTER();
- MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->videobin &&
player->pipeline->videobin[MMPLAYER_V_SINK].gst,
MM_ERROR_PLAYER_NO_OP); /* invalid op */
g_object_get(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "disable-overlay", &disable_overlay, NULL);
- if (audio_only == (bool)disable_overlay) {
- LOGE("It's the same with current setting: (%d)", audio_only);
+ if (disable == (bool)disable_overlay) {
+ LOGE("It's the same with current setting: (%d)", disable);
return MM_ERROR_NONE;
}
- if (audio_only) {
+ if (disable) {
LOGE("disable overlay");
g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "disable-overlay", TRUE, NULL);
/* release overlay resource */
if (__mmplayer_release_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY) != MM_ERROR_NONE) {
LOGE("failed to release overlay resource");
- goto ERROR;
+ return MM_ERROR_PLAYER_INTERNAL;
}
} else {
if (_mmplayer_acquire_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY) != MM_ERROR_NONE) {
LOGE("failed to acquire video overlay resource");
- goto ERROR;
+ return MM_ERROR_PLAYER_INTERNAL;
}
player->interrupted_by_resource = FALSE;
g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "disable-overlay", FALSE, NULL);
}
-ERROR:
MMPLAYER_FLEAVE();
return MM_ERROR_NONE;
}
int
-_mmplayer_get_audio_only(MMHandleType hplayer, bool *paudio_only)
+_mmplayer_set_audio_only(MMHandleType hplayer, bool audio_only)
{
+ int ret = MM_ERROR_NONE;
mmplayer_t *player = (mmplayer_t *)hplayer;
- gboolean disable_overlay = FALSE;
MMPLAYER_FENTER();
-
MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
- MMPLAYER_RETURN_VAL_IF_FAIL(paudio_only, MM_ERROR_INVALID_ARGUMENT);
- MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->videobin &&
- player->pipeline->videobin[MMPLAYER_V_SINK].gst,
- MM_ERROR_PLAYER_NO_OP); /* invalid op */
- if (!g_object_class_find_property(G_OBJECT_GET_CLASS(player->pipeline->videobin[MMPLAYER_V_SINK].gst), "disable-overlay")) {
- LOGW("Display control is not supported");
- return MM_ERROR_PLAYER_INTERNAL;
+ if (MMPLAYER_USE_DECODEBIN(player)) {
+ ret = __mmplayer_set_disable_overlay_option(player, audio_only);
+ goto EXIT;
}
- g_object_get(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "disable-overlay", &disable_overlay, NULL);
+ if (audio_only) {
+ MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->videobin &&
+ player->pipeline->videobin[MMPLAYER_V_SINK].gst,
+ MM_ERROR_PLAYER_NO_OP); /* invalid op */
- *paudio_only = (bool)disable_overlay;
+ __mmplayer_switch_stream(player, MM_PLAYER_TRACK_TYPE_VIDEO, INVALID_TRACK_INDEX);
- LOGD("audio_only : %d", *paudio_only);
+ /* release decoder resource */
+ if (__mmplayer_release_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER) != MM_ERROR_NONE) {
+ LOGE("failed to release video decoder resources");
+ return MM_ERROR_PLAYER_INTERNAL;
+ }
+ player->can_support_codec &= ~FOUND_PLUGIN_VIDEO;
+ } else {
+ __mmplayer_switch_stream(player, MM_PLAYER_TRACK_TYPE_VIDEO, DEFAULT_TRACK_INDEX);
+ }
- MMPLAYER_FLEAVE();
+EXIT:
+ mm_player_set_attribute(hplayer, NULL, MM_PLAYER_AUDIO_ONLY, (int)audio_only, (char *)NULL);
- return MM_ERROR_NONE;
+ MMPLAYER_FLEAVE();
+ return ret;
}
int
MMPLAYER_RETURN_IF_FAIL(unused);
MMPLAYER_RETURN_IF_FAIL(data);
- caps = gst_pad_get_current_caps(pad);
- if (!caps)
- return;
-
MMPLAYER_GST_GET_CAPS_INFO_FROM_PAD(pad, caps, str, name, caps_ret);
if (!caps_ret)
goto ERROR;
MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "no-more-pads", G_CALLBACK(__mmplayer_gst_audio_deinterleave_no_more_pads), (gpointer)player);
player->no_more_pad = FALSE;
} else {
- /* 4-2. create fakesink to extract interlevaed pcm */
+ /* 4-2. create fakesink to extract interleaved pcm */
LOGD("add audio fakesink for interleaved audio");
MMPLAYER_CREATE_ELEMENT(audiobin, extract_sink_id, "fakesink", "fakeaudiosink", *bucket, player);
if (!(player->audio_extract_opt & MM_PLAYER_AUDIO_EXTRACT_NO_SYNC_WITH_CLOCK))
GList *l = NULL;
MMPLAYER_RETURN_VAL_IF_FAIL(player, NULL);
gboolean ret = TRUE;
+ gint64 end_time = 0;
/* check DRC, if it is, destroy the prev bo list to create again */
if (player->video_bo_size != size) {
}
}
+ if (player->ini.video_bo_timeout > 0)
+ end_time = g_get_monotonic_time() + player->ini.video_bo_timeout * G_TIME_SPAN_SECOND;
+
while (TRUE) {
/* get bo from list*/
for (l = g_list_first(player->video_bo_list); l; l = g_list_next(l)) {
return tbm_bo_ref(tmp->bo);
}
}
- if (!ret) {
- LOGE("failed to get bo in %d timeout", player->ini.video_bo_timeout);
- MMPLAYER_VIDEO_BO_UNLOCK(player);
- return NULL;
- }
if (player->ini.video_bo_timeout <= 0) {
MMPLAYER_VIDEO_BO_WAIT(player);
} else {
- gint64 timeout = g_get_monotonic_time() + player->ini.video_bo_timeout * G_TIME_SPAN_SECOND;
- ret = MMPLAYER_VIDEO_BO_WAIT_UNTIL(player, timeout);
+ ret = MMPLAYER_VIDEO_BO_WAIT_UNTIL(player, end_time);
+ if (!ret) {
+ LOGE("failed to get bo in %d timeout", player->ini.video_bo_timeout);
+ break;
+ }
}
- continue;
}
+
+ MMPLAYER_VIDEO_BO_UNLOCK(player);
+ return NULL;
}
static void
LOGD("adding created elements to bin");
if (!_mmplayer_gst_element_add_bucket_to_bin(GST_BIN(textbin[MMPLAYER_T_BIN].gst), element_bucket)) {
LOGE("failed to add elements");
+ g_list_free(element_bucket);
goto ERROR;
}
LOGD("Linking elements in the bucket by added order.");
if (_mmplayer_gst_element_link_bucket(element_bucket) == -1) {
LOGE("failed to link elements");
+ g_list_free(element_bucket);
goto ERROR;
}
return MM_ERROR_NONE;
ERROR:
- g_list_free(element_bucket);
if (!player->play_subtitle && textbin[MMPLAYER_T_FAKE_SINK].gst) {
LOGE("remove textbin sink from sink list");
__mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_ALL);
if (mainbin) {
- mmplayer_gst_element_t *audiobin = player->pipeline->audiobin;
- mmplayer_gst_element_t *videobin = player->pipeline->videobin;
- mmplayer_gst_element_t *textbin = player->pipeline->textbin;
GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(mainbin[MMPLAYER_M_PIPE].gst));
gst_bus_set_sync_handler(bus, NULL, NULL, NULL);
gst_object_unref(bus);
if (mainbin[MMPLAYER_M_SRC_FAKESINK].gst)
gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_SRC_FAKESINK].gst));
- MMPLAYER_FREEIF(audiobin);
- MMPLAYER_FREEIF(videobin);
- MMPLAYER_FREEIF(textbin);
+ MMPLAYER_FREEIF(player->pipeline->audiobin);
+ MMPLAYER_FREEIF(player->pipeline->videobin);
+ MMPLAYER_FREEIF(player->pipeline->textbin);
MMPLAYER_FREEIF(mainbin);
}
player->interrupted_by_resource = TRUE;
+ MMPLAYER_POST_MSG(player, MM_MESSAGE_INTERRUPT_STARTED, NULL);
+
/* get last play position */
if (_mmplayer_gst_get_position(player, &pos) == MM_ERROR_NONE) {
msg.union_type = MM_MSG_UNION_TIME;
ret = _mmplayer_initialize_video_capture(player);
if (ret != MM_ERROR_NONE) {
- LOGE("failed to initialize video capture");
- goto ERROR;
+ LOGW("video capture is not supported");
+ /* do not handle as error for headless profile */
}
/* initialize resource manager */
player->pipeline->mainbin,
MM_ERROR_PLAYER_NOT_INITIALIZED);
- LOGD("set the pipeline state to READY");
+ if (player->pipeline->videobin && player->pipeline->videobin[MMPLAYER_V_BIN].gst) {
+ LOGD("set the videobin state to READY");
+ ret = _mmplayer_gst_set_state(player, player->pipeline->videobin[MMPLAYER_V_BIN].gst,
+ GST_STATE_READY, TRUE, MMPLAYER_STATE_CHANGE_TIMEOUT(player));
+
+ }
+
+ if (player->pipeline->audiobin && player->pipeline->audiobin[MMPLAYER_A_BIN].gst) {
+ LOGD("set the audiobin state to READY");
+ ret = _mmplayer_gst_set_state(player, player->pipeline->audiobin[MMPLAYER_A_BIN].gst,
+ GST_STATE_READY, TRUE, MMPLAYER_STATE_CHANGE_TIMEOUT(player));
+
+ }
- /* set state to READY */
+ LOGD("set the pipeline state to READY");
ret = _mmplayer_gst_set_state(player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst,
GST_STATE_READY, FALSE, MMPLAYER_STATE_CHANGE_TIMEOUT(player));
+
if (ret != MM_ERROR_NONE) {
LOGE("fail to change state to READY");
return MM_ERROR_PLAYER_INTERNAL;
player->uri_info.uri_list = g_list_append(player->uri_info.uri_list, g_strdup(uri));
SECURE_LOGD("add original path : %s", uri);
} else {
- player->uri_info.uri_list = g_list_delete_link(player->uri_info.uri_list, g_list_nth(player->uri_info.uri_list, 0));
- player->uri_info.uri_list = g_list_insert(player->uri_info.uri_list, g_strdup(uri), 0);
-
+ g_free(g_list_nth_data(player->uri_info.uri_list, 0));
+ player->uri_info.uri_list = g_list_prepend(
+ g_list_delete_link(player->uri_info.uri_list, player->uri_info.uri_list), g_strdup(uri));
SECURE_LOGD("change original path : %s", uri);
}
} else {
MMPLAYER_FREEIF(caps_str);
} else if (g_str_has_prefix(mime, "video") && player->videodec_linked) {
- LOGD("already video linked");
- ret = FALSE;
+ if((MMPLAYER_IS_HTTP_LIVE_STREAMING(player)) || (MMPLAYER_IS_DASH_STREAMING(player))) {
+ LOGD("video is already linked, allow the stream switch");
+ ret = TRUE;
+ } else {
+ LOGD("video is already linked");
+ ret = FALSE;
+ }
} else {
LOGD("found new stream");
}
}
void
-_mmplayer_gst_decode_pad_removed(GstElement *elem, GstPad *new_pad,
+_mmplayer_gst_decode_pad_removed(GstElement *elem, GstPad *pad,
gpointer data)
{
- //mmplayer_t *player = (mmplayer_t *)data;
- GstCaps *caps = NULL;
+ int ret = MM_ERROR_NONE;
+ mmplayer_t *player = (mmplayer_t *)data;
+ mmplayer_gst_element_t *mainbin = player->pipeline->mainbin;
+ mmplayer_gst_element_t *videobin = player->pipeline->videobin;
+ gint timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player);
- LOGD("[Decodebin2] pad-removed signal");
+ MMPLAYER_FENTER();
+ MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && mainbin);
- caps = gst_pad_query_caps(new_pad, NULL);
- if (!caps) {
- LOGW("query caps is NULL");
+ LOGD("decoded pad %s:%s removed", GST_DEBUG_PAD_NAME(pad));
+
+ if (MMPLAYER_USE_DECODEBIN(player))
+ return;
+
+ if (!videobin || !g_str_has_prefix(GST_PAD_NAME (pad), "video"))
return;
+
+ __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_VIDEOBIN);
+
+ if (!gst_bin_remove(GST_BIN_CAST(mainbin[MMPLAYER_M_PIPE].gst), videobin[MMPLAYER_V_BIN].gst)) {
+ LOGE("failed to remove videobin");
}
- gchar *caps_str = NULL;
- caps_str = gst_caps_to_string(caps);
+ if (!gst_bin_remove(GST_BIN_CAST(mainbin[MMPLAYER_M_PIPE].gst), mainbin[MMPLAYER_M_V_CONCAT].gst)) {
+ LOGE("failed to remove video concat");
+ }
- LOGD("pad removed caps : %s from %s", caps_str, GST_ELEMENT_NAME(elem));
+ ret = _mmplayer_gst_set_state(player, videobin[MMPLAYER_V_BIN].gst, GST_STATE_NULL, FALSE, timeout);
+ if (ret != MM_ERROR_NONE) {
+ LOGE("fail to change state to NULL");
+ return;
+ }
- MMPLAYER_FREEIF(caps_str);
- gst_caps_unref(caps);
+ ret = _mmplayer_gst_set_state(player, mainbin[MMPLAYER_M_V_CONCAT].gst, GST_STATE_NULL, FALSE, timeout);
+ if (ret != MM_ERROR_NONE) {
+ LOGE("fail to change state to NULL");
+ return;
+ }
+
+ gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_V_CONCAT].gst));
+ mainbin[MMPLAYER_M_V_CONCAT].gst = NULL;
+ mainbin[MMPLAYER_M_V_CONCAT].id = 0;
+
+ gst_object_unref(GST_OBJECT(videobin[MMPLAYER_V_BIN].gst));
+ MMPLAYER_FREEIF(player->pipeline->videobin);
+
+ ret = __mmplayer_release_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY);
+ if (ret != MM_ERROR_NONE)
+ LOGE("failed to release overlay resources");
+
+ player->videodec_linked = 0;
+
+ MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-pad-removed");
+ MMPLAYER_FLEAVE();
}
void
_mmplayer_set_reconfigure_state(player, TRUE);
MMPLAYER_CMD_UNLOCK(player);
- MMPLAYER_POST_MSG(player, MM_MESSAGE_GAPLESS_CONSTRUCTION, NULL);
+ MMPLAYER_POST_MSG(player, MM_MESSAGE_FLUSH_BUFFER, NULL);
__mmplayer_deactivate_old_path(player);
MMPLAYER_FLEAVE();
player->gapless.update_segment[MM_PLAYER_TRACK_TYPE_VIDEO] = FALSE;
/* deactivate pipeline except sinkbins to set up the new pipeline of next uri*/
- MMPLAYER_POST_MSG(player, MM_MESSAGE_GAPLESS_CONSTRUCTION, NULL); /* post message for gapless */
+ MMPLAYER_POST_MSG(player, MM_MESSAGE_FLUSH_BUFFER, NULL); /* post message for gapless */
__mmplayer_deactivate_old_path(player);
MMPLAYER_FLEAVE();
#endif
player->pipeline->mainbin[MMPLAYER_M_DEMUX].id = MMPLAYER_M_DEMUX;
player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst = element;
+ } else if (g_strrstr(klass, "Parser") && (g_strrstr(klass, "Video"))) {
+ player->pipeline->mainbin[MMPLAYER_M_V_PARSE].id = MMPLAYER_M_V_PARSE;
+ player->pipeline->mainbin[MMPLAYER_M_V_PARSE].gst = element;
}
if (g_strrstr(factory_name, "asfdemux") || g_strrstr(factory_name, "qtdemux") || g_strrstr(factory_name, "avidemux")) {
}
} else if (g_strrstr(factory_name, player->ini.videocodec_element_hw)) {
player->pipeline->mainbin[MMPLAYER_M_DEC1].gst = element;
+ } else if (g_strrstr(factory_name, "omxdec_h264")) {
+ GstElement *video_parse = player->pipeline->mainbin[MMPLAYER_M_V_PARSE].gst;
+ if (video_parse && (g_object_class_find_property(G_OBJECT_GET_CLASS(video_parse), "config-interval"))) {
+ g_object_set(G_OBJECT(video_parse), "config-interval", -1, NULL);
+ LOGD("Send SPS and PPS Insertion every IDR frame");
+ }
}
if ((player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst) &&
static void
__mmplayer_release_misc_post(mmplayer_t *player)
{
- char *original_uri = NULL;
+ gchar *original_uri = NULL;
MMPLAYER_FENTER();
/* player->pipeline is already released before. */
player->audio_stream_changed_cb = NULL;
player->audio_stream_changed_cb_user_param = NULL;
- mm_player_set_attribute((MMHandleType)player, NULL, "content_video_found", 0, NULL);
+ mm_player_set_attribute((MMHandleType)player, NULL,
+ "content_video_found", 0, MM_PLAYER_AUDIO_ONLY, 0, NULL);
/* clean found audio decoders */
if (player->audio_decoders) {
mm_player_set_attribute((MMHandleType)player, NULL, "profile_uri",
original_uri, (original_uri) ? strlen(original_uri) : (0), NULL);
-
+ MMPLAYER_FREEIF(original_uri);
}
/* clear the audio stream buffer list */
for (; sig_list; sig_list = sig_list->next) {
item = sig_list->data;
- if (item && item->obj && GST_IS_ELEMENT(item->obj)) {
+ if (item && item->obj) {
if (g_signal_handler_is_connected(item->obj, item->sig))
g_signal_handler_disconnect(item->obj, item->sig);
}
guint active_idx = 0;
GstStream *stream = NULL;
GList *streams = NULL;
- GstEvent *ev = NULL;
GstCaps *caps = NULL;
+ MMPLAYER_FENTER();
LOGD("Switching Streams... type: %d, index: %d", type, index);
player->track[type].active_track_index = index;
for (int i = 0; i < MM_PLAYER_TRACK_TYPE_MAX; i++) {
/* FIXME: need to consider the non display type or audio only in case of MM_PLAYER_TRACK_TYPE_VIDEO */
- if (player->track[i].total_track_num > 0) {
+ LOGD("track type:%d, total: %d, active: %d", i,
+ player->track[i].total_track_num, player->track[i].active_track_index);
+ if (player->track[i].total_track_num > 0 &&
+ player->track[i].active_track_index > INVALID_TRACK_INDEX) {
active_idx = player->track[i].active_track_index;
stream = g_ptr_array_index(player->track[i].streams, active_idx);
streams = g_list_append (streams, (gchar *)gst_stream_get_stream_id(stream));
}
}
- ev = gst_event_new_select_streams(streams);
- gst_element_send_event(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, ev);
- g_list_free(streams);
+ if (streams) {
+ LOGD("send select stream event");
+ gst_element_send_event(player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst,
+ gst_event_new_select_streams(streams));
+ g_list_free(streams);
+ }
+ MMPLAYER_FLEAVE();
return MM_ERROR_NONE;
}
}
p = gst_caps_get_structure(caps_a, 0);
-
- mm_attrs_get_int_by_name(attrs, "content_audio_samplerate", &samplerate);
-
gst_structure_get_int(p, "rate", &samplerate);
gst_structure_get_int(p, "channels", &channels);