mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-10 01:54:11 +00:00
player: Make use of GstStreams API with playbin3
Allow use of playbin3 and GstStreams API by setting the environment variable "GST_PLAYER_USE_PLAYBIN3" https://bugzilla.gnome.org/show_bug.cgi?id=775487
This commit is contained in:
parent
7ee593e493
commit
e25da85a65
3 changed files with 443 additions and 36 deletions
gst-libs/gst/player
|
@ -32,6 +32,7 @@ struct _GstPlayerStreamInfo
|
|||
GstCaps *caps;
|
||||
gint stream_index;
|
||||
GstTagList *tags;
|
||||
gchar *stream_id;
|
||||
};
|
||||
|
||||
struct _GstPlayerStreamInfoClass
|
||||
|
|
|
@ -47,6 +47,7 @@ gst_player_stream_info_finalize (GObject * object)
|
|||
GstPlayerStreamInfo *sinfo = GST_PLAYER_STREAM_INFO (object);
|
||||
|
||||
g_free (sinfo->codec);
|
||||
g_free (sinfo->stream_id);
|
||||
|
||||
if (sinfo->caps)
|
||||
gst_caps_unref (sinfo->caps);
|
||||
|
@ -543,6 +544,8 @@ gst_player_stream_info_copy (GstPlayerStreamInfo * ref)
|
|||
info->caps = gst_caps_copy (ref->caps);
|
||||
if (ref->codec)
|
||||
info->codec = g_strdup (ref->codec);
|
||||
if (ref->stream_id)
|
||||
info->stream_id = g_strdup (ref->stream_id);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
|
|
@ -189,6 +189,14 @@ struct _GstPlayer
|
|||
* state-changed:GST_PLAYER_STATE_STOPPED/PAUSED. This ensures that no signal
|
||||
* is emitted after gst_player_stop/pause() has been called by the user. */
|
||||
gboolean inhibit_sigs;
|
||||
|
||||
/* For playbin3 */
|
||||
gboolean use_playbin3;
|
||||
GstStreamCollection *collection;
|
||||
gchar *video_sid;
|
||||
gchar *audio_sid;
|
||||
gchar *subtitle_sid;
|
||||
gulong stream_notify_id;
|
||||
};
|
||||
|
||||
struct _GstPlayerClass
|
||||
|
@ -240,6 +248,18 @@ static void gst_player_audio_info_update (GstPlayer * self,
|
|||
static void gst_player_subtitle_info_update (GstPlayer * self,
|
||||
GstPlayerStreamInfo * stream_info);
|
||||
|
||||
/* For playbin3 */
|
||||
static void gst_player_streams_info_create_from_collection (GstPlayer * self,
|
||||
GstPlayerMediaInfo * media_info, GstStreamCollection * collection);
|
||||
static void gst_player_stream_info_update_from_stream (GstPlayer * self,
|
||||
GstPlayerStreamInfo * s, GstStream * stream);
|
||||
static GstPlayerStreamInfo *gst_player_stream_info_find_from_stream_id
|
||||
(GstPlayerMediaInfo * media_info, const gchar * stream_id);
|
||||
static GstPlayerStreamInfo *gst_player_stream_info_get_current_from_stream_id
|
||||
(GstPlayer * self, const gchar * stream_id, GType type);
|
||||
static void stream_notify_cb (GstStreamCollection * collection,
|
||||
GstStream * stream, GParamSpec * pspec, GstPlayer * self);
|
||||
|
||||
static void emit_media_info_updated_signal (GstPlayer * self);
|
||||
|
||||
static void *get_title (GstTagList * tags);
|
||||
|
@ -492,6 +512,9 @@ gst_player_finalize (GObject * object)
|
|||
g_free (self->uri);
|
||||
g_free (self->redirect_uri);
|
||||
g_free (self->suburi);
|
||||
g_free (self->video_sid);
|
||||
g_free (self->audio_sid);
|
||||
g_free (self->subtitle_sid);
|
||||
if (self->global_tags)
|
||||
gst_tag_list_unref (self->global_tags);
|
||||
if (self->video_renderer)
|
||||
|
@ -502,6 +525,8 @@ gst_player_finalize (GObject * object)
|
|||
gst_object_unref (self->current_vis_element);
|
||||
if (self->config)
|
||||
gst_structure_free (self->config);
|
||||
if (self->collection)
|
||||
gst_object_unref (self->collection);
|
||||
g_mutex_clear (&self->lock);
|
||||
g_cond_clear (&self->cond);
|
||||
|
||||
|
@ -1812,6 +1837,113 @@ element_cb (G_GNUC_UNUSED GstBus * bus, GstMessage * msg, gpointer user_data)
|
|||
}
|
||||
}
|
||||
|
||||
/* Must be called with lock */
|
||||
static gboolean
|
||||
update_stream_collection (GstPlayer * self, GstStreamCollection * collection)
|
||||
{
|
||||
if (self->collection && self->collection == collection)
|
||||
return FALSE;
|
||||
|
||||
if (self->collection && self->stream_notify_id)
|
||||
g_signal_handler_disconnect (self->collection, self->stream_notify_id);
|
||||
|
||||
gst_object_replace ((GstObject **) & self->collection,
|
||||
(GstObject *) collection);
|
||||
if (self->media_info) {
|
||||
gst_object_unref (self->media_info);
|
||||
self->media_info = gst_player_media_info_create (self);
|
||||
}
|
||||
|
||||
self->stream_notify_id =
|
||||
g_signal_connect (self->collection, "stream-notify",
|
||||
G_CALLBACK (stream_notify_cb), self);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
stream_collection_cb (G_GNUC_UNUSED GstBus * bus, GstMessage * msg,
|
||||
gpointer user_data)
|
||||
{
|
||||
GstPlayer *self = GST_PLAYER (user_data);
|
||||
GstStreamCollection *collection = NULL;
|
||||
gboolean updated = FALSE;
|
||||
|
||||
gst_message_parse_stream_collection (msg, &collection);
|
||||
|
||||
if (!collection)
|
||||
return;
|
||||
|
||||
g_mutex_lock (&self->lock);
|
||||
updated = update_stream_collection (self, collection);
|
||||
gst_object_unref (collection);
|
||||
g_mutex_unlock (&self->lock);
|
||||
|
||||
if (self->media_info && updated)
|
||||
emit_media_info_updated_signal (self);
|
||||
}
|
||||
|
||||
static void
|
||||
streams_selected_cb (G_GNUC_UNUSED GstBus * bus, GstMessage * msg,
|
||||
gpointer user_data)
|
||||
{
|
||||
GstPlayer *self = GST_PLAYER (user_data);
|
||||
GstStreamCollection *collection = NULL;
|
||||
gboolean updated = FALSE;
|
||||
guint i, len;
|
||||
|
||||
gst_message_parse_streams_selected (msg, &collection);
|
||||
|
||||
if (!collection)
|
||||
return;
|
||||
|
||||
g_mutex_lock (&self->lock);
|
||||
updated = update_stream_collection (self, collection);
|
||||
gst_object_unref (collection);
|
||||
|
||||
g_free (self->video_sid);
|
||||
g_free (self->audio_sid);
|
||||
g_free (self->subtitle_sid);
|
||||
self->video_sid = NULL;
|
||||
self->audio_sid = NULL;
|
||||
self->subtitle_sid = NULL;
|
||||
|
||||
len = gst_message_streams_selected_get_size (msg);
|
||||
for (i = 0; i < len; i++) {
|
||||
GstStream *stream;
|
||||
GstStreamType stream_type;
|
||||
const gchar *stream_id;
|
||||
gchar **current_sid;
|
||||
stream = gst_message_streams_selected_get_stream (msg, i);
|
||||
stream_type = gst_stream_get_stream_type (stream);
|
||||
stream_id = gst_stream_get_stream_id (stream);
|
||||
if (stream_type & GST_STREAM_TYPE_AUDIO)
|
||||
current_sid = &self->audio_sid;
|
||||
else if (stream_type & GST_STREAM_TYPE_VIDEO)
|
||||
current_sid = &self->video_sid;
|
||||
else if (stream_type & GST_STREAM_TYPE_TEXT)
|
||||
current_sid = &self->subtitle_sid;
|
||||
else {
|
||||
GST_WARNING_OBJECT (self,
|
||||
"Unknown stream-id %s with type 0x%x", stream_id, stream_type);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (G_UNLIKELY (*current_sid)) {
|
||||
GST_FIXME_OBJECT (self,
|
||||
"Multiple streams are selected for type %s, choose the first one",
|
||||
gst_stream_type_get_name (stream_type));
|
||||
continue;
|
||||
}
|
||||
|
||||
*current_sid = g_strdup (stream_id);
|
||||
}
|
||||
g_mutex_unlock (&self->lock);
|
||||
|
||||
if (self->media_info && updated)
|
||||
emit_media_info_updated_signal (self);
|
||||
}
|
||||
|
||||
static void
|
||||
player_set_flag (GstPlayer * self, gint pos)
|
||||
{
|
||||
|
@ -1949,10 +2081,15 @@ gst_player_subtitle_info_update (GstPlayer * self,
|
|||
|
||||
g_object_get (G_OBJECT (self->playbin), "current-suburi", &suburi, NULL);
|
||||
if (suburi) {
|
||||
g_object_get (G_OBJECT (self->playbin), "current-text", &text_index,
|
||||
NULL);
|
||||
if (text_index == gst_player_stream_info_get_index (stream_info))
|
||||
info->language = g_path_get_basename (suburi);
|
||||
if (self->use_playbin3) {
|
||||
if (g_str_equal (self->subtitle_sid, stream_info->stream_id))
|
||||
info->language = g_path_get_basename (suburi);
|
||||
} else {
|
||||
g_object_get (G_OBJECT (self->playbin), "current-text", &text_index,
|
||||
NULL);
|
||||
if (text_index == gst_player_stream_info_get_index (stream_info))
|
||||
info->language = g_path_get_basename (suburi);
|
||||
}
|
||||
g_free (suburi);
|
||||
}
|
||||
}
|
||||
|
@ -2133,6 +2270,27 @@ gst_player_stream_info_find (GstPlayerMediaInfo * media_info,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static GstPlayerStreamInfo *
|
||||
gst_player_stream_info_find_from_stream_id (GstPlayerMediaInfo * media_info,
|
||||
const gchar * stream_id)
|
||||
{
|
||||
GList *list, *l;
|
||||
GstPlayerStreamInfo *info = NULL;
|
||||
|
||||
if (!media_info)
|
||||
return NULL;
|
||||
|
||||
list = gst_player_media_info_get_stream_list (media_info);
|
||||
for (l = list; l != NULL; l = l->next) {
|
||||
info = (GstPlayerStreamInfo *) l->data;
|
||||
if (g_str_equal (info->stream_id, stream_id)) {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_track_enabled (GstPlayer * self, gint pos)
|
||||
{
|
||||
|
@ -2166,6 +2324,56 @@ gst_player_stream_info_get_current (GstPlayer * self, const gchar * prop,
|
|||
return info;
|
||||
}
|
||||
|
||||
static GstPlayerStreamInfo *
|
||||
gst_player_stream_info_get_current_from_stream_id (GstPlayer * self,
|
||||
const gchar * stream_id, GType type)
|
||||
{
|
||||
GstPlayerStreamInfo *info;
|
||||
|
||||
if (!self->media_info || !stream_id)
|
||||
return NULL;
|
||||
|
||||
g_mutex_lock (&self->lock);
|
||||
info =
|
||||
gst_player_stream_info_find_from_stream_id (self->media_info, stream_id);
|
||||
if (info && G_OBJECT_TYPE (info) == type)
|
||||
info = gst_player_stream_info_copy (info);
|
||||
else
|
||||
info = NULL;
|
||||
g_mutex_unlock (&self->lock);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
static void
|
||||
stream_notify_cb (GstStreamCollection * collection, GstStream * stream,
|
||||
GParamSpec * pspec, GstPlayer * self)
|
||||
{
|
||||
GstPlayerStreamInfo *info;
|
||||
const gchar *stream_id;
|
||||
gboolean emit_signal = FALSE;
|
||||
|
||||
if (!self->media_info)
|
||||
return;
|
||||
|
||||
if (G_PARAM_SPEC_VALUE_TYPE (pspec) != GST_TYPE_CAPS &&
|
||||
G_PARAM_SPEC_VALUE_TYPE (pspec) != GST_TYPE_TAG_LIST)
|
||||
return;
|
||||
|
||||
stream_id = gst_stream_get_stream_id (stream);
|
||||
g_mutex_lock (&self->lock);
|
||||
info =
|
||||
gst_player_stream_info_find_from_stream_id (self->media_info, stream_id);
|
||||
if (info) {
|
||||
gst_player_stream_info_update_from_stream (self, info, stream);
|
||||
emit_signal = TRUE;
|
||||
}
|
||||
g_mutex_unlock (&self->lock);
|
||||
|
||||
if (emit_signal)
|
||||
emit_media_info_updated_signal (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_player_stream_info_update (GstPlayer * self, GstPlayerStreamInfo * s)
|
||||
{
|
||||
|
@ -2290,6 +2498,86 @@ gst_player_streams_info_create (GstPlayer * self,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_player_stream_info_update_from_stream (GstPlayer * self,
|
||||
GstPlayerStreamInfo * s, GstStream * stream)
|
||||
{
|
||||
if (s->tags)
|
||||
gst_tag_list_unref (s->tags);
|
||||
s->tags = gst_stream_get_tags (stream);
|
||||
|
||||
if (s->caps)
|
||||
gst_caps_unref (s->caps);
|
||||
s->caps = gst_stream_get_caps (stream);
|
||||
|
||||
g_free (s->codec);
|
||||
s->codec = stream_info_get_codec (s);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "%s index: %d tags: %p caps: %p",
|
||||
gst_player_stream_info_get_stream_type (s), s->stream_index,
|
||||
s->tags, s->caps);
|
||||
|
||||
gst_player_stream_info_update (self, s);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_player_streams_info_create_from_collection (GstPlayer * self,
|
||||
GstPlayerMediaInfo * media_info, GstStreamCollection * collection)
|
||||
{
|
||||
guint i;
|
||||
guint total;
|
||||
GstPlayerStreamInfo *s;
|
||||
guint n_audio = 0;
|
||||
guint n_video = 0;
|
||||
guint n_text = 0;
|
||||
|
||||
if (!media_info || !collection)
|
||||
return;
|
||||
|
||||
total = gst_stream_collection_get_size (collection);
|
||||
|
||||
for (i = 0; i < total; i++) {
|
||||
GstStream *stream = gst_stream_collection_get_stream (collection, i);
|
||||
GstStreamType stream_type = gst_stream_get_stream_type (stream);
|
||||
const gchar *stream_id = gst_stream_get_stream_id (stream);
|
||||
|
||||
if (stream_type & GST_STREAM_TYPE_AUDIO) {
|
||||
s = gst_player_stream_info_new (n_audio, GST_TYPE_PLAYER_AUDIO_INFO);
|
||||
n_audio++;
|
||||
} else if (stream_type & GST_STREAM_TYPE_VIDEO) {
|
||||
s = gst_player_stream_info_new (n_video, GST_TYPE_PLAYER_VIDEO_INFO);
|
||||
n_video++;
|
||||
} else if (stream_type & GST_STREAM_TYPE_TEXT) {
|
||||
s = gst_player_stream_info_new (n_text, GST_TYPE_PLAYER_SUBTITLE_INFO);
|
||||
n_text++;
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (self, "Unknown type stream %d", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
s->stream_id = g_strdup (stream_id);
|
||||
|
||||
/* add the object in stream list */
|
||||
media_info->stream_list = g_list_append (media_info->stream_list, s);
|
||||
|
||||
/* based on type, add the object in its corresponding stream_ list */
|
||||
if (GST_IS_PLAYER_AUDIO_INFO (s))
|
||||
media_info->audio_stream_list = g_list_append
|
||||
(media_info->audio_stream_list, s);
|
||||
else if (GST_IS_PLAYER_VIDEO_INFO (s))
|
||||
media_info->video_stream_list = g_list_append
|
||||
(media_info->video_stream_list, s);
|
||||
else
|
||||
media_info->subtitle_stream_list = g_list_append
|
||||
(media_info->subtitle_stream_list, s);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "create %s stream stream_index: %d",
|
||||
gst_player_stream_info_get_stream_type (s), s->stream_index);
|
||||
|
||||
gst_player_stream_info_update_from_stream (self, s, stream);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
video_changed_cb (G_GNUC_UNUSED GObject * object, gpointer user_data)
|
||||
{
|
||||
|
@ -2423,13 +2711,18 @@ gst_player_media_info_create (GstPlayer * self)
|
|||
gst_query_parse_seeking (query, NULL, &media_info->seekable, NULL, NULL);
|
||||
gst_query_unref (query);
|
||||
|
||||
/* create audio/video/sub streams */
|
||||
gst_player_streams_info_create (self, media_info, "n-video",
|
||||
GST_TYPE_PLAYER_VIDEO_INFO);
|
||||
gst_player_streams_info_create (self, media_info, "n-audio",
|
||||
GST_TYPE_PLAYER_AUDIO_INFO);
|
||||
gst_player_streams_info_create (self, media_info, "n-text",
|
||||
GST_TYPE_PLAYER_SUBTITLE_INFO);
|
||||
if (self->use_playbin3 && self->collection) {
|
||||
gst_player_streams_info_create_from_collection (self, media_info,
|
||||
self->collection);
|
||||
} else {
|
||||
/* create audio/video/sub streams */
|
||||
gst_player_streams_info_create (self, media_info, "n-video",
|
||||
GST_TYPE_PLAYER_VIDEO_INFO);
|
||||
gst_player_streams_info_create (self, media_info, "n-audio",
|
||||
GST_TYPE_PLAYER_AUDIO_INFO);
|
||||
gst_player_streams_info_create (self, media_info, "n-text",
|
||||
GST_TYPE_PLAYER_SUBTITLE_INFO);
|
||||
}
|
||||
|
||||
media_info->title = get_from_tags (self, media_info, get_title);
|
||||
media_info->container =
|
||||
|
@ -2563,6 +2856,7 @@ gst_player_main (gpointer data)
|
|||
GSource *source;
|
||||
GSource *bus_source;
|
||||
GstElement *scaletempo;
|
||||
const gchar *env;
|
||||
|
||||
GST_TRACE_OBJECT (self, "Starting main thread");
|
||||
|
||||
|
@ -2574,7 +2868,15 @@ gst_player_main (gpointer data)
|
|||
g_source_attach (source, self->context);
|
||||
g_source_unref (source);
|
||||
|
||||
self->playbin = gst_element_factory_make ("playbin", "playbin");
|
||||
env = g_getenv ("GST_PLAYER_USE_PLAYBIN3");
|
||||
if (env && g_str_has_prefix (env, "1"))
|
||||
self->use_playbin3 = TRUE;
|
||||
|
||||
if (self->use_playbin3) {
|
||||
GST_DEBUG_OBJECT (self, "playbin3 enabled");
|
||||
self->playbin = gst_element_factory_make ("playbin3", "playbin3");
|
||||
} else
|
||||
self->playbin = gst_element_factory_make ("playbin", "playbin");
|
||||
|
||||
if (self->video_renderer) {
|
||||
GstElement *video_sink =
|
||||
|
@ -2620,19 +2922,27 @@ gst_player_main (gpointer data)
|
|||
G_CALLBACK (element_cb), self);
|
||||
g_signal_connect (G_OBJECT (bus), "message::tag", G_CALLBACK (tags_cb), self);
|
||||
|
||||
g_signal_connect (self->playbin, "video-changed",
|
||||
G_CALLBACK (video_changed_cb), self);
|
||||
g_signal_connect (self->playbin, "audio-changed",
|
||||
G_CALLBACK (audio_changed_cb), self);
|
||||
g_signal_connect (self->playbin, "text-changed",
|
||||
G_CALLBACK (subtitle_changed_cb), self);
|
||||
if (self->use_playbin3) {
|
||||
g_signal_connect (G_OBJECT (bus), "message::stream-collection",
|
||||
G_CALLBACK (stream_collection_cb), self);
|
||||
g_signal_connect (G_OBJECT (bus), "message::streams-selected",
|
||||
G_CALLBACK (streams_selected_cb), self);
|
||||
} else {
|
||||
g_signal_connect (self->playbin, "video-changed",
|
||||
G_CALLBACK (video_changed_cb), self);
|
||||
g_signal_connect (self->playbin, "audio-changed",
|
||||
G_CALLBACK (audio_changed_cb), self);
|
||||
g_signal_connect (self->playbin, "text-changed",
|
||||
G_CALLBACK (subtitle_changed_cb), self);
|
||||
|
||||
g_signal_connect (self->playbin, "video-tags-changed",
|
||||
G_CALLBACK (video_tags_changed_cb), self);
|
||||
g_signal_connect (self->playbin, "audio-tags-changed",
|
||||
G_CALLBACK (audio_tags_changed_cb), self);
|
||||
g_signal_connect (self->playbin, "text-tags-changed",
|
||||
G_CALLBACK (subtitle_tags_changed_cb), self);
|
||||
}
|
||||
|
||||
g_signal_connect (self->playbin, "video-tags-changed",
|
||||
G_CALLBACK (video_tags_changed_cb), self);
|
||||
g_signal_connect (self->playbin, "audio-tags-changed",
|
||||
G_CALLBACK (audio_tags_changed_cb), self);
|
||||
g_signal_connect (self->playbin, "text-tags-changed",
|
||||
G_CALLBACK (subtitle_tags_changed_cb), self);
|
||||
g_signal_connect (self->playbin, "notify::volume",
|
||||
G_CALLBACK (volume_notify_cb), self);
|
||||
g_signal_connect (self->playbin, "notify::mute",
|
||||
|
@ -2924,6 +3234,19 @@ gst_player_stop_internal (GstPlayer * self, gboolean transient)
|
|||
self->seek_position = GST_CLOCK_TIME_NONE;
|
||||
self->last_seek_time = GST_CLOCK_TIME_NONE;
|
||||
self->rate = 1.0;
|
||||
if (self->collection) {
|
||||
if (self->stream_notify_id)
|
||||
g_signal_handler_disconnect (self->collection, self->stream_notify_id);
|
||||
self->stream_notify_id = 0;
|
||||
gst_object_unref (self->collection);
|
||||
self->collection = NULL;
|
||||
}
|
||||
g_free (self->video_sid);
|
||||
g_free (self->audio_sid);
|
||||
g_free (self->subtitle_sid);
|
||||
self->video_sid = NULL;
|
||||
self->audio_sid = NULL;
|
||||
self->subtitle_sid = NULL;
|
||||
g_mutex_unlock (&self->lock);
|
||||
}
|
||||
|
||||
|
@ -3383,8 +3706,15 @@ gst_player_get_current_audio_track (GstPlayer * self)
|
|||
if (!is_track_enabled (self, GST_PLAY_FLAG_AUDIO))
|
||||
return NULL;
|
||||
|
||||
info = (GstPlayerAudioInfo *) gst_player_stream_info_get_current (self,
|
||||
"current-audio", GST_TYPE_PLAYER_AUDIO_INFO);
|
||||
if (self->use_playbin3) {
|
||||
info = (GstPlayerAudioInfo *)
|
||||
gst_player_stream_info_get_current_from_stream_id (self,
|
||||
self->audio_sid, GST_TYPE_PLAYER_AUDIO_INFO);
|
||||
} else {
|
||||
info = (GstPlayerAudioInfo *) gst_player_stream_info_get_current (self,
|
||||
"current-audio", GST_TYPE_PLAYER_AUDIO_INFO);
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
|
@ -3408,8 +3738,15 @@ gst_player_get_current_video_track (GstPlayer * self)
|
|||
if (!is_track_enabled (self, GST_PLAY_FLAG_VIDEO))
|
||||
return NULL;
|
||||
|
||||
info = (GstPlayerVideoInfo *) gst_player_stream_info_get_current (self,
|
||||
"current-video", GST_TYPE_PLAYER_VIDEO_INFO);
|
||||
if (self->use_playbin3) {
|
||||
info = (GstPlayerVideoInfo *)
|
||||
gst_player_stream_info_get_current_from_stream_id (self,
|
||||
self->video_sid, GST_TYPE_PLAYER_VIDEO_INFO);
|
||||
} else {
|
||||
info = (GstPlayerVideoInfo *) gst_player_stream_info_get_current (self,
|
||||
"current-video", GST_TYPE_PLAYER_VIDEO_INFO);
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
|
@ -3433,11 +3770,45 @@ gst_player_get_current_subtitle_track (GstPlayer * self)
|
|||
if (!is_track_enabled (self, GST_PLAY_FLAG_SUBTITLE))
|
||||
return NULL;
|
||||
|
||||
info = (GstPlayerSubtitleInfo *) gst_player_stream_info_get_current (self,
|
||||
"current-text", GST_TYPE_PLAYER_SUBTITLE_INFO);
|
||||
if (self->use_playbin3) {
|
||||
info = (GstPlayerSubtitleInfo *)
|
||||
gst_player_stream_info_get_current_from_stream_id (self,
|
||||
self->subtitle_sid, GST_TYPE_PLAYER_SUBTITLE_INFO);
|
||||
} else {
|
||||
info = (GstPlayerSubtitleInfo *) gst_player_stream_info_get_current (self,
|
||||
"current-text", GST_TYPE_PLAYER_SUBTITLE_INFO);
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
/* Must be called with lock */
|
||||
static gboolean
|
||||
gst_player_select_streams (GstPlayer * self)
|
||||
{
|
||||
GList *stream_list = NULL;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
if (self->audio_sid)
|
||||
stream_list = g_list_append (stream_list, g_strdup (self->audio_sid));
|
||||
if (self->video_sid)
|
||||
stream_list = g_list_append (stream_list, g_strdup (self->video_sid));
|
||||
if (self->subtitle_sid)
|
||||
stream_list = g_list_append (stream_list, g_strdup (self->subtitle_sid));
|
||||
|
||||
g_mutex_unlock (&self->lock);
|
||||
if (stream_list) {
|
||||
ret = gst_element_send_event (self->playbin,
|
||||
gst_event_new_select_streams (stream_list));
|
||||
g_list_free_full (stream_list, g_free);
|
||||
} else {
|
||||
GST_ERROR_OBJECT (self, "No available streams for select-streams");
|
||||
}
|
||||
g_mutex_lock (&self->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_player_set_audio_track:
|
||||
* @player: #GstPlayer instance
|
||||
|
@ -3451,6 +3822,7 @@ gboolean
|
|||
gst_player_set_audio_track (GstPlayer * self, gint stream_index)
|
||||
{
|
||||
GstPlayerStreamInfo *info;
|
||||
gboolean ret = TRUE;
|
||||
|
||||
g_return_val_if_fail (GST_IS_PLAYER (self), 0);
|
||||
|
||||
|
@ -3463,9 +3835,19 @@ gst_player_set_audio_track (GstPlayer * self, gint stream_index)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
g_object_set (G_OBJECT (self->playbin), "current-audio", stream_index, NULL);
|
||||
if (self->use_playbin3) {
|
||||
g_mutex_lock (&self->lock);
|
||||
g_free (self->audio_sid);
|
||||
self->audio_sid = g_strdup (info->stream_id);
|
||||
ret = gst_player_select_streams (self);
|
||||
g_mutex_unlock (&self->lock);
|
||||
} else {
|
||||
g_object_set (G_OBJECT (self->playbin), "current-audio", stream_index,
|
||||
NULL);
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (self, "set stream index '%d'", stream_index);
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3481,6 +3863,7 @@ gboolean
|
|||
gst_player_set_video_track (GstPlayer * self, gint stream_index)
|
||||
{
|
||||
GstPlayerStreamInfo *info;
|
||||
gboolean ret = TRUE;
|
||||
|
||||
g_return_val_if_fail (GST_IS_PLAYER (self), 0);
|
||||
|
||||
|
@ -3494,9 +3877,19 @@ gst_player_set_video_track (GstPlayer * self, gint stream_index)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
g_object_set (G_OBJECT (self->playbin), "current-video", stream_index, NULL);
|
||||
if (self->use_playbin3) {
|
||||
g_mutex_lock (&self->lock);
|
||||
g_free (self->video_sid);
|
||||
self->video_sid = g_strdup (info->stream_id);
|
||||
ret = gst_player_select_streams (self);
|
||||
g_mutex_unlock (&self->lock);
|
||||
} else {
|
||||
g_object_set (G_OBJECT (self->playbin), "current-video", stream_index,
|
||||
NULL);
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (self, "set stream index '%d'", stream_index);
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3512,6 +3905,7 @@ gboolean
|
|||
gst_player_set_subtitle_track (GstPlayer * self, gint stream_index)
|
||||
{
|
||||
GstPlayerStreamInfo *info;
|
||||
gboolean ret = TRUE;
|
||||
|
||||
g_return_val_if_fail (GST_IS_PLAYER (self), 0);
|
||||
|
||||
|
@ -3524,9 +3918,18 @@ gst_player_set_subtitle_track (GstPlayer * self, gint stream_index)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
g_object_set (G_OBJECT (self->playbin), "current-text", stream_index, NULL);
|
||||
if (self->use_playbin3) {
|
||||
g_mutex_lock (&self->lock);
|
||||
g_free (self->subtitle_sid);
|
||||
self->subtitle_sid = g_strdup (info->stream_id);
|
||||
ret = gst_player_select_streams (self);
|
||||
g_mutex_unlock (&self->lock);
|
||||
} else {
|
||||
g_object_set (G_OBJECT (self->playbin), "current-text", stream_index, NULL);
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (self, "set stream index '%d'", stream_index);
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue