static gboolean __mmplayer_check_subtitle(mmplayer_t *player);
static int __mmplayer_handle_missed_plugin(mmplayer_t *player);
-static int __mmplayer_check_not_supported_codec(mmplayer_t *player, const gchar *factory_class, const gchar *mime);
static void __mmplayer_add_sink(mmplayer_t *player, GstElement *sink, gboolean first);
static void __mmplayer_del_sink(mmplayer_t *player, GstElement *sink);
static void __mmplayer_release_signal_connection(mmplayer_t *player, mmplayer_signal_type_e type);
mainbin = player->pipeline->mainbin;
- MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_MUXED_S_BUFFER);
- MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_ID3DEMUX);
- MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_AUTOPLUG);
- MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_TYPEFIND);
- MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_SRC);
+ if (MMPLAYER_USE_DECODEBIN(player)) {
+ MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_MUXED_S_BUFFER);
+ MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_AUTOPLUG); /* decodebin */
+ MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_TYPEFIND);
+ MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_SRC);
+ } else {
+ MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_AUTOPLUG); /* uridecodebin */
+ mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst = NULL;
+ mainbin[MMPLAYER_M_SRC].gst = NULL;
+ }
/* Initialize Player values */
__mmplayer_initialize_gapless_play(player);
}
/* link */
- sinkpad = gst_element_get_request_pad(combiner, "sink_%u");
+ sinkpad = gst_element_request_pad_simple(combiner, "sink_%u");
LOGD("pad link: %s:%s - %s:%s", GST_DEBUG_PAD_NAME(pad), GST_DEBUG_PAD_NAME(sinkpad));
sinkpad = NULL;
}
+ MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-pad-added");
return;
}
player->pipeline->videobin[MMPLAYER_V_SINK].gst,
MM_ERROR_PLAYER_NO_OP); /* invalid op */
+ __mmplayer_del_sink(player, player->pipeline->videobin[MMPLAYER_V_SINK].gst);
+
__mmplayer_switch_stream(player, MM_PLAYER_TRACK_TYPE_VIDEO, INVALID_TRACK_INDEX);
/* release decoder resource */
return FALSE;
}
-static int
-__mmplayer_check_not_supported_codec(mmplayer_t *player, const gchar *factory_class, const gchar *mime)
+int
+_mmplayer_update_not_supported_codec_info(mmplayer_t *player, const gchar *factory_class, const gchar *mime)
{
MMPLAYER_FENTER();
MMPLAYER_FREEIF(caps_str);
/* There is no available codec. */
- __mmplayer_check_not_supported_codec(player, klass, mime);
+ _mmplayer_update_not_supported_codec_info(player, klass, mime);
}
gboolean
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);
MMPLAYER_FENTER();
MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && mainbin);
__mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_VIDEOBIN);
+ __mmplayer_del_sink(player, videobin[MMPLAYER_V_SINK].gst);
+
+ LOGD("remove videobin");
+ 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 of videobin to NULL");
+ return;
+ }
+
if (!gst_bin_remove(GST_BIN_CAST(mainbin[MMPLAYER_M_PIPE].gst), videobin[MMPLAYER_V_BIN].gst)) {
LOGE("failed to remove videobin");
gst_object_unref(GST_OBJECT(videobin[MMPLAYER_V_BIN].gst));
}
+ LOGD("remove concat");
+ 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 of concat to NULL");
+ return;
+ }
+
if (!gst_bin_remove(GST_BIN_CAST(mainbin[MMPLAYER_M_PIPE].gst), mainbin[MMPLAYER_M_V_CONCAT].gst)) {
LOGE("failed to remove video concat");
gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_V_CONCAT].gst));
}
void
-_mmplayer_gst_element_added(GstElement *bin, GstElement *element, gpointer data)
+_mmplayer_gst_element_added(GstBin *bin, GstElement *element, gpointer data)
{
mmplayer_t *player = (mmplayer_t *)data;
const gchar *klass = NULL;
if (__mmplayer_add_dump_buffer_probe(player, element))
LOGD("add buffer probe");
- if (g_strrstr(klass, "Codec/Decoder/Audio")) {
- gchar *selected = NULL;
- selected = g_strdup(GST_ELEMENT_NAME(element));
- player->audio_decoders = g_list_append(player->audio_decoders, selected);
-
- /* update codec info */
- player->not_supported_codec &= MISSING_PLUGIN_VIDEO;
- player->can_support_codec |= FOUND_PLUGIN_AUDIO;
- player->audiodec_linked = 1;
- } else if (g_strrstr(klass, "Codec/Decoder/Video")) {
- /* update codec info */
- player->not_supported_codec &= MISSING_PLUGIN_AUDIO;
- player->can_support_codec |= FOUND_PLUGIN_VIDEO;
- player->videodec_linked = 1;
- }
-
- if (g_strrstr(klass, "Demuxer/Adaptive")) {
- player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].id = MMPLAYER_M_ADAPTIVE_DEMUX;
- player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst = element;
+ if (g_strrstr(klass, "Decoder")) {
+ if (g_strrstr(klass, "Audio")) {
+ player->audio_decoders = g_list_append(player->audio_decoders,
+ g_strdup(GST_ELEMENT_NAME(element)));
- LOGD("set max variant limit: %d, %d %d", player->adaptive_info.limit.bandwidth,
- player->adaptive_info.limit.width, player->adaptive_info.limit.height);
+ /* update codec info */
+ player->not_supported_codec &= MISSING_PLUGIN_VIDEO;
+ player->can_support_codec |= FOUND_PLUGIN_AUDIO;
+ player->audiodec_linked = 1;
+ } else if (g_strrstr(klass, "Video")) {
+ GstElement *video_parse = player->pipeline->mainbin[MMPLAYER_M_V_PARSE].gst;
+ /* update codec info */
+ player->not_supported_codec &= MISSING_PLUGIN_AUDIO;
+ player->can_support_codec |= FOUND_PLUGIN_VIDEO;
+ player->videodec_linked = 1;
+
+ if (video_parse) {
+ GstPad *srcpad = gst_element_get_static_pad (video_parse, "src");
+ if (srcpad) {
+ GstCaps *caps = NULL;
+ GstStructure *str = NULL;
+ const gchar *name = NULL;
+ gboolean caps_ret = TRUE;
+
+ MMPLAYER_GST_GET_CAPS_INFO_FROM_PAD (srcpad, caps, str, name, caps_ret);
+ if (caps_ret && str) {
+ const gchar *stream_format = gst_structure_get_string (str, "stream-format");
+ if (stream_format && g_strrstr(stream_format, "byte-stream")) {
+ if ((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");
+ }
+ }
+ }
+ gst_object_unref(GST_OBJECT(srcpad));
+ }
+ }
+ }
+ } else if (g_strrstr(klass, "Demuxer")) {
+ if (g_strrstr(klass, "Adaptive")) {
+ player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].id = MMPLAYER_M_ADAPTIVE_DEMUX;
+ player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst = element;
- g_object_set(player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst,
- "max-bandwidth", player->adaptive_info.limit.bandwidth,
- "max-video-width", player->adaptive_info.limit.width,
- "max-video-height", player->adaptive_info.limit.height, NULL);
+ LOGD("set max variant limit: %d, %d %d", player->adaptive_info.limit.bandwidth,
+ player->adaptive_info.limit.width, player->adaptive_info.limit.height);
- } else if (g_strrstr(klass, "Demuxer")) {
+ g_object_set(player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst,
+ "max-bandwidth", player->adaptive_info.limit.bandwidth,
+ "max-video-width", player->adaptive_info.limit.width,
+ "max-video-height", player->adaptive_info.limit.height, NULL);
+ } else {
#ifdef __DEBUG__
- LOGD("plugged element is demuxer. take it");
+ LOGD("plugged element is demuxer. take it");
#endif
- player->pipeline->mainbin[MMPLAYER_M_DEMUX].id = MMPLAYER_M_DEMUX;
- player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst = element;
+ 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")) {
- int surface_type = 0;
-
- mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &surface_type);
- }
-
- // to support trust-zone only
- if (g_strrstr(factory_name, "asfdemux")) {
- LOGD("set file-location %s", player->profile.uri);
- g_object_set(G_OBJECT(element), "file-location", player->profile.uri, NULL);
- } else if (g_strrstr(factory_name, "legacyh264parse")) {
- LOGD("[%s] output-format to legacyh264parse", "mssdemux");
- g_object_set(G_OBJECT(element), "output-format", 1, NULL); /* NALU/Byte Stream format */
- } else if (g_strrstr(factory_name, "mpegaudioparse")) {
+ if (g_strrstr(factory_name, "mpegaudioparse")) {
if ((MMPLAYER_IS_HTTP_STREAMING(player)) &&
(__mmplayer_is_only_mp3_type(player->type))) {
LOGD("[mpegaudioparse] set streaming pull mode.");
g_object_set(G_OBJECT(element), "http-pull-mp3dec", TRUE, NULL);
}
- } 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) &&
+ } else if ((player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst) &&
(g_strrstr(GST_ELEMENT_NAME(element), "multiqueue"))) {
LOGD("plugged element is multiqueue. take it %s", GST_ELEMENT_NAME(element));
_mm_player_streaming_set_multiqueue(player->streamer, element);
_mm_player_streaming_sync_property(player->streamer, player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst);
}
-
}
return;
current_state = GST_STATE(mainbin[MMPLAYER_M_PIPE].gst);
// sync clock with current pipeline
- curr_clock = GST_ELEMENT_CLOCK(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst);
+ curr_clock = gst_element_get_clock(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst);
curr_time = gst_clock_get_time(curr_clock);
base_time = gst_element_get_base_time(GST_ELEMENT_CAST(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst));
if (GST_STATE_CHANGE_FAILURE == ret) {
LOGE("fail to state change.");
result = MM_ERROR_PLAYER_INTERNAL;
+ if (curr_clock)
+ gst_object_unref(curr_clock);
goto ERROR;
}
}
g_list_free(streams);
}
+ /* in paused state, seek to current pos to flush mq buffer and release waiting task */
+ if (MMPLAYER_CURRENT_STATE(player) == MM_PLAYER_STATE_PAUSED) {
+ gint64 pos_nsec = GST_CLOCK_TIME_NONE;
+
+ if (!gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &pos_nsec))
+ pos_nsec = player->last_position;
+
+ LOGD("current pos %" GST_TIME_FORMAT ", rate = %f", GST_TIME_ARGS(pos_nsec), player->playback_rate);
+
+ if (!_mmplayer_gst_seek(player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst,
+ player->playback_rate, GST_FORMAT_TIME,
+ (GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE),
+ GST_SEEK_TYPE_SET, pos_nsec, GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE)) {
+ LOGW("failed to seek");
+ return MM_ERROR_PLAYER_INTERNAL;
+ }
+ }
+
MMPLAYER_FLEAVE();
return MM_ERROR_NONE;
}