1From c193043d8bc9731674d2a055d5b3ce97c3e33ff2 Mon Sep 17 00:00:00 2001 2From: Jeffy Chen <jeffy.chen@rock-chips.com> 3Date: Tue, 20 Nov 2018 14:51:36 +0800 4Subject: [PATCH 05/14] playbin3: Fix Qt videoplayer cannot change video state 5 6Change-Id: I765bbe0caebe333855bd16fdd0843e0257491246 7Signed-off-by: shine.liu <shine.liu@rock-chips.com> 8Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> 9--- 10 gst/playback/gstplaybin3.c | 252 +++++++++++++++++++++++++++++++++++++ 11 1 file changed, 252 insertions(+) 12 13diff --git a/gst/playback/gstplaybin3.c b/gst/playback/gstplaybin3.c 14index 46eb478..f059474 100644 15--- a/gst/playback/gstplaybin3.c 16+++ b/gst/playback/gstplaybin3.c 17@@ -388,6 +388,16 @@ struct _GstPlayBin3Class 18 19 /* get the last video sample and convert it to the given caps */ 20 GstSample *(*convert_sample) (GstPlayBin3 * playbin, GstCaps * caps); 21+ 22+ /* notify app that number of audio/video/text streams changed */ 23+ void (*video_changed) (GstPlayBin3 * playbin); 24+ void (*audio_changed) (GstPlayBin3 * playbin); 25+ void (*text_changed) (GstPlayBin3 * playbin); 26+ 27+ /* get audio/video/text tags for a stream */ 28+ GstTagList *(*get_video_tags) (GstPlayBin3 * playbin, gint stream); 29+ GstTagList *(*get_audio_tags) (GstPlayBin3 * playbin, gint stream); 30+ GstTagList *(*get_text_tags) (GstPlayBin3 * playbin, gint stream); 31 }; 32 33 /* props */ 34@@ -421,6 +431,12 @@ enum 35 PROP_SUBURI, 36 PROP_CURRENT_SUBURI, 37 PROP_FLAGS, 38+ PROP_N_VIDEO, 39+ PROP_CURRENT_VIDEO, 40+ PROP_N_AUDIO, 41+ PROP_CURRENT_AUDIO, 42+ PROP_N_TEXT, 43+ PROP_CURRENT_TEXT, 44 PROP_SUBTITLE_ENCODING, 45 PROP_AUDIO_SINK, 46 PROP_VIDEO_SINK, 47@@ -454,6 +470,12 @@ enum 48 SIGNAL_CONVERT_SAMPLE, 49 SIGNAL_SOURCE_SETUP, 50 SIGNAL_ELEMENT_SETUP, 51+ SIGNAL_VIDEO_CHANGED, 52+ SIGNAL_AUDIO_CHANGED, 53+ SIGNAL_TEXT_CHANGED, 54+ SIGNAL_GET_VIDEO_TAGS, 55+ SIGNAL_GET_AUDIO_TAGS, 56+ SIGNAL_GET_TEXT_TAGS, 57 LAST_SIGNAL 58 }; 59 60@@ -473,6 +495,13 @@ static void gst_play_bin3_deep_element_added (GstBin * playbin, 61 static gboolean gst_play_bin3_send_event (GstElement * element, 62 GstEvent * event); 63 64+static GstTagList *gst_play_bin3_get_video_tags (GstPlayBin3 * playbin, 65+ gint stream); 66+static GstTagList *gst_play_bin3_get_audio_tags (GstPlayBin3 * playbin, 67+ gint stream); 68+static GstTagList *gst_play_bin3_get_text_tags (GstPlayBin3 * playbin, 69+ gint stream); 70+ 71 static GstSample *gst_play_bin3_convert_sample (GstPlayBin3 * playbin, 72 GstCaps * caps); 73 74@@ -610,6 +639,36 @@ gst_play_bin3_class_init (GstPlayBin3Class * klass) 75 GST_TYPE_PLAY_FLAGS, DEFAULT_FLAGS, 76 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); 77 78+ g_object_class_install_property (gobject_klass, PROP_N_VIDEO, 79+ g_param_spec_int ("n-video", "Number Video", 80+ "Total number of video streams", 0, G_MAXINT, 0, 81+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); 82+ 83+ g_object_class_install_property (gobject_klass, PROP_CURRENT_VIDEO, 84+ g_param_spec_int ("current-video", "Current Video", 85+ "Currently playing video stream (-1 = auto)", 86+ -1, G_MAXINT, -1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); 87+ 88+ g_object_class_install_property (gobject_klass, PROP_N_AUDIO, 89+ g_param_spec_int ("n-audio", "Number Audio", 90+ "Total number of audio streams", 0, G_MAXINT, 0, 91+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); 92+ 93+ g_object_class_install_property (gobject_klass, PROP_CURRENT_AUDIO, 94+ g_param_spec_int ("current-audio", "Current audio", 95+ "Currently playing audio stream (-1 = auto)", 96+ -1, G_MAXINT, -1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); 97+ 98+ g_object_class_install_property (gobject_klass, PROP_N_TEXT, 99+ g_param_spec_int ("n-text", "Number Text", 100+ "Total number of text streams", 0, G_MAXINT, 0, 101+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); 102+ 103+ g_object_class_install_property (gobject_klass, PROP_CURRENT_TEXT, 104+ g_param_spec_int ("current-text", "Current Text", 105+ "Currently playing text stream (-1 = auto)", 106+ -1, G_MAXINT, -1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); 107+ 108 g_object_class_install_property (gobject_klass, PROP_SUBTITLE_ENCODING, 109 g_param_spec_string ("subtitle-encoding", "subtitle encoding", 110 "Encoding to assume if input subtitles are not in UTF-8 encoding. " 111@@ -893,6 +952,41 @@ gst_play_bin3_class_init (GstPlayBin3Class * klass) 112 g_signal_new ("element-setup", G_TYPE_FROM_CLASS (klass), 113 G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, GST_TYPE_ELEMENT); 114 115+ gst_play_bin3_signals[SIGNAL_VIDEO_CHANGED] = 116+ g_signal_new ("video-changed", G_TYPE_FROM_CLASS (klass), 117+ G_SIGNAL_RUN_LAST, 118+ G_STRUCT_OFFSET (GstPlayBin3Class, video_changed), NULL, NULL, 119+ g_cclosure_marshal_generic, G_TYPE_NONE, 0, G_TYPE_NONE); 120+ 121+ gst_play_bin3_signals[SIGNAL_AUDIO_CHANGED] = 122+ g_signal_new ("audio-changed", G_TYPE_FROM_CLASS (klass), 123+ G_SIGNAL_RUN_LAST, 124+ G_STRUCT_OFFSET (GstPlayBin3Class, audio_changed), NULL, NULL, 125+ g_cclosure_marshal_generic, G_TYPE_NONE, 0, G_TYPE_NONE); 126+ 127+ gst_play_bin3_signals[SIGNAL_TEXT_CHANGED] = 128+ g_signal_new ("text-changed", G_TYPE_FROM_CLASS (klass), 129+ G_SIGNAL_RUN_LAST, 130+ G_STRUCT_OFFSET (GstPlayBin3Class, text_changed), NULL, NULL, 131+ g_cclosure_marshal_generic, G_TYPE_NONE, 0, G_TYPE_NONE); 132+ 133+ gst_play_bin3_signals[SIGNAL_GET_VIDEO_TAGS] = 134+ g_signal_new ("get-video-tags", G_TYPE_FROM_CLASS (klass), 135+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, 136+ G_STRUCT_OFFSET (GstPlayBin3Class, get_video_tags), NULL, NULL, 137+ g_cclosure_marshal_generic, GST_TYPE_TAG_LIST, 1, G_TYPE_INT); 138+ 139+ gst_play_bin3_signals[SIGNAL_GET_AUDIO_TAGS] = 140+ g_signal_new ("get-audio-tags", G_TYPE_FROM_CLASS (klass), 141+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, 142+ G_STRUCT_OFFSET (GstPlayBin3Class, get_audio_tags), NULL, NULL, 143+ g_cclosure_marshal_generic, GST_TYPE_TAG_LIST, 1, G_TYPE_INT); 144+ 145+ gst_play_bin3_signals[SIGNAL_GET_TEXT_TAGS] = 146+ g_signal_new ("get-text-tags", G_TYPE_FROM_CLASS (klass), 147+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, 148+ G_STRUCT_OFFSET (GstPlayBin3Class, get_text_tags), NULL, NULL, 149+ g_cclosure_marshal_generic, GST_TYPE_TAG_LIST, 1, G_TYPE_INT); 150 /** 151 * GstPlayBin3::convert-sample 152 * @playbin: a #GstPlayBin3 153@@ -914,6 +1008,10 @@ gst_play_bin3_class_init (GstPlayBin3Class * klass) 154 G_STRUCT_OFFSET (GstPlayBin3Class, convert_sample), NULL, NULL, 155 NULL, GST_TYPE_SAMPLE, 1, GST_TYPE_CAPS); 156 157+ klass->get_video_tags = gst_play_bin3_get_video_tags; 158+ klass->get_audio_tags = gst_play_bin3_get_audio_tags; 159+ klass->get_text_tags = gst_play_bin3_get_text_tags; 160+ 161 klass->convert_sample = gst_play_bin3_convert_sample; 162 163 gst_element_class_set_static_metadata (gstelement_klass, 164@@ -1232,6 +1330,73 @@ gst_play_bin3_set_flags (GstPlayBin3 * playbin, GstPlayFlags flags) 165 "use-buffering", ((flags & GST_PLAY_FLAG_BUFFERING) != 0), NULL); 166 } 167 168+static GstTagList * 169+get_tags (GstPlayBin3 * playbin, gint type, gint stream) 170+{ 171+ GstTagList *result; 172+ GPtrArray *channels; 173+ GstPad *sinkpad; 174+ 175+ switch (type) { 176+ case PLAYBIN_STREAM_AUDIO: 177+ channels = playbin->combiner[PLAYBIN_STREAM_AUDIO].streams; 178+ break; 179+ case PLAYBIN_STREAM_VIDEO: 180+ channels = playbin->combiner[PLAYBIN_STREAM_VIDEO].streams; 181+ break; 182+ case PLAYBIN_STREAM_TEXT: 183+ channels = playbin->combiner[PLAYBIN_STREAM_TEXT].streams; 184+ break; 185+ default: 186+ channels = NULL; 187+ break; 188+ } 189+ 190+ if (!channels || stream >= channels->len) 191+ return NULL; 192+ 193+ sinkpad = g_ptr_array_index (channels, stream); 194+ g_object_get (sinkpad, "tags", &result, NULL); 195+ 196+ return result; 197+} 198+ 199+static GstTagList * 200+gst_play_bin3_get_video_tags (GstPlayBin3 * playbin, gint stream) 201+{ 202+ GstTagList *result; 203+ 204+ GST_PLAY_BIN3_LOCK (playbin); 205+ result = get_tags (playbin, PLAYBIN_STREAM_VIDEO, stream); 206+ GST_PLAY_BIN3_UNLOCK (playbin); 207+ 208+ return result; 209+} 210+ 211+static GstTagList * 212+gst_play_bin3_get_audio_tags (GstPlayBin3 * playbin, gint stream) 213+{ 214+ GstTagList *result; 215+ 216+ GST_PLAY_BIN3_LOCK (playbin); 217+ result = get_tags (playbin, PLAYBIN_STREAM_AUDIO, stream); 218+ GST_PLAY_BIN3_UNLOCK (playbin); 219+ 220+ return result; 221+} 222+ 223+static GstTagList * 224+gst_play_bin3_get_text_tags (GstPlayBin3 * playbin, gint stream) 225+{ 226+ GstTagList *result; 227+ 228+ GST_PLAY_BIN3_LOCK (playbin); 229+ result = get_tags (playbin, PLAYBIN_STREAM_TEXT, stream); 230+ GST_PLAY_BIN3_UNLOCK (playbin); 231+ 232+ return result; 233+} 234+ 235 static GstSample * 236 gst_play_bin3_convert_sample (GstPlayBin3 * playbin, GstCaps * caps) 237 { 238@@ -1435,6 +1600,15 @@ gst_play_bin3_set_property (GObject * object, guint prop_id, 239 case PROP_FLAGS: 240 gst_play_bin3_set_flags (playbin, g_value_get_flags (value)); 241 break; 242+ case PROP_CURRENT_VIDEO: 243+ gst_play_bin3_set_current_video_stream (playbin, g_value_get_int (value)); 244+ break; 245+ case PROP_CURRENT_AUDIO: 246+ gst_play_bin3_set_current_audio_stream (playbin, g_value_get_int (value)); 247+ break; 248+ case PROP_CURRENT_TEXT: 249+ gst_play_bin3_set_current_text_stream (playbin, g_value_get_int (value)); 250+ break; 251 case PROP_SUBTITLE_ENCODING: 252 gst_play_bin3_set_encoding (playbin, g_value_get_string (value)); 253 break; 254@@ -1595,6 +1769,57 @@ gst_play_bin3_get_property (GObject * object, guint prop_id, GValue * value, 255 case PROP_FLAGS: 256 g_value_set_flags (value, gst_play_sink_get_flags (playbin->playsink)); 257 break; 258+ case PROP_N_VIDEO: 259+ { 260+ gint n_video; 261+ 262+ GST_PLAY_BIN3_LOCK (playbin); 263+ n_video = 264+ (playbin->combiner[PLAYBIN_STREAM_VIDEO].streams ? playbin-> 265+ combiner[PLAYBIN_STREAM_VIDEO].streams->len : 0); 266+ g_value_set_int (value, n_video); 267+ GST_PLAY_BIN3_UNLOCK (playbin); 268+ break; 269+ } 270+ case PROP_CURRENT_VIDEO: 271+ GST_PLAY_BIN3_LOCK (playbin); 272+ g_value_set_int (value, playbin->current_video); 273+ GST_PLAY_BIN3_UNLOCK (playbin); 274+ break; 275+ case PROP_N_AUDIO: 276+ { 277+ gint n_audio; 278+ 279+ GST_PLAY_BIN3_LOCK (playbin); 280+ n_audio = 281+ (playbin->combiner[PLAYBIN_STREAM_AUDIO].streams ? playbin-> 282+ combiner[PLAYBIN_STREAM_AUDIO].streams->len : 0); 283+ g_value_set_int (value, n_audio); 284+ GST_PLAY_BIN3_UNLOCK (playbin); 285+ break; 286+ } 287+ case PROP_CURRENT_AUDIO: 288+ GST_PLAY_BIN3_LOCK (playbin); 289+ g_value_set_int (value, playbin->current_audio); 290+ GST_PLAY_BIN3_UNLOCK (playbin); 291+ break; 292+ case PROP_N_TEXT: 293+ { 294+ gint n_text; 295+ 296+ GST_PLAY_BIN3_LOCK (playbin); 297+ n_text = 298+ (playbin->combiner[PLAYBIN_STREAM_TEXT].streams ? playbin-> 299+ combiner[PLAYBIN_STREAM_TEXT].streams->len : 0); 300+ g_value_set_int (value, n_text); 301+ GST_PLAY_BIN3_UNLOCK (playbin); 302+ break; 303+ } 304+ case PROP_CURRENT_TEXT: 305+ GST_PLAY_BIN3_LOCK (playbin); 306+ g_value_set_int (value, playbin->current_text); 307+ GST_PLAY_BIN3_UNLOCK (playbin); 308+ break; 309 case PROP_SUBTITLE_ENCODING: 310 GST_PLAY_BIN3_LOCK (playbin); 311 g_value_take_string (value, 312@@ -2429,6 +2654,7 @@ pad_added_cb (GstElement * uridecodebin, GstPad * pad, GstPlayBin3 * playbin) 313 gchar *pad_name; 314 GstPad *combine_pad; 315 GstStreamType selected, active, cur; 316+ gboolean changed = FALSE; 317 318 pad_name = gst_object_get_name (GST_OBJECT (pad)); 319 320@@ -2476,10 +2702,36 @@ pad_added_cb (GstElement * uridecodebin, GstPad * pad, GstPlayBin3 * playbin) 321 } 322 323 combine_pad = combiner_control_pad (playbin, combine, pad); 324+ if (combine_pad) 325+ changed = combine->combiner ? TRUE : FALSE; 326+ 327 control_source_pad (playbin, pad, combine_pad, combine->stream_type); 328 329 GST_PLAY_BIN3_UNLOCK (playbin); 330 331+ if (changed) { 332+ int signal; 333+ 334+ switch (combine->stream_type) { 335+ case GST_STREAM_TYPE_VIDEO: 336+ signal = SIGNAL_VIDEO_CHANGED; 337+ break; 338+ case GST_STREAM_TYPE_AUDIO: 339+ signal = SIGNAL_AUDIO_CHANGED; 340+ break; 341+ case GST_STREAM_TYPE_TEXT: 342+ signal = SIGNAL_TEXT_CHANGED; 343+ break; 344+ default: 345+ signal = -1; 346+ } 347+ 348+ if (signal >= 0) { 349+ g_signal_emit (G_OBJECT (playbin), gst_play_bin3_signals[signal], 0, 350+ NULL); 351+ } 352+ } 353+ 354 return; 355 356 /* ERRORS */ 357-- 3582.20.1 359 360