From 7cd226beb3d0b95be6e7419af2a3ef439ccba985 Mon Sep 17 00:00:00 2001
|
From: Jeffy Chen <jeffy.chen@rock-chips.com>
|
Date: Tue, 20 Nov 2018 14:51:36 +0800
|
Subject: [PATCH 05/11] playbin3: Fix qt videoplayer cannot change video state
|
|
Change-Id: I765bbe0caebe333855bd16fdd0843e0257491246
|
Signed-off-by: shine.liu <shine.liu@rock-chips.com>
|
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
|
---
|
gst/playback/gstplaybin3.c | 256 ++++++++++++++++++++++++++++++++++++-
|
1 file changed, 252 insertions(+), 4 deletions(-)
|
|
diff --git a/gst/playback/gstplaybin3.c b/gst/playback/gstplaybin3.c
|
index e86eb627b..dd8284ee0 100644
|
--- a/gst/playback/gstplaybin3.c
|
+++ b/gst/playback/gstplaybin3.c
|
@@ -530,6 +530,16 @@ struct _GstPlayBin3Class
|
|
/* get the last video sample and convert it to the given caps */
|
GstSample *(*convert_sample) (GstPlayBin3 * playbin, GstCaps * caps);
|
+
|
+ /* notify app that number of audio/video/text streams changed */
|
+ void (*video_changed) (GstPlayBin3 * playbin);
|
+ void (*audio_changed) (GstPlayBin3 * playbin);
|
+ void (*text_changed) (GstPlayBin3 * playbin);
|
+
|
+ /* get audio/video/text tags for a stream */
|
+ GstTagList *(*get_video_tags) (GstPlayBin3 * playbin, gint stream);
|
+ GstTagList *(*get_audio_tags) (GstPlayBin3 * playbin, gint stream);
|
+ GstTagList *(*get_text_tags) (GstPlayBin3 * playbin, gint stream);
|
};
|
|
/* props */
|
@@ -563,6 +573,12 @@ enum
|
PROP_SUBURI,
|
PROP_CURRENT_SUBURI,
|
PROP_FLAGS,
|
+ PROP_N_VIDEO,
|
+ PROP_CURRENT_VIDEO,
|
+ PROP_N_AUDIO,
|
+ PROP_CURRENT_AUDIO,
|
+ PROP_N_TEXT,
|
+ PROP_CURRENT_TEXT,
|
PROP_SUBTITLE_ENCODING,
|
PROP_AUDIO_SINK,
|
PROP_VIDEO_SINK,
|
@@ -595,6 +611,12 @@ enum
|
SIGNAL_CONVERT_SAMPLE,
|
SIGNAL_SOURCE_SETUP,
|
SIGNAL_ELEMENT_SETUP,
|
+ SIGNAL_VIDEO_CHANGED,
|
+ SIGNAL_AUDIO_CHANGED,
|
+ SIGNAL_TEXT_CHANGED,
|
+ SIGNAL_GET_VIDEO_TAGS,
|
+ SIGNAL_GET_AUDIO_TAGS,
|
+ SIGNAL_GET_TEXT_TAGS,
|
LAST_SIGNAL
|
};
|
|
@@ -619,6 +641,13 @@ static void gst_play_bin3_deep_element_added (GstBin * playbin,
|
static gboolean gst_play_bin3_send_event (GstElement * element,
|
GstEvent * event);
|
|
+static GstTagList *gst_play_bin3_get_video_tags (GstPlayBin3 * playbin,
|
+ gint stream);
|
+static GstTagList *gst_play_bin3_get_audio_tags (GstPlayBin3 * playbin,
|
+ gint stream);
|
+static GstTagList *gst_play_bin3_get_text_tags (GstPlayBin3 * playbin,
|
+ gint stream);
|
+
|
static GstSample *gst_play_bin3_convert_sample (GstPlayBin3 * playbin,
|
GstCaps * caps);
|
|
@@ -753,6 +782,36 @@ gst_play_bin3_class_init (GstPlayBin3Class * klass)
|
GST_TYPE_PLAY_FLAGS, DEFAULT_FLAGS,
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
|
+ g_object_class_install_property (gobject_klass, PROP_N_VIDEO,
|
+ g_param_spec_int ("n-video", "Number Video",
|
+ "Total number of video streams", 0, G_MAXINT, 0,
|
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
+
|
+ g_object_class_install_property (gobject_klass, PROP_CURRENT_VIDEO,
|
+ g_param_spec_int ("current-video", "Current Video",
|
+ "Currently playing video stream (-1 = auto)",
|
+ -1, G_MAXINT, -1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
+
|
+ g_object_class_install_property (gobject_klass, PROP_N_AUDIO,
|
+ g_param_spec_int ("n-audio", "Number Audio",
|
+ "Total number of audio streams", 0, G_MAXINT, 0,
|
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
+
|
+ g_object_class_install_property (gobject_klass, PROP_CURRENT_AUDIO,
|
+ g_param_spec_int ("current-audio", "Current audio",
|
+ "Currently playing audio stream (-1 = auto)",
|
+ -1, G_MAXINT, -1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
+
|
+ g_object_class_install_property (gobject_klass, PROP_N_TEXT,
|
+ g_param_spec_int ("n-text", "Number Text",
|
+ "Total number of text streams", 0, G_MAXINT, 0,
|
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
+
|
+ g_object_class_install_property (gobject_klass, PROP_CURRENT_TEXT,
|
+ g_param_spec_int ("current-text", "Current Text",
|
+ "Currently playing text stream (-1 = auto)",
|
+ -1, G_MAXINT, -1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
+
|
g_object_class_install_property (gobject_klass, PROP_SUBTITLE_ENCODING,
|
g_param_spec_string ("subtitle-encoding", "subtitle encoding",
|
"Encoding to assume if input subtitles are not in UTF-8 encoding. "
|
@@ -1022,6 +1081,41 @@ gst_play_bin3_class_init (GstPlayBin3Class * klass)
|
g_signal_new ("element-setup", G_TYPE_FROM_CLASS (klass),
|
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
|
|
+ gst_play_bin3_signals[SIGNAL_VIDEO_CHANGED] =
|
+ g_signal_new ("video-changed", G_TYPE_FROM_CLASS (klass),
|
+ G_SIGNAL_RUN_LAST,
|
+ G_STRUCT_OFFSET (GstPlayBin3Class, video_changed), NULL, NULL,
|
+ g_cclosure_marshal_generic, G_TYPE_NONE, 0, G_TYPE_NONE);
|
+
|
+ gst_play_bin3_signals[SIGNAL_AUDIO_CHANGED] =
|
+ g_signal_new ("audio-changed", G_TYPE_FROM_CLASS (klass),
|
+ G_SIGNAL_RUN_LAST,
|
+ G_STRUCT_OFFSET (GstPlayBin3Class, audio_changed), NULL, NULL,
|
+ g_cclosure_marshal_generic, G_TYPE_NONE, 0, G_TYPE_NONE);
|
+
|
+ gst_play_bin3_signals[SIGNAL_TEXT_CHANGED] =
|
+ g_signal_new ("text-changed", G_TYPE_FROM_CLASS (klass),
|
+ G_SIGNAL_RUN_LAST,
|
+ G_STRUCT_OFFSET (GstPlayBin3Class, text_changed), NULL, NULL,
|
+ g_cclosure_marshal_generic, G_TYPE_NONE, 0, G_TYPE_NONE);
|
+
|
+ gst_play_bin3_signals[SIGNAL_GET_VIDEO_TAGS] =
|
+ g_signal_new ("get-video-tags", G_TYPE_FROM_CLASS (klass),
|
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
|
+ G_STRUCT_OFFSET (GstPlayBin3Class, get_video_tags), NULL, NULL,
|
+ g_cclosure_marshal_generic, GST_TYPE_TAG_LIST, 1, G_TYPE_INT);
|
+
|
+ gst_play_bin3_signals[SIGNAL_GET_AUDIO_TAGS] =
|
+ g_signal_new ("get-audio-tags", G_TYPE_FROM_CLASS (klass),
|
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
|
+ G_STRUCT_OFFSET (GstPlayBin3Class, get_audio_tags), NULL, NULL,
|
+ g_cclosure_marshal_generic, GST_TYPE_TAG_LIST, 1, G_TYPE_INT);
|
+
|
+ gst_play_bin3_signals[SIGNAL_GET_TEXT_TAGS] =
|
+ g_signal_new ("get-text-tags", G_TYPE_FROM_CLASS (klass),
|
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
|
+ G_STRUCT_OFFSET (GstPlayBin3Class, get_text_tags), NULL, NULL,
|
+ g_cclosure_marshal_generic, GST_TYPE_TAG_LIST, 1, G_TYPE_INT);
|
/**
|
* GstPlayBin3::convert-sample
|
* @playbin: a #GstPlayBin3
|
@@ -1043,6 +1137,10 @@ gst_play_bin3_class_init (GstPlayBin3Class * klass)
|
G_STRUCT_OFFSET (GstPlayBin3Class, convert_sample), NULL, NULL,
|
NULL, GST_TYPE_SAMPLE, 1, GST_TYPE_CAPS);
|
|
+ klass->get_video_tags = gst_play_bin3_get_video_tags;
|
+ klass->get_audio_tags = gst_play_bin3_get_audio_tags;
|
+ klass->get_text_tags = gst_play_bin3_get_text_tags;
|
+
|
klass->convert_sample = gst_play_bin3_convert_sample;
|
|
gst_element_class_set_static_metadata (gstelement_klass,
|
@@ -1553,6 +1651,72 @@ get_group (GstPlayBin3 * playbin)
|
return result;
|
}
|
|
+static GstTagList *
|
+get_tags (GstPlayBin3 * playbin, gint type, gint stream)
|
+{
|
+ GstTagList *result;
|
+ GPtrArray *channels;
|
+ GstPad *sinkpad;
|
+
|
+ switch (type) {
|
+ case PLAYBIN_STREAM_AUDIO:
|
+ channels = playbin->combiner[PLAYBIN_STREAM_AUDIO].streams;
|
+ break;
|
+ case PLAYBIN_STREAM_VIDEO:
|
+ channels = playbin->combiner[PLAYBIN_STREAM_VIDEO].streams;
|
+ break;
|
+ case PLAYBIN_STREAM_TEXT:
|
+ channels = playbin->combiner[PLAYBIN_STREAM_TEXT].streams;
|
+ break;
|
+ default:
|
+ channels = NULL;
|
+ break;
|
+ }
|
+
|
+ if (!channels || stream >= channels->len)
|
+ return NULL;
|
+
|
+ sinkpad = g_ptr_array_index (channels, stream);
|
+ g_object_get (sinkpad, "tags", &result, NULL);
|
+
|
+ return result;
|
+}
|
+
|
+static GstTagList *
|
+gst_play_bin3_get_video_tags (GstPlayBin3 * playbin, gint stream)
|
+{
|
+ GstTagList *result;
|
+
|
+ GST_PLAY_BIN3_LOCK (playbin);
|
+ result = get_tags (playbin, PLAYBIN_STREAM_VIDEO, stream);
|
+ GST_PLAY_BIN3_UNLOCK (playbin);
|
+
|
+ return result;
|
+}
|
+
|
+static GstTagList *
|
+gst_play_bin3_get_audio_tags (GstPlayBin3 * playbin, gint stream)
|
+{
|
+ GstTagList *result;
|
+
|
+ GST_PLAY_BIN3_LOCK (playbin);
|
+ result = get_tags (playbin, PLAYBIN_STREAM_AUDIO, stream);
|
+ GST_PLAY_BIN3_UNLOCK (playbin);
|
+
|
+ return result;
|
+}
|
+
|
+static GstTagList *
|
+gst_play_bin3_get_text_tags (GstPlayBin3 * playbin, gint stream)
|
+{
|
+ GstTagList *result;
|
+
|
+ GST_PLAY_BIN3_LOCK (playbin);
|
+ result = get_tags (playbin, PLAYBIN_STREAM_TEXT, stream);
|
+ GST_PLAY_BIN3_UNLOCK (playbin);
|
+
|
+ return result;
|
+}
|
|
static GstSample *
|
gst_play_bin3_convert_sample (GstPlayBin3 * playbin, GstCaps * caps)
|
@@ -1766,6 +1930,15 @@ gst_play_bin3_set_property (GObject * object, guint prop_id,
|
GST_SOURCE_GROUP_UNLOCK (playbin->curr_group);
|
}
|
break;
|
+ case PROP_CURRENT_VIDEO:
|
+ gst_play_bin3_set_current_video_stream (playbin, g_value_get_int (value));
|
+ break;
|
+ case PROP_CURRENT_AUDIO:
|
+ gst_play_bin3_set_current_audio_stream (playbin, g_value_get_int (value));
|
+ break;
|
+ case PROP_CURRENT_TEXT:
|
+ gst_play_bin3_set_current_text_stream (playbin, g_value_get_int (value));
|
+ break;
|
case PROP_SUBTITLE_ENCODING:
|
gst_play_bin3_set_encoding (playbin, g_value_get_string (value));
|
break;
|
@@ -1954,6 +2127,57 @@ gst_play_bin3_get_property (GObject * object, guint prop_id, GValue * value,
|
case PROP_FLAGS:
|
g_value_set_flags (value, gst_play_bin3_get_flags (playbin));
|
break;
|
+ case PROP_N_VIDEO:
|
+ {
|
+ gint n_video;
|
+
|
+ GST_PLAY_BIN3_LOCK (playbin);
|
+ n_video =
|
+ (playbin->combiner[PLAYBIN_STREAM_VIDEO].streams ? playbin->
|
+ combiner[PLAYBIN_STREAM_VIDEO].streams->len : 0);
|
+ g_value_set_int (value, n_video);
|
+ GST_PLAY_BIN3_UNLOCK (playbin);
|
+ break;
|
+ }
|
+ case PROP_CURRENT_VIDEO:
|
+ GST_PLAY_BIN3_LOCK (playbin);
|
+ g_value_set_int (value, playbin->current_video);
|
+ GST_PLAY_BIN3_UNLOCK (playbin);
|
+ break;
|
+ case PROP_N_AUDIO:
|
+ {
|
+ gint n_audio;
|
+
|
+ GST_PLAY_BIN3_LOCK (playbin);
|
+ n_audio =
|
+ (playbin->combiner[PLAYBIN_STREAM_AUDIO].streams ? playbin->
|
+ combiner[PLAYBIN_STREAM_AUDIO].streams->len : 0);
|
+ g_value_set_int (value, n_audio);
|
+ GST_PLAY_BIN3_UNLOCK (playbin);
|
+ break;
|
+ }
|
+ case PROP_CURRENT_AUDIO:
|
+ GST_PLAY_BIN3_LOCK (playbin);
|
+ g_value_set_int (value, playbin->current_audio);
|
+ GST_PLAY_BIN3_UNLOCK (playbin);
|
+ break;
|
+ case PROP_N_TEXT:
|
+ {
|
+ gint n_text;
|
+
|
+ GST_PLAY_BIN3_LOCK (playbin);
|
+ n_text =
|
+ (playbin->combiner[PLAYBIN_STREAM_TEXT].streams ? playbin->
|
+ combiner[PLAYBIN_STREAM_TEXT].streams->len : 0);
|
+ g_value_set_int (value, n_text);
|
+ GST_PLAY_BIN3_UNLOCK (playbin);
|
+ break;
|
+ }
|
+ case PROP_CURRENT_TEXT:
|
+ GST_PLAY_BIN3_LOCK (playbin);
|
+ g_value_set_int (value, playbin->current_text);
|
+ GST_PLAY_BIN3_UNLOCK (playbin);
|
+ break;
|
case PROP_SUBTITLE_ENCODING:
|
GST_PLAY_BIN3_LOCK (playbin);
|
g_value_take_string (value,
|
@@ -2539,9 +2763,7 @@ gst_play_bin3_handle_message (GstBin * bin, GstMessage * msg)
|
if (target_group)
|
gst_object_replace ((GstObject **) & target_group->collection,
|
(GstObject *) collection);
|
- /* FIXME: Only do the following if it's the current group? */
|
- if (target_group == playbin->curr_group)
|
- update_combiner_info (playbin, target_group->collection);
|
+ update_combiner_info (playbin, target_group->collection);
|
if (pstate)
|
playbin->do_stream_selections = FALSE;
|
do_stream_selection (playbin, target_group);
|
@@ -3038,6 +3260,8 @@ pad_added_cb (GstElement * uridecodebin, GstPad * pad, GstSourceGroup * group)
|
gchar *pad_name;
|
GstPlayBin3 *playbin = group->playbin;
|
|
+ gboolean changed = FALSE;
|
+
|
GST_PLAY_BIN3_SHUTDOWN_LOCK (playbin, shutdown);
|
|
pad_name = gst_object_get_name (GST_OBJECT (pad));
|
@@ -3066,7 +3290,8 @@ pad_added_cb (GstElement * uridecodebin, GstPad * pad, GstSourceGroup * group)
|
|
combine = &playbin->combiner[pb_stream_type];
|
|
- combiner_control_pad (playbin, combine, pad);
|
+ if (combiner_control_pad (playbin, combine, pad))
|
+ changed = combine->combiner ? TRUE : FALSE;
|
|
control_source_pad (group, pad, combine->stream_type);
|
|
@@ -3081,6 +3306,29 @@ pad_added_cb (GstElement * uridecodebin, GstPad * pad, GstSourceGroup * group)
|
|
GST_PLAY_BIN3_SHUTDOWN_UNLOCK (playbin);
|
|
+ if (changed) {
|
+ int signal;
|
+
|
+ switch (combine->type) {
|
+ case GST_PLAY_SINK_TYPE_VIDEO:
|
+ signal = SIGNAL_VIDEO_CHANGED;
|
+ break;
|
+ case GST_PLAY_SINK_TYPE_AUDIO:
|
+ signal = SIGNAL_AUDIO_CHANGED;
|
+ break;
|
+ case GST_PLAY_SINK_TYPE_TEXT:
|
+ signal = SIGNAL_TEXT_CHANGED;
|
+ break;
|
+ default:
|
+ signal = -1;
|
+ }
|
+
|
+ if (signal >= 0) {
|
+ g_signal_emit (G_OBJECT (playbin), gst_play_bin3_signals[signal], 0,
|
+ NULL);
|
+ }
|
+ }
|
+
|
return;
|
|
/* ERRORS */
|
--
|
2.20.1
|