1From 14aeb6ae37c0f137d7f3038efc51d25f8f371751 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/11] 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 | 256 ++++++++++++++++++++++++++++++++++++- 11 1 file changed, 252 insertions(+), 4 deletions(-) 12 13diff --git a/gst/playback/gstplaybin3.c b/gst/playback/gstplaybin3.c 14index a732160..c22d9db 100644 15--- a/gst/playback/gstplaybin3.c 16+++ b/gst/playback/gstplaybin3.c 17@@ -532,6 +532,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@@ -565,6 +575,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@@ -597,6 +613,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@@ -621,6 +643,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@@ -755,6 +784,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@@ -1024,6 +1083,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@@ -1045,6 +1139,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@@ -1559,6 +1657,72 @@ get_group (GstPlayBin3 * playbin) 165 return result; 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@@ -1772,6 +1936,15 @@ gst_play_bin3_set_property (GObject * object, guint prop_id, 238 GST_SOURCE_GROUP_UNLOCK (playbin->curr_group); 239 } 240 break; 241+ case PROP_CURRENT_VIDEO: 242+ gst_play_bin3_set_current_video_stream (playbin, g_value_get_int (value)); 243+ break; 244+ case PROP_CURRENT_AUDIO: 245+ gst_play_bin3_set_current_audio_stream (playbin, g_value_get_int (value)); 246+ break; 247+ case PROP_CURRENT_TEXT: 248+ gst_play_bin3_set_current_text_stream (playbin, g_value_get_int (value)); 249+ break; 250 case PROP_SUBTITLE_ENCODING: 251 gst_play_bin3_set_encoding (playbin, g_value_get_string (value)); 252 break; 253@@ -1960,6 +2133,57 @@ gst_play_bin3_get_property (GObject * object, guint prop_id, GValue * value, 254 case PROP_FLAGS: 255 g_value_set_flags (value, gst_play_bin3_get_flags (playbin)); 256 break; 257+ case PROP_N_VIDEO: 258+ { 259+ gint n_video; 260+ 261+ GST_PLAY_BIN3_LOCK (playbin); 262+ n_video = 263+ (playbin->combiner[PLAYBIN_STREAM_VIDEO].streams ? playbin-> 264+ combiner[PLAYBIN_STREAM_VIDEO].streams->len : 0); 265+ g_value_set_int (value, n_video); 266+ GST_PLAY_BIN3_UNLOCK (playbin); 267+ break; 268+ } 269+ case PROP_CURRENT_VIDEO: 270+ GST_PLAY_BIN3_LOCK (playbin); 271+ g_value_set_int (value, playbin->current_video); 272+ GST_PLAY_BIN3_UNLOCK (playbin); 273+ break; 274+ case PROP_N_AUDIO: 275+ { 276+ gint n_audio; 277+ 278+ GST_PLAY_BIN3_LOCK (playbin); 279+ n_audio = 280+ (playbin->combiner[PLAYBIN_STREAM_AUDIO].streams ? playbin-> 281+ combiner[PLAYBIN_STREAM_AUDIO].streams->len : 0); 282+ g_value_set_int (value, n_audio); 283+ GST_PLAY_BIN3_UNLOCK (playbin); 284+ break; 285+ } 286+ case PROP_CURRENT_AUDIO: 287+ GST_PLAY_BIN3_LOCK (playbin); 288+ g_value_set_int (value, playbin->current_audio); 289+ GST_PLAY_BIN3_UNLOCK (playbin); 290+ break; 291+ case PROP_N_TEXT: 292+ { 293+ gint n_text; 294+ 295+ GST_PLAY_BIN3_LOCK (playbin); 296+ n_text = 297+ (playbin->combiner[PLAYBIN_STREAM_TEXT].streams ? playbin-> 298+ combiner[PLAYBIN_STREAM_TEXT].streams->len : 0); 299+ g_value_set_int (value, n_text); 300+ GST_PLAY_BIN3_UNLOCK (playbin); 301+ break; 302+ } 303+ case PROP_CURRENT_TEXT: 304+ GST_PLAY_BIN3_LOCK (playbin); 305+ g_value_set_int (value, playbin->current_text); 306+ GST_PLAY_BIN3_UNLOCK (playbin); 307+ break; 308 case PROP_SUBTITLE_ENCODING: 309 GST_PLAY_BIN3_LOCK (playbin); 310 g_value_take_string (value, 311@@ -2569,9 +2793,7 @@ gst_play_bin3_handle_message (GstBin * bin, GstMessage * msg) 312 if (target_group) 313 gst_object_replace ((GstObject **) & target_group->collection, 314 (GstObject *) collection); 315- /* FIXME: Only do the following if it's the current group? */ 316- if (target_group == playbin->curr_group) 317- update_combiner_info (playbin, target_group->collection); 318+ update_combiner_info (playbin, target_group->collection); 319 if (pstate) 320 playbin->do_stream_selections = FALSE; 321 do_stream_selection (playbin, target_group); 322@@ -3068,6 +3290,8 @@ pad_added_cb (GstElement * uridecodebin, GstPad * pad, GstSourceGroup * group) 323 gchar *pad_name; 324 GstPlayBin3 *playbin = group->playbin; 325 326+ gboolean changed = FALSE; 327+ 328 GST_PLAY_BIN3_SHUTDOWN_LOCK (playbin, shutdown); 329 330 pad_name = gst_object_get_name (GST_OBJECT (pad)); 331@@ -3096,7 +3320,8 @@ pad_added_cb (GstElement * uridecodebin, GstPad * pad, GstSourceGroup * group) 332 333 combine = &playbin->combiner[pb_stream_type]; 334 335- combiner_control_pad (playbin, combine, pad); 336+ if (combiner_control_pad (playbin, combine, pad)) 337+ changed = combine->combiner ? TRUE : FALSE; 338 339 control_source_pad (group, pad, combine->stream_type); 340 341@@ -3111,6 +3336,29 @@ pad_added_cb (GstElement * uridecodebin, GstPad * pad, GstSourceGroup * group) 342 343 GST_PLAY_BIN3_SHUTDOWN_UNLOCK (playbin); 344 345+ if (changed) { 346+ int signal; 347+ 348+ switch (combine->type) { 349+ case GST_PLAY_SINK_TYPE_VIDEO: 350+ signal = SIGNAL_VIDEO_CHANGED; 351+ break; 352+ case GST_PLAY_SINK_TYPE_AUDIO: 353+ signal = SIGNAL_AUDIO_CHANGED; 354+ break; 355+ case GST_PLAY_SINK_TYPE_TEXT: 356+ signal = SIGNAL_TEXT_CHANGED; 357+ break; 358+ default: 359+ signal = -1; 360+ } 361+ 362+ if (signal >= 0) { 363+ g_signal_emit (G_OBJECT (playbin), gst_play_bin3_signals[signal], 0, 364+ NULL); 365+ } 366+ } 367+ 368 return; 369 370 /* ERRORS */ 371-- 3722.20.1 373 374