1 /* GStreamer
2 * Copyright (C) <2006> Edward Hervey <edward@fluendo.com>
3 * Copyright (C) <2009> Sebastian Dröge <sebastian.droege@collabora.co.uk>
4 * Copyright (C) <2011> Hewlett-Packard Development Company, L.P.
5 * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
6 * Copyright (C) <2013> Collabora Ltd.
7 * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23 */
24
25 /**
26 * SECTION:element-decodebin
27 * @title: decodebin
28 *
29 * #GstBin that auto-magically constructs a decoding pipeline using available
30 * decoders and demuxers via auto-plugging.
31 *
32 * decodebin is considered stable now and replaces the old #decodebin element.
33 * #uridecodebin uses decodebin internally and is often more convenient to
34 * use, as it creates a suitable source element as well.
35 */
36
37 /* Implementation notes:
38 *
39 * The following section describes how decodebin works internally.
40 *
41 * The first part of decodebin is its typefind element, which tries
42 * to determine the media type of the input stream. If the type is found
43 * autoplugging starts.
44 *
45 * decodebin internally organizes the elements it autoplugged into GstDecodeChains
46 * and GstDecodeGroups. A decode chain is a single chain of decoding, this
47 * means that if decodebin every autoplugs an element with two+ srcpads
48 * (e.g. a demuxer) this will end the chain and everything following this
49 * demuxer will be put into decode groups below the chain. Otherwise,
50 * if an element has a single srcpad that outputs raw data the decode chain
51 * is ended too and a GstDecodePad is stored and blocked.
52 *
53 * A decode group combines a number of chains that are created by a
54 * demuxer element. All those chains are connected through a multiqueue to
55 * the demuxer. A new group for the same demuxer is only created if the
56 * demuxer has signaled no-more-pads, in which case all following pads
57 * create a new chain in the new group.
58 *
59 * This continues until the top-level decode chain is complete. A decode
60 * chain is complete if it either ends with a blocked endpad, if autoplugging
61 * stopped because no suitable plugins could be found or if the active group
62 * is complete. A decode group on the other hand is complete if all child
63 * chains are complete.
64 *
65 * If this happens at some point, all endpads of all active groups are exposed.
66 * For this decodebin adds the endpads, signals no-more-pads and then unblocks
67 * them. Now playback starts.
68 *
69 * If one of the chains that end on a endpad receives EOS decodebin checks
70 * if all chains and groups are drained. In that case everything goes into EOS.
71 * If there is a chain where the active group is drained but there exist next
72 * groups, the active group is hidden (endpads are removed) and the next group
73 * is exposed. This means that in some cases more pads may be created even
74 * after the initial no-more-pads signal. This happens for example with
75 * so-called "chained oggs", most commonly found among ogg/vorbis internet
76 * radio streams.
77 *
78 * Note 1: If we're talking about blocked endpads this really means that the
79 * *target* pads of the endpads are blocked. Pads that are exposed to the outside
80 * should never ever be blocked!
81 *
82 * Note 2: If a group is complete and the parent's chain demuxer adds new pads
83 * but never signaled no-more-pads this additional pads will be ignored!
84 *
85 */
86
87 /* FIXME 0.11: suppress warnings for deprecated API such as GValueArray
88 * with newer GLib versions (>= 2.31.0) */
89 #define GLIB_DISABLE_DEPRECATION_WARNINGS
90
91 #ifdef HAVE_CONFIG_H
92 #include "config.h"
93 #endif
94
95 #include <gst/gst-i18n-plugin.h>
96
97 #include <string.h>
98 #include <gst/gst.h>
99 #include <gst/pbutils/pbutils.h>
100
101 #include "gstplay-enum.h"
102 #include "gstplayback.h"
103 #include "gstrawcaps.h"
104 #include "gstplaybackutils.h"
105
106 /* generic templates */
107 static GstStaticPadTemplate decoder_bin_sink_template =
108 GST_STATIC_PAD_TEMPLATE ("sink",
109 GST_PAD_SINK,
110 GST_PAD_ALWAYS,
111 GST_STATIC_CAPS_ANY);
112
113 static GstStaticPadTemplate decoder_bin_src_template =
114 GST_STATIC_PAD_TEMPLATE ("src_%u",
115 GST_PAD_SRC,
116 GST_PAD_SOMETIMES,
117 GST_STATIC_CAPS_ANY);
118
119 GST_DEBUG_CATEGORY_STATIC (gst_decode_bin_debug);
120 #define GST_CAT_DEFAULT gst_decode_bin_debug
121
122 typedef struct _GstPendingPad GstPendingPad;
123 typedef struct _GstDecodeElement GstDecodeElement;
124 typedef struct _GstDemuxerPad GstDemuxerPad;
125 typedef struct _GstDecodeChain GstDecodeChain;
126 typedef struct _GstDecodeGroup GstDecodeGroup;
127 typedef struct _GstDecodePad GstDecodePad;
128 typedef GstGhostPadClass GstDecodePadClass;
129 typedef struct _GstDecodeBin GstDecodeBin;
130 typedef struct _GstDecodeBinClass GstDecodeBinClass;
131
132 #define GST_TYPE_DECODE_BIN (gst_decode_bin_get_type())
133 #define GST_DECODE_BIN_CAST(obj) ((GstDecodeBin*)(obj))
134 #define GST_DECODE_BIN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DECODE_BIN,GstDecodeBin))
135 #define GST_DECODE_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DECODE_BIN,GstDecodeBinClass))
136 #define GST_IS_DECODE_BIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DECODE_BIN))
137 #define GST_IS_DECODE_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DECODE_BIN))
138
139 /**
140 * GstDecodeBin:
141 *
142 * The opaque #GstDecodeBin data structure
143 */
144 struct _GstDecodeBin
145 {
146 GstBin bin; /* we extend GstBin */
147
148 /* properties */
149 GstCaps *caps; /* caps on which to stop decoding */
150 gchar *encoding; /* encoding of subtitles */
151 gboolean use_buffering; /* configure buffering on multiqueues */
152 gint low_percent;
153 gint high_percent;
154 guint max_size_bytes;
155 guint max_size_buffers;
156 guint64 max_size_time;
157 gboolean post_stream_topology;
158 guint64 connection_speed;
159
160 GstElement *typefind; /* this holds the typefind object */
161
162 GMutex expose_lock; /* Protects exposal and removal of groups */
163 GstDecodeChain *decode_chain; /* Top level decode chain */
164 guint nbpads; /* unique identifier for source pads */
165
166 GMutex factories_lock;
167 guint32 factories_cookie; /* Cookie from last time when factories was updated */
168 GList *factories; /* factories we can use for selecting elements */
169
170 GMutex subtitle_lock; /* Protects changes to subtitles and encoding */
171 GList *subtitles; /* List of elements with subtitle-encoding,
172 * protected by above mutex! */
173
174 gboolean have_type; /* if we received the have_type signal */
175 guint have_type_id; /* signal id for have-type from typefind */
176
177 gboolean async_pending; /* async-start has been emitted */
178
179 GMutex dyn_lock; /* lock protecting pad blocking */
180 gboolean shutdown; /* if we are shutting down */
181 GList *blocked_pads; /* pads that have set to block */
182
183 gboolean expose_allstreams; /* Whether to expose unknow type streams or not */
184
185 GList *filtered; /* elements for which error messages are filtered */
186 GList *filtered_errors; /* filtered error messages */
187
188 GList *buffering_status; /* element currently buffering messages */
189 GMutex buffering_lock;
190 GMutex buffering_post_lock;
191
192 GMutex cleanup_lock; /* Mutex used to protect the cleanup thread */
193 GThread *cleanup_thread; /* thread used to free chains asynchronously.
194 * We store it to make sure we end up joining it
195 * before stopping the element.
196 * Protected by the object lock */
197 GList *cleanup_groups; /* List of groups to free */
198
199 #ifdef OHOS_EXT_FUNC
200 // ohos.ext.func.0013
201 guint mq_num_use_buffering;
202 #endif
203 };
204
205 struct _GstDecodeBinClass
206 {
207 GstBinClass parent_class;
208
209 /* signal fired when we found a pad that we cannot decode */
210 void (*unknown_type) (GstElement * element, GstPad * pad, GstCaps * caps);
211
212 /* signal fired to know if we continue trying to decode the given caps */
213 gboolean (*autoplug_continue) (GstElement * element, GstPad * pad,
214 GstCaps * caps);
215 /* signal fired to get a list of factories to try to autoplug */
216 GValueArray *(*autoplug_factories) (GstElement * element, GstPad * pad,
217 GstCaps * caps);
218 /* signal fired to sort the factories */
219 GValueArray *(*autoplug_sort) (GstElement * element, GstPad * pad,
220 GstCaps * caps, GValueArray * factories);
221 /* signal fired to select from the proposed list of factories */
222 GstAutoplugSelectResult (*autoplug_select) (GstElement * element,
223 GstPad * pad, GstCaps * caps, GstElementFactory * factory);
224 /* signal fired when a autoplugged element that is not linked downstream
225 * or exposed wants to query something */
226 gboolean (*autoplug_query) (GstElement * element, GstPad * pad,
227 GstQuery * query);
228
229 /* fired when the last group is drained */
230 void (*drained) (GstElement * element);
231 };
232
233 /* signals */
234 enum
235 {
236 SIGNAL_UNKNOWN_TYPE,
237 SIGNAL_AUTOPLUG_CONTINUE,
238 SIGNAL_AUTOPLUG_FACTORIES,
239 SIGNAL_AUTOPLUG_SELECT,
240 SIGNAL_AUTOPLUG_SORT,
241 SIGNAL_AUTOPLUG_QUERY,
242 SIGNAL_DRAINED,
243 LAST_SIGNAL
244 };
245
246 /* automatic sizes, while prerolling we buffer up to 2MB, we ignore time
247 * and buffers in this case. */
248 #define AUTO_PREROLL_SIZE_BYTES 2 * 1024 * 1024
249 #define AUTO_PREROLL_SIZE_BUFFERS 0
250 #define AUTO_PREROLL_NOT_SEEKABLE_SIZE_TIME 10 * GST_SECOND
251 #define AUTO_PREROLL_SEEKABLE_SIZE_TIME 0
252
253 /* when playing, keep a max of 2MB of data but try to keep the number of buffers
254 * as low as possible (try to aim for 5 buffers) */
255 #define AUTO_PLAY_SIZE_BYTES 2 * 1024 * 1024
256 #define AUTO_PLAY_SIZE_BUFFERS 5
257 #define AUTO_PLAY_SIZE_TIME 0
258
259 #define DEFAULT_SUBTITLE_ENCODING NULL
260 #define DEFAULT_USE_BUFFERING FALSE
261 #define DEFAULT_LOW_PERCENT 10
262 #define DEFAULT_HIGH_PERCENT 99
263 /* by default we use the automatic values above */
264 #define DEFAULT_MAX_SIZE_BYTES 0
265 #define DEFAULT_MAX_SIZE_BUFFERS 0
266 #define DEFAULT_MAX_SIZE_TIME 0
267 #define DEFAULT_POST_STREAM_TOPOLOGY FALSE
268 #define DEFAULT_EXPOSE_ALL_STREAMS TRUE
269 #define DEFAULT_CONNECTION_SPEED 0
270
271 #ifdef OHOS_EXT_FUNC
272 // ohos.ext.func.0013
273 #define DEFAULT_TIMEOUT 15
274 #endif
275
276 /* Properties */
277 enum
278 {
279 PROP_0,
280 PROP_CAPS,
281 PROP_SUBTITLE_ENCODING,
282 PROP_SINK_CAPS,
283 PROP_USE_BUFFERING,
284 PROP_LOW_PERCENT,
285 PROP_HIGH_PERCENT,
286 PROP_MAX_SIZE_BYTES,
287 PROP_MAX_SIZE_BUFFERS,
288 PROP_MAX_SIZE_TIME,
289 PROP_POST_STREAM_TOPOLOGY,
290 PROP_EXPOSE_ALL_STREAMS,
291 #ifdef OHOS_EXT_FUNC
292 // ohos.ext.func.0013
293 PROP_MQ_NUM_USE_BUFFRING,
294 PROP_TIMEOUT,
295 PROP_STATE_CHANGE,
296 PROP_EXIT_BLOCK,
297 #endif
298 PROP_CONNECTION_SPEED
299 };
300
301 static GstBinClass *parent_class;
302 static guint gst_decode_bin_signals[LAST_SIGNAL] = { 0 };
303
304 static GstStaticCaps default_raw_caps = GST_STATIC_CAPS (DEFAULT_RAW_CAPS);
305
306 static void do_async_start (GstDecodeBin * dbin);
307 static void do_async_done (GstDecodeBin * dbin);
308
309 static void type_found (GstElement * typefind, guint probability,
310 GstCaps * caps, GstDecodeBin * decode_bin);
311
312 static void decodebin_set_queue_size (GstDecodeBin * dbin,
313 GstElement * multiqueue, gboolean preroll, gboolean seekable);
314 static void decodebin_set_queue_size_full (GstDecodeBin * dbin,
315 GstElement * multiqueue, gboolean use_buffering, gboolean preroll,
316 gboolean seekable);
317
318 static gboolean gst_decode_bin_autoplug_continue (GstElement * element,
319 GstPad * pad, GstCaps * caps);
320 static GValueArray *gst_decode_bin_autoplug_factories (GstElement *
321 element, GstPad * pad, GstCaps * caps);
322 static GValueArray *gst_decode_bin_autoplug_sort (GstElement * element,
323 GstPad * pad, GstCaps * caps, GValueArray * factories);
324 static GstAutoplugSelectResult gst_decode_bin_autoplug_select (GstElement *
325 element, GstPad * pad, GstCaps * caps, GstElementFactory * factory);
326 static gboolean gst_decode_bin_autoplug_query (GstElement * element,
327 GstPad * pad, GstQuery * query);
328
329 static void gst_decode_bin_set_property (GObject * object, guint prop_id,
330 const GValue * value, GParamSpec * pspec);
331 static void gst_decode_bin_get_property (GObject * object, guint prop_id,
332 GValue * value, GParamSpec * pspec);
333 static void gst_decode_bin_set_caps (GstDecodeBin * dbin, GstCaps * caps);
334 static GstCaps *gst_decode_bin_get_caps (GstDecodeBin * dbin);
335 static void caps_notify_cb (GstPad * pad, GParamSpec * unused,
336 GstDecodeChain * chain);
337
338 static void flush_chain (GstDecodeChain * chain, gboolean flushing);
339 static void flush_group (GstDecodeGroup * group, gboolean flushing);
340 static GstPad *find_sink_pad (GstElement * element);
341 static GstStateChangeReturn gst_decode_bin_change_state (GstElement * element,
342 GstStateChange transition);
343 static void gst_decode_bin_handle_message (GstBin * bin, GstMessage * message);
344 static gboolean gst_decode_bin_remove_element (GstBin * bin,
345 GstElement * element);
346
347 static gboolean check_upstream_seekable (GstDecodeBin * dbin, GstPad * pad);
348
349 static GstCaps *get_pad_caps (GstPad * pad);
350 static void unblock_pads (GstDecodeBin * dbin);
351
352 #define EXPOSE_LOCK(dbin) G_STMT_START { \
353 GST_LOG_OBJECT (dbin, \
354 "expose locking from thread %p", \
355 g_thread_self ()); \
356 g_mutex_lock (&GST_DECODE_BIN_CAST(dbin)->expose_lock); \
357 GST_LOG_OBJECT (dbin, \
358 "expose locked from thread %p", \
359 g_thread_self ()); \
360 } G_STMT_END
361
362 #define EXPOSE_UNLOCK(dbin) G_STMT_START { \
363 GST_LOG_OBJECT (dbin, \
364 "expose unlocking from thread %p", \
365 g_thread_self ()); \
366 g_mutex_unlock (&GST_DECODE_BIN_CAST(dbin)->expose_lock); \
367 } G_STMT_END
368
369 #define DYN_LOCK(dbin) G_STMT_START { \
370 GST_LOG_OBJECT (dbin, \
371 "dynlocking from thread %p", \
372 g_thread_self ()); \
373 g_mutex_lock (&GST_DECODE_BIN_CAST(dbin)->dyn_lock); \
374 GST_LOG_OBJECT (dbin, \
375 "dynlocked from thread %p", \
376 g_thread_self ()); \
377 } G_STMT_END
378
379 #define DYN_UNLOCK(dbin) G_STMT_START { \
380 GST_LOG_OBJECT (dbin, \
381 "dynunlocking from thread %p", \
382 g_thread_self ()); \
383 g_mutex_unlock (&GST_DECODE_BIN_CAST(dbin)->dyn_lock); \
384 } G_STMT_END
385
386 #define SUBTITLE_LOCK(dbin) G_STMT_START { \
387 GST_LOG_OBJECT (dbin, \
388 "subtitle locking from thread %p", \
389 g_thread_self ()); \
390 g_mutex_lock (&GST_DECODE_BIN_CAST(dbin)->subtitle_lock); \
391 GST_LOG_OBJECT (dbin, \
392 "subtitle lock from thread %p", \
393 g_thread_self ()); \
394 } G_STMT_END
395
396 #define SUBTITLE_UNLOCK(dbin) G_STMT_START { \
397 GST_LOG_OBJECT (dbin, \
398 "subtitle unlocking from thread %p", \
399 g_thread_self ()); \
400 g_mutex_unlock (&GST_DECODE_BIN_CAST(dbin)->subtitle_lock); \
401 } G_STMT_END
402
403 #define BUFFERING_LOCK(dbin) G_STMT_START { \
404 GST_LOG_OBJECT (dbin, \
405 "buffering locking from thread %p", \
406 g_thread_self ()); \
407 g_mutex_lock (&GST_DECODE_BIN_CAST(dbin)->buffering_lock); \
408 GST_LOG_OBJECT (dbin, \
409 "buffering lock from thread %p", \
410 g_thread_self ()); \
411 } G_STMT_END
412
413 #define BUFFERING_UNLOCK(dbin) G_STMT_START { \
414 GST_LOG_OBJECT (dbin, \
415 "buffering unlocking from thread %p", \
416 g_thread_self ()); \
417 g_mutex_unlock (&GST_DECODE_BIN_CAST(dbin)->buffering_lock); \
418 } G_STMT_END
419
420 struct _GstPendingPad
421 {
422 GstPad *pad;
423 GstDecodeChain *chain;
424 gulong event_probe_id;
425 gulong notify_caps_id;
426 };
427
428 struct _GstDecodeElement
429 {
430 GstElement *element;
431 GstElement *capsfilter; /* Optional capsfilter for Parser/Convert */
432 gulong pad_added_id;
433 gulong pad_removed_id;
434 gulong no_more_pads_id;
435 };
436
437 struct _GstDemuxerPad
438 {
439 GWeakRef weakPad;
440 gulong event_probe_id;
441 gulong query_probe_id;
442 };
443
444
445 /* GstDecodeGroup
446 *
447 * Streams belonging to the same group/chain of a media file
448 *
449 * When changing something here lock the parent chain!
450 */
451 struct _GstDecodeGroup
452 {
453 GstDecodeBin *dbin;
454 GstDecodeChain *parent;
455
456 GstElement *multiqueue; /* Used for linking all child chains */
457 gulong overrunsig; /* the overrun signal for multiqueue */
458
459 gboolean overrun; /* TRUE if the multiqueue signaled overrun. This
460 * means that we should really expose the group */
461
462 gboolean no_more_pads; /* TRUE if the demuxer signaled no-more-pads */
463 gboolean drained; /* TRUE if the all children are drained */
464
465 GList *children; /* List of GstDecodeChains in this group */
466 GList *demuxer_pad_probe_ids;
467
468 GList *reqpads; /* List of RequestPads for multiqueue, there is
469 * exactly one RequestPad per child chain */
470 };
471
472 struct _GstDecodeChain
473 {
474 GstDecodeGroup *parent;
475 GstDecodeBin *dbin;
476
477 gint refs; /* Number of references to this object */
478
479 GMutex lock; /* Protects this chain and its groups */
480
481 GstPad *pad; /* srcpad that caused creation of this chain */
482 gulong pad_probe_id; /* id for the demuxer_source_pad_probe probe */
483
484 gboolean drained; /* TRUE if the all children are drained */
485 gboolean demuxer; /* TRUE if elements->data is a demuxer */
486 gboolean adaptive_demuxer; /* TRUE if elements->data is an adaptive streaming demuxer */
487 gboolean seekable; /* TRUE if this chain ends on a demuxer and is seekable */
488 GList *elements; /* All elements in this group, first
489 is the latest and most downstream element */
490
491 /* Note: there are only groups if the last element of this chain
492 * is a demuxer, otherwise the chain will end with an endpad.
493 * The other way around this means, that endpad only exists if this
494 * chain doesn't end with a demuxer! */
495
496 GstDecodeGroup *active_group; /* Currently active group */
497 GList *next_groups; /* head is newest group, tail is next group.
498 a new group will be created only if the head
499 group had no-more-pads. If it's only exposed
500 all new pads will be ignored! */
501 GList *pending_pads; /* Pads that have no fixed caps yet */
502
503 GstDecodePad *current_pad; /* Current ending pad of the chain that can't
504 * be exposed yet but would be the same as endpad
505 * once it can be exposed */
506 GstDecodePad *endpad; /* Pad of this chain that could be exposed */
507 gboolean deadend; /* This chain is incomplete and can't be completed,
508 e.g. no suitable decoder could be found
509 e.g. stream got EOS without buffers
510 */
511 gchar *deadend_details;
512 GstCaps *endcaps; /* Caps that were used when linking to the endpad
513 or that resulted in the deadend
514 */
515
516 /* FIXME: This should be done directly via a thread! */
517 GList *old_groups; /* Groups that should be freed later */
518 };
519
520 static GstDecodeChain *gst_decode_chain_ref (GstDecodeChain * chain);
521 static void gst_decode_chain_unref (GstDecodeChain * chain);
522 static void gst_decode_chain_free (GstDecodeChain * chain);
523 static GstDecodeChain *gst_decode_chain_new (GstDecodeBin * dbin,
524 GstDecodeGroup * group, GstPad * pad);
525 static void gst_decode_group_hide (GstDecodeGroup * group);
526 static void gst_decode_group_free (GstDecodeGroup * group);
527 static GstDecodeGroup *gst_decode_group_new (GstDecodeBin * dbin,
528 GstDecodeChain * chain);
529 static gboolean gst_decode_chain_is_complete (GstDecodeChain * chain);
530 static gboolean gst_decode_chain_expose (GstDecodeChain * chain,
531 GList ** endpads, gboolean * missing_plugin,
532 GString * missing_plugin_details, gboolean * last_group);
533 static gboolean gst_decode_chain_is_drained (GstDecodeChain * chain);
534 static gboolean gst_decode_chain_reset_buffering (GstDecodeChain * chain);
535 static gboolean gst_decode_group_is_complete (GstDecodeGroup * group);
536 static GstPad *gst_decode_group_control_demuxer_pad (GstDecodeGroup * group,
537 GstPad * pad);
538 static gboolean gst_decode_group_is_drained (GstDecodeGroup * group);
539 static gboolean gst_decode_group_reset_buffering (GstDecodeGroup * group);
540
541 static gboolean gst_decode_bin_expose (GstDecodeBin * dbin);
542 static void gst_decode_bin_reset_buffering (GstDecodeBin * dbin);
543
544 #define CHAIN_MUTEX_LOCK(chain) G_STMT_START { \
545 GST_LOG_OBJECT (chain->dbin, \
546 "locking chain %p from thread %p", \
547 chain, g_thread_self ()); \
548 g_mutex_lock (&chain->lock); \
549 GST_LOG_OBJECT (chain->dbin, \
550 "locked chain %p from thread %p", \
551 chain, g_thread_self ()); \
552 } G_STMT_END
553
554 #define CHAIN_MUTEX_UNLOCK(chain) G_STMT_START { \
555 GST_LOG_OBJECT (chain->dbin, \
556 "unlocking chain %p from thread %p", \
557 chain, g_thread_self ()); \
558 g_mutex_unlock (&chain->lock); \
559 } G_STMT_END
560
561 /* GstDecodePad
562 *
563 * GstPad private used for source pads of chains
564 */
565 struct _GstDecodePad
566 {
567 GstGhostPad parent;
568 GstDecodeBin *dbin;
569 GstDecodeChain *chain;
570
571 gboolean blocked; /* the *target* pad is blocked */
572 gboolean exposed; /* the pad is exposed */
573 gboolean drained; /* an EOS has been seen on the pad */
574
575 gulong block_id;
576 };
577
578 GType gst_decode_pad_get_type (void);
579 G_DEFINE_TYPE (GstDecodePad, gst_decode_pad, GST_TYPE_GHOST_PAD);
580 #define GST_TYPE_DECODE_PAD (gst_decode_pad_get_type ())
581 #define GST_DECODE_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DECODE_PAD,GstDecodePad))
582
583 static GstDecodePad *gst_decode_pad_new (GstDecodeBin * dbin,
584 GstDecodeChain * chain);
585 static void gst_decode_pad_activate (GstDecodePad * dpad,
586 GstDecodeChain * chain);
587 static void gst_decode_pad_unblock (GstDecodePad * dpad);
588 static void gst_decode_pad_set_blocked (GstDecodePad * dpad, gboolean blocked);
589 static gboolean gst_decode_pad_query (GstPad * pad, GstObject * parent,
590 GstQuery * query);
591 static gboolean gst_decode_pad_is_exposable (GstDecodePad * endpad);
592
593 static void gst_pending_pad_free (GstPendingPad * ppad);
594 static GstPadProbeReturn pad_event_cb (GstPad * pad, GstPadProbeInfo * info,
595 gpointer data);
596
597 /********************************
598 * Standard GObject boilerplate *
599 ********************************/
600
601 static void gst_decode_bin_class_init (GstDecodeBinClass * klass);
602 static void gst_decode_bin_init (GstDecodeBin * decode_bin);
603 static void gst_decode_bin_dispose (GObject * object);
604 static void gst_decode_bin_finalize (GObject * object);
605
606 static GType
gst_decode_bin_get_type(void)607 gst_decode_bin_get_type (void)
608 {
609 static GType gst_decode_bin_type = 0;
610
611 if (!gst_decode_bin_type) {
612 static const GTypeInfo gst_decode_bin_info = {
613 sizeof (GstDecodeBinClass),
614 NULL,
615 NULL,
616 (GClassInitFunc) gst_decode_bin_class_init,
617 NULL,
618 NULL,
619 sizeof (GstDecodeBin),
620 0,
621 (GInstanceInitFunc) gst_decode_bin_init,
622 NULL
623 };
624
625 gst_decode_bin_type =
626 g_type_register_static (GST_TYPE_BIN, "GstDecodeBin",
627 &gst_decode_bin_info, 0);
628 }
629
630 return gst_decode_bin_type;
631 }
632
633 static gboolean
_gst_boolean_accumulator(GSignalInvocationHint * ihint,GValue * return_accu,const GValue * handler_return,gpointer dummy)634 _gst_boolean_accumulator (GSignalInvocationHint * ihint,
635 GValue * return_accu, const GValue * handler_return, gpointer dummy)
636 {
637 gboolean myboolean;
638
639 myboolean = g_value_get_boolean (handler_return);
640 if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
641 g_value_set_boolean (return_accu, myboolean);
642
643 /* stop emission if FALSE */
644 return myboolean;
645 }
646
647 static gboolean
_gst_boolean_or_accumulator(GSignalInvocationHint * ihint,GValue * return_accu,const GValue * handler_return,gpointer dummy)648 _gst_boolean_or_accumulator (GSignalInvocationHint * ihint,
649 GValue * return_accu, const GValue * handler_return, gpointer dummy)
650 {
651 gboolean myboolean;
652 gboolean retboolean;
653
654 myboolean = g_value_get_boolean (handler_return);
655 retboolean = g_value_get_boolean (return_accu);
656
657 if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
658 g_value_set_boolean (return_accu, myboolean || retboolean);
659
660 return TRUE;
661 }
662
663 /* we collect the first result */
664 static gboolean
_gst_array_accumulator(GSignalInvocationHint * ihint,GValue * return_accu,const GValue * handler_return,gpointer dummy)665 _gst_array_accumulator (GSignalInvocationHint * ihint,
666 GValue * return_accu, const GValue * handler_return, gpointer dummy)
667 {
668 gpointer array;
669
670 array = g_value_get_boxed (handler_return);
671 if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
672 g_value_set_boxed (return_accu, array);
673
674 return FALSE;
675 }
676
677 static gboolean
_gst_select_accumulator(GSignalInvocationHint * ihint,GValue * return_accu,const GValue * handler_return,gpointer dummy)678 _gst_select_accumulator (GSignalInvocationHint * ihint,
679 GValue * return_accu, const GValue * handler_return, gpointer dummy)
680 {
681 GstAutoplugSelectResult res;
682
683 res = g_value_get_enum (handler_return);
684 if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
685 g_value_set_enum (return_accu, res);
686
687 /* Call the next handler in the chain (if any) when the current callback
688 * returns TRY. This makes it possible to register separate autoplug-select
689 * handlers that implement different TRY/EXPOSE/SKIP strategies.
690 */
691 if (res == GST_AUTOPLUG_SELECT_TRY)
692 return TRUE;
693
694 return FALSE;
695 }
696
697 static gboolean
_gst_array_hasvalue_accumulator(GSignalInvocationHint * ihint,GValue * return_accu,const GValue * handler_return,gpointer dummy)698 _gst_array_hasvalue_accumulator (GSignalInvocationHint * ihint,
699 GValue * return_accu, const GValue * handler_return, gpointer dummy)
700 {
701 gpointer array;
702
703 array = g_value_get_boxed (handler_return);
704 if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
705 g_value_set_boxed (return_accu, array);
706
707 if (array != NULL)
708 return FALSE;
709
710 return TRUE;
711 }
712
713 static void
gst_decode_bin_class_init(GstDecodeBinClass * klass)714 gst_decode_bin_class_init (GstDecodeBinClass * klass)
715 {
716 GObjectClass *gobject_klass;
717 GstElementClass *gstelement_klass;
718 GstBinClass *gstbin_klass;
719
720 gobject_klass = (GObjectClass *) klass;
721 gstelement_klass = (GstElementClass *) klass;
722 gstbin_klass = (GstBinClass *) klass;
723
724 parent_class = g_type_class_peek_parent (klass);
725
726 gobject_klass->dispose = gst_decode_bin_dispose;
727 gobject_klass->finalize = gst_decode_bin_finalize;
728 gobject_klass->set_property = gst_decode_bin_set_property;
729 gobject_klass->get_property = gst_decode_bin_get_property;
730
731 /**
732 * GstDecodeBin::unknown-type:
733 * @bin: The decodebin.
734 * @pad: The new pad containing caps that cannot be resolved to a 'final'
735 * stream type.
736 * @caps: The #GstCaps of the pad that cannot be resolved.
737 *
738 * This signal is emitted when a pad for which there is no further possible
739 * decoding is added to the decodebin.
740 */
741 gst_decode_bin_signals[SIGNAL_UNKNOWN_TYPE] =
742 g_signal_new ("unknown-type", G_TYPE_FROM_CLASS (klass),
743 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDecodeBinClass, unknown_type),
744 NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 2,
745 GST_TYPE_PAD, GST_TYPE_CAPS);
746
747 /**
748 * GstDecodeBin::autoplug-continue:
749 * @bin: The decodebin.
750 * @pad: The #GstPad.
751 * @caps: The #GstCaps found.
752 *
753 * This signal is emitted whenever decodebin finds a new stream. It is
754 * emitted before looking for any elements that can handle that stream.
755 *
756 * > Invocation of signal handlers stops after the first signal handler
757 * > returns %FALSE. Signal handlers are invoked in the order they were
758 * > connected in.
759 *
760 * Returns: %TRUE if you wish decodebin to look for elements that can
761 * handle the given @caps. If %FALSE, those caps will be considered as
762 * final and the pad will be exposed as such (see 'pad-added' signal of
763 * #GstElement).
764 */
765 gst_decode_bin_signals[SIGNAL_AUTOPLUG_CONTINUE] =
766 g_signal_new ("autoplug-continue", G_TYPE_FROM_CLASS (klass),
767 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDecodeBinClass, autoplug_continue),
768 _gst_boolean_accumulator, NULL, g_cclosure_marshal_generic,
769 G_TYPE_BOOLEAN, 2, GST_TYPE_PAD, GST_TYPE_CAPS);
770
771 /**
772 * GstDecodeBin::autoplug-factories:
773 * @bin: The decodebin.
774 * @pad: The #GstPad.
775 * @caps: The #GstCaps found.
776 *
777 * This signal is emitted when an array of possible factories for @caps on
778 * @pad is needed. Decodebin will by default return an array with all
779 * compatible factories, sorted by rank.
780 *
781 * If this function returns NULL, @pad will be exposed as a final caps.
782 *
783 * If this function returns an empty array, the pad will be considered as
784 * having an unhandled type media type.
785 *
786 * > Only the signal handler that is connected first will ever by invoked.
787 * > Don't connect signal handlers with the #G_CONNECT_AFTER flag to this
788 * > signal, they will never be invoked!
789 *
790 * Returns: a #GValueArray* with a list of factories to try. The factories are
791 * by default tried in the returned order or based on the index returned by
792 * "autoplug-select".
793 */
794 gst_decode_bin_signals[SIGNAL_AUTOPLUG_FACTORIES] =
795 g_signal_new ("autoplug-factories", G_TYPE_FROM_CLASS (klass),
796 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDecodeBinClass,
797 autoplug_factories), _gst_array_accumulator, NULL,
798 g_cclosure_marshal_generic, G_TYPE_VALUE_ARRAY, 2,
799 GST_TYPE_PAD, GST_TYPE_CAPS);
800
801 /**
802 * GstDecodeBin::autoplug-sort:
803 * @bin: The decodebin.
804 * @pad: The #GstPad.
805 * @caps: The #GstCaps.
806 * @factories: A #GValueArray of possible #GstElementFactory to use.
807 *
808 * Once decodebin has found the possible #GstElementFactory objects to try
809 * for @caps on @pad, this signal is emitted. The purpose of the signal is for
810 * the application to perform additional sorting or filtering on the element
811 * factory array.
812 *
813 * The callee should copy and modify @factories or return %NULL if the
814 * order should not change.
815 *
816 * > Invocation of signal handlers stops after one signal handler has
817 * > returned something else than %NULL. Signal handlers are invoked in
818 * > the order they were connected in.
819 * > Don't connect signal handlers with the #G_CONNECT_AFTER flag to this
820 * > signal, they will never be invoked!
821 *
822 * Returns: A new sorted array of #GstElementFactory objects.
823 */
824 gst_decode_bin_signals[SIGNAL_AUTOPLUG_SORT] =
825 g_signal_new ("autoplug-sort", G_TYPE_FROM_CLASS (klass),
826 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDecodeBinClass, autoplug_sort),
827 _gst_array_hasvalue_accumulator, NULL,
828 g_cclosure_marshal_generic, G_TYPE_VALUE_ARRAY, 3, GST_TYPE_PAD,
829 GST_TYPE_CAPS, G_TYPE_VALUE_ARRAY | G_SIGNAL_TYPE_STATIC_SCOPE);
830
831 /**
832 * GstDecodeBin::autoplug-select:
833 * @bin: The decodebin.
834 * @pad: The #GstPad.
835 * @caps: The #GstCaps.
836 * @factory: A #GstElementFactory to use.
837 *
838 * This signal is emitted once decodebin has found all the possible
839 * #GstElementFactory that can be used to handle the given @caps. For each of
840 * those factories, this signal is emitted.
841 *
842 * The signal handler should return a #GST_TYPE_AUTOPLUG_SELECT_RESULT enum
843 * value indicating what decodebin should do next.
844 *
845 * A value of #GST_AUTOPLUG_SELECT_TRY will try to autoplug an element from
846 * @factory.
847 *
848 * A value of #GST_AUTOPLUG_SELECT_EXPOSE will expose @pad without plugging
849 * any element to it.
850 *
851 * A value of #GST_AUTOPLUG_SELECT_SKIP will skip @factory and move to the
852 * next factory.
853 *
854 * > The signal handler will not be invoked if any of the previously
855 * > registered signal handlers (if any) return a value other than
856 * > GST_AUTOPLUG_SELECT_TRY. Which also means that if you return
857 * > GST_AUTOPLUG_SELECT_TRY from one signal handler, handlers that get
858 * > registered next (again, if any) can override that decision.
859 *
860 * Returns: a #GST_TYPE_AUTOPLUG_SELECT_RESULT that indicates the required
861 * operation. the default handler will always return
862 * #GST_AUTOPLUG_SELECT_TRY.
863 */
864 gst_decode_bin_signals[SIGNAL_AUTOPLUG_SELECT] =
865 g_signal_new ("autoplug-select", G_TYPE_FROM_CLASS (klass),
866 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDecodeBinClass, autoplug_select),
867 _gst_select_accumulator, NULL,
868 g_cclosure_marshal_generic,
869 GST_TYPE_AUTOPLUG_SELECT_RESULT, 3, GST_TYPE_PAD, GST_TYPE_CAPS,
870 GST_TYPE_ELEMENT_FACTORY);
871
872 /**
873 * GstDecodeBin::autoplug-query:
874 * @bin: The decodebin.
875 * @pad: The #GstPad.
876 * @child: The child element doing the query
877 * @query: The #GstQuery.
878 *
879 * This signal is emitted whenever an autoplugged element that is
880 * not linked downstream yet and not exposed does a query. It can
881 * be used to tell the element about the downstream supported caps
882 * for example.
883 *
884 * Returns: %TRUE if the query was handled, %FALSE otherwise.
885 */
886 gst_decode_bin_signals[SIGNAL_AUTOPLUG_QUERY] =
887 g_signal_new ("autoplug-query", G_TYPE_FROM_CLASS (klass),
888 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDecodeBinClass, autoplug_query),
889 _gst_boolean_or_accumulator, NULL, g_cclosure_marshal_generic,
890 G_TYPE_BOOLEAN, 3, GST_TYPE_PAD, GST_TYPE_ELEMENT,
891 GST_TYPE_QUERY | G_SIGNAL_TYPE_STATIC_SCOPE);
892
893 /**
894 * GstDecodeBin::drained
895 * @bin: The decodebin
896 *
897 * This signal is emitted once decodebin has finished decoding all the data.
898 */
899 gst_decode_bin_signals[SIGNAL_DRAINED] =
900 g_signal_new ("drained", G_TYPE_FROM_CLASS (klass),
901 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDecodeBinClass, drained),
902 NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 0, G_TYPE_NONE);
903
904 g_object_class_install_property (gobject_klass, PROP_CAPS,
905 g_param_spec_boxed ("caps", "Caps", "The caps on which to stop decoding.",
906 GST_TYPE_CAPS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
907
908 g_object_class_install_property (gobject_klass, PROP_SUBTITLE_ENCODING,
909 g_param_spec_string ("subtitle-encoding", "subtitle encoding",
910 "Encoding to assume if input subtitles are not in UTF-8 encoding. "
911 "If not set, the GST_SUBTITLE_ENCODING environment variable will "
912 "be checked for an encoding to use. If that is not set either, "
913 "ISO-8859-15 will be assumed.", NULL,
914 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
915
916 g_object_class_install_property (gobject_klass, PROP_SINK_CAPS,
917 g_param_spec_boxed ("sink-caps", "Sink Caps",
918 "The caps of the input data. (NULL = use typefind element)",
919 GST_TYPE_CAPS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
920
921 /**
922 * GstDecodeBin::use-buffering
923 *
924 * Activate buffering in decodebin. This will instruct the multiqueues behind
925 * decoders to emit BUFFERING messages.
926 */
927 g_object_class_install_property (gobject_klass, PROP_USE_BUFFERING,
928 g_param_spec_boolean ("use-buffering", "Use Buffering",
929 "Emit GST_MESSAGE_BUFFERING based on low-/high-percent thresholds",
930 DEFAULT_USE_BUFFERING, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
931
932 /**
933 * GstDecodeBin:low-percent
934 *
935 * Low threshold percent for buffering to start.
936 */
937 g_object_class_install_property (gobject_klass, PROP_LOW_PERCENT,
938 g_param_spec_int ("low-percent", "Low percent",
939 "Low threshold for buffering to start", 0, 100,
940 DEFAULT_LOW_PERCENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
941 /**
942 * GstDecodeBin:high-percent
943 *
944 * High threshold percent for buffering to finish.
945 */
946 g_object_class_install_property (gobject_klass, PROP_HIGH_PERCENT,
947 g_param_spec_int ("high-percent", "High percent",
948 "High threshold for buffering to finish", 0, 100,
949 DEFAULT_HIGH_PERCENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
950
951 /**
952 * GstDecodeBin:max-size-bytes
953 *
954 * Max amount of bytes in the queue (0=automatic).
955 */
956 g_object_class_install_property (gobject_klass, PROP_MAX_SIZE_BYTES,
957 g_param_spec_uint ("max-size-bytes", "Max. size (bytes)",
958 "Max. amount of bytes in the queue (0=automatic)",
959 0, G_MAXUINT, DEFAULT_MAX_SIZE_BYTES,
960 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
961 /**
962 * GstDecodeBin:max-size-buffers
963 *
964 * Max amount of buffers in the queue (0=automatic).
965 */
966 g_object_class_install_property (gobject_klass, PROP_MAX_SIZE_BUFFERS,
967 g_param_spec_uint ("max-size-buffers", "Max. size (buffers)",
968 "Max. number of buffers in the queue (0=automatic)",
969 0, G_MAXUINT, DEFAULT_MAX_SIZE_BUFFERS,
970 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
971 /**
972 * GstDecodeBin:max-size-time
973 *
974 * Max amount of time in the queue (in ns, 0=automatic).
975 */
976 g_object_class_install_property (gobject_klass, PROP_MAX_SIZE_TIME,
977 g_param_spec_uint64 ("max-size-time", "Max. size (ns)",
978 "Max. amount of data in the queue (in ns, 0=automatic)",
979 0, G_MAXUINT64,
980 DEFAULT_MAX_SIZE_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
981
982 /**
983 * GstDecodeBin::post-stream-topology
984 *
985 * Post stream-topology messages on the bus every time the topology changes.
986 */
987 g_object_class_install_property (gobject_klass, PROP_POST_STREAM_TOPOLOGY,
988 g_param_spec_boolean ("post-stream-topology", "Post Stream Topology",
989 "Post stream-topology messages",
990 DEFAULT_POST_STREAM_TOPOLOGY,
991 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
992
993 /**
994 * GstDecodeBin::expose-all-streams
995 *
996 * Expose streams of unknown type.
997 *
998 * If set to %FALSE, then only the streams that can be decoded to the final
999 * caps (see 'caps' property) will have a pad exposed. Streams that do not
1000 * match those caps but could have been decoded will not have decoder plugged
1001 * in internally and will not have a pad exposed.
1002 */
1003 g_object_class_install_property (gobject_klass, PROP_EXPOSE_ALL_STREAMS,
1004 g_param_spec_boolean ("expose-all-streams", "Expose All Streams",
1005 "Expose all streams, including those of unknown type or that don't match the 'caps' property",
1006 DEFAULT_EXPOSE_ALL_STREAMS,
1007 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1008
1009 /**
1010 * GstDecodeBin2::connection-speed
1011 *
1012 * Network connection speed in kbps (0 = unknownw)
1013 */
1014 g_object_class_install_property (gobject_klass, PROP_CONNECTION_SPEED,
1015 g_param_spec_uint64 ("connection-speed", "Connection Speed",
1016 "Network connection speed in kbps (0 = unknown)",
1017 0, G_MAXUINT64 / 1000, DEFAULT_CONNECTION_SPEED,
1018 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1019
1020 #ifdef OHOS_EXT_FUNC
1021 // ohos.ext.func.0012
1022 g_object_class_install_property (gobject_klass, PROP_MQ_NUM_USE_BUFFRING,
1023 g_param_spec_uint ("mq-num-use-buffering", "Mq num use buffering",
1024 "multiqueue number of use buffering", 0, 100,
1025 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1026
1027 g_object_class_install_property (gobject_klass, PROP_TIMEOUT,
1028 g_param_spec_uint ("timeout", "timeout",
1029 "Value in seconds to timeout a blocking I/O (0 = No timeout).", 0,
1030 3600, DEFAULT_TIMEOUT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1031
1032 g_object_class_install_property (gobject_klass, PROP_STATE_CHANGE,
1033 g_param_spec_int ("state-change", "state-change from adaptive-demux",
1034 "state-change from adaptive-demux", 0, (gint) (G_MAXINT32), 0,
1035 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1036
1037 g_object_class_install_property (gobject_klass, PROP_EXIT_BLOCK,
1038 g_param_spec_int ("exit-block", "EXIT BLOCK",
1039 "souphttpsrc exit block", 0, (gint) (G_MAXINT32), 0,
1040 G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
1041 #endif
1042
1043 klass->autoplug_continue =
1044 GST_DEBUG_FUNCPTR (gst_decode_bin_autoplug_continue);
1045 klass->autoplug_factories =
1046 GST_DEBUG_FUNCPTR (gst_decode_bin_autoplug_factories);
1047 klass->autoplug_sort = GST_DEBUG_FUNCPTR (gst_decode_bin_autoplug_sort);
1048 klass->autoplug_select = GST_DEBUG_FUNCPTR (gst_decode_bin_autoplug_select);
1049 klass->autoplug_query = GST_DEBUG_FUNCPTR (gst_decode_bin_autoplug_query);
1050
1051 gst_element_class_add_static_pad_template (gstelement_klass,
1052 &decoder_bin_sink_template);
1053 gst_element_class_add_static_pad_template (gstelement_klass,
1054 &decoder_bin_src_template);
1055
1056 gst_element_class_set_static_metadata (gstelement_klass,
1057 "Decoder Bin", "Generic/Bin/Decoder",
1058 "Autoplug and decode to raw media",
1059 "Edward Hervey <edward.hervey@collabora.co.uk>, "
1060 "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
1061
1062 gstelement_klass->change_state =
1063 GST_DEBUG_FUNCPTR (gst_decode_bin_change_state);
1064
1065 gstbin_klass->handle_message =
1066 GST_DEBUG_FUNCPTR (gst_decode_bin_handle_message);
1067
1068 gstbin_klass->remove_element =
1069 GST_DEBUG_FUNCPTR (gst_decode_bin_remove_element);
1070
1071 g_type_class_ref (GST_TYPE_DECODE_PAD);
1072 }
1073
1074 /* Must be called with factories lock! */
1075 static void
gst_decode_bin_update_factories_list(GstDecodeBin * dbin)1076 gst_decode_bin_update_factories_list (GstDecodeBin * dbin)
1077 {
1078 guint cookie;
1079
1080 cookie = gst_registry_get_feature_list_cookie (gst_registry_get ());
1081 if (!dbin->factories || dbin->factories_cookie != cookie) {
1082 if (dbin->factories)
1083 gst_plugin_feature_list_free (dbin->factories);
1084 dbin->factories =
1085 gst_element_factory_list_get_elements
1086 (GST_ELEMENT_FACTORY_TYPE_DECODABLE, GST_RANK_MARGINAL);
1087 dbin->factories =
1088 g_list_sort (dbin->factories,
1089 gst_playback_utils_compare_factories_func);
1090 dbin->factories_cookie = cookie;
1091 }
1092 }
1093
1094 static void
gst_decode_bin_init(GstDecodeBin * decode_bin)1095 gst_decode_bin_init (GstDecodeBin * decode_bin)
1096 {
1097 /* first filter out the interesting element factories */
1098 g_mutex_init (&decode_bin->factories_lock);
1099
1100 /* we create the typefind element only once */
1101 decode_bin->typefind = gst_element_factory_make ("typefind", "typefind");
1102 if (!decode_bin->typefind) {
1103 g_warning ("can't find typefind element, decodebin will not work");
1104 } else {
1105 GstPad *pad;
1106 GstPad *gpad;
1107 GstPadTemplate *pad_tmpl;
1108
1109 /* add the typefind element */
1110 if (!gst_bin_add (GST_BIN (decode_bin), decode_bin->typefind)) {
1111 g_warning ("Could not add typefind element, decodebin will not work");
1112 gst_object_unref (decode_bin->typefind);
1113 decode_bin->typefind = NULL;
1114 }
1115
1116 /* get the sinkpad */
1117 pad = gst_element_get_static_pad (decode_bin->typefind, "sink");
1118
1119 /* get the pad template */
1120 pad_tmpl = gst_static_pad_template_get (&decoder_bin_sink_template);
1121
1122 /* ghost the sink pad to ourself */
1123 gpad = gst_ghost_pad_new_from_template ("sink", pad, pad_tmpl);
1124 gst_pad_set_active (gpad, TRUE);
1125 gst_element_add_pad (GST_ELEMENT (decode_bin), gpad);
1126
1127 gst_object_unref (pad_tmpl);
1128 gst_object_unref (pad);
1129 }
1130
1131 g_mutex_init (&decode_bin->expose_lock);
1132 decode_bin->decode_chain = NULL;
1133
1134 g_mutex_init (&decode_bin->dyn_lock);
1135 decode_bin->shutdown = FALSE;
1136 decode_bin->blocked_pads = NULL;
1137
1138 g_mutex_init (&decode_bin->subtitle_lock);
1139 g_mutex_init (&decode_bin->buffering_lock);
1140 g_mutex_init (&decode_bin->buffering_post_lock);
1141
1142 g_mutex_init (&decode_bin->cleanup_lock);
1143 decode_bin->cleanup_thread = NULL;
1144
1145 decode_bin->encoding = g_strdup (DEFAULT_SUBTITLE_ENCODING);
1146 decode_bin->caps = gst_static_caps_get (&default_raw_caps);
1147 decode_bin->use_buffering = DEFAULT_USE_BUFFERING;
1148 decode_bin->low_percent = DEFAULT_LOW_PERCENT;
1149 decode_bin->high_percent = DEFAULT_HIGH_PERCENT;
1150
1151 decode_bin->max_size_bytes = DEFAULT_MAX_SIZE_BYTES;
1152 decode_bin->max_size_buffers = DEFAULT_MAX_SIZE_BUFFERS;
1153 decode_bin->max_size_time = DEFAULT_MAX_SIZE_TIME;
1154
1155 decode_bin->expose_allstreams = DEFAULT_EXPOSE_ALL_STREAMS;
1156 decode_bin->connection_speed = DEFAULT_CONNECTION_SPEED;
1157 #ifdef OHOS_EXT_FUNC
1158 // ohos.ext.func.0013
1159 decode_bin->mq_num_use_buffering = 0;
1160 #endif
1161 }
1162
1163 static void
gst_decode_bin_dispose(GObject * object)1164 gst_decode_bin_dispose (GObject * object)
1165 {
1166 GstDecodeBin *decode_bin;
1167
1168 decode_bin = GST_DECODE_BIN (object);
1169
1170 if (decode_bin->factories)
1171 gst_plugin_feature_list_free (decode_bin->factories);
1172 decode_bin->factories = NULL;
1173
1174 if (decode_bin->decode_chain)
1175 gst_decode_chain_free (decode_bin->decode_chain);
1176 decode_bin->decode_chain = NULL;
1177
1178 if (decode_bin->caps)
1179 gst_caps_unref (decode_bin->caps);
1180 decode_bin->caps = NULL;
1181
1182 g_free (decode_bin->encoding);
1183 decode_bin->encoding = NULL;
1184
1185 g_list_free (decode_bin->subtitles);
1186 decode_bin->subtitles = NULL;
1187
1188 unblock_pads (decode_bin);
1189
1190 G_OBJECT_CLASS (parent_class)->dispose (object);
1191 }
1192
1193 static void
gst_decode_bin_finalize(GObject * object)1194 gst_decode_bin_finalize (GObject * object)
1195 {
1196 GstDecodeBin *decode_bin;
1197
1198 decode_bin = GST_DECODE_BIN (object);
1199
1200 g_mutex_clear (&decode_bin->expose_lock);
1201 g_mutex_clear (&decode_bin->dyn_lock);
1202 g_mutex_clear (&decode_bin->subtitle_lock);
1203 g_mutex_clear (&decode_bin->buffering_lock);
1204 g_mutex_clear (&decode_bin->buffering_post_lock);
1205 g_mutex_clear (&decode_bin->factories_lock);
1206 g_mutex_clear (&decode_bin->cleanup_lock);
1207
1208 G_OBJECT_CLASS (parent_class)->finalize (object);
1209 }
1210
1211 /* _set_caps
1212 * Changes the caps on which decodebin will stop decoding.
1213 * Will unref the previously set one. The refcount of the given caps will be
1214 * increased.
1215 * @caps can be NULL.
1216 *
1217 * MT-safe
1218 */
1219 static void
gst_decode_bin_set_caps(GstDecodeBin * dbin,GstCaps * caps)1220 gst_decode_bin_set_caps (GstDecodeBin * dbin, GstCaps * caps)
1221 {
1222 GST_DEBUG_OBJECT (dbin, "Setting new caps: %" GST_PTR_FORMAT, caps);
1223
1224 GST_OBJECT_LOCK (dbin);
1225 gst_caps_replace (&dbin->caps, caps);
1226 GST_OBJECT_UNLOCK (dbin);
1227 }
1228
1229 /* _get_caps
1230 * Returns the currently configured caps on which decodebin will stop decoding.
1231 * The returned caps (if not NULL), will have its refcount incremented.
1232 *
1233 * MT-safe
1234 */
1235 static GstCaps *
gst_decode_bin_get_caps(GstDecodeBin * dbin)1236 gst_decode_bin_get_caps (GstDecodeBin * dbin)
1237 {
1238 GstCaps *caps;
1239
1240 GST_DEBUG_OBJECT (dbin, "Getting currently set caps");
1241
1242 GST_OBJECT_LOCK (dbin);
1243 caps = dbin->caps;
1244 if (caps)
1245 gst_caps_ref (caps);
1246 GST_OBJECT_UNLOCK (dbin);
1247
1248 return caps;
1249 }
1250
1251 static void
gst_decode_bin_set_sink_caps(GstDecodeBin * dbin,GstCaps * caps)1252 gst_decode_bin_set_sink_caps (GstDecodeBin * dbin, GstCaps * caps)
1253 {
1254 GST_DEBUG_OBJECT (dbin, "Setting new caps: %" GST_PTR_FORMAT, caps);
1255
1256 g_object_set (dbin->typefind, "force-caps", caps, NULL);
1257 }
1258
1259 static GstCaps *
gst_decode_bin_get_sink_caps(GstDecodeBin * dbin)1260 gst_decode_bin_get_sink_caps (GstDecodeBin * dbin)
1261 {
1262 GstCaps *caps;
1263
1264 GST_DEBUG_OBJECT (dbin, "Getting currently set caps");
1265
1266 g_object_get (dbin->typefind, "force-caps", &caps, NULL);
1267
1268 return caps;
1269 }
1270
1271 static void
gst_decode_bin_set_subs_encoding(GstDecodeBin * dbin,const gchar * encoding)1272 gst_decode_bin_set_subs_encoding (GstDecodeBin * dbin, const gchar * encoding)
1273 {
1274 GList *walk;
1275
1276 GST_DEBUG_OBJECT (dbin, "Setting new encoding: %s", GST_STR_NULL (encoding));
1277
1278 SUBTITLE_LOCK (dbin);
1279 g_free (dbin->encoding);
1280 dbin->encoding = g_strdup (encoding);
1281
1282 /* set the subtitle encoding on all added elements */
1283 for (walk = dbin->subtitles; walk; walk = g_list_next (walk)) {
1284 g_object_set (G_OBJECT (walk->data), "subtitle-encoding", dbin->encoding,
1285 NULL);
1286 }
1287 SUBTITLE_UNLOCK (dbin);
1288 }
1289
1290 static gchar *
gst_decode_bin_get_subs_encoding(GstDecodeBin * dbin)1291 gst_decode_bin_get_subs_encoding (GstDecodeBin * dbin)
1292 {
1293 gchar *encoding;
1294
1295 GST_DEBUG_OBJECT (dbin, "Getting currently set encoding");
1296
1297 SUBTITLE_LOCK (dbin);
1298 encoding = g_strdup (dbin->encoding);
1299 SUBTITLE_UNLOCK (dbin);
1300
1301 return encoding;
1302 }
1303
1304 #ifdef OHOS_EXT_FUNC
1305 // ohos.ext.func.0012
1306 static void
set_property_handle_to_element(GstDecodeBin * dbin,guint property_id,const void * property_value)1307 set_property_handle_to_element (GstDecodeBin *dbin, guint property_id, const void *property_value)
1308 {
1309 GList *walk = NULL;
1310 GstBin *bin = (GstBin *) dbin;
1311
1312 for (walk = bin->children; walk != NULL; walk = g_list_next (walk)) {
1313 GObject *element = G_OBJECT (walk->data);
1314 if ((element == NULL) || !GST_IS_ELEMENT (element)) {
1315 continue;
1316 }
1317
1318 GstElementFactory *fac = gst_element_get_factory ((GstElement *)element);
1319 if (fac == NULL) {
1320 continue;
1321 }
1322 gboolean is_demux = gst_element_factory_list_is_type (fac, GST_ELEMENT_FACTORY_TYPE_DEMUXER);
1323 if (!is_demux) {
1324 continue;
1325 }
1326 GObjectClass *theclass = g_type_class_peek (gst_element_factory_get_element_type (fac));
1327 if (property_id == PROP_TIMEOUT) {
1328 const guint *timeout = (const guint *) property_value;
1329 if ((theclass != NULL) && g_object_class_find_property (theclass, "timeout")) {
1330 g_object_set (element, "timeout", *timeout, NULL);
1331 }
1332 } else if (property_id == PROP_STATE_CHANGE) {
1333 const gint *state = (const gint *) property_value;
1334 if ((theclass != NULL) && g_object_class_find_property (theclass, "state-change")) {
1335 g_object_set (element, "state-change", *state, NULL);
1336 }
1337 } else if (property_id == PROP_EXIT_BLOCK) {
1338 const gint *exit_block = (const gint *) property_value;
1339 if ((theclass != NULL) && g_object_class_find_property (theclass, "exit-block")) {
1340 g_object_set (element, "exit-block", *exit_block, NULL);
1341 }
1342 }
1343 }
1344 return;
1345 }
1346 #endif
1347
1348 static void
gst_decode_bin_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)1349 gst_decode_bin_set_property (GObject * object, guint prop_id,
1350 const GValue * value, GParamSpec * pspec)
1351 {
1352 GstDecodeBin *dbin;
1353
1354 dbin = GST_DECODE_BIN (object);
1355
1356 switch (prop_id) {
1357 case PROP_CAPS:
1358 gst_decode_bin_set_caps (dbin, g_value_get_boxed (value));
1359 break;
1360 case PROP_SUBTITLE_ENCODING:
1361 gst_decode_bin_set_subs_encoding (dbin, g_value_get_string (value));
1362 break;
1363 case PROP_SINK_CAPS:
1364 gst_decode_bin_set_sink_caps (dbin, g_value_get_boxed (value));
1365 break;
1366 case PROP_USE_BUFFERING:
1367 dbin->use_buffering = g_value_get_boolean (value);
1368 break;
1369 case PROP_LOW_PERCENT:
1370 dbin->low_percent = g_value_get_int (value);
1371 break;
1372 case PROP_HIGH_PERCENT:
1373 dbin->high_percent = g_value_get_int (value);
1374 break;
1375 case PROP_MAX_SIZE_BYTES:
1376 dbin->max_size_bytes = g_value_get_uint (value);
1377 break;
1378 case PROP_MAX_SIZE_BUFFERS:
1379 dbin->max_size_buffers = g_value_get_uint (value);
1380 break;
1381 case PROP_MAX_SIZE_TIME:
1382 dbin->max_size_time = g_value_get_uint64 (value);
1383 break;
1384 case PROP_POST_STREAM_TOPOLOGY:
1385 dbin->post_stream_topology = g_value_get_boolean (value);
1386 break;
1387 case PROP_EXPOSE_ALL_STREAMS:
1388 dbin->expose_allstreams = g_value_get_boolean (value);
1389 break;
1390 case PROP_CONNECTION_SPEED:
1391 GST_OBJECT_LOCK (dbin);
1392 dbin->connection_speed = g_value_get_uint64 (value) * 1000;
1393 GST_OBJECT_UNLOCK (dbin);
1394 break;
1395
1396 #ifdef OHOS_EXT_FUNC
1397 // ohos.ext.func.0013
1398 case PROP_TIMEOUT: {
1399 guint timeout = g_value_get_uint (value);
1400 set_property_handle_to_element (dbin, prop_id, (void *)&timeout);
1401 break;
1402 }
1403 case PROP_STATE_CHANGE: {
1404 gint state = g_value_get_int (value);
1405 set_property_handle_to_element (dbin, prop_id, (void *)&state);
1406 break;
1407 }
1408 case PROP_EXIT_BLOCK: {
1409 gint exit_block = g_value_get_int (value);
1410 set_property_handle_to_element (dbin, prop_id, (void *)&exit_block);
1411 break;
1412 }
1413 #endif
1414 default:
1415 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1416 break;
1417 }
1418 }
1419
1420 static void
gst_decode_bin_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)1421 gst_decode_bin_get_property (GObject * object, guint prop_id,
1422 GValue * value, GParamSpec * pspec)
1423 {
1424 GstDecodeBin *dbin;
1425
1426 dbin = GST_DECODE_BIN (object);
1427 switch (prop_id) {
1428 case PROP_CAPS:
1429 g_value_take_boxed (value, gst_decode_bin_get_caps (dbin));
1430 break;
1431 case PROP_SUBTITLE_ENCODING:
1432 g_value_take_string (value, gst_decode_bin_get_subs_encoding (dbin));
1433 break;
1434 case PROP_SINK_CAPS:
1435 g_value_take_boxed (value, gst_decode_bin_get_sink_caps (dbin));
1436 break;
1437 case PROP_USE_BUFFERING:
1438 g_value_set_boolean (value, dbin->use_buffering);
1439 break;
1440 case PROP_LOW_PERCENT:
1441 g_value_set_int (value, dbin->low_percent);
1442 break;
1443 case PROP_HIGH_PERCENT:
1444 g_value_set_int (value, dbin->high_percent);
1445 break;
1446 case PROP_MAX_SIZE_BYTES:
1447 g_value_set_uint (value, dbin->max_size_bytes);
1448 break;
1449 case PROP_MAX_SIZE_BUFFERS:
1450 g_value_set_uint (value, dbin->max_size_buffers);
1451 break;
1452 case PROP_MAX_SIZE_TIME:
1453 g_value_set_uint64 (value, dbin->max_size_time);
1454 break;
1455 case PROP_POST_STREAM_TOPOLOGY:
1456 g_value_set_boolean (value, dbin->post_stream_topology);
1457 break;
1458 case PROP_EXPOSE_ALL_STREAMS:
1459 g_value_set_boolean (value, dbin->expose_allstreams);
1460 break;
1461 case PROP_CONNECTION_SPEED:
1462 GST_OBJECT_LOCK (dbin);
1463 g_value_set_uint64 (value, dbin->connection_speed / 1000);
1464 GST_OBJECT_UNLOCK (dbin);
1465 break;
1466 #ifdef OHOS_EXT_FUNC
1467 // ohos.ext.func.0013
1468 case PROP_MQ_NUM_USE_BUFFRING:
1469 CHAIN_MUTEX_LOCK (dbin->decode_chain);
1470 g_value_set_uint64 (value, dbin->mq_num_use_buffering);
1471 CHAIN_MUTEX_UNLOCK (dbin->decode_chain);
1472 break;
1473 #endif
1474 default:
1475 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1476 break;
1477 }
1478 }
1479
1480
1481 /*****
1482 * Default autoplug signal handlers
1483 *****/
1484 static gboolean
gst_decode_bin_autoplug_continue(GstElement * element,GstPad * pad,GstCaps * caps)1485 gst_decode_bin_autoplug_continue (GstElement * element, GstPad * pad,
1486 GstCaps * caps)
1487 {
1488 GST_DEBUG_OBJECT (element, "autoplug-continue returns TRUE");
1489
1490 /* by default we always continue */
1491 return TRUE;
1492 }
1493
1494 static GValueArray *
gst_decode_bin_autoplug_factories(GstElement * element,GstPad * pad,GstCaps * caps)1495 gst_decode_bin_autoplug_factories (GstElement * element, GstPad * pad,
1496 GstCaps * caps)
1497 {
1498 GList *list, *tmp;
1499 GValueArray *result;
1500 GstDecodeBin *dbin = GST_DECODE_BIN_CAST (element);
1501
1502 GST_DEBUG_OBJECT (element, "finding factories");
1503
1504 /* return all compatible factories for caps */
1505 g_mutex_lock (&dbin->factories_lock);
1506 gst_decode_bin_update_factories_list (dbin);
1507 list =
1508 gst_element_factory_list_filter (dbin->factories, caps, GST_PAD_SINK,
1509 gst_caps_is_fixed (caps));
1510 g_mutex_unlock (&dbin->factories_lock);
1511
1512 result = g_value_array_new (g_list_length (list));
1513 for (tmp = list; tmp; tmp = tmp->next) {
1514 GstElementFactory *factory = GST_ELEMENT_FACTORY_CAST (tmp->data);
1515 GValue val = { 0, };
1516
1517 g_value_init (&val, G_TYPE_OBJECT);
1518 g_value_set_object (&val, factory);
1519 g_value_array_append (result, &val);
1520 g_value_unset (&val);
1521 }
1522 gst_plugin_feature_list_free (list);
1523
1524 GST_DEBUG_OBJECT (element, "autoplug-factories returns %p", result);
1525
1526 return result;
1527 }
1528
1529 static GValueArray *
gst_decode_bin_autoplug_sort(GstElement * element,GstPad * pad,GstCaps * caps,GValueArray * factories)1530 gst_decode_bin_autoplug_sort (GstElement * element, GstPad * pad,
1531 GstCaps * caps, GValueArray * factories)
1532 {
1533 return NULL;
1534 }
1535
1536 static GstAutoplugSelectResult
gst_decode_bin_autoplug_select(GstElement * element,GstPad * pad,GstCaps * caps,GstElementFactory * factory)1537 gst_decode_bin_autoplug_select (GstElement * element, GstPad * pad,
1538 GstCaps * caps, GstElementFactory * factory)
1539 {
1540 GST_DEBUG_OBJECT (element, "default autoplug-select returns TRY");
1541
1542 /* Try factory. */
1543 return GST_AUTOPLUG_SELECT_TRY;
1544 }
1545
1546 static gboolean
gst_decode_bin_autoplug_query(GstElement * element,GstPad * pad,GstQuery * query)1547 gst_decode_bin_autoplug_query (GstElement * element, GstPad * pad,
1548 GstQuery * query)
1549 {
1550 /* No query handled here */
1551 return FALSE;
1552 }
1553
1554 /********
1555 * Discovery methods
1556 *****/
1557
1558 static gboolean are_final_caps (GstDecodeBin * dbin, GstCaps * caps);
1559 static gboolean is_demuxer_element (GstElement * srcelement);
1560 static gboolean is_adaptive_demuxer_element (GstElement * srcelement);
1561
1562 static gboolean connect_pad (GstDecodeBin * dbin, GstElement * src,
1563 GstDecodePad * dpad, GstPad * pad, GstCaps * caps, GValueArray * factories,
1564 GstDecodeChain * chain, gchar ** deadend_details);
1565 static GList *connect_element (GstDecodeBin * dbin, GstDecodeElement * delem,
1566 GstDecodeChain * chain);
1567 static void expose_pad (GstDecodeBin * dbin, GstElement * src,
1568 GstDecodePad * dpad, GstPad * pad, GstCaps * caps, GstDecodeChain * chain);
1569
1570 static void pad_added_cb (GstElement * element, GstPad * pad,
1571 GstDecodeChain * chain);
1572 static void pad_removed_cb (GstElement * element, GstPad * pad,
1573 GstDecodeChain * chain);
1574 static void no_more_pads_cb (GstElement * element, GstDecodeChain * chain);
1575
1576 static GstDecodeGroup *gst_decode_chain_get_current_group (GstDecodeChain *
1577 chain);
1578
1579 static gboolean
clear_sticky_events(GstPad * pad,GstEvent ** event,gpointer user_data)1580 clear_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data)
1581 {
1582 GST_DEBUG_OBJECT (pad, "clearing sticky event %" GST_PTR_FORMAT, *event);
1583 gst_event_unref (*event);
1584 *event = NULL;
1585 return TRUE;
1586 }
1587
1588 static gboolean
copy_sticky_events(GstPad * pad,GstEvent ** event,gpointer user_data)1589 copy_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data)
1590 {
1591 GstPad *gpad = GST_PAD_CAST (user_data);
1592
1593 GST_DEBUG_OBJECT (gpad, "store sticky event %" GST_PTR_FORMAT, *event);
1594 gst_pad_store_sticky_event (gpad, *event);
1595
1596 return TRUE;
1597 }
1598
1599 static void
decode_pad_set_target(GstDecodePad * dpad,GstPad * target)1600 decode_pad_set_target (GstDecodePad * dpad, GstPad * target)
1601 {
1602 gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (dpad), target);
1603 if (target == NULL)
1604 gst_pad_sticky_events_foreach (GST_PAD_CAST (dpad), clear_sticky_events,
1605 NULL);
1606 else
1607 gst_pad_sticky_events_foreach (target, copy_sticky_events, dpad);
1608 }
1609
1610 /* called when a new pad is discovered. It will perform some basic actions
1611 * before trying to link something to it.
1612 *
1613 * - Check the caps, don't do anything when there are no caps or when they have
1614 * no good type.
1615 * - signal AUTOPLUG_CONTINUE to check if we need to continue autoplugging this
1616 * pad.
1617 * - if the caps are non-fixed, setup a handler to continue autoplugging when
1618 * the caps become fixed (connect to notify::caps).
1619 * - get list of factories to autoplug.
1620 * - continue autoplugging to one of the factories.
1621 */
1622 /* returns whether to expose the pad */
1623 static gboolean
analyze_new_pad(GstDecodeBin * dbin,GstElement * src,GstPad * pad,GstCaps * caps,GstDecodeChain * chain,GstDecodeChain ** new_chain)1624 analyze_new_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
1625 GstCaps * caps, GstDecodeChain * chain, GstDecodeChain ** new_chain)
1626 {
1627 gboolean apcontinue = TRUE;
1628 GValueArray *factories = NULL, *result = NULL;
1629 GstDecodePad *dpad;
1630 GstElementFactory *factory;
1631 const gchar *classification;
1632 gboolean is_parser_converter = FALSE;
1633 gboolean res;
1634 gchar *deadend_details = NULL;
1635
1636 GST_DEBUG_OBJECT (dbin, "Pad %s:%s caps:%" GST_PTR_FORMAT,
1637 GST_DEBUG_PAD_NAME (pad), caps);
1638
1639 if (new_chain)
1640 *new_chain = chain;
1641
1642 if (chain->elements
1643 && src != ((GstDecodeElement *) chain->elements->data)->element
1644 && src != ((GstDecodeElement *) chain->elements->data)->capsfilter) {
1645 GST_ERROR_OBJECT (dbin, "New pad from not the last element in this chain");
1646 return FALSE;
1647 }
1648
1649 if (chain->endpad) {
1650 GST_ERROR_OBJECT (dbin, "New pad in a chain that is already complete");
1651 return FALSE;
1652 }
1653
1654 if (chain->demuxer) {
1655 GstDecodeGroup *group;
1656 GstDecodeChain *oldchain = chain;
1657 GstDecodeElement *demux = (chain->elements ? chain->elements->data : NULL);
1658
1659 if (chain->current_pad)
1660 gst_object_unref (chain->current_pad);
1661 chain->current_pad = NULL;
1662
1663 /* we are adding a new pad for a demuxer (see is_demuxer_element(),
1664 * start a new chain for it */
1665 CHAIN_MUTEX_LOCK (oldchain);
1666 group = gst_decode_chain_get_current_group (chain);
1667 if (group && !g_list_find (group->children, chain)) {
1668 g_assert (new_chain != NULL);
1669 *new_chain = chain = gst_decode_chain_new (dbin, group, pad);
1670 group->children = g_list_prepend (group->children, chain);
1671 }
1672 CHAIN_MUTEX_UNLOCK (oldchain);
1673 if (!group) {
1674 GST_WARNING_OBJECT (dbin, "No current group");
1675 return FALSE;
1676 }
1677
1678 /* If this is not a dynamic pad demuxer, we're no-more-pads
1679 * already before anything else happens
1680 */
1681 if (demux == NULL || !demux->no_more_pads_id)
1682 group->no_more_pads = TRUE;
1683 }
1684
1685 /* From here on we own a reference to the caps as
1686 * we might create new caps below and would need
1687 * to unref them later */
1688 if (caps)
1689 gst_caps_ref (caps);
1690
1691 if ((caps == NULL) || gst_caps_is_empty (caps))
1692 goto unknown_type;
1693
1694 if (gst_caps_is_any (caps))
1695 goto any_caps;
1696
1697 if (!chain->current_pad)
1698 chain->current_pad = gst_decode_pad_new (dbin, chain);
1699
1700 dpad = gst_object_ref (chain->current_pad);
1701 gst_pad_set_active (GST_PAD_CAST (dpad), TRUE);
1702 decode_pad_set_target (dpad, pad);
1703
1704 /* 1. Emit 'autoplug-continue' the result will tell us if this pads needs
1705 * further autoplugging. Only do this for fixed caps, for unfixed caps
1706 * we will later come here again from the notify::caps handler. The
1707 * problem with unfixed caps is that, we can't reliably tell if the output
1708 * is e.g. accepted by a sink because only parts of the possible final
1709 * caps might be accepted by the sink. */
1710 if (gst_caps_is_fixed (caps))
1711 g_signal_emit (G_OBJECT (dbin),
1712 gst_decode_bin_signals[SIGNAL_AUTOPLUG_CONTINUE], 0, dpad, caps,
1713 &apcontinue);
1714 else
1715 apcontinue = TRUE;
1716
1717 /* 1.a if autoplug-continue is FALSE or caps is a raw format, goto pad_is_final */
1718 if ((!apcontinue) || are_final_caps (dbin, caps))
1719 goto expose_pad;
1720
1721 /* 1.b For Parser/Converter that can output different stream formats
1722 * we insert a capsfilter with the sorted caps of all possible next
1723 * elements and continue with the capsfilter srcpad */
1724 factory = gst_element_get_factory (src);
1725 classification =
1726 gst_element_factory_get_metadata (factory, GST_ELEMENT_METADATA_KLASS);
1727 is_parser_converter = (strstr (classification, "Parser")
1728 && strstr (classification, "Converter"));
1729
1730 /* 1.c when the caps are not fixed yet, we can't be sure what element to
1731 * connect. We delay autoplugging until the caps are fixed */
1732 if (!is_parser_converter && !gst_caps_is_fixed (caps)) {
1733 goto non_fixed;
1734 } else if (!is_parser_converter) {
1735 gst_caps_unref (caps);
1736 caps = gst_pad_get_current_caps (pad);
1737 if (!caps) {
1738 GST_DEBUG_OBJECT (dbin, "No final caps set yet, delaying autoplugging");
1739 gst_object_unref (dpad);
1740 goto setup_caps_delay;
1741 }
1742 }
1743
1744 /* 1.d else get the factories and if there's no compatible factory goto
1745 * unknown_type */
1746 g_signal_emit (G_OBJECT (dbin),
1747 gst_decode_bin_signals[SIGNAL_AUTOPLUG_FACTORIES], 0, dpad, caps,
1748 &factories);
1749
1750 /* NULL means that we can expose the pad */
1751 if (factories == NULL)
1752 goto expose_pad;
1753
1754 /* if the array is empty, we have a type for which we have no decoder */
1755 if (factories->n_values == 0) {
1756 if (!dbin->expose_allstreams) {
1757 GstCaps *raw = gst_static_caps_get (&default_raw_caps);
1758
1759 /* If the caps are raw, this just means we don't want to expose them */
1760 if (gst_caps_is_subset (caps, raw)) {
1761 g_value_array_free (factories);
1762 gst_caps_unref (raw);
1763 gst_object_unref (dpad);
1764 goto discarded_type;
1765 }
1766 gst_caps_unref (raw);
1767 }
1768
1769 /* if not we have a unhandled type with no compatible factories */
1770 g_value_array_free (factories);
1771 gst_object_unref (dpad);
1772 goto unknown_type;
1773 }
1774
1775 /* 1.e sort some more. */
1776 g_signal_emit (G_OBJECT (dbin),
1777 gst_decode_bin_signals[SIGNAL_AUTOPLUG_SORT], 0, dpad, caps, factories,
1778 &result);
1779 if (result) {
1780 g_value_array_free (factories);
1781 factories = result;
1782 }
1783
1784 /* At this point we have a potential decoder, but we might not need it
1785 * if it doesn't match the output caps */
1786 if (!dbin->expose_allstreams && gst_caps_is_fixed (caps)) {
1787 guint i;
1788 const GList *tmps;
1789 gboolean dontuse = FALSE;
1790
1791 GST_DEBUG ("Checking if we can abort early");
1792
1793 /* 1.f Do an early check to see if the candidates are potential decoders, but
1794 * due to the fact that they decode to a mediatype that is not final we don't
1795 * need them */
1796
1797 for (i = 0; i < factories->n_values && !dontuse; i++) {
1798 GstElementFactory *factory =
1799 g_value_get_object (g_value_array_get_nth (factories, i));
1800 GstCaps *tcaps;
1801
1802 /* We are only interested in skipping decoders */
1803 if (strstr (gst_element_factory_get_metadata (factory,
1804 GST_ELEMENT_METADATA_KLASS), "Decoder")) {
1805
1806 GST_DEBUG ("Trying factory %s",
1807 gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
1808
1809 /* Check the source pad template caps to see if they match raw caps but don't match
1810 * our final caps*/
1811 for (tmps = gst_element_factory_get_static_pad_templates (factory);
1812 tmps && !dontuse; tmps = tmps->next) {
1813 GstStaticPadTemplate *st = (GstStaticPadTemplate *) tmps->data;
1814 if (st->direction != GST_PAD_SRC)
1815 continue;
1816 tcaps = gst_static_pad_template_get_caps (st);
1817
1818 apcontinue = TRUE;
1819
1820 /* Emit autoplug-continue to see if the caps are considered to be raw caps */
1821 g_signal_emit (G_OBJECT (dbin),
1822 gst_decode_bin_signals[SIGNAL_AUTOPLUG_CONTINUE], 0, dpad, tcaps,
1823 &apcontinue);
1824
1825 /* If autoplug-continue returns TRUE and the caps are not final, don't use them */
1826 if (apcontinue && !are_final_caps (dbin, tcaps))
1827 dontuse = TRUE;
1828 gst_caps_unref (tcaps);
1829 }
1830 }
1831 }
1832
1833 if (dontuse) {
1834 gst_object_unref (dpad);
1835 g_value_array_free (factories);
1836 goto discarded_type;
1837 }
1838 }
1839
1840 /* 1.g now get the factory template caps and insert the capsfilter if this
1841 * is a parser/converter
1842 */
1843 if (is_parser_converter) {
1844 GstCaps *filter_caps;
1845 gint i;
1846 GstElement *capsfilter;
1847 GstPad *p;
1848 GstDecodeElement *delem;
1849
1850 filter_caps = gst_caps_new_empty ();
1851 for (i = 0; i < factories->n_values; i++) {
1852 GstElementFactory *factory =
1853 g_value_get_object (g_value_array_get_nth (factories, i));
1854 GstCaps *tcaps, *intersection;
1855 const GList *tmps;
1856
1857 GST_DEBUG ("Trying factory %s",
1858 gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
1859
1860 if (gst_element_get_factory (src) == factory ||
1861 gst_element_factory_list_is_type (factory,
1862 GST_ELEMENT_FACTORY_TYPE_PARSER)) {
1863 GST_DEBUG ("Skipping factory");
1864 continue;
1865 }
1866
1867 for (tmps = gst_element_factory_get_static_pad_templates (factory); tmps;
1868 tmps = tmps->next) {
1869 GstStaticPadTemplate *st = (GstStaticPadTemplate *) tmps->data;
1870 if (st->direction != GST_PAD_SINK || st->presence != GST_PAD_ALWAYS)
1871 continue;
1872 tcaps = gst_static_pad_template_get_caps (st);
1873 intersection =
1874 gst_caps_intersect_full (tcaps, caps, GST_CAPS_INTERSECT_FIRST);
1875 filter_caps = gst_caps_merge (filter_caps, intersection);
1876 gst_caps_unref (tcaps);
1877 }
1878 }
1879
1880 /* Append the parser caps to prevent any not-negotiated errors */
1881 filter_caps = gst_caps_merge (filter_caps, gst_caps_ref (caps));
1882
1883 if (chain->elements) {
1884 delem = (GstDecodeElement *) chain->elements->data;
1885 capsfilter = delem->capsfilter =
1886 gst_element_factory_make ("capsfilter", NULL);
1887 } else {
1888 delem = g_slice_new0 (GstDecodeElement);
1889 capsfilter = delem->element =
1890 gst_element_factory_make ("capsfilter", NULL);
1891 delem->capsfilter = NULL;
1892 chain->elements = g_list_prepend (chain->elements, delem);
1893 }
1894
1895 g_object_set (G_OBJECT (capsfilter), "caps", filter_caps, NULL);
1896 gst_caps_unref (filter_caps);
1897 gst_element_set_state (capsfilter, GST_STATE_PAUSED);
1898 gst_bin_add (GST_BIN_CAST (dbin), gst_object_ref (capsfilter));
1899
1900 decode_pad_set_target (dpad, NULL);
1901 p = gst_element_get_static_pad (capsfilter, "sink");
1902 gst_pad_link_full (pad, p, GST_PAD_LINK_CHECK_NOTHING);
1903 gst_object_unref (p);
1904 p = gst_element_get_static_pad (capsfilter, "src");
1905 decode_pad_set_target (dpad, p);
1906 pad = p;
1907
1908 gst_caps_unref (caps);
1909
1910 caps = gst_pad_get_current_caps (pad);
1911 if (!caps) {
1912 GST_DEBUG_OBJECT (dbin, "No final caps set yet, delaying autoplugging");
1913 gst_object_unref (dpad);
1914 g_value_array_free (factories);
1915 goto setup_caps_delay;
1916 }
1917 }
1918
1919 /* 1.h else continue autoplugging something from the list. */
1920 GST_LOG_OBJECT (pad, "Let's continue discovery on this pad");
1921 res =
1922 connect_pad (dbin, src, dpad, pad, caps, factories, chain,
1923 &deadend_details);
1924
1925 /* Need to unref the capsfilter srcpad here if
1926 * we inserted a capsfilter */
1927 if (is_parser_converter)
1928 gst_object_unref (pad);
1929
1930 gst_object_unref (dpad);
1931 g_value_array_free (factories);
1932
1933 if (!res)
1934 goto unknown_type;
1935
1936 gst_caps_unref (caps);
1937
1938 return FALSE;
1939
1940 expose_pad:
1941 {
1942 GST_LOG_OBJECT (dbin, "Pad is final and should expose the pad. "
1943 "autoplug-continue:%d", apcontinue);
1944 gst_object_unref (dpad);
1945 gst_caps_unref (caps);
1946 return TRUE;
1947 }
1948
1949 discarded_type:
1950 {
1951 GST_LOG_OBJECT (pad, "Known type, but discarded because not final caps");
1952 chain->deadend = TRUE;
1953 chain->endcaps = caps;
1954 gst_object_replace ((GstObject **) & chain->current_pad, NULL);
1955
1956 /* Try to expose anything */
1957 EXPOSE_LOCK (dbin);
1958 if (dbin->decode_chain) {
1959 if (gst_decode_chain_is_complete (dbin->decode_chain)) {
1960 gst_decode_bin_expose (dbin);
1961 }
1962 }
1963 EXPOSE_UNLOCK (dbin);
1964 do_async_done (dbin);
1965
1966 return FALSE;
1967 }
1968
1969 unknown_type:
1970 {
1971 GST_LOG_OBJECT (pad, "Unknown type, posting message and firing signal");
1972
1973 chain->deadend_details = deadend_details;
1974 chain->deadend = TRUE;
1975 chain->endcaps = caps;
1976 gst_object_replace ((GstObject **) & chain->current_pad, NULL);
1977
1978 gst_element_post_message (GST_ELEMENT_CAST (dbin),
1979 gst_missing_decoder_message_new (GST_ELEMENT_CAST (dbin), caps));
1980
1981 g_signal_emit (G_OBJECT (dbin),
1982 gst_decode_bin_signals[SIGNAL_UNKNOWN_TYPE], 0, pad, caps);
1983
1984 /* Try to expose anything */
1985 EXPOSE_LOCK (dbin);
1986 if (dbin->decode_chain) {
1987 if (gst_decode_chain_is_complete (dbin->decode_chain)) {
1988 gst_decode_bin_expose (dbin);
1989 }
1990 }
1991 EXPOSE_UNLOCK (dbin);
1992
1993 if (src == dbin->typefind) {
1994 if (!caps || gst_caps_is_empty (caps)) {
1995 GST_ELEMENT_ERROR (dbin, STREAM, TYPE_NOT_FOUND,
1996 (_("Could not determine type of stream")), (NULL));
1997 }
1998 do_async_done (dbin);
1999 }
2000 return FALSE;
2001 }
2002 non_fixed:
2003 {
2004 GST_DEBUG_OBJECT (pad, "pad has non-fixed caps delay autoplugging");
2005 gst_object_unref (dpad);
2006 goto setup_caps_delay;
2007 }
2008 any_caps:
2009 {
2010 GST_DEBUG_OBJECT (pad, "pad has ANY caps, delaying auto-pluggin");
2011 goto setup_caps_delay;
2012 }
2013 setup_caps_delay:
2014 {
2015 GstPendingPad *ppad;
2016
2017 /* connect to caps notification */
2018 CHAIN_MUTEX_LOCK (chain);
2019 GST_LOG_OBJECT (dbin, "Chain %p has now %d dynamic pads", chain,
2020 g_list_length (chain->pending_pads));
2021 ppad = g_slice_new0 (GstPendingPad);
2022 ppad->pad = gst_object_ref (pad);
2023 ppad->chain = chain;
2024 ppad->event_probe_id =
2025 gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
2026 pad_event_cb, ppad, NULL);
2027 chain->pending_pads = g_list_prepend (chain->pending_pads, ppad);
2028 ppad->notify_caps_id = g_signal_connect (pad, "notify::caps",
2029 G_CALLBACK (caps_notify_cb), chain);
2030 CHAIN_MUTEX_UNLOCK (chain);
2031
2032 /* If we're here because we have a Parser/Converter
2033 * we have to unref the pad */
2034 if (is_parser_converter)
2035 gst_object_unref (pad);
2036 if (caps)
2037 gst_caps_unref (caps);
2038
2039 return FALSE;
2040 }
2041 }
2042
2043 static void
add_error_filter(GstDecodeBin * dbin,GstElement * element)2044 add_error_filter (GstDecodeBin * dbin, GstElement * element)
2045 {
2046 GST_OBJECT_LOCK (dbin);
2047 dbin->filtered = g_list_prepend (dbin->filtered, element);
2048 GST_OBJECT_UNLOCK (dbin);
2049 }
2050
2051 static void
remove_error_filter(GstDecodeBin * dbin,GstElement * element,GstMessage ** error)2052 remove_error_filter (GstDecodeBin * dbin, GstElement * element,
2053 GstMessage ** error)
2054 {
2055 GList *l;
2056
2057 GST_OBJECT_LOCK (dbin);
2058 dbin->filtered = g_list_remove (dbin->filtered, element);
2059
2060 if (error)
2061 *error = NULL;
2062
2063 l = dbin->filtered_errors;
2064 while (l) {
2065 GstMessage *msg = l->data;
2066
2067 if (GST_MESSAGE_SRC (msg) == GST_OBJECT_CAST (element)) {
2068 /* Get the last error of this element, i.e. the earliest */
2069 if (error)
2070 gst_message_replace (error, msg);
2071 gst_message_unref (msg);
2072 l = dbin->filtered_errors = g_list_delete_link (dbin->filtered_errors, l);
2073 } else {
2074 l = l->next;
2075 }
2076 }
2077 GST_OBJECT_UNLOCK (dbin);
2078 }
2079
2080 typedef struct
2081 {
2082 gboolean ret;
2083 GstPad *peer;
2084 } SendStickyEventsData;
2085
2086 static gboolean
send_sticky_event(GstPad * pad,GstEvent ** event,gpointer user_data)2087 send_sticky_event (GstPad * pad, GstEvent ** event, gpointer user_data)
2088 {
2089 SendStickyEventsData *data = user_data;
2090 gboolean ret;
2091
2092 ret = gst_pad_send_event (data->peer, gst_event_ref (*event));
2093 if (!ret)
2094 data->ret = FALSE;
2095
2096 return data->ret;
2097 }
2098
2099 static gboolean
send_sticky_events(GstDecodeBin * dbin,GstPad * pad)2100 send_sticky_events (GstDecodeBin * dbin, GstPad * pad)
2101 {
2102 SendStickyEventsData data;
2103
2104 data.ret = TRUE;
2105 data.peer = gst_pad_get_peer (pad);
2106
2107 gst_pad_sticky_events_foreach (pad, send_sticky_event, &data);
2108
2109 gst_object_unref (data.peer);
2110
2111 return data.ret;
2112 }
2113
2114 static gchar *
error_message_to_string(GstMessage * msg)2115 error_message_to_string (GstMessage * msg)
2116 {
2117 GError *err;
2118 gchar *debug, *message, *full_message;
2119
2120 gst_message_parse_error (msg, &err, &debug);
2121
2122 message = gst_error_get_message (err->domain, err->code);
2123
2124 if (debug)
2125 full_message = g_strdup_printf ("%s\n%s\n%s", message, err->message, debug);
2126 else
2127 full_message = g_strdup_printf ("%s\n%s", message, err->message);
2128
2129 g_free (message);
2130 g_free (debug);
2131 g_clear_error (&err);
2132
2133 return full_message;
2134 }
2135
2136 static GstPadProbeReturn
demuxer_source_pad_probe(GstPad * pad,GstPadProbeInfo * info,gpointer user_data)2137 demuxer_source_pad_probe (GstPad * pad, GstPadProbeInfo * info,
2138 gpointer user_data)
2139 {
2140 GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
2141 GstDecodeGroup *group = (GstDecodeGroup *) user_data;
2142 GstDecodeChain *parent_chain = group->parent;
2143
2144 GST_DEBUG_OBJECT (pad, "Saw event %s", GST_EVENT_TYPE_NAME (event));
2145 /* Check if we are the active group, if not we need to proxy the flush
2146 * events to the other groups (of which at least one is exposed, ensuring
2147 * flushing properly propagates downstream of decodebin */
2148 if (parent_chain->active_group == group)
2149 return GST_PAD_PROBE_OK;
2150
2151 switch (GST_EVENT_TYPE (event)) {
2152 case GST_EVENT_FLUSH_START:
2153 case GST_EVENT_FLUSH_STOP:
2154 {
2155 GList *tmp;
2156 GST_DEBUG_OBJECT (pad, "Proxying flush events to inactive groups");
2157 /* Proxy to active group */
2158 for (tmp = parent_chain->active_group->reqpads; tmp; tmp = tmp->next) {
2159 GstPad *reqpad = (GstPad *) tmp->data;
2160 gst_pad_send_event (reqpad, gst_event_ref (event));
2161 }
2162 /* Proxy to other non-active groups (except ourself) */
2163 for (tmp = parent_chain->next_groups; tmp; tmp = tmp->next) {
2164 GList *tmp2;
2165 GstDecodeGroup *tmpgroup = (GstDecodeGroup *) tmp->data;
2166 if (tmpgroup != group) {
2167 for (tmp2 = tmpgroup->reqpads; tmp2; tmp2 = tmp2->next) {
2168 GstPad *reqpad = (GstPad *) tmp2->data;
2169 gst_pad_send_event (reqpad, gst_event_ref (event));
2170 }
2171 }
2172 }
2173 flush_chain (parent_chain,
2174 GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_START);
2175 }
2176 break;
2177 default:
2178 break;
2179 }
2180
2181 return GST_PAD_PROBE_OK;
2182 }
2183
2184 typedef struct
2185 {
2186 GstDecodeChain *chain;
2187 GstPad *pad;
2188 } PadExposeData;
2189
2190 /* connect_pad:
2191 *
2192 * Try to connect the given pad to an element created from one of the factories,
2193 * and recursively.
2194 *
2195 * Note that dpad is ghosting pad, and so pad is linked; be sure to unset dpad's
2196 * target before trying to link pad.
2197 *
2198 * Returns TRUE if an element was properly created and linked
2199 */
2200 static gboolean
connect_pad(GstDecodeBin * dbin,GstElement * src,GstDecodePad * dpad,GstPad * pad,GstCaps * caps,GValueArray * factories,GstDecodeChain * chain,gchar ** deadend_details)2201 connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad,
2202 GstPad * pad, GstCaps * caps, GValueArray * factories,
2203 GstDecodeChain * chain, gchar ** deadend_details)
2204 {
2205 gboolean res = FALSE;
2206 GstPad *mqpad = NULL;
2207 gboolean is_demuxer = chain->parent && !chain->elements; /* First pad after the demuxer */
2208 GString *error_details = NULL;
2209
2210 g_return_val_if_fail (factories != NULL, FALSE);
2211 g_return_val_if_fail (factories->n_values > 0, FALSE);
2212
2213 GST_DEBUG_OBJECT (dbin,
2214 "pad %s:%s , chain:%p, %d factories, caps %" GST_PTR_FORMAT,
2215 GST_DEBUG_PAD_NAME (pad), chain, factories->n_values, caps);
2216
2217 /* 1. is element demuxer or parser */
2218 if (is_demuxer) {
2219 GST_LOG_OBJECT (src,
2220 "is a demuxer, connecting the pad through multiqueue '%s'",
2221 GST_OBJECT_NAME (chain->parent->multiqueue));
2222
2223 /* Set a flush-start/-stop probe on the downstream events */
2224 chain->pad_probe_id =
2225 gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_FLUSH,
2226 demuxer_source_pad_probe, chain->parent, NULL);
2227
2228 decode_pad_set_target (dpad, NULL);
2229 if (!(mqpad = gst_decode_group_control_demuxer_pad (chain->parent, pad)))
2230 goto beach;
2231 src = chain->parent->multiqueue;
2232 /* Forward sticky events to mq src pad to allow factory initialization */
2233 gst_pad_sticky_events_foreach (pad, copy_sticky_events, mqpad);
2234 pad = mqpad;
2235 decode_pad_set_target (dpad, pad);
2236 }
2237
2238 error_details = g_string_new ("");
2239
2240 /* 2. Try to create an element and link to it */
2241 while (factories->n_values > 0) {
2242 GstAutoplugSelectResult ret;
2243 GstElementFactory *factory;
2244 GstDecodeElement *delem;
2245 GstElement *element;
2246 GstPad *sinkpad;
2247 GParamSpec *pspec;
2248 gboolean subtitle;
2249 GList *to_connect = NULL;
2250 GList *to_expose = NULL;
2251 gboolean is_parser = FALSE;
2252 gboolean is_decoder = FALSE;
2253
2254 /* Set dpad target to pad again, it might've been unset
2255 * below but we came back here because something failed
2256 */
2257 decode_pad_set_target (dpad, pad);
2258
2259 /* take first factory */
2260 factory = g_value_get_object (g_value_array_get_nth (factories, 0));
2261 /* Remove selected factory from the list. */
2262 g_value_array_remove (factories, 0);
2263
2264 GST_LOG_OBJECT (src, "trying factory %" GST_PTR_FORMAT, factory);
2265
2266 /* Check if the caps are really supported by the factory. The
2267 * factory list is non-empty-subset filtered while caps
2268 * are only accepted by a pad if they are a subset of the
2269 * pad caps.
2270 *
2271 * FIXME: Only do this for fixed caps here. Non-fixed caps
2272 * can happen if a Parser/Converter was autoplugged before
2273 * this. We then assume that it will be able to convert to
2274 * everything that the decoder would want.
2275 *
2276 * A subset check will fail here because the parser caps
2277 * will be generic and while the decoder will only
2278 * support a subset of the parser caps.
2279 */
2280 if (gst_caps_is_fixed (caps)) {
2281 const GList *templs;
2282 gboolean skip = FALSE;
2283
2284 templs = gst_element_factory_get_static_pad_templates (factory);
2285
2286 while (templs) {
2287 GstStaticPadTemplate *templ = (GstStaticPadTemplate *) templs->data;
2288
2289 if (templ->direction == GST_PAD_SINK) {
2290 GstCaps *templcaps = gst_static_caps_get (&templ->static_caps);
2291
2292 if (!gst_caps_is_subset (caps, templcaps)) {
2293 GST_DEBUG_OBJECT (src,
2294 "caps %" GST_PTR_FORMAT " not subset of %" GST_PTR_FORMAT, caps,
2295 templcaps);
2296 gst_caps_unref (templcaps);
2297 skip = TRUE;
2298 break;
2299 }
2300
2301 gst_caps_unref (templcaps);
2302 }
2303 templs = g_list_next (templs);
2304 }
2305 if (skip)
2306 continue;
2307 }
2308
2309 /* If the factory is for a parser we first check if the factory
2310 * was already used for the current chain. If it was used already
2311 * we would otherwise create an infinite loop here because the
2312 * parser apparently accepts its own output as input.
2313 * This is only done for parsers because it's perfectly valid
2314 * to have other element classes after each other because a
2315 * parser is the only one that does not change the data. A
2316 * valid example for this would be multiple id3demux in a row.
2317 */
2318 is_parser = strstr (gst_element_factory_get_metadata (factory,
2319 GST_ELEMENT_METADATA_KLASS), "Parser") != NULL;
2320
2321 if (is_parser) {
2322 gboolean skip = FALSE;
2323 GList *l;
2324
2325 CHAIN_MUTEX_LOCK (chain);
2326 for (l = chain->elements; l; l = l->next) {
2327 GstDecodeElement *delem = (GstDecodeElement *) l->data;
2328 GstElement *otherelement = delem->element;
2329
2330 if (gst_element_get_factory (otherelement) == factory) {
2331 skip = TRUE;
2332 break;
2333 }
2334 }
2335
2336 if (!skip && chain->parent && chain->parent->parent) {
2337 GstDecodeChain *parent_chain = chain->parent->parent;
2338 GstDecodeElement *pelem =
2339 parent_chain->elements ? parent_chain->elements->data : NULL;
2340
2341 if (pelem && gst_element_get_factory (pelem->element) == factory)
2342 skip = TRUE;
2343 }
2344 CHAIN_MUTEX_UNLOCK (chain);
2345 if (skip) {
2346 GST_DEBUG_OBJECT (dbin,
2347 "Skipping factory '%s' because it was already used in this chain",
2348 gst_plugin_feature_get_name (GST_PLUGIN_FEATURE_CAST (factory)));
2349 continue;
2350 }
2351
2352 }
2353
2354 /* emit autoplug-select to see what we should do with it. */
2355 g_signal_emit (G_OBJECT (dbin),
2356 gst_decode_bin_signals[SIGNAL_AUTOPLUG_SELECT],
2357 0, dpad, caps, factory, &ret);
2358
2359 switch (ret) {
2360 case GST_AUTOPLUG_SELECT_TRY:
2361 GST_DEBUG_OBJECT (dbin, "autoplug select requested try");
2362 break;
2363 case GST_AUTOPLUG_SELECT_EXPOSE:
2364 GST_DEBUG_OBJECT (dbin, "autoplug select requested expose");
2365 /* expose the pad, we don't have the source element */
2366 expose_pad (dbin, src, dpad, pad, caps, chain);
2367 res = TRUE;
2368 goto beach;
2369 case GST_AUTOPLUG_SELECT_SKIP:
2370 GST_DEBUG_OBJECT (dbin, "autoplug select requested skip");
2371 continue;
2372 default:
2373 GST_WARNING_OBJECT (dbin, "autoplug select returned unhandled %d", ret);
2374 break;
2375 }
2376
2377 /* 2.0. Unlink pad */
2378 decode_pad_set_target (dpad, NULL);
2379
2380 /* 2.1. Try to create an element */
2381 if ((element = gst_element_factory_create (factory, NULL)) == NULL) {
2382 GST_WARNING_OBJECT (dbin, "Could not create an element from %s",
2383 gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
2384 g_string_append_printf (error_details,
2385 "Could not create an element from %s\n",
2386 gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
2387 continue;
2388 }
2389
2390 /* Filter errors, this will prevent the element from causing the pipeline
2391 * to error while we test it using READY state. */
2392 add_error_filter (dbin, element);
2393
2394 /* We don't yet want the bin to control the element's state */
2395 gst_element_set_locked_state (element, TRUE);
2396
2397 /* ... add it ... */
2398 if (!(gst_bin_add (GST_BIN_CAST (dbin), element))) {
2399 GST_WARNING_OBJECT (dbin, "Couldn't add %s to the bin",
2400 GST_ELEMENT_NAME (element));
2401 remove_error_filter (dbin, element, NULL);
2402 g_string_append_printf (error_details, "Couldn't add %s to the bin\n",
2403 GST_ELEMENT_NAME (element));
2404 gst_object_unref (element);
2405 continue;
2406 }
2407
2408 /* Find its sink pad. */
2409 if (!(sinkpad = find_sink_pad (element))) {
2410 GST_WARNING_OBJECT (dbin, "Element %s doesn't have a sink pad",
2411 GST_ELEMENT_NAME (element));
2412 remove_error_filter (dbin, element, NULL);
2413 g_string_append_printf (error_details,
2414 "Element %s doesn't have a sink pad", GST_ELEMENT_NAME (element));
2415 gst_bin_remove (GST_BIN (dbin), element);
2416 continue;
2417 }
2418
2419 /* ... and try to link */
2420 if ((gst_pad_link_full (pad, sinkpad,
2421 GST_PAD_LINK_CHECK_NOTHING)) != GST_PAD_LINK_OK) {
2422 GST_WARNING_OBJECT (dbin, "Link failed on pad %s:%s",
2423 GST_DEBUG_PAD_NAME (sinkpad));
2424 remove_error_filter (dbin, element, NULL);
2425 g_string_append_printf (error_details, "Link failed on pad %s:%s",
2426 GST_DEBUG_PAD_NAME (sinkpad));
2427 gst_object_unref (sinkpad);
2428 gst_bin_remove (GST_BIN (dbin), element);
2429 continue;
2430 }
2431
2432 /* ... activate it ... */
2433 if ((gst_element_set_state (element,
2434 GST_STATE_READY)) == GST_STATE_CHANGE_FAILURE) {
2435 GstMessage *error_msg;
2436
2437 GST_WARNING_OBJECT (dbin, "Couldn't set %s to READY",
2438 GST_ELEMENT_NAME (element));
2439 remove_error_filter (dbin, element, &error_msg);
2440
2441 if (error_msg) {
2442 gchar *error_string = error_message_to_string (error_msg);
2443 g_string_append_printf (error_details, "Couldn't set %s to READY:\n%s",
2444 GST_ELEMENT_NAME (element), error_string);
2445 gst_message_unref (error_msg);
2446 g_free (error_string);
2447 } else {
2448 g_string_append_printf (error_details, "Couldn't set %s to READY",
2449 GST_ELEMENT_NAME (element));
2450 }
2451 gst_object_unref (sinkpad);
2452 gst_bin_remove (GST_BIN (dbin), element);
2453 continue;
2454 }
2455
2456 /* check if we still accept the caps on the pad after setting
2457 * the element to READY */
2458 if (!gst_pad_query_accept_caps (sinkpad, caps)) {
2459 GstMessage *error_msg;
2460
2461 GST_WARNING_OBJECT (dbin, "Element %s does not accept caps",
2462 GST_ELEMENT_NAME (element));
2463
2464 remove_error_filter (dbin, element, &error_msg);
2465
2466 if (error_msg) {
2467 gchar *error_string = error_message_to_string (error_msg);
2468 g_string_append_printf (error_details,
2469 "Element %s does not accept caps:\n%s", GST_ELEMENT_NAME (element),
2470 error_string);
2471 gst_message_unref (error_msg);
2472 g_free (error_string);
2473 } else {
2474 g_string_append_printf (error_details,
2475 "Element %s does not accept caps", GST_ELEMENT_NAME (element));
2476 }
2477
2478 gst_element_set_state (element, GST_STATE_NULL);
2479 gst_object_unref (sinkpad);
2480 gst_bin_remove (GST_BIN (dbin), element);
2481 continue;
2482 }
2483
2484 gst_object_unref (sinkpad);
2485 GST_LOG_OBJECT (dbin, "linked on pad %s:%s", GST_DEBUG_PAD_NAME (pad));
2486
2487 CHAIN_MUTEX_LOCK (chain);
2488 delem = g_slice_new0 (GstDecodeElement);
2489 delem->element = gst_object_ref (element);
2490 delem->capsfilter = NULL;
2491 chain->elements = g_list_prepend (chain->elements, delem);
2492 chain->demuxer = is_demuxer_element (element);
2493 chain->adaptive_demuxer = is_adaptive_demuxer_element (element);
2494
2495 is_decoder = strstr (gst_element_factory_get_metadata (factory,
2496 GST_ELEMENT_METADATA_KLASS), "Decoder") != NULL;
2497
2498 /* For adaptive streaming demuxer we insert a multiqueue after
2499 * this demuxer.
2500 * Now for the case where we have a container stream inside these
2501 * buffers, another demuxer will be plugged and after this second
2502 * demuxer there will be a second multiqueue. This second multiqueue
2503 * will get smaller buffers and will be the one emitting buffering
2504 * messages.
2505 * If we don't have a container stream inside the fragment buffers,
2506 * we'll insert a multiqueue below right after the next element after
2507 * the adaptive streaming demuxer. This is going to be a parser or
2508 * decoder, and will output smaller buffers.
2509 */
2510 if (chain->parent && chain->parent->parent) {
2511 GstDecodeChain *parent_chain = chain->parent->parent;
2512
2513 if (parent_chain->adaptive_demuxer && (is_parser || is_decoder))
2514 chain->demuxer = TRUE;
2515 }
2516
2517 /* If we are configured to use buffering and there is no demuxer in the
2518 * chain, we still want a multiqueue, otherwise we will ignore the
2519 * use-buffering property. In that case, we will insert a multiqueue after
2520 * the parser or decoder - not elsewhere, otherwise we won't have
2521 * timestamps.
2522 */
2523
2524 if (!chain->parent && (is_parser || is_decoder) && dbin->use_buffering) {
2525 chain->demuxer = TRUE;
2526 if (is_decoder) {
2527 GST_WARNING_OBJECT (dbin,
2528 "Buffering messages used for decoded and non-parsed data");
2529 }
2530 }
2531
2532 CHAIN_MUTEX_UNLOCK (chain);
2533
2534 /* Set connection-speed property if needed */
2535 if (chain->demuxer) {
2536 GParamSpec *pspec;
2537
2538 if ((pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (element),
2539 "connection-speed"))) {
2540 guint64 speed = dbin->connection_speed / 1000;
2541 gboolean wrong_type = FALSE;
2542
2543 if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_UINT) {
2544 GParamSpecUInt *pspecuint = G_PARAM_SPEC_UINT (pspec);
2545
2546 speed = CLAMP (speed, pspecuint->minimum, pspecuint->maximum);
2547 } else if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_INT) {
2548 GParamSpecInt *pspecint = G_PARAM_SPEC_INT (pspec);
2549
2550 speed = CLAMP (speed, pspecint->minimum, pspecint->maximum);
2551 } else if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_UINT64) {
2552 GParamSpecUInt64 *pspecuint = G_PARAM_SPEC_UINT64 (pspec);
2553
2554 speed = CLAMP (speed, pspecuint->minimum, pspecuint->maximum);
2555 } else if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_INT64) {
2556 GParamSpecInt64 *pspecint = G_PARAM_SPEC_INT64 (pspec);
2557
2558 speed = CLAMP (speed, pspecint->minimum, pspecint->maximum);
2559 } else {
2560 GST_WARNING_OBJECT (dbin,
2561 "The connection speed property %" G_GUINT64_FORMAT " of type %s"
2562 " is not usefull not setting it", speed,
2563 g_type_name (G_PARAM_SPEC_TYPE (pspec)));
2564 wrong_type = TRUE;
2565 }
2566
2567 if (!wrong_type) {
2568 GST_DEBUG_OBJECT (dbin, "setting connection-speed=%" G_GUINT64_FORMAT
2569 " to demuxer element", speed);
2570
2571 g_object_set (element, "connection-speed", speed, NULL);
2572 }
2573 }
2574 }
2575
2576 /* try to configure the subtitle encoding property when we can */
2577 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (element),
2578 "subtitle-encoding");
2579 if (pspec && G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_STRING) {
2580 SUBTITLE_LOCK (dbin);
2581 GST_DEBUG_OBJECT (dbin,
2582 "setting subtitle-encoding=%s to element", dbin->encoding);
2583 g_object_set (G_OBJECT (element), "subtitle-encoding", dbin->encoding,
2584 NULL);
2585 SUBTITLE_UNLOCK (dbin);
2586 subtitle = TRUE;
2587 } else {
2588 subtitle = FALSE;
2589 }
2590
2591 /* link this element further */
2592 to_connect = connect_element (dbin, delem, chain);
2593
2594 while (to_connect) {
2595 GstPad *opad = to_connect->data;
2596 gboolean expose_pad = FALSE;
2597 GstDecodeChain *new_chain;
2598 GstCaps *ocaps;
2599
2600 ocaps = get_pad_caps (opad);
2601 expose_pad =
2602 analyze_new_pad (dbin, delem->element, opad, ocaps, chain,
2603 &new_chain);
2604
2605 if (ocaps)
2606 gst_caps_unref (ocaps);
2607
2608 if (expose_pad) {
2609 PadExposeData *expose_data = g_new0 (PadExposeData, 1);
2610 expose_data->chain = new_chain;
2611 expose_data->pad = gst_object_ref (opad);
2612 to_expose = g_list_prepend (to_expose, expose_data);
2613 }
2614
2615 gst_object_unref (opad);
2616 to_connect = g_list_delete_link (to_connect, to_connect);
2617 }
2618 /* any pads left in to_expose are to be exposed */
2619
2620 /* Bring the element to the state of the parent */
2621
2622 /* First lock element's sinkpad stream lock so no data reaches
2623 * the possible new element added when caps are sent by element
2624 * while we're still sending sticky events */
2625 GST_PAD_STREAM_LOCK (sinkpad);
2626
2627 if ((gst_element_set_state (element,
2628 GST_STATE_PAUSED)) == GST_STATE_CHANGE_FAILURE ||
2629 !send_sticky_events (dbin, pad)) {
2630 GstDecodeElement *dtmp = NULL;
2631 GstElement *tmp = NULL;
2632 GstMessage *error_msg;
2633
2634 GST_PAD_STREAM_UNLOCK (sinkpad);
2635
2636 GST_WARNING_OBJECT (dbin, "Couldn't set %s to PAUSED",
2637 GST_ELEMENT_NAME (element));
2638
2639 while (to_expose) {
2640 PadExposeData *expose_data = to_expose->data;
2641 gst_object_unref (expose_data->pad);
2642 g_free (expose_data);
2643 to_expose = g_list_delete_link (to_expose, to_expose);
2644 }
2645
2646 remove_error_filter (dbin, element, &error_msg);
2647
2648 if (error_msg) {
2649 gchar *error_string = error_message_to_string (error_msg);
2650 g_string_append_printf (error_details, "Couldn't set %s to PAUSED:\n%s",
2651 GST_ELEMENT_NAME (element), error_string);
2652 gst_message_unref (error_msg);
2653 g_free (error_string);
2654 } else {
2655 g_string_append_printf (error_details, "Couldn't set %s to PAUSED",
2656 GST_ELEMENT_NAME (element));
2657 }
2658
2659 /* Remove all elements in this chain that were just added. No
2660 * other thread could've added elements in the meantime */
2661 CHAIN_MUTEX_LOCK (chain);
2662 do {
2663 GList *l;
2664
2665 dtmp = chain->elements->data;
2666 tmp = dtmp->element;
2667
2668 /* Disconnect any signal handlers that might be connected
2669 * in connect_element() or analyze_pad() */
2670 if (dtmp->pad_added_id)
2671 g_signal_handler_disconnect (tmp, dtmp->pad_added_id);
2672 if (dtmp->pad_removed_id)
2673 g_signal_handler_disconnect (tmp, dtmp->pad_removed_id);
2674 if (dtmp->no_more_pads_id)
2675 g_signal_handler_disconnect (tmp, dtmp->no_more_pads_id);
2676
2677 for (l = chain->pending_pads; l;) {
2678 GstPendingPad *pp = l->data;
2679 GList *n;
2680
2681 if (GST_PAD_PARENT (pp->pad) != tmp) {
2682 l = l->next;
2683 continue;
2684 }
2685
2686 gst_pending_pad_free (pp);
2687
2688 /* Remove element from the list, update list head and go to the
2689 * next element in the list */
2690 n = l->next;
2691 chain->pending_pads = g_list_delete_link (chain->pending_pads, l);
2692 l = n;
2693 }
2694
2695 if (dtmp->capsfilter) {
2696 gst_bin_remove (GST_BIN (dbin), dtmp->capsfilter);
2697 gst_element_set_state (dtmp->capsfilter, GST_STATE_NULL);
2698 gst_object_unref (dtmp->capsfilter);
2699 }
2700
2701 gst_bin_remove (GST_BIN (dbin), tmp);
2702 gst_element_set_state (tmp, GST_STATE_NULL);
2703
2704 gst_object_unref (tmp);
2705 g_slice_free (GstDecodeElement, dtmp);
2706
2707 chain->elements = g_list_delete_link (chain->elements, chain->elements);
2708 } while (tmp != element);
2709 CHAIN_MUTEX_UNLOCK (chain);
2710
2711 continue;
2712 } else {
2713 /* Everything went well, the spice must flow now */
2714 GST_PAD_STREAM_UNLOCK (sinkpad);
2715 }
2716
2717 /* Remove error filter now, from now on we can't gracefully
2718 * handle errors of the element anymore */
2719 remove_error_filter (dbin, element, NULL);
2720
2721 /* Now let the bin handle the state */
2722 gst_element_set_locked_state (element, FALSE);
2723
2724 if (subtitle) {
2725 SUBTITLE_LOCK (dbin);
2726 /* we added the element now, add it to the list of subtitle-encoding
2727 * elements when we can set the property */
2728 dbin->subtitles = g_list_prepend (dbin->subtitles, element);
2729 SUBTITLE_UNLOCK (dbin);
2730 }
2731
2732 while (to_expose) {
2733 PadExposeData *expose_data = to_expose->data;
2734 GstCaps *ocaps;
2735
2736 ocaps = get_pad_caps (expose_data->pad);
2737 expose_pad (dbin, delem->element, expose_data->chain->current_pad,
2738 expose_data->pad, ocaps, expose_data->chain);
2739
2740 if (ocaps)
2741 gst_caps_unref (ocaps);
2742
2743 gst_object_unref (expose_data->pad);
2744 g_free (expose_data);
2745 to_expose = g_list_delete_link (to_expose, to_expose);
2746 }
2747
2748 res = TRUE;
2749 break;
2750 }
2751
2752 beach:
2753 if (mqpad)
2754 gst_object_unref (mqpad);
2755
2756 if (error_details)
2757 *deadend_details = g_string_free (error_details, (error_details->len == 0
2758 || res));
2759 else
2760 *deadend_details = NULL;
2761
2762 return res;
2763 }
2764
2765 static GstCaps *
get_pad_caps(GstPad * pad)2766 get_pad_caps (GstPad * pad)
2767 {
2768 GstCaps *caps;
2769
2770 /* first check the pad caps, if this is set, we are positively sure it is
2771 * fixed and exactly what the element will produce. */
2772 caps = gst_pad_get_current_caps (pad);
2773
2774 /* then use the getcaps function if we don't have caps. These caps might not
2775 * be fixed in some cases, in which case analyze_new_pad will set up a
2776 * notify::caps signal to continue autoplugging. */
2777 if (caps == NULL)
2778 caps = gst_pad_query_caps (pad, NULL);
2779
2780 return caps;
2781 }
2782
2783 /* Returns a list of pads that can be connected to already and
2784 * connects to pad-added and related signals */
2785 static GList *
connect_element(GstDecodeBin * dbin,GstDecodeElement * delem,GstDecodeChain * chain)2786 connect_element (GstDecodeBin * dbin, GstDecodeElement * delem,
2787 GstDecodeChain * chain)
2788 {
2789 GstElement *element = delem->element;
2790 GList *pads;
2791 gboolean dynamic = FALSE;
2792 GList *to_connect = NULL;
2793
2794 GST_DEBUG_OBJECT (dbin, "Attempting to connect element %s [chain:%p] further",
2795 GST_ELEMENT_NAME (element), chain);
2796
2797 /* 1. Loop over pad templates, grabbing existing pads along the way */
2798 for (pads = GST_ELEMENT_GET_CLASS (element)->padtemplates; pads;
2799 pads = g_list_next (pads)) {
2800 GstPadTemplate *templ = GST_PAD_TEMPLATE (pads->data);
2801 const gchar *templ_name;
2802
2803 /* we are only interested in source pads */
2804 if (GST_PAD_TEMPLATE_DIRECTION (templ) != GST_PAD_SRC)
2805 continue;
2806
2807 templ_name = GST_PAD_TEMPLATE_NAME_TEMPLATE (templ);
2808 GST_DEBUG_OBJECT (dbin, "got a source pad template %s", templ_name);
2809
2810 /* figure out what kind of pad this is */
2811 switch (GST_PAD_TEMPLATE_PRESENCE (templ)) {
2812 case GST_PAD_ALWAYS:
2813 {
2814 /* get the pad that we need to autoplug */
2815 GstPad *pad = gst_element_get_static_pad (element, templ_name);
2816
2817 if (pad) {
2818 GST_DEBUG_OBJECT (dbin, "got the pad for always template %s",
2819 templ_name);
2820 /* here is the pad, we need to autoplug it */
2821 to_connect = g_list_prepend (to_connect, pad);
2822 } else {
2823 /* strange, pad is marked as always but it's not
2824 * there. Fix the element */
2825 GST_WARNING_OBJECT (dbin,
2826 "could not get the pad for always template %s", templ_name);
2827 }
2828 break;
2829 }
2830 case GST_PAD_SOMETIMES:
2831 {
2832 /* try to get the pad to see if it is already created or
2833 * not */
2834 GstPad *pad = gst_element_get_static_pad (element, templ_name);
2835
2836 if (pad) {
2837 GST_DEBUG_OBJECT (dbin, "got the pad for sometimes template %s",
2838 templ_name);
2839 /* the pad is created, we need to autoplug it */
2840 to_connect = g_list_prepend (to_connect, pad);
2841 } else {
2842 GST_DEBUG_OBJECT (dbin,
2843 "did not get the sometimes pad of template %s", templ_name);
2844 /* we have an element that will create dynamic pads */
2845 dynamic = TRUE;
2846 }
2847 break;
2848 }
2849 case GST_PAD_REQUEST:
2850 /* ignore request pads */
2851 GST_DEBUG_OBJECT (dbin, "ignoring request padtemplate %s", templ_name);
2852 break;
2853 }
2854 }
2855
2856 /* 2. if there are more potential pads, connect to relevant signals */
2857 if (dynamic) {
2858 GST_LOG_OBJECT (dbin, "Adding signals to element %s in chain %p",
2859 GST_ELEMENT_NAME (element), chain);
2860 delem->pad_added_id = g_signal_connect (element, "pad-added",
2861 G_CALLBACK (pad_added_cb), chain);
2862 delem->pad_removed_id = g_signal_connect (element, "pad-removed",
2863 G_CALLBACK (pad_removed_cb), chain);
2864 delem->no_more_pads_id = g_signal_connect (element, "no-more-pads",
2865 G_CALLBACK (no_more_pads_cb), chain);
2866 }
2867
2868 /* 3. return all pads that can be connected to already */
2869
2870 return to_connect;
2871 }
2872
2873 /* expose_pad:
2874 *
2875 * Expose the given pad on the chain as a decoded pad.
2876 */
2877 static void
expose_pad(GstDecodeBin * dbin,GstElement * src,GstDecodePad * dpad,GstPad * pad,GstCaps * caps,GstDecodeChain * chain)2878 expose_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad,
2879 GstPad * pad, GstCaps * caps, GstDecodeChain * chain)
2880 {
2881 GstPad *mqpad = NULL;
2882
2883 GST_DEBUG_OBJECT (dbin, "pad %s:%s, chain:%p",
2884 GST_DEBUG_PAD_NAME (pad), chain);
2885
2886 /* If this is the first pad for this chain, there are no other elements
2887 * and the source element is not the multiqueue we must link through the
2888 * multiqueue.
2889 *
2890 * This is the case if a demuxer directly exposed a raw pad.
2891 */
2892 if (chain->parent && !chain->elements && src != chain->parent->multiqueue) {
2893 GST_LOG_OBJECT (src, "connecting the pad through multiqueue");
2894
2895 decode_pad_set_target (dpad, NULL);
2896 if (!(mqpad = gst_decode_group_control_demuxer_pad (chain->parent, pad)))
2897 goto beach;
2898 pad = mqpad;
2899 decode_pad_set_target (dpad, pad);
2900 }
2901
2902 gst_decode_pad_activate (dpad, chain);
2903 chain->endpad = gst_object_ref (dpad);
2904 chain->endcaps = gst_caps_ref (caps);
2905
2906 EXPOSE_LOCK (dbin);
2907 if (dbin->decode_chain) {
2908 if (gst_decode_chain_is_complete (dbin->decode_chain)) {
2909 gst_decode_bin_expose (dbin);
2910 }
2911 }
2912 EXPOSE_UNLOCK (dbin);
2913
2914 if (mqpad)
2915 gst_object_unref (mqpad);
2916
2917 beach:
2918 return;
2919 }
2920
2921 /* check_upstream_seekable:
2922 *
2923 * Check if upstream is seekable.
2924 */
2925 static gboolean
check_upstream_seekable(GstDecodeBin * dbin,GstPad * pad)2926 check_upstream_seekable (GstDecodeBin * dbin, GstPad * pad)
2927 {
2928 GstQuery *query;
2929 gint64 start = -1, stop = -1;
2930 gboolean seekable = FALSE;
2931
2932 query = gst_query_new_seeking (GST_FORMAT_BYTES);
2933 if (!gst_pad_peer_query (pad, query)) {
2934 GST_DEBUG_OBJECT (dbin, "seeking query failed");
2935 goto done;
2936 }
2937
2938 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
2939
2940 /* try harder to query upstream size if we didn't get it the first time */
2941 if (seekable && stop == -1) {
2942 GST_DEBUG_OBJECT (dbin, "doing duration query to fix up unset stop");
2943 gst_pad_peer_query_duration (pad, GST_FORMAT_BYTES, &stop);
2944 }
2945
2946 /* if upstream doesn't know the size, it's likely that it's not seekable in
2947 * practice even if it technically may be seekable */
2948 if (seekable && (start != 0 || stop <= start)) {
2949 GST_DEBUG_OBJECT (dbin, "seekable but unknown start/stop -> disable");
2950 seekable = FALSE;
2951 } else {
2952 GST_DEBUG_OBJECT (dbin, "upstream seekable: %d", seekable);
2953 }
2954
2955 done:
2956 gst_query_unref (query);
2957 return seekable;
2958 }
2959
2960 static void
type_found(GstElement * typefind,guint probability,GstCaps * caps,GstDecodeBin * decode_bin)2961 type_found (GstElement * typefind, guint probability,
2962 GstCaps * caps, GstDecodeBin * decode_bin)
2963 {
2964 GstPad *pad, *sink_pad;
2965 GstDecodeChain *chain;
2966
2967 GST_DEBUG_OBJECT (decode_bin, "typefind found caps %" GST_PTR_FORMAT, caps);
2968
2969 /* If the typefinder (but not something else) finds text/plain - i.e. that's
2970 * the top-level type of the file - then error out.
2971 */
2972 if (gst_structure_has_name (gst_caps_get_structure (caps, 0), "text/plain")) {
2973 GST_ELEMENT_ERROR (decode_bin, STREAM, WRONG_TYPE,
2974 (_("This appears to be a text file")),
2975 ("decodebin cannot decode plain text files"));
2976 goto exit;
2977 }
2978
2979 pad = gst_element_get_static_pad (typefind, "src");
2980 sink_pad = gst_element_get_static_pad (typefind, "sink");
2981
2982 /* need some lock here to prevent race with shutdown state change
2983 * which might yank away e.g. decode_chain while building stuff here.
2984 * In typical cases, STREAM_LOCK is held and handles that, it need not
2985 * be held (if called from a proxied setcaps), so grab it anyway */
2986 GST_PAD_STREAM_LOCK (sink_pad);
2987 /* FIXME: we can only deal with one type, we don't yet support dynamically changing
2988 * caps from the typefind element */
2989 if (decode_bin->have_type || decode_bin->decode_chain) {
2990 } else {
2991 decode_bin->have_type = TRUE;
2992
2993 decode_bin->decode_chain = gst_decode_chain_new (decode_bin, NULL, pad);
2994 chain = gst_decode_chain_ref (decode_bin->decode_chain);
2995
2996 if (analyze_new_pad (decode_bin, typefind, pad, caps,
2997 decode_bin->decode_chain, NULL))
2998 expose_pad (decode_bin, typefind, decode_bin->decode_chain->current_pad,
2999 pad, caps, decode_bin->decode_chain);
3000
3001 gst_decode_chain_unref (chain);
3002 }
3003
3004 GST_PAD_STREAM_UNLOCK (sink_pad);
3005 gst_object_unref (sink_pad);
3006 gst_object_unref (pad);
3007
3008 exit:
3009 return;
3010 }
3011
3012 static GstPadProbeReturn
pad_event_cb(GstPad * pad,GstPadProbeInfo * info,gpointer data)3013 pad_event_cb (GstPad * pad, GstPadProbeInfo * info, gpointer data)
3014 {
3015 GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
3016 GstPendingPad *ppad = (GstPendingPad *) data;
3017 GstDecodeChain *chain = ppad->chain;
3018 GstDecodeBin *dbin = chain->dbin;
3019
3020 g_assert (ppad);
3021 g_assert (chain);
3022 g_assert (dbin);
3023 switch (GST_EVENT_TYPE (event)) {
3024 case GST_EVENT_EOS:
3025 GST_DEBUG_OBJECT (pad, "Received EOS on a non final pad, this stream "
3026 "ended too early");
3027 chain->deadend = TRUE;
3028 chain->drained = TRUE;
3029 gst_object_replace ((GstObject **) & chain->current_pad, NULL);
3030 /* we don't set the endcaps because NULL endcaps means early EOS */
3031
3032 EXPOSE_LOCK (dbin);
3033 if (dbin->decode_chain)
3034 if (gst_decode_chain_is_complete (dbin->decode_chain))
3035 gst_decode_bin_expose (dbin);
3036 EXPOSE_UNLOCK (dbin);
3037 break;
3038 default:
3039 break;
3040 }
3041 return GST_PAD_PROBE_OK;
3042 }
3043
3044 static void
pad_added_cb(GstElement * element,GstPad * pad,GstDecodeChain * chain)3045 pad_added_cb (GstElement * element, GstPad * pad, GstDecodeChain * chain)
3046 {
3047 GstCaps *caps;
3048 GstDecodeBin *dbin;
3049 GstDecodeChain *new_chain;
3050
3051 dbin = chain->dbin;
3052
3053 GST_DEBUG_OBJECT (pad, "pad added, chain:%p", chain);
3054 GST_PAD_STREAM_LOCK (pad);
3055 if (!gst_pad_is_active (pad)) {
3056 GST_PAD_STREAM_UNLOCK (pad);
3057 GST_DEBUG_OBJECT (pad, "Ignoring pad-added from a deactivated pad");
3058 return;
3059 }
3060
3061 caps = get_pad_caps (pad);
3062 if (analyze_new_pad (dbin, element, pad, caps, chain, &new_chain))
3063 expose_pad (dbin, element, new_chain->current_pad, pad, caps, new_chain);
3064 if (caps)
3065 gst_caps_unref (caps);
3066
3067 GST_PAD_STREAM_UNLOCK (pad);
3068 }
3069
3070 static GstPadProbeReturn
sink_pad_event_probe(GstPad * pad,GstPadProbeInfo * info,gpointer user_data)3071 sink_pad_event_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
3072 {
3073 GstDecodeGroup *group = (GstDecodeGroup *) user_data;
3074 GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
3075 GstPad *peer = gst_pad_get_peer (pad);
3076 GstPadProbeReturn proberet = GST_PAD_PROBE_OK;
3077
3078 GST_DEBUG_OBJECT (pad, "Got upstream event %s", GST_EVENT_TYPE_NAME (event));
3079
3080 if (peer == NULL) {
3081 GST_DEBUG_OBJECT (pad, "We are unlinked !");
3082 if (group->parent && group->parent->next_groups) {
3083 GstDecodeGroup *last_group =
3084 g_list_last (group->parent->next_groups)->data;
3085 GST_DEBUG_OBJECT (pad, "We could send the event to another group (%p)",
3086 last_group);
3087 /* Grab another sinkpad for that last group through which we will forward this event */
3088 if (last_group->reqpads) {
3089 GstPad *sinkpad = (GstPad *) last_group->reqpads->data;
3090 GstPad *otherpeer = gst_pad_get_peer (sinkpad);
3091 if (otherpeer) {
3092 GST_DEBUG_OBJECT (otherpeer, "Attempting to forward event");
3093 if (gst_pad_send_event (otherpeer, gst_event_ref (event))) {
3094 gst_event_unref (event);
3095 proberet = GST_PAD_PROBE_HANDLED;
3096 }
3097 gst_object_unref (otherpeer);
3098 }
3099 } else {
3100 GST_DEBUG_OBJECT (pad, "No request pads, can't forward event");
3101 }
3102 }
3103 } else {
3104 gst_object_unref (peer);
3105 }
3106
3107 return proberet;
3108 }
3109
3110 static GstPadProbeReturn
sink_pad_query_probe(GstPad * pad,GstPadProbeInfo * info,gpointer user_data)3111 sink_pad_query_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
3112 {
3113 GstDecodeGroup *group = (GstDecodeGroup *) user_data;
3114 GstPad *peer = gst_pad_get_peer (pad);
3115 GstQuery *query = GST_PAD_PROBE_INFO_QUERY (info);
3116 GstPadProbeReturn proberet = GST_PAD_PROBE_OK;
3117
3118 GST_DEBUG_OBJECT (pad, "Got upstream query %s", GST_QUERY_TYPE_NAME (query));
3119
3120 if (peer == NULL) {
3121 GST_DEBUG_OBJECT (pad, "We are unlinked !");
3122 if (group->parent && group->parent->next_groups) {
3123 GstDecodeGroup *last_group =
3124 g_list_last (group->parent->next_groups)->data;
3125 GST_DEBUG_OBJECT (pad, "We could send the query to another group");
3126 /* Grab another sinkpad for that last group through which we will forward this event */
3127 if (last_group->reqpads) {
3128 GstPad *sinkpad = (GstPad *) last_group->reqpads->data;
3129 GstPad *otherpeer = gst_pad_get_peer (sinkpad);
3130 if (otherpeer) {
3131 GST_DEBUG_OBJECT (otherpeer, "Attempting to forward query");
3132 if (gst_pad_query (otherpeer, query)) {
3133 proberet = GST_PAD_PROBE_HANDLED;
3134 } else
3135 GST_DEBUG ("FAILURE");
3136 gst_object_unref (otherpeer);
3137 } else
3138 GST_DEBUG_OBJECT (sinkpad, "request pad not connected ??");
3139 } else
3140 GST_DEBUG_OBJECT (pad, "No request pads ???");
3141 }
3142 } else
3143 gst_object_unref (peer);
3144
3145 return proberet;
3146 }
3147
3148 static void
pad_removed_cb(GstElement * element,GstPad * pad,GstDecodeChain * chain)3149 pad_removed_cb (GstElement * element, GstPad * pad, GstDecodeChain * chain)
3150 {
3151 GList *l;
3152
3153 GST_LOG_OBJECT (pad, "pad removed, chain:%p", chain);
3154
3155 /* In fact, we don't have to do anything here, the active group will be
3156 * removed when the group's multiqueue is drained */
3157 CHAIN_MUTEX_LOCK (chain);
3158 for (l = chain->pending_pads; l; l = l->next) {
3159 GstPendingPad *ppad = l->data;
3160 GstPad *opad = ppad->pad;
3161
3162 if (pad == opad) {
3163 gst_pending_pad_free (ppad);
3164 chain->pending_pads = g_list_delete_link (chain->pending_pads, l);
3165 break;
3166 }
3167 }
3168 CHAIN_MUTEX_UNLOCK (chain);
3169 }
3170
3171 static void
no_more_pads_cb(GstElement * element,GstDecodeChain * chain)3172 no_more_pads_cb (GstElement * element, GstDecodeChain * chain)
3173 {
3174 GstDecodeGroup *group = NULL;
3175
3176 GST_LOG_OBJECT (element, "got no more pads");
3177
3178 CHAIN_MUTEX_LOCK (chain);
3179 if (!chain->elements
3180 || ((GstDecodeElement *) chain->elements->data)->element != element) {
3181 GST_LOG_OBJECT (chain->dbin, "no-more-pads from old chain element '%s'",
3182 GST_OBJECT_NAME (element));
3183 CHAIN_MUTEX_UNLOCK (chain);
3184 return;
3185 } else if (!chain->demuxer) {
3186 GST_LOG_OBJECT (chain->dbin, "no-more-pads from a non-demuxer element '%s'",
3187 GST_OBJECT_NAME (element));
3188 CHAIN_MUTEX_UNLOCK (chain);
3189 return;
3190 }
3191
3192 /* when we received no_more_pads, we can complete the pads of the chain */
3193 if (!chain->next_groups && chain->active_group) {
3194 group = chain->active_group;
3195 } else if (chain->next_groups) {
3196 GList *iter;
3197 for (iter = chain->next_groups; iter; iter = g_list_next (iter)) {
3198 group = iter->data;
3199 if (!group->no_more_pads)
3200 break;
3201 }
3202 }
3203 if (!group) {
3204 GST_ERROR_OBJECT (chain->dbin, "can't find group for element");
3205 CHAIN_MUTEX_UNLOCK (chain);
3206 return;
3207 }
3208
3209 GST_DEBUG_OBJECT (element, "Setting group %p to complete", group);
3210
3211 group->no_more_pads = TRUE;
3212 /* this group has prerolled enough to not need more pads,
3213 * we can probably set its buffering state to playing now */
3214 GST_DEBUG_OBJECT (group->dbin, "Setting group %p multiqueue to "
3215 "'playing' buffering mode", group);
3216 decodebin_set_queue_size (group->dbin, group->multiqueue, FALSE,
3217 (group->parent ? group->parent->seekable : TRUE));
3218 CHAIN_MUTEX_UNLOCK (chain);
3219
3220 EXPOSE_LOCK (chain->dbin);
3221 if (chain->dbin->decode_chain) {
3222 if (gst_decode_chain_is_complete (chain->dbin->decode_chain)) {
3223 gst_decode_bin_expose (chain->dbin);
3224 }
3225 }
3226 EXPOSE_UNLOCK (chain->dbin);
3227 }
3228
3229 static void
caps_notify_cb(GstPad * pad,GParamSpec * unused,GstDecodeChain * chain)3230 caps_notify_cb (GstPad * pad, GParamSpec * unused, GstDecodeChain * chain)
3231 {
3232 GstElement *element;
3233 GList *l;
3234
3235 GST_LOG_OBJECT (pad, "Notified caps for pad %s:%s", GST_DEBUG_PAD_NAME (pad));
3236
3237 /* Disconnect this; if we still need it, we'll reconnect to this in
3238 * analyze_new_pad */
3239 element = GST_ELEMENT_CAST (gst_pad_get_parent (pad));
3240
3241 CHAIN_MUTEX_LOCK (chain);
3242 for (l = chain->pending_pads; l; l = l->next) {
3243 GstPendingPad *ppad = l->data;
3244 if (ppad->pad == pad) {
3245 gst_pending_pad_free (ppad);
3246 chain->pending_pads = g_list_delete_link (chain->pending_pads, l);
3247 break;
3248 }
3249 }
3250 CHAIN_MUTEX_UNLOCK (chain);
3251
3252 pad_added_cb (element, pad, chain);
3253
3254 gst_object_unref (element);
3255 }
3256
3257 /* Decide whether an element is a demuxer based on the
3258 * klass and number/type of src pad templates it has */
3259 static gboolean
is_demuxer_element(GstElement * srcelement)3260 is_demuxer_element (GstElement * srcelement)
3261 {
3262 GstElementFactory *srcfactory;
3263 GstElementClass *elemclass;
3264 GList *walk;
3265 const gchar *klass;
3266 gint potential_src_pads = 0;
3267
3268 srcfactory = gst_element_get_factory (srcelement);
3269 klass =
3270 gst_element_factory_get_metadata (srcfactory, GST_ELEMENT_METADATA_KLASS);
3271
3272 /* Can't be a demuxer unless it has Demux in the klass name */
3273 if (!strstr (klass, "Demux"))
3274 return FALSE;
3275
3276 /* Walk the src pad templates and count how many the element
3277 * might produce */
3278 elemclass = GST_ELEMENT_GET_CLASS (srcelement);
3279
3280 walk = gst_element_class_get_pad_template_list (elemclass);
3281 while (walk != NULL) {
3282 GstPadTemplate *templ;
3283
3284 templ = (GstPadTemplate *) walk->data;
3285 if (GST_PAD_TEMPLATE_DIRECTION (templ) == GST_PAD_SRC) {
3286 switch (GST_PAD_TEMPLATE_PRESENCE (templ)) {
3287 case GST_PAD_ALWAYS:
3288 case GST_PAD_SOMETIMES:
3289 if (strstr (GST_PAD_TEMPLATE_NAME_TEMPLATE (templ), "%"))
3290 potential_src_pads += 2; /* Might make multiple pads */
3291 else
3292 potential_src_pads += 1;
3293 break;
3294 case GST_PAD_REQUEST:
3295 potential_src_pads += 2;
3296 break;
3297 }
3298 }
3299 walk = g_list_next (walk);
3300 }
3301
3302 if (potential_src_pads < 2)
3303 return FALSE;
3304
3305 return TRUE;
3306 }
3307
3308 static gboolean
is_adaptive_demuxer_element(GstElement * srcelement)3309 is_adaptive_demuxer_element (GstElement * srcelement)
3310 {
3311 GstElementFactory *srcfactory;
3312 const gchar *klass;
3313
3314 srcfactory = gst_element_get_factory (srcelement);
3315 klass =
3316 gst_element_factory_get_metadata (srcfactory, GST_ELEMENT_METADATA_KLASS);
3317
3318 /* Can't be a demuxer unless it has Demux in the klass name */
3319 if (!strstr (klass, "Demux") || !strstr (klass, "Adaptive"))
3320 return FALSE;
3321
3322 return TRUE;
3323 }
3324
3325 /* Returns TRUE if the caps are compatible with the caps specified in the 'caps'
3326 * property (which by default are the raw caps)
3327 *
3328 * The decodebin_lock should be taken !
3329 */
3330 static gboolean
are_final_caps(GstDecodeBin * dbin,GstCaps * caps)3331 are_final_caps (GstDecodeBin * dbin, GstCaps * caps)
3332 {
3333 gboolean res;
3334
3335 GST_LOG_OBJECT (dbin, "Checking with caps %" GST_PTR_FORMAT, caps);
3336
3337 /* lock for getting the caps */
3338 GST_OBJECT_LOCK (dbin);
3339 res = gst_caps_is_subset (caps, dbin->caps);
3340 GST_OBJECT_UNLOCK (dbin);
3341
3342 GST_LOG_OBJECT (dbin, "Caps are %sfinal caps", res ? "" : "not ");
3343
3344 return res;
3345 }
3346
3347 /* gst_decode_bin_reset_buffering:
3348 *
3349 * Enables buffering on the last multiqueue of each group only,
3350 * disabling the rest
3351 *
3352 */
3353 static void
gst_decode_bin_reset_buffering(GstDecodeBin * dbin)3354 gst_decode_bin_reset_buffering (GstDecodeBin * dbin)
3355 {
3356 if (!dbin->use_buffering)
3357 return;
3358
3359 GST_DEBUG_OBJECT (dbin, "Reseting multiqueues buffering");
3360 if (dbin->decode_chain) {
3361 CHAIN_MUTEX_LOCK (dbin->decode_chain);
3362 gst_decode_chain_reset_buffering (dbin->decode_chain);
3363
3364 #ifdef OHOS_EXT_FUNC
3365 // ohos.ext.func.0013
3366 GstMessage *msg_mq_num_use_buffering =
3367 gst_message_new_mq_num_use_buffering (GST_OBJECT_CAST (dbin), dbin->mq_num_use_buffering);
3368 if (msg_mq_num_use_buffering != NULL) {
3369 gst_element_post_message (GST_ELEMENT_CAST (dbin), msg_mq_num_use_buffering);
3370 }
3371 #endif
3372 CHAIN_MUTEX_UNLOCK (dbin->decode_chain);
3373 }
3374 }
3375
3376 /****
3377 * GstDecodeChain functions
3378 ****/
3379
3380 static gboolean
gst_decode_chain_reset_buffering(GstDecodeChain * chain)3381 gst_decode_chain_reset_buffering (GstDecodeChain * chain)
3382 {
3383 GstDecodeGroup *group;
3384
3385 group = chain->active_group;
3386 GST_LOG_OBJECT (chain->dbin, "Resetting chain %p buffering, active group: %p",
3387 chain, group);
3388 if (group) {
3389 return gst_decode_group_reset_buffering (group);
3390 }
3391 return FALSE;
3392 }
3393
3394 /* gst_decode_chain_get_current_group:
3395 *
3396 * Returns the current group of this chain, to which
3397 * new chains should be attached or NULL if the last
3398 * group didn't have no-more-pads.
3399 *
3400 * Not MT-safe: Call with parent chain lock!
3401 */
3402 static GstDecodeGroup *
gst_decode_chain_get_current_group(GstDecodeChain * chain)3403 gst_decode_chain_get_current_group (GstDecodeChain * chain)
3404 {
3405 GstDecodeGroup *group;
3406
3407 if (!chain->next_groups && chain->active_group
3408 && chain->active_group->overrun && !chain->active_group->no_more_pads) {
3409 GST_WARNING_OBJECT (chain->dbin,
3410 "Currently active group %p is exposed"
3411 " and wants to add a new pad without having signaled no-more-pads",
3412 chain->active_group);
3413 return NULL;
3414 }
3415
3416 if (chain->next_groups && (group = chain->next_groups->data) && group->overrun
3417 && !group->no_more_pads) {
3418 GST_WARNING_OBJECT (chain->dbin,
3419 "Currently newest pending group %p "
3420 "had overflow but didn't signal no-more-pads", group);
3421 return NULL;
3422 }
3423
3424 /* Now we know that we can really return something useful */
3425 if (!chain->active_group) {
3426 chain->active_group = group = gst_decode_group_new (chain->dbin, chain);
3427 } else if (!chain->active_group->overrun
3428 && !chain->active_group->no_more_pads) {
3429 group = chain->active_group;
3430 } else {
3431 GList *iter;
3432 group = NULL;
3433 for (iter = chain->next_groups; iter; iter = g_list_next (iter)) {
3434 GstDecodeGroup *next_group = iter->data;
3435
3436 if (!next_group->overrun && !next_group->no_more_pads) {
3437 group = next_group;
3438 break;
3439 }
3440 }
3441 }
3442 if (!group) {
3443 group = gst_decode_group_new (chain->dbin, chain);
3444 chain->next_groups = g_list_append (chain->next_groups, group);
3445 }
3446
3447 return group;
3448 }
3449
3450 static void gst_decode_group_free_internal (GstDecodeGroup * group,
3451 gboolean hide);
3452
3453 static void
gst_decode_chain_unref(GstDecodeChain * chain)3454 gst_decode_chain_unref (GstDecodeChain * chain)
3455 {
3456 if (g_atomic_int_dec_and_test (&chain->refs)) {
3457 g_mutex_clear (&chain->lock);
3458 g_slice_free (GstDecodeChain, chain);
3459 }
3460 }
3461
3462 static GstDecodeChain *
gst_decode_chain_ref(GstDecodeChain * chain)3463 gst_decode_chain_ref (GstDecodeChain * chain)
3464 {
3465 g_atomic_int_inc (&chain->refs);
3466 return chain;
3467 }
3468
3469 static void
gst_decode_chain_free_internal(GstDecodeChain * chain,gboolean hide)3470 gst_decode_chain_free_internal (GstDecodeChain * chain, gboolean hide)
3471 {
3472 GList *l, *set_to_null = NULL;
3473
3474 CHAIN_MUTEX_LOCK (chain);
3475
3476 GST_DEBUG_OBJECT (chain->dbin, "%s chain %p", (hide ? "Hiding" : "Freeing"),
3477 chain);
3478
3479 if (chain->active_group) {
3480 gst_decode_group_free_internal (chain->active_group, hide);
3481 if (!hide)
3482 chain->active_group = NULL;
3483 }
3484
3485 for (l = chain->next_groups; l; l = l->next) {
3486 gst_decode_group_free_internal ((GstDecodeGroup *) l->data, hide);
3487 if (!hide)
3488 l->data = NULL;
3489 }
3490 if (!hide) {
3491 g_list_free (chain->next_groups);
3492 chain->next_groups = NULL;
3493 }
3494
3495 if (!hide) {
3496 for (l = chain->old_groups; l; l = l->next) {
3497 GstDecodeGroup *group = l->data;
3498
3499 gst_decode_group_free (group);
3500 }
3501 g_list_free (chain->old_groups);
3502 chain->old_groups = NULL;
3503 }
3504
3505 for (l = chain->pending_pads; l; l = l->next) {
3506 GstPendingPad *ppad = l->data;
3507 gst_pending_pad_free (ppad);
3508 l->data = NULL;
3509 }
3510 g_list_free (chain->pending_pads);
3511 chain->pending_pads = NULL;
3512
3513 for (l = chain->elements; l; l = l->next) {
3514 GstDecodeElement *delem = l->data;
3515 GstElement *element = delem->element;
3516
3517 if (delem->pad_added_id)
3518 g_signal_handler_disconnect (element, delem->pad_added_id);
3519 delem->pad_added_id = 0;
3520 if (delem->pad_removed_id)
3521 g_signal_handler_disconnect (element, delem->pad_removed_id);
3522 delem->pad_removed_id = 0;
3523 if (delem->no_more_pads_id)
3524 g_signal_handler_disconnect (element, delem->no_more_pads_id);
3525 delem->no_more_pads_id = 0;
3526
3527 if (delem->capsfilter) {
3528 if (GST_OBJECT_PARENT (delem->capsfilter) ==
3529 GST_OBJECT_CAST (chain->dbin))
3530 gst_bin_remove (GST_BIN_CAST (chain->dbin), delem->capsfilter);
3531 if (!hide) {
3532 set_to_null =
3533 g_list_append (set_to_null, gst_object_ref (delem->capsfilter));
3534 }
3535 }
3536
3537 if (GST_OBJECT_PARENT (element) == GST_OBJECT_CAST (chain->dbin))
3538 gst_bin_remove (GST_BIN_CAST (chain->dbin), element);
3539 if (!hide) {
3540 set_to_null = g_list_append (set_to_null, gst_object_ref (element));
3541 }
3542
3543 SUBTITLE_LOCK (chain->dbin);
3544 /* remove possible subtitle element */
3545 chain->dbin->subtitles = g_list_remove (chain->dbin->subtitles, element);
3546 SUBTITLE_UNLOCK (chain->dbin);
3547
3548 if (!hide) {
3549 if (delem->capsfilter) {
3550 gst_object_unref (delem->capsfilter);
3551 delem->capsfilter = NULL;
3552 }
3553
3554 gst_object_unref (element);
3555 l->data = NULL;
3556
3557 g_slice_free (GstDecodeElement, delem);
3558 }
3559 }
3560 if (!hide) {
3561 g_list_free (chain->elements);
3562 chain->elements = NULL;
3563 }
3564
3565 if (chain->endpad) {
3566 if (chain->endpad->exposed) {
3567 gst_element_remove_pad (GST_ELEMENT_CAST (chain->dbin),
3568 GST_PAD_CAST (chain->endpad));
3569 }
3570
3571 decode_pad_set_target (chain->endpad, NULL);
3572 chain->endpad->exposed = FALSE;
3573 if (!hide) {
3574 gst_object_unref (chain->endpad);
3575 chain->endpad = NULL;
3576 }
3577 }
3578
3579 if (!hide && chain->current_pad) {
3580 gst_object_unref (chain->current_pad);
3581 chain->current_pad = NULL;
3582 }
3583
3584 if (chain->pad) {
3585 gst_object_unref (chain->pad);
3586 chain->pad = NULL;
3587 }
3588
3589 if (chain->endcaps) {
3590 gst_caps_unref (chain->endcaps);
3591 chain->endcaps = NULL;
3592 }
3593 g_free (chain->deadend_details);
3594 chain->deadend_details = NULL;
3595
3596 GST_DEBUG_OBJECT (chain->dbin, "%s chain %p", (hide ? "Hidden" : "Freed"),
3597 chain);
3598 CHAIN_MUTEX_UNLOCK (chain);
3599
3600 while (set_to_null) {
3601 GstElement *element = set_to_null->data;
3602 set_to_null = g_list_delete_link (set_to_null, set_to_null);
3603 gst_element_set_state (element, GST_STATE_NULL);
3604 gst_object_unref (element);
3605 }
3606
3607 if (!hide)
3608 gst_decode_chain_unref (chain);
3609 }
3610
3611 /* gst_decode_chain_free:
3612 *
3613 * Completely frees and removes the chain and all
3614 * child groups from decodebin.
3615 *
3616 * MT-safe, don't hold the chain lock or any child chain's lock
3617 * when calling this!
3618 */
3619 static void
gst_decode_chain_free(GstDecodeChain * chain)3620 gst_decode_chain_free (GstDecodeChain * chain)
3621 {
3622 gst_decode_chain_free_internal (chain, FALSE);
3623 }
3624
3625 /* gst_decode_chain_new:
3626 *
3627 * Creates a new decode chain and initializes it.
3628 *
3629 * It's up to the caller to add it to the list of child chains of
3630 * a group!
3631 */
3632 static GstDecodeChain *
gst_decode_chain_new(GstDecodeBin * dbin,GstDecodeGroup * parent,GstPad * pad)3633 gst_decode_chain_new (GstDecodeBin * dbin, GstDecodeGroup * parent,
3634 GstPad * pad)
3635 {
3636 GstDecodeChain *chain = g_slice_new0 (GstDecodeChain);
3637
3638 GST_DEBUG_OBJECT (dbin, "Creating new chain %p with parent group %p", chain,
3639 parent);
3640
3641 chain->dbin = dbin;
3642 chain->parent = parent;
3643 chain->refs = 1;
3644 g_mutex_init (&chain->lock);
3645 chain->pad = gst_object_ref (pad);
3646
3647 return chain;
3648 }
3649
3650 /****
3651 * GstDecodeGroup functions
3652 ****/
3653
3654 /* The overrun callback is used to expose groups that have not yet had their
3655 * no_more_pads called while the (large) multiqueue overflowed. When this
3656 * happens we must assume that the no_more_pads will not arrive anymore and we
3657 * must expose the pads that we have.
3658 */
3659 static void
multi_queue_overrun_cb(GstElement * queue,GstDecodeGroup * group)3660 multi_queue_overrun_cb (GstElement * queue, GstDecodeGroup * group)
3661 {
3662 GstDecodeBin *dbin;
3663
3664 dbin = group->dbin;
3665
3666 GST_LOG_OBJECT (dbin, "multiqueue '%s' (%p) is full", GST_OBJECT_NAME (queue),
3667 queue);
3668
3669 group->overrun = TRUE;
3670 /* this group has prerolled enough to not need more pads,
3671 * we can probably set its buffering state to playing now */
3672 GST_DEBUG_OBJECT (group->dbin, "Setting group %p multiqueue to "
3673 "'playing' buffering mode", group);
3674 decodebin_set_queue_size (group->dbin, group->multiqueue, FALSE,
3675 (group->parent ? group->parent->seekable : TRUE));
3676
3677 /* FIXME: We should make sure that everything gets exposed now
3678 * even if child chains are not complete because the will never
3679 * be complete! Ignore any non-complete chains when exposing
3680 * and never expose them later
3681 */
3682
3683 EXPOSE_LOCK (dbin);
3684 if (dbin->decode_chain) {
3685 if (gst_decode_chain_is_complete (dbin->decode_chain)) {
3686 if (!gst_decode_bin_expose (dbin))
3687 GST_WARNING_OBJECT (dbin, "Couldn't expose group");
3688 }
3689 }
3690 EXPOSE_UNLOCK (dbin);
3691 }
3692
3693 static void
gst_decode_group_free_internal(GstDecodeGroup * group,gboolean hide)3694 gst_decode_group_free_internal (GstDecodeGroup * group, gboolean hide)
3695 {
3696 GList *l;
3697
3698 GST_DEBUG_OBJECT (group->dbin, "%s group %p", (hide ? "Hiding" : "Freeing"),
3699 group);
3700
3701 if (!hide) {
3702 for (l = group->demuxer_pad_probe_ids; l != NULL; l = l->next) {
3703 GstDemuxerPad *demuxer_pad = l->data;
3704 GstPad *sinkpad = g_weak_ref_get (&demuxer_pad->weakPad);
3705
3706 if (sinkpad != NULL) {
3707 gst_pad_remove_probe (sinkpad, demuxer_pad->event_probe_id);
3708 gst_pad_remove_probe (sinkpad, demuxer_pad->query_probe_id);
3709 g_weak_ref_clear (&demuxer_pad->weakPad);
3710 gst_object_unref (sinkpad);
3711 }
3712 g_free (demuxer_pad);
3713 }
3714 g_list_free (group->demuxer_pad_probe_ids);
3715 group->demuxer_pad_probe_ids = NULL;
3716 }
3717
3718 for (l = group->children; l; l = l->next) {
3719 GstDecodeChain *chain = (GstDecodeChain *) l->data;
3720
3721 gst_decode_chain_free_internal (chain, hide);
3722 if (!hide)
3723 l->data = NULL;
3724 }
3725 if (!hide) {
3726 g_list_free (group->children);
3727 group->children = NULL;
3728 }
3729
3730 if (!hide) {
3731 for (l = group->reqpads; l; l = l->next) {
3732 GstPad *pad = l->data;
3733
3734 gst_element_release_request_pad (group->multiqueue, pad);
3735 gst_object_unref (pad);
3736 l->data = NULL;
3737 }
3738 g_list_free (group->reqpads);
3739 group->reqpads = NULL;
3740 }
3741
3742 if (group->multiqueue) {
3743 if (group->overrunsig) {
3744 g_signal_handler_disconnect (group->multiqueue, group->overrunsig);
3745 group->overrunsig = 0;
3746 }
3747
3748 if (GST_OBJECT_PARENT (group->multiqueue) == GST_OBJECT_CAST (group->dbin))
3749 gst_bin_remove (GST_BIN_CAST (group->dbin), group->multiqueue);
3750 if (!hide) {
3751 gst_element_set_state (group->multiqueue, GST_STATE_NULL);
3752 gst_object_unref (group->multiqueue);
3753 group->multiqueue = NULL;
3754 }
3755 }
3756
3757 GST_DEBUG_OBJECT (group->dbin, "%s group %p", (hide ? "Hid" : "Freed"),
3758 group);
3759 if (!hide)
3760 g_slice_free (GstDecodeGroup, group);
3761 }
3762
3763 /* gst_decode_group_free:
3764 *
3765 * Completely frees and removes the decode group and all
3766 * it's children.
3767 *
3768 * Never call this from any streaming thread!
3769 *
3770 * Not MT-safe, call with parent's chain lock!
3771 */
3772 static void
gst_decode_group_free(GstDecodeGroup * group)3773 gst_decode_group_free (GstDecodeGroup * group)
3774 {
3775 gst_decode_group_free_internal (group, FALSE);
3776 }
3777
3778 /* gst_decode_group_hide:
3779 *
3780 * Hide the decode group only, this means that
3781 * all child endpads are removed from decodebin
3782 * and all signals are unconnected.
3783 *
3784 * No element is set to NULL state and completely
3785 * unrefed here.
3786 *
3787 * Can be called from streaming threads.
3788 *
3789 * Not MT-safe, call with parent's chain lock!
3790 */
3791 static void
gst_decode_group_hide(GstDecodeGroup * group)3792 gst_decode_group_hide (GstDecodeGroup * group)
3793 {
3794 gst_decode_group_free_internal (group, TRUE);
3795 }
3796
3797 /* gst_decode_chain_free_hidden_groups:
3798 *
3799 * Frees any decode groups that were hidden previously.
3800 * This allows keeping memory use from ballooning when
3801 * switching chains repeatedly.
3802 *
3803 * A new throwaway thread will be created to free the
3804 * groups, so any delay does not block the setup of a
3805 * new group.
3806 *
3807 * Not MT-safe, call with parent's chain lock!
3808 */
3809 static void
gst_decode_chain_free_hidden_groups(GList * old_groups)3810 gst_decode_chain_free_hidden_groups (GList * old_groups)
3811 {
3812 GList *l;
3813
3814 for (l = old_groups; l; l = l->next) {
3815 GstDecodeGroup *group = l->data;
3816
3817 gst_decode_group_free (group);
3818 }
3819 g_list_free (old_groups);
3820 }
3821
3822 static void
gst_decode_chain_start_free_hidden_groups_thread(GstDecodeChain * chain)3823 gst_decode_chain_start_free_hidden_groups_thread (GstDecodeChain * chain)
3824 {
3825 GThread *thread;
3826 GError *error = NULL;
3827 GList *old_groups;
3828 GstDecodeBin *dbin = chain->dbin;
3829
3830 old_groups = chain->old_groups;
3831 if (!old_groups)
3832 return;
3833
3834 /* If we already have a thread running, wait for it to finish */
3835 g_mutex_lock (&dbin->cleanup_lock);
3836 if (dbin->cleanup_thread) {
3837 g_thread_join (dbin->cleanup_thread);
3838 dbin->cleanup_thread = NULL;
3839 }
3840
3841 chain->old_groups = NULL;
3842
3843 if (dbin->shutdown) {
3844 /* If we're shutting down, add the groups to be cleaned up in the
3845 * state change handler (which *is* another thread). Also avoids
3846 * playing racy games with the state change handler */
3847 dbin->cleanup_groups = g_list_concat (dbin->cleanup_groups, old_groups);
3848 g_mutex_unlock (&dbin->cleanup_lock);
3849 return;
3850 }
3851
3852 thread = g_thread_try_new ("free-hidden-groups",
3853 (GThreadFunc) gst_decode_chain_free_hidden_groups, old_groups, &error);
3854 if (!thread || error) {
3855 GST_ERROR ("Failed to start free-hidden-groups thread: %s",
3856 error ? error->message : "unknown reason");
3857 g_clear_error (&error);
3858 chain->old_groups = old_groups;
3859 g_mutex_unlock (&dbin->cleanup_lock);
3860 return;
3861 }
3862
3863 dbin->cleanup_thread = thread;
3864 g_mutex_unlock (&dbin->cleanup_lock);
3865
3866 GST_DEBUG_OBJECT (chain->dbin, "Started free-hidden-groups thread");
3867 }
3868
3869 static void
decodebin_set_queue_size(GstDecodeBin * dbin,GstElement * multiqueue,gboolean preroll,gboolean seekable)3870 decodebin_set_queue_size (GstDecodeBin * dbin, GstElement * multiqueue,
3871 gboolean preroll, gboolean seekable)
3872 {
3873 gboolean use_buffering;
3874
3875 /* get the current config from the multiqueue */
3876 g_object_get (multiqueue, "use-buffering", &use_buffering, NULL);
3877
3878 decodebin_set_queue_size_full (dbin, multiqueue, use_buffering, preroll,
3879 seekable);
3880 }
3881
3882 /* configure queue sizes, this depends on the buffering method and if we are
3883 * playing or prerolling. */
3884 static void
decodebin_set_queue_size_full(GstDecodeBin * dbin,GstElement * multiqueue,gboolean use_buffering,gboolean preroll,gboolean seekable)3885 decodebin_set_queue_size_full (GstDecodeBin * dbin, GstElement * multiqueue,
3886 gboolean use_buffering, gboolean preroll, gboolean seekable)
3887 {
3888 guint max_bytes, max_buffers;
3889 guint64 max_time;
3890
3891 GST_DEBUG_OBJECT (multiqueue, "use buffering %d", use_buffering);
3892
3893 if (preroll || use_buffering) {
3894 /* takes queue limits, initially we only queue up up to the max bytes limit,
3895 * with a default of 2MB. we use the same values for buffering mode. */
3896 if (preroll || (max_bytes = dbin->max_size_bytes) == 0)
3897 max_bytes = AUTO_PREROLL_SIZE_BYTES;
3898 if (preroll || (max_buffers = dbin->max_size_buffers) == 0)
3899 max_buffers = AUTO_PREROLL_SIZE_BUFFERS;
3900 if (preroll || (max_time = dbin->max_size_time) == 0) {
3901 if (dbin->use_buffering && !preroll)
3902 max_time = 5 * GST_SECOND;
3903 else
3904 max_time = seekable ? AUTO_PREROLL_SEEKABLE_SIZE_TIME :
3905 AUTO_PREROLL_NOT_SEEKABLE_SIZE_TIME;
3906 }
3907 } else {
3908 /* update runtime limits. At runtime, we try to keep the amount of buffers
3909 * in the queues as low as possible (but at least 5 buffers). */
3910 if (dbin->use_buffering)
3911 max_bytes = 0;
3912 else if ((max_bytes = dbin->max_size_bytes) == 0)
3913 max_bytes = AUTO_PLAY_SIZE_BYTES;
3914 if ((max_buffers = dbin->max_size_buffers) == 0)
3915 max_buffers = AUTO_PLAY_SIZE_BUFFERS;
3916 /* this is a multiqueue with disabled buffering, don't limit max_time */
3917 if (dbin->use_buffering)
3918 max_time = 0;
3919 else if ((max_time = dbin->max_size_time) == 0)
3920 max_time = AUTO_PLAY_SIZE_TIME;
3921 }
3922
3923 GST_DEBUG_OBJECT (multiqueue, "setting limits %u bytes, %u buffers, "
3924 "%" G_GUINT64_FORMAT " time", max_bytes, max_buffers, max_time);
3925 g_object_set (multiqueue,
3926 "max-size-bytes", max_bytes, "max-size-time", max_time,
3927 "max-size-buffers", max_buffers, NULL);
3928 }
3929
3930 /* gst_decode_group_new:
3931 * @dbin: Parent decodebin
3932 * @parent: Parent chain or %NULL
3933 *
3934 * Creates a new GstDecodeGroup. It is up to the caller to add it to the list
3935 * of groups.
3936 */
3937 static GstDecodeGroup *
gst_decode_group_new(GstDecodeBin * dbin,GstDecodeChain * parent)3938 gst_decode_group_new (GstDecodeBin * dbin, GstDecodeChain * parent)
3939 {
3940 GstDecodeGroup *group = g_slice_new0 (GstDecodeGroup);
3941 GstElement *mq;
3942 gboolean seekable;
3943
3944 GST_DEBUG_OBJECT (dbin, "Creating new group %p with parent chain %p", group,
3945 parent);
3946
3947 group->dbin = dbin;
3948 group->parent = parent;
3949
3950 mq = group->multiqueue = gst_element_factory_make ("multiqueue", NULL);
3951 if (G_UNLIKELY (!group->multiqueue))
3952 goto missing_multiqueue;
3953
3954 /* configure queue sizes for preroll */
3955 seekable = FALSE;
3956 if (parent && parent->demuxer) {
3957 GstElement *element =
3958 ((GstDecodeElement *) parent->elements->data)->element;
3959 GstPad *pad = gst_element_get_static_pad (element, "sink");
3960 if (pad) {
3961 seekable = parent->seekable = check_upstream_seekable (dbin, pad);
3962 gst_object_unref (pad);
3963 }
3964 }
3965 decodebin_set_queue_size_full (dbin, mq, FALSE, TRUE, seekable);
3966
3967 group->overrunsig = g_signal_connect (mq, "overrun",
3968 G_CALLBACK (multi_queue_overrun_cb), group);
3969 group->demuxer_pad_probe_ids = NULL;
3970
3971 gst_element_set_state (mq, GST_STATE_PAUSED);
3972 gst_bin_add (GST_BIN (dbin), gst_object_ref (mq));
3973
3974 return group;
3975
3976 /* ERRORS */
3977 missing_multiqueue:
3978 {
3979 gst_element_post_message (GST_ELEMENT_CAST (dbin),
3980 gst_missing_element_message_new (GST_ELEMENT_CAST (dbin),
3981 "multiqueue"));
3982 GST_ELEMENT_ERROR (dbin, CORE, MISSING_PLUGIN, (NULL), ("no multiqueue!"));
3983 g_slice_free (GstDecodeGroup, group);
3984 return NULL;
3985 }
3986 }
3987
3988 /* gst_decode_group_control_demuxer_pad
3989 *
3990 * Adds a new demuxer srcpad to the given group.
3991 *
3992 * Returns the srcpad of the multiqueue corresponding the given pad.
3993 * Returns NULL if there was an error.
3994 */
3995 static GstPad *
gst_decode_group_control_demuxer_pad(GstDecodeGroup * group,GstPad * pad)3996 gst_decode_group_control_demuxer_pad (GstDecodeGroup * group, GstPad * pad)
3997 {
3998 GstDecodeBin *dbin;
3999 GstDemuxerPad *demuxer_pad;
4000 GstPad *srcpad, *sinkpad;
4001 GstIterator *it = NULL;
4002 GValue item = { 0, };
4003
4004 dbin = group->dbin;
4005
4006 GST_LOG_OBJECT (dbin, "group:%p pad %s:%s", group, GST_DEBUG_PAD_NAME (pad));
4007
4008 srcpad = NULL;
4009
4010 if (G_UNLIKELY (!group->multiqueue))
4011 return NULL;
4012
4013 if (!(sinkpad = gst_element_get_request_pad (group->multiqueue, "sink_%u"))) {
4014 GST_ERROR_OBJECT (dbin, "Couldn't get sinkpad from multiqueue");
4015 return NULL;
4016 }
4017
4018 if ((gst_pad_link_full (pad, sinkpad,
4019 GST_PAD_LINK_CHECK_NOTHING) != GST_PAD_LINK_OK)) {
4020 GST_ERROR_OBJECT (dbin, "Couldn't link demuxer and multiqueue");
4021 goto error;
4022 }
4023
4024 it = gst_pad_iterate_internal_links (sinkpad);
4025
4026 if (!it || (gst_iterator_next (it, &item)) != GST_ITERATOR_OK
4027 || ((srcpad = g_value_dup_object (&item)) == NULL)) {
4028 GST_ERROR_OBJECT (dbin,
4029 "Couldn't get srcpad from multiqueue for sinkpad %" GST_PTR_FORMAT,
4030 sinkpad);
4031 goto error;
4032 }
4033
4034 CHAIN_MUTEX_LOCK (group->parent);
4035
4036 /* Note: GWeakRefs can't be moved in memory once they're in use, so do a
4037 * dedicated alloc for the GstDemuxerPad struct that contains it */
4038 demuxer_pad = g_new0 (GstDemuxerPad, 1);
4039 demuxer_pad->event_probe_id = gst_pad_add_probe (sinkpad,
4040 GST_PAD_PROBE_TYPE_EVENT_UPSTREAM, sink_pad_event_probe, group, NULL);
4041 demuxer_pad->query_probe_id = gst_pad_add_probe (sinkpad,
4042 GST_PAD_PROBE_TYPE_QUERY_UPSTREAM, sink_pad_query_probe, group, NULL);
4043
4044 g_weak_ref_set (&demuxer_pad->weakPad, sinkpad);
4045 group->demuxer_pad_probe_ids =
4046 g_list_prepend (group->demuxer_pad_probe_ids, demuxer_pad);
4047
4048 group->reqpads = g_list_prepend (group->reqpads, gst_object_ref (sinkpad));
4049 CHAIN_MUTEX_UNLOCK (group->parent);
4050
4051 beach:
4052 if (G_IS_VALUE (&item))
4053 g_value_unset (&item);
4054 if (it)
4055 gst_iterator_free (it);
4056 gst_object_unref (sinkpad);
4057 return srcpad;
4058
4059 error:
4060 gst_element_release_request_pad (group->multiqueue, sinkpad);
4061 goto beach;
4062 }
4063
4064 /* gst_decode_group_is_complete:
4065 *
4066 * Checks if the group is complete, this means that
4067 * a) overrun of the multiqueue or no-more-pads happened
4068 * b) all child chains are complete
4069 *
4070 * Not MT-safe, always call with decodebin expose lock
4071 */
4072 static gboolean
gst_decode_group_is_complete(GstDecodeGroup * group)4073 gst_decode_group_is_complete (GstDecodeGroup * group)
4074 {
4075 GList *l;
4076 gboolean complete = TRUE;
4077
4078 if (!group->overrun && !group->no_more_pads) {
4079 complete = FALSE;
4080 goto out;
4081 }
4082
4083 for (l = group->children; l; l = l->next) {
4084 GstDecodeChain *chain = l->data;
4085
4086 if (!gst_decode_chain_is_complete (chain)) {
4087 complete = FALSE;
4088 goto out;
4089 }
4090 }
4091
4092 out:
4093 GST_DEBUG_OBJECT (group->dbin, "Group %p is complete: %d", group, complete);
4094 return complete;
4095 }
4096
4097 /* gst_decode_chain_is_complete:
4098 *
4099 * Returns TRUE if the chain is complete, this means either
4100 * a) This chain is a dead end, i.e. we have no suitable plugins
4101 * b) This chain ends in an endpad and this is blocked or exposed
4102 *
4103 * Not MT-safe, always call with decodebin expose lock
4104 */
4105 static gboolean
gst_decode_chain_is_complete(GstDecodeChain * chain)4106 gst_decode_chain_is_complete (GstDecodeChain * chain)
4107 {
4108 gboolean complete = FALSE;
4109
4110 CHAIN_MUTEX_LOCK (chain);
4111 if (chain->dbin->shutdown)
4112 goto out;
4113
4114 if (chain->deadend) {
4115 complete = TRUE;
4116 goto out;
4117 }
4118
4119 if (chain->endpad && gst_decode_pad_is_exposable (chain->endpad)) {
4120 complete = TRUE;
4121 goto out;
4122 }
4123
4124 if (chain->demuxer) {
4125 if (chain->active_group
4126 && gst_decode_group_is_complete (chain->active_group)) {
4127 complete = TRUE;
4128 goto out;
4129 }
4130 }
4131
4132 out:
4133 CHAIN_MUTEX_UNLOCK (chain);
4134 GST_DEBUG_OBJECT (chain->dbin, "Chain %p is complete: %d", chain, complete);
4135 return complete;
4136 }
4137
4138 /* Flushing group/chains */
4139 static void
flush_group(GstDecodeGroup * group,gboolean flushing)4140 flush_group (GstDecodeGroup * group, gboolean flushing)
4141 {
4142 GList *tmp;
4143
4144 GST_DEBUG ("group %p flushing:%d", group, flushing);
4145
4146 if (group->drained == flushing)
4147 return;
4148 for (tmp = group->children; tmp; tmp = tmp->next) {
4149 GstDecodeChain *chain = (GstDecodeChain *) tmp->data;
4150 flush_chain (chain, flushing);
4151 }
4152 GST_DEBUG ("Setting group %p to drained:%d", group, flushing);
4153 group->drained = flushing;
4154 }
4155
4156 static void
flush_chain(GstDecodeChain * chain,gboolean flushing)4157 flush_chain (GstDecodeChain * chain, gboolean flushing)
4158 {
4159 GList *tmp;
4160 GstDecodeBin *dbin = chain->dbin;
4161
4162 GST_DEBUG_OBJECT (dbin, "chain %p (pad %s:%s) flushing:%d", chain,
4163 GST_DEBUG_PAD_NAME (chain->pad), flushing);
4164 if (chain->drained == flushing)
4165 return;
4166 /* if unflushing, check if we should switch to last group */
4167 if (flushing == FALSE && chain->next_groups) {
4168 GstDecodeGroup *target_group =
4169 (GstDecodeGroup *) g_list_last (chain->next_groups)->data;
4170 gst_decode_chain_start_free_hidden_groups_thread (chain);
4171 /* Hide active group (we're sure it's not that one we'll be using) */
4172 GST_DEBUG_OBJECT (dbin, "Switching from active group %p to group %p",
4173 chain->active_group, target_group);
4174 gst_decode_group_hide (chain->active_group);
4175 chain->old_groups = g_list_prepend (chain->old_groups, chain->active_group);
4176 chain->active_group = target_group;
4177 /* Hide all groups but the target_group */
4178 for (tmp = chain->next_groups; tmp; tmp = tmp->next) {
4179 GstDecodeGroup *group = (GstDecodeGroup *) tmp->data;
4180 if (group != target_group) {
4181 gst_decode_group_hide (group);
4182 chain->old_groups = g_list_prepend (chain->old_groups, group);
4183 }
4184 }
4185 /* Clear next groups */
4186 g_list_free (chain->next_groups);
4187 chain->next_groups = NULL;
4188 }
4189 /* Mark all groups as flushing */
4190 if (chain->active_group)
4191 flush_group (chain->active_group, flushing);
4192 for (tmp = chain->next_groups; tmp; tmp = tmp->next) {
4193 GstDecodeGroup *group = (GstDecodeGroup *) tmp->data;
4194 flush_group (group, flushing);
4195 }
4196 GST_DEBUG ("Setting chain %p to drained:%d", chain, flushing);
4197 chain->drained = flushing;
4198 }
4199
4200 static gboolean
4201 drain_and_switch_chains (GstDecodeChain * chain, GstDecodePad * drainpad,
4202 gboolean * last_group, gboolean * drained, gboolean * switched);
4203 /* drain_and_switch_chains/groups:
4204 *
4205 * CALL WITH CHAIN LOCK (or group parent) TAKEN !
4206 *
4207 * Goes down the chains/groups until it finds the chain
4208 * to which the drainpad belongs.
4209 *
4210 * It marks that pad/chain as drained and then will figure
4211 * out which group to switch to or not.
4212 *
4213 * last_chain will be set to TRUE if the group to which the
4214 * pad belongs is the last one.
4215 *
4216 * drained will be set to TRUE if the chain/group is drained.
4217 *
4218 * Returns: TRUE if the chain contained the target pad */
4219 static gboolean
drain_and_switch_group(GstDecodeGroup * group,GstDecodePad * drainpad,gboolean * last_group,gboolean * drained,gboolean * switched)4220 drain_and_switch_group (GstDecodeGroup * group, GstDecodePad * drainpad,
4221 gboolean * last_group, gboolean * drained, gboolean * switched)
4222 {
4223 gboolean handled = FALSE;
4224 GList *tmp;
4225
4226 GST_DEBUG ("Checking group %p (target pad %s:%s)",
4227 group, GST_DEBUG_PAD_NAME (drainpad));
4228
4229 /* Definitely can't be in drained groups */
4230 if (G_UNLIKELY (group->drained)) {
4231 goto beach;
4232 }
4233
4234 /* Figure out if all our chains are drained with the
4235 * new information */
4236 group->drained = TRUE;
4237 for (tmp = group->children; tmp; tmp = tmp->next) {
4238 GstDecodeChain *chain = (GstDecodeChain *) tmp->data;
4239 gboolean subdrained = FALSE;
4240
4241 handled |=
4242 drain_and_switch_chains (chain, drainpad, last_group, &subdrained,
4243 switched);
4244 if (!subdrained)
4245 group->drained = FALSE;
4246 }
4247
4248 beach:
4249 GST_DEBUG ("group %p (last_group:%d, drained:%d, switched:%d, handled:%d)",
4250 group, *last_group, group->drained, *switched, handled);
4251 *drained = group->drained;
4252 return handled;
4253 }
4254
4255 static gboolean
drain_and_switch_chains(GstDecodeChain * chain,GstDecodePad * drainpad,gboolean * last_group,gboolean * drained,gboolean * switched)4256 drain_and_switch_chains (GstDecodeChain * chain, GstDecodePad * drainpad,
4257 gboolean * last_group, gboolean * drained, gboolean * switched)
4258 {
4259 gboolean handled = FALSE;
4260 GstDecodeBin *dbin = chain->dbin;
4261
4262 GST_DEBUG ("Checking chain %p %s:%s (target pad %s:%s)",
4263 chain, GST_DEBUG_PAD_NAME (chain->pad), GST_DEBUG_PAD_NAME (drainpad));
4264
4265 CHAIN_MUTEX_LOCK (chain);
4266
4267 if (chain->pad_probe_id) {
4268 gst_pad_remove_probe (chain->pad, chain->pad_probe_id);
4269 chain->pad_probe_id = 0;
4270 }
4271
4272 /* Definitely can't be in drained chains */
4273 if (G_UNLIKELY (chain->drained)) {
4274 goto beach;
4275 }
4276
4277 if (chain->endpad) {
4278 /* Check if we're reached the target endchain */
4279 if (drainpad != NULL && chain == drainpad->chain) {
4280 GST_DEBUG ("Found the target chain");
4281 drainpad->drained = TRUE;
4282 handled = TRUE;
4283 }
4284
4285 chain->drained = chain->endpad->drained;
4286 goto beach;
4287 }
4288
4289 /* We known there are groups to switch to */
4290 if (chain->next_groups)
4291 *last_group = FALSE;
4292
4293 /* Check the active group */
4294 if (chain->active_group) {
4295 gboolean subdrained = FALSE;
4296 handled = drain_and_switch_group (chain->active_group, drainpad,
4297 last_group, &subdrained, switched);
4298
4299 /* The group is drained, see if we can switch to another */
4300 if ((handled || drainpad == NULL) && subdrained && !*switched) {
4301 if (chain->next_groups) {
4302 /* Switch to next group */
4303 GST_DEBUG_OBJECT (dbin, "Hiding current group %p", chain->active_group);
4304 gst_decode_group_hide (chain->active_group);
4305 chain->old_groups =
4306 g_list_prepend (chain->old_groups, chain->active_group);
4307 GST_DEBUG_OBJECT (dbin, "Switching to next group %p",
4308 chain->next_groups->data);
4309 chain->active_group = chain->next_groups->data;
4310 chain->next_groups =
4311 g_list_delete_link (chain->next_groups, chain->next_groups);
4312 gst_decode_chain_start_free_hidden_groups_thread (chain);
4313 *switched = TRUE;
4314 chain->drained = FALSE;
4315 } else {
4316 GST_DEBUG ("Group %p was the last in chain %p", chain->active_group,
4317 chain);
4318 chain->drained = TRUE;
4319 /* We're drained ! */
4320 }
4321 } else {
4322 if (subdrained && !chain->next_groups)
4323 *drained = TRUE;
4324 }
4325 }
4326
4327 beach:
4328 CHAIN_MUTEX_UNLOCK (chain);
4329
4330 GST_DEBUG ("Chain %p (handled:%d, last_group:%d, drained:%d, switched:%d)",
4331 chain, handled, *last_group, chain->drained, *switched);
4332
4333 *drained = chain->drained;
4334
4335 if (*drained)
4336 g_signal_emit (dbin, gst_decode_bin_signals[SIGNAL_DRAINED], 0, NULL);
4337
4338 return handled;
4339 }
4340
4341 /* check if the group is drained, meaning all pads have seen an EOS
4342 * event. */
4343 static gboolean
gst_decode_pad_handle_eos(GstDecodePad * pad)4344 gst_decode_pad_handle_eos (GstDecodePad * pad)
4345 {
4346 gboolean last_group = TRUE;
4347 gboolean switched = FALSE;
4348 gboolean drained = FALSE;
4349 GstDecodeChain *chain = pad->chain;
4350 GstDecodeBin *dbin = chain->dbin;
4351 GstEvent *tmp;
4352
4353 GST_LOG_OBJECT (dbin, "pad %p", pad);
4354
4355 /* Send a stream-group-done event in case downstream needs
4356 * to unblock before we can drain */
4357 tmp = gst_pad_get_sticky_event (GST_PAD (pad), GST_EVENT_STREAM_START, 0);
4358 if (tmp) {
4359 guint group_id;
4360 if (gst_event_parse_group_id (tmp, &group_id)) {
4361 GstPad *peer = gst_pad_get_peer (GST_PAD (pad));
4362
4363 if (peer) {
4364 GST_DEBUG_OBJECT (dbin,
4365 "Sending stream-group-done for group %u to pad %"
4366 GST_PTR_FORMAT, group_id, pad);
4367 gst_pad_send_event (peer, gst_event_new_stream_group_done (group_id));
4368 gst_object_unref (peer);
4369 }
4370 } else {
4371 GST_DEBUG_OBJECT (dbin,
4372 "No group ID to send stream-group-done on pad %" GST_PTR_FORMAT, pad);
4373 }
4374 gst_event_unref (tmp);
4375 }
4376
4377 EXPOSE_LOCK (dbin);
4378 if (dbin->decode_chain) {
4379 drain_and_switch_chains (dbin->decode_chain, pad, &last_group, &drained,
4380 &switched);
4381
4382 if (switched) {
4383 /* If we resulted in a group switch, expose what's needed */
4384 if (gst_decode_chain_is_complete (dbin->decode_chain))
4385 gst_decode_bin_expose (dbin);
4386 }
4387 }
4388 EXPOSE_UNLOCK (dbin);
4389
4390 return last_group;
4391 }
4392
4393 /* gst_decode_group_is_drained:
4394 *
4395 * Check is this group is drained and cache this result.
4396 * The group is drained if all child chains are drained.
4397 *
4398 * Not MT-safe, call with group->parent's lock */
4399 static gboolean
gst_decode_group_is_drained(GstDecodeGroup * group)4400 gst_decode_group_is_drained (GstDecodeGroup * group)
4401 {
4402 GList *l;
4403 gboolean drained = TRUE;
4404
4405 if (group->drained) {
4406 drained = TRUE;
4407 goto out;
4408 }
4409
4410 for (l = group->children; l; l = l->next) {
4411 GstDecodeChain *chain = l->data;
4412
4413 CHAIN_MUTEX_LOCK (chain);
4414 if (!gst_decode_chain_is_drained (chain))
4415 drained = FALSE;
4416 CHAIN_MUTEX_UNLOCK (chain);
4417 if (!drained)
4418 goto out;
4419 }
4420 group->drained = drained;
4421
4422 out:
4423 GST_DEBUG_OBJECT (group->dbin, "Group %p is drained: %d", group, drained);
4424 return drained;
4425 }
4426
4427 /* gst_decode_chain_is_drained:
4428 *
4429 * Check is the chain is drained, which means that
4430 * either
4431 *
4432 * a) it's endpad is drained
4433 * b) there are no pending pads, the active group is drained
4434 * and there are no next groups
4435 *
4436 * Not MT-safe, call with chain lock
4437 */
4438 static gboolean
gst_decode_chain_is_drained(GstDecodeChain * chain)4439 gst_decode_chain_is_drained (GstDecodeChain * chain)
4440 {
4441 gboolean drained = FALSE;
4442
4443 if (chain->endpad) {
4444 drained = chain->endpad->drained;
4445 goto out;
4446 }
4447
4448 if (chain->pending_pads) {
4449 drained = FALSE;
4450 goto out;
4451 }
4452
4453 if (chain->active_group && gst_decode_group_is_drained (chain->active_group)
4454 && !chain->next_groups) {
4455 drained = TRUE;
4456 goto out;
4457 }
4458
4459 out:
4460 GST_DEBUG_OBJECT (chain->dbin, "Chain %p is drained: %d", chain, drained);
4461 return drained;
4462 }
4463
4464 static gboolean
gst_decode_group_reset_buffering(GstDecodeGroup * group)4465 gst_decode_group_reset_buffering (GstDecodeGroup * group)
4466 {
4467 GList *l;
4468 gboolean ret = TRUE;
4469
4470 GST_DEBUG_OBJECT (group->dbin, "Group reset buffering %p %s", group,
4471 GST_ELEMENT_NAME (group->multiqueue));
4472 for (l = group->children; l; l = l->next) {
4473 GstDecodeChain *chain = l->data;
4474
4475 CHAIN_MUTEX_LOCK (chain);
4476 if (!gst_decode_chain_reset_buffering (chain)) {
4477 ret = FALSE;
4478 }
4479 CHAIN_MUTEX_UNLOCK (chain);
4480 }
4481
4482 decodebin_set_queue_size_full (group->dbin, group->multiqueue, !ret,
4483 FALSE, (group->parent ? group->parent->seekable : TRUE));
4484
4485 if (ret) {
4486 /* all chains are buffering already, no need to do it here */
4487 g_object_set (group->multiqueue, "use-buffering", FALSE, NULL);
4488 } else {
4489 #ifdef OHOS_EXT_FUNC
4490 // ohos.ext.func.0013
4491 g_object_set (group->multiqueue, "use-buffering", TRUE,
4492 "low-percent", group->dbin->low_percent,
4493 "high-percent", group->dbin->high_percent,
4494 "mq-num-id", group->dbin->mq_num_use_buffering, NULL);
4495
4496 group->dbin->mq_num_use_buffering++;
4497 #else
4498 g_object_set (group->multiqueue, "use-buffering", TRUE,
4499 "low-percent", group->dbin->low_percent,
4500 "high-percent", group->dbin->high_percent, NULL);
4501 #endif
4502 }
4503
4504 GST_DEBUG_OBJECT (group->dbin, "Setting %s buffering to %d",
4505 GST_ELEMENT_NAME (group->multiqueue), !ret);
4506 return TRUE;
4507 }
4508
4509
4510 /* sort_end_pads:
4511 * GCompareFunc to use with lists of GstPad.
4512 * Sorts pads by mime type.
4513 * First video (raw, then non-raw), then audio (raw, then non-raw),
4514 * then others.
4515 *
4516 * Return: negative if a<b, 0 if a==b, positive if a>b
4517 */
4518 static gint
sort_end_pads(GstDecodePad * da,GstDecodePad * db)4519 sort_end_pads (GstDecodePad * da, GstDecodePad * db)
4520 {
4521 gint va, vb;
4522 GstCaps *capsa, *capsb;
4523 GstStructure *sa, *sb;
4524 const gchar *namea, *nameb;
4525 gchar *ida, *idb;
4526 gint ret;
4527
4528 capsa = get_pad_caps (GST_PAD_CAST (da));
4529 capsb = get_pad_caps (GST_PAD_CAST (db));
4530
4531 sa = gst_caps_get_structure ((const GstCaps *) capsa, 0);
4532 sb = gst_caps_get_structure ((const GstCaps *) capsb, 0);
4533
4534 namea = gst_structure_get_name (sa);
4535 nameb = gst_structure_get_name (sb);
4536
4537 if (g_strrstr (namea, "video/x-raw"))
4538 va = 0;
4539 else if (g_strrstr (namea, "video/"))
4540 va = 1;
4541 else if (g_strrstr (namea, "audio/x-raw"))
4542 va = 2;
4543 else if (g_strrstr (namea, "audio/"))
4544 va = 3;
4545 else
4546 va = 4;
4547
4548 if (g_strrstr (nameb, "video/x-raw"))
4549 vb = 0;
4550 else if (g_strrstr (nameb, "video/"))
4551 vb = 1;
4552 else if (g_strrstr (nameb, "audio/x-raw"))
4553 vb = 2;
4554 else if (g_strrstr (nameb, "audio/"))
4555 vb = 3;
4556 else
4557 vb = 4;
4558
4559 gst_caps_unref (capsa);
4560 gst_caps_unref (capsb);
4561
4562 if (va != vb)
4563 return va - vb;
4564
4565 /* if otherwise the same, sort by stream-id */
4566 ida = gst_pad_get_stream_id (GST_PAD_CAST (da));
4567 idb = gst_pad_get_stream_id (GST_PAD_CAST (db));
4568 ret = (ida) ? ((idb) ? strcmp (ida, idb) : -1) : 1;
4569 g_free (ida);
4570 g_free (idb);
4571
4572 return ret;
4573 }
4574
4575 static GstCaps *
_gst_element_get_linked_caps(GstElement * src,GstElement * sink,GstElement * capsfilter,GstPad ** srcpad)4576 _gst_element_get_linked_caps (GstElement * src, GstElement * sink,
4577 GstElement * capsfilter, GstPad ** srcpad)
4578 {
4579 GstIterator *it;
4580 GstElement *parent;
4581 GstPad *pad, *peer;
4582 gboolean done = FALSE;
4583 GstCaps *caps = NULL;
4584 GValue item = { 0, };
4585
4586 it = gst_element_iterate_src_pads (src);
4587 while (!done) {
4588 switch (gst_iterator_next (it, &item)) {
4589 case GST_ITERATOR_OK:
4590 pad = g_value_get_object (&item);
4591 peer = gst_pad_get_peer (pad);
4592 if (peer) {
4593 parent = gst_pad_get_parent_element (peer);
4594 if (parent == sink || (capsfilter != NULL && parent == capsfilter)) {
4595 caps = gst_pad_get_current_caps (pad);
4596 *srcpad = gst_object_ref (pad);
4597 done = TRUE;
4598 }
4599
4600 if (parent)
4601 gst_object_unref (parent);
4602 gst_object_unref (peer);
4603 }
4604 g_value_reset (&item);
4605 break;
4606 case GST_ITERATOR_RESYNC:
4607 gst_iterator_resync (it);
4608 break;
4609 case GST_ITERATOR_ERROR:
4610 case GST_ITERATOR_DONE:
4611 done = TRUE;
4612 break;
4613 }
4614 }
4615 g_value_unset (&item);
4616 gst_iterator_free (it);
4617
4618 return caps;
4619 }
4620
4621 static GQuark topology_structure_name = 0;
4622 static GQuark topology_caps = 0;
4623 static GQuark topology_next = 0;
4624 static GQuark topology_pad = 0;
4625 static GQuark topology_element_srcpad = 0;
4626
4627 /* FIXME: Invent gst_structure_take_structure() to prevent all the
4628 * structure copying for nothing
4629 */
4630 static GstStructure *
gst_decode_chain_get_topology(GstDecodeChain * chain)4631 gst_decode_chain_get_topology (GstDecodeChain * chain)
4632 {
4633 GstStructure *s, *u;
4634 GList *l;
4635 GstCaps *caps;
4636
4637 if (G_UNLIKELY ((chain->endpad || chain->deadend)
4638 && (chain->endcaps == NULL))) {
4639 GST_WARNING ("End chain without valid caps !");
4640 return NULL;
4641 }
4642
4643 u = gst_structure_new_id_empty (topology_structure_name);
4644
4645 /* Now at the last element */
4646 if ((chain->elements || !chain->active_group) &&
4647 (chain->endpad || chain->deadend)) {
4648 GstPad *srcpad;
4649
4650 s = gst_structure_new_id_empty (topology_structure_name);
4651 gst_structure_id_set (u, topology_caps, GST_TYPE_CAPS, chain->endcaps,
4652 NULL);
4653
4654 if (chain->endpad) {
4655 gst_structure_id_set (u, topology_pad, GST_TYPE_PAD, chain->endpad, NULL);
4656
4657 srcpad = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (chain->endpad));
4658 gst_structure_id_set (u, topology_element_srcpad, GST_TYPE_PAD,
4659 srcpad, NULL);
4660
4661 gst_object_unref (srcpad);
4662 }
4663
4664 gst_structure_id_set (s, topology_next, GST_TYPE_STRUCTURE, u, NULL);
4665 gst_structure_free (u);
4666 u = s;
4667 } else if (chain->active_group) {
4668 GValue list = { 0, };
4669 GValue item = { 0, };
4670
4671 g_value_init (&list, GST_TYPE_LIST);
4672 g_value_init (&item, GST_TYPE_STRUCTURE);
4673 for (l = chain->active_group->children; l; l = l->next) {
4674 s = gst_decode_chain_get_topology (l->data);
4675 if (s) {
4676 gst_value_set_structure (&item, s);
4677 gst_value_list_append_value (&list, &item);
4678 g_value_reset (&item);
4679 gst_structure_free (s);
4680 }
4681 }
4682 gst_structure_id_set_value (u, topology_next, &list);
4683 g_value_unset (&list);
4684 g_value_unset (&item);
4685 }
4686
4687 /* Get caps between all elements in this chain */
4688 l = (chain->elements && chain->elements->next) ? chain->elements : NULL;
4689 for (; l && l->next; l = l->next) {
4690 GstDecodeElement *delem, *delem_next;
4691 GstElement *elem, *capsfilter, *elem_next;
4692 GstCaps *caps;
4693 GstPad *srcpad;
4694
4695 delem = l->data;
4696 elem = delem->element;
4697 delem_next = l->next->data;
4698 elem_next = delem_next->element;
4699 capsfilter = delem_next->capsfilter;
4700 srcpad = NULL;
4701
4702 caps = _gst_element_get_linked_caps (elem_next, elem, capsfilter, &srcpad);
4703
4704 if (caps) {
4705 s = gst_structure_new_id_empty (topology_structure_name);
4706 gst_structure_id_set (u, topology_caps, GST_TYPE_CAPS, caps, NULL);
4707 gst_caps_unref (caps);
4708
4709 gst_structure_id_set (s, topology_next, GST_TYPE_STRUCTURE, u, NULL);
4710 gst_structure_free (u);
4711 u = s;
4712 }
4713
4714 if (srcpad) {
4715 gst_structure_id_set (u, topology_element_srcpad, GST_TYPE_PAD, srcpad,
4716 NULL);
4717 gst_object_unref (srcpad);
4718 }
4719 }
4720
4721 /* Caps that resulted in this chain */
4722 caps = get_pad_caps (chain->pad);
4723 if (G_UNLIKELY (!caps)) {
4724 GST_WARNING_OBJECT (chain->pad, "Couldn't get the caps of decode chain");
4725 return u;
4726 }
4727 gst_structure_id_set (u, topology_caps, GST_TYPE_CAPS, caps, NULL);
4728 gst_structure_id_set (u, topology_element_srcpad, GST_TYPE_PAD, chain->pad,
4729 NULL);
4730 gst_caps_unref (caps);
4731
4732 return u;
4733 }
4734
4735 static void
gst_decode_bin_post_topology_message(GstDecodeBin * dbin)4736 gst_decode_bin_post_topology_message (GstDecodeBin * dbin)
4737 {
4738 GstStructure *s;
4739 GstMessage *msg;
4740
4741 s = gst_decode_chain_get_topology (dbin->decode_chain);
4742
4743 if (G_UNLIKELY (s == NULL))
4744 return;
4745 msg = gst_message_new_element (GST_OBJECT (dbin), s);
4746 gst_element_post_message (GST_ELEMENT (dbin), msg);
4747 }
4748
4749 static gboolean
debug_sticky_event(GstPad * pad,GstEvent ** event,gpointer user_data)4750 debug_sticky_event (GstPad * pad, GstEvent ** event, gpointer user_data)
4751 {
4752 GST_DEBUG_OBJECT (pad, "sticky event %s (%p)", GST_EVENT_TYPE_NAME (*event),
4753 *event);
4754 return TRUE;
4755 }
4756
4757
4758 /* Must only be called if the toplevel chain is complete and blocked! */
4759 /* Not MT-safe, call with decodebin expose lock! */
4760 static gboolean
gst_decode_bin_expose(GstDecodeBin * dbin)4761 gst_decode_bin_expose (GstDecodeBin * dbin)
4762 {
4763 GList *tmp, *endpads;
4764 gboolean missing_plugin;
4765 GString *missing_plugin_details;
4766 gboolean already_exposed;
4767 gboolean last_group;
4768
4769 retry:
4770 endpads = NULL;
4771 missing_plugin = FALSE;
4772 already_exposed = TRUE;
4773 last_group = TRUE;
4774
4775 missing_plugin_details = g_string_new ("");
4776
4777 GST_DEBUG_OBJECT (dbin, "Exposing currently active chains/groups");
4778
4779 /* Don't expose if we're currently shutting down */
4780 DYN_LOCK (dbin);
4781 if (G_UNLIKELY (dbin->shutdown)) {
4782 GST_WARNING_OBJECT (dbin, "Currently, shutting down, aborting exposing");
4783 DYN_UNLOCK (dbin);
4784 return FALSE;
4785 }
4786 DYN_UNLOCK (dbin);
4787
4788 /* Get the pads that we're going to expose and mark things as exposed */
4789 if (!gst_decode_chain_expose (dbin->decode_chain, &endpads, &missing_plugin,
4790 missing_plugin_details, &last_group)) {
4791 g_list_foreach (endpads, (GFunc) gst_object_unref, NULL);
4792 g_list_free (endpads);
4793 g_string_free (missing_plugin_details, TRUE);
4794 /* Failures could be due to the fact that we are currently shutting down (recheck) */
4795 DYN_LOCK (dbin);
4796 if (G_UNLIKELY (dbin->shutdown)) {
4797 GST_WARNING_OBJECT (dbin, "Currently, shutting down, aborting exposing");
4798 DYN_UNLOCK (dbin);
4799 return FALSE;
4800 }
4801 DYN_UNLOCK (dbin);
4802 GST_ERROR_OBJECT (dbin, "Broken chain/group tree");
4803 g_return_val_if_reached (FALSE);
4804 return FALSE;
4805 }
4806 if (endpads == NULL) {
4807 if (missing_plugin) {
4808 if (missing_plugin_details->len > 0) {
4809 gchar *details = g_string_free (missing_plugin_details, FALSE);
4810 GST_ELEMENT_ERROR (dbin, CORE, MISSING_PLUGIN, (NULL),
4811 ("no suitable plugins found:\n%s", details));
4812 g_free (details);
4813 } else {
4814 g_string_free (missing_plugin_details, TRUE);
4815 GST_ELEMENT_ERROR (dbin, CORE, MISSING_PLUGIN, (NULL),
4816 ("no suitable plugins found"));
4817 }
4818 } else {
4819 /* in this case, the stream ended without buffers,
4820 * just post a warning */
4821 g_string_free (missing_plugin_details, TRUE);
4822
4823 GST_WARNING_OBJECT (dbin, "All streams finished without buffers. "
4824 "Last group: %d", last_group);
4825 if (last_group) {
4826 GST_ELEMENT_ERROR (dbin, STREAM, FAILED, (NULL),
4827 ("all streams without buffers"));
4828 } else {
4829 gboolean switched = FALSE;
4830 gboolean drained = FALSE;
4831
4832 drain_and_switch_chains (dbin->decode_chain, NULL, &last_group,
4833 &drained, &switched);
4834 GST_ELEMENT_WARNING (dbin, STREAM, FAILED, (NULL),
4835 ("all streams without buffers"));
4836 if (switched) {
4837 if (gst_decode_chain_is_complete (dbin->decode_chain))
4838 goto retry;
4839 else
4840 return FALSE;
4841 }
4842 }
4843 }
4844
4845 do_async_done (dbin);
4846 return FALSE;
4847 }
4848
4849 g_string_free (missing_plugin_details, TRUE);
4850
4851 /* Check if this was called when everything was exposed already */
4852 for (tmp = endpads; tmp && already_exposed; tmp = tmp->next) {
4853 GstDecodePad *dpad = tmp->data;
4854
4855 already_exposed &= dpad->exposed;
4856 if (!already_exposed)
4857 break;
4858 }
4859 if (already_exposed) {
4860 GST_DEBUG_OBJECT (dbin, "Everything was exposed already!");
4861 g_list_foreach (endpads, (GFunc) gst_object_unref, NULL);
4862 g_list_free (endpads);
4863 return TRUE;
4864 }
4865
4866 /* going to expose something, reset buffering */
4867 gst_decode_bin_reset_buffering (dbin);
4868
4869 /* Set all already exposed pads to blocked */
4870 for (tmp = endpads; tmp; tmp = tmp->next) {
4871 GstDecodePad *dpad = tmp->data;
4872
4873 if (dpad->exposed) {
4874 GST_DEBUG_OBJECT (dpad, "blocking exposed pad");
4875 gst_decode_pad_set_blocked (dpad, TRUE);
4876 }
4877 }
4878
4879 /* re-order pads : video, then audio, then others */
4880 endpads = g_list_sort (endpads, (GCompareFunc) sort_end_pads);
4881
4882 /* Don't add pads if we are shutting down */
4883 DYN_LOCK (dbin);
4884 if (G_UNLIKELY (dbin->shutdown)) {
4885 GST_WARNING_OBJECT (dbin, "Currently, shutting down, aborting exposing");
4886 DYN_UNLOCK (dbin);
4887 return FALSE;
4888 }
4889
4890 /* Expose pads */
4891 for (tmp = endpads; tmp; tmp = tmp->next) {
4892 GstDecodePad *dpad = (GstDecodePad *) tmp->data;
4893 gchar *padname;
4894
4895 /* 1. rewrite name */
4896 padname = g_strdup_printf ("src_%u", dbin->nbpads);
4897 dbin->nbpads++;
4898 GST_DEBUG_OBJECT (dbin, "About to expose dpad %s as %s",
4899 GST_OBJECT_NAME (dpad), padname);
4900 gst_object_set_name (GST_OBJECT (dpad), padname);
4901 g_free (padname);
4902
4903 gst_pad_sticky_events_foreach (GST_PAD_CAST (dpad), debug_sticky_event,
4904 dpad);
4905
4906 /* 2. activate and add */
4907 if (!dpad->exposed) {
4908 dpad->exposed = TRUE;
4909 if (!gst_element_add_pad (GST_ELEMENT (dbin), GST_PAD_CAST (dpad))) {
4910 /* not really fatal, we can try to add the other pads */
4911 g_warning ("error adding pad to decodebin");
4912 dpad->exposed = FALSE;
4913 continue;
4914 }
4915 }
4916
4917 /* 3. emit signal */
4918 GST_INFO_OBJECT (dpad, "added new decoded pad");
4919 }
4920 DYN_UNLOCK (dbin);
4921
4922 /* 4. Signal no-more-pads. This allows the application to hook stuff to the
4923 * exposed pads */
4924 GST_LOG_OBJECT (dbin, "signaling no-more-pads");
4925 gst_element_no_more_pads (GST_ELEMENT (dbin));
4926
4927 /* 5. Send a custom element message with the stream topology */
4928 if (dbin->post_stream_topology)
4929 gst_decode_bin_post_topology_message (dbin);
4930
4931 /* 6. Unblock internal pads. The application should have connected stuff now
4932 * so that streaming can continue. */
4933 for (tmp = endpads; tmp; tmp = tmp->next) {
4934 GstDecodePad *dpad = (GstDecodePad *) tmp->data;
4935
4936 GST_DEBUG_OBJECT (dpad, "unblocking");
4937 gst_decode_pad_unblock (dpad);
4938 GST_DEBUG_OBJECT (dpad, "unblocked");
4939 gst_object_unref (dpad);
4940 }
4941 g_list_free (endpads);
4942
4943 do_async_done (dbin);
4944 GST_DEBUG_OBJECT (dbin, "Exposed everything");
4945 return TRUE;
4946 }
4947
4948 /* gst_decode_chain_expose:
4949 *
4950 * Check if the chain can be exposed and add all endpads
4951 * to the endpads list.
4952 *
4953 * Also update the active group's multiqueue to the
4954 * runtime limits.
4955 *
4956 * Not MT-safe, call with decodebin expose lock! *
4957 */
4958 static gboolean
gst_decode_chain_expose(GstDecodeChain * chain,GList ** endpads,gboolean * missing_plugin,GString * missing_plugin_details,gboolean * last_group)4959 gst_decode_chain_expose (GstDecodeChain * chain, GList ** endpads,
4960 gboolean * missing_plugin, GString * missing_plugin_details,
4961 gboolean * last_group)
4962 {
4963 GstDecodeGroup *group;
4964 GList *l;
4965 GstDecodeBin *dbin;
4966
4967 if (chain->deadend) {
4968 if (chain->endcaps) {
4969 if (chain->deadend_details) {
4970 g_string_append (missing_plugin_details, chain->deadend_details);
4971 g_string_append_c (missing_plugin_details, '\n');
4972 } else {
4973 gchar *desc = gst_pb_utils_get_codec_description (chain->endcaps);
4974 gchar *caps_str = gst_caps_to_string (chain->endcaps);
4975 g_string_append_printf (missing_plugin_details,
4976 "Missing decoder: %s (%s)\n", desc, caps_str);
4977 g_free (caps_str);
4978 g_free (desc);
4979 }
4980 *missing_plugin = TRUE;
4981 }
4982 return TRUE;
4983 }
4984
4985 if (chain->endpad) {
4986 if (!gst_decode_pad_is_exposable (chain->endpad) && !chain->endpad->exposed)
4987 return FALSE;
4988 *endpads = g_list_prepend (*endpads, gst_object_ref (chain->endpad));
4989 return TRUE;
4990 }
4991
4992 if (chain->next_groups)
4993 *last_group = FALSE;
4994
4995 group = chain->active_group;
4996 if (!group)
4997 return FALSE;
4998 if (!group->no_more_pads && !group->overrun)
4999 return FALSE;
5000
5001 dbin = group->dbin;
5002
5003 /* we can now disconnect any overrun signal, which is used to expose the
5004 * group. */
5005 if (group->overrunsig) {
5006 GST_LOG_OBJECT (dbin, "Disconnecting overrun");
5007 g_signal_handler_disconnect (group->multiqueue, group->overrunsig);
5008 group->overrunsig = 0;
5009 }
5010
5011 for (l = group->children; l; l = l->next) {
5012 GstDecodeChain *childchain = l->data;
5013
5014 if (!gst_decode_chain_expose (childchain, endpads, missing_plugin,
5015 missing_plugin_details, last_group))
5016 return FALSE;
5017 }
5018
5019 return TRUE;
5020 }
5021
5022 /*************************
5023 * GstDecodePad functions
5024 *************************/
5025
5026 static void
gst_decode_pad_class_init(GstDecodePadClass * klass)5027 gst_decode_pad_class_init (GstDecodePadClass * klass)
5028 {
5029 }
5030
5031 static void
gst_decode_pad_init(GstDecodePad * pad)5032 gst_decode_pad_init (GstDecodePad * pad)
5033 {
5034 pad->chain = NULL;
5035 pad->blocked = FALSE;
5036 pad->exposed = FALSE;
5037 pad->drained = FALSE;
5038 gst_object_ref_sink (pad);
5039 }
5040
5041 static GstPadProbeReturn
source_pad_blocked_cb(GstPad * pad,GstPadProbeInfo * info,gpointer user_data)5042 source_pad_blocked_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
5043 {
5044 GstDecodePad *dpad = user_data;
5045 GstDecodeChain *chain;
5046 GstDecodeBin *dbin;
5047 GstPadProbeReturn ret = GST_PAD_PROBE_OK;
5048
5049 if (GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM) {
5050 GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
5051
5052 GST_LOG_OBJECT (pad, "Seeing event '%s'", GST_EVENT_TYPE_NAME (event));
5053
5054 if (!GST_EVENT_IS_SERIALIZED (event)) {
5055 /* do not block on sticky or out of band events otherwise the allocation query
5056 from demuxer might block the loop thread */
5057 GST_LOG_OBJECT (pad, "Letting OOB event through");
5058 return GST_PAD_PROBE_PASS;
5059 }
5060
5061 if (GST_EVENT_IS_STICKY (event) && GST_EVENT_TYPE (event) != GST_EVENT_EOS) {
5062 /* manually push sticky events to ghost pad to avoid exposing pads
5063 * that don't have the sticky events. Handle EOS separately as we
5064 * want to block the pad on it if we didn't get any buffers before
5065 * EOS and expose the pad then. */
5066 gst_pad_push_event (GST_PAD_CAST (dpad), gst_event_ref (event));
5067
5068 /* let the sticky events pass */
5069 ret = GST_PAD_PROBE_PASS;
5070
5071 /* we only want to try to expose on CAPS events */
5072 if (GST_EVENT_TYPE (event) != GST_EVENT_CAPS) {
5073 GST_LOG_OBJECT (pad, "Letting sticky non-CAPS event through");
5074 goto done;
5075 }
5076 }
5077 } else if (GST_PAD_PROBE_INFO_TYPE (info) &
5078 GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM) {
5079 GstQuery *query = GST_PAD_PROBE_INFO_QUERY (info);
5080
5081 if (!GST_QUERY_IS_SERIALIZED (query)) {
5082 /* do not block on non-serialized queries */
5083 GST_LOG_OBJECT (pad, "Letting non-serialized query through");
5084 return GST_PAD_PROBE_PASS;
5085 }
5086 if (!gst_pad_has_current_caps (pad)) {
5087 /* do not block on allocation queries before we have caps,
5088 * this would deadlock because we are doing no autoplugging
5089 * without caps.
5090 * TODO: Try to do autoplugging based on the query caps
5091 */
5092 GST_LOG_OBJECT (pad, "Letting serialized query before caps through");
5093 return GST_PAD_PROBE_PASS;
5094 }
5095 }
5096 chain = dpad->chain;
5097 dbin = chain->dbin;
5098
5099 GST_LOG_OBJECT (dpad, "blocked: dpad->chain:%p", chain);
5100
5101 dpad->blocked = TRUE;
5102
5103 EXPOSE_LOCK (dbin);
5104 if (dbin->decode_chain) {
5105 if (gst_decode_chain_is_complete (dbin->decode_chain)) {
5106 if (!gst_decode_bin_expose (dbin))
5107 GST_WARNING_OBJECT (dbin, "Couldn't expose group");
5108 }
5109 }
5110 EXPOSE_UNLOCK (dbin);
5111
5112 done:
5113 return ret;
5114 }
5115
5116 static GstPadProbeReturn
source_pad_event_probe(GstPad * pad,GstPadProbeInfo * info,gpointer user_data)5117 source_pad_event_probe (GstPad * pad, GstPadProbeInfo * info,
5118 gpointer user_data)
5119 {
5120 GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
5121 GstDecodePad *dpad = user_data;
5122 gboolean res = TRUE;
5123
5124 GST_LOG_OBJECT (pad, "%s dpad:%p", GST_EVENT_TYPE_NAME (event), dpad);
5125
5126 if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
5127 GST_DEBUG_OBJECT (pad, "we received EOS");
5128
5129 /* Check if all pads are drained.
5130 * * If there is no next group, we will let the EOS go through.
5131 * * If there is a next group but the current group isn't completely
5132 * drained, we will drop the EOS event.
5133 * * If there is a next group to expose and this was the last non-drained
5134 * pad for that group, we will remove the ghostpad of the current group
5135 * first, which unlinks the peer and so drops the EOS. */
5136 res = gst_decode_pad_handle_eos (dpad);
5137 }
5138 if (res)
5139 return GST_PAD_PROBE_OK;
5140 else
5141 return GST_PAD_PROBE_DROP;
5142 }
5143
5144 static void
gst_decode_pad_set_blocked(GstDecodePad * dpad,gboolean blocked)5145 gst_decode_pad_set_blocked (GstDecodePad * dpad, gboolean blocked)
5146 {
5147 GstDecodeBin *dbin = dpad->dbin;
5148 GstPad *opad;
5149
5150 DYN_LOCK (dbin);
5151
5152 GST_DEBUG_OBJECT (dpad, "blocking pad: %d", blocked);
5153
5154 opad = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (dpad));
5155 if (!opad)
5156 goto out;
5157
5158 /* do not block if shutting down.
5159 * we do not consider/expect it blocked further below, but use other trick */
5160 if (!blocked || !dbin->shutdown) {
5161 if (blocked) {
5162 if (dpad->block_id == 0)
5163 dpad->block_id =
5164 gst_pad_add_probe (opad,
5165 GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM |
5166 GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM, source_pad_blocked_cb,
5167 gst_object_ref (dpad), (GDestroyNotify) gst_object_unref);
5168 } else {
5169 if (dpad->block_id != 0) {
5170 gst_pad_remove_probe (opad, dpad->block_id);
5171 dpad->block_id = 0;
5172 }
5173 dpad->blocked = FALSE;
5174 }
5175 }
5176
5177 if (blocked) {
5178 if (dbin->shutdown) {
5179 /* deactivate to force flushing state to prevent NOT_LINKED errors */
5180 gst_pad_set_active (GST_PAD_CAST (dpad), FALSE);
5181 /* note that deactivating the target pad would have no effect here,
5182 * since elements are typically connected first (and pads exposed),
5183 * and only then brought to PAUSED state (so pads activated) */
5184 } else {
5185 gst_object_ref (dpad);
5186 dbin->blocked_pads = g_list_prepend (dbin->blocked_pads, dpad);
5187 }
5188 } else {
5189 GList *l;
5190
5191 if ((l = g_list_find (dbin->blocked_pads, dpad))) {
5192 gst_object_unref (dpad);
5193 dbin->blocked_pads = g_list_delete_link (dbin->blocked_pads, l);
5194 }
5195 }
5196 gst_object_unref (opad);
5197 out:
5198 DYN_UNLOCK (dbin);
5199 }
5200
5201 static void
gst_decode_pad_add_drained_check(GstDecodePad * dpad)5202 gst_decode_pad_add_drained_check (GstDecodePad * dpad)
5203 {
5204 gst_pad_add_probe (GST_PAD_CAST (dpad), GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
5205 source_pad_event_probe, dpad, NULL);
5206 }
5207
5208 static void
gst_decode_pad_activate(GstDecodePad * dpad,GstDecodeChain * chain)5209 gst_decode_pad_activate (GstDecodePad * dpad, GstDecodeChain * chain)
5210 {
5211 g_return_if_fail (chain != NULL);
5212
5213 dpad->chain = chain;
5214 gst_pad_set_active (GST_PAD_CAST (dpad), TRUE);
5215 gst_decode_pad_set_blocked (dpad, TRUE);
5216 gst_decode_pad_add_drained_check (dpad);
5217 }
5218
5219 static void
gst_decode_pad_unblock(GstDecodePad * dpad)5220 gst_decode_pad_unblock (GstDecodePad * dpad)
5221 {
5222 gst_decode_pad_set_blocked (dpad, FALSE);
5223 }
5224
5225 static gboolean
gst_decode_pad_event(GstPad * pad,GstObject * parent,GstEvent * event)5226 gst_decode_pad_event (GstPad * pad, GstObject * parent, GstEvent * event)
5227 {
5228 GstDecodeBin *dbin = GST_DECODE_BIN (parent);
5229
5230 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK && dbin && dbin->decode_chain) {
5231 GstElement *demuxer = NULL;
5232
5233 /* For adaptive demuxers we send the seek event directly to the demuxer.
5234 * See https://bugzilla.gnome.org/show_bug.cgi?id=606382
5235 */
5236 CHAIN_MUTEX_LOCK (dbin->decode_chain);
5237 if (dbin->decode_chain->adaptive_demuxer) {
5238 GstDecodeElement *delem = dbin->decode_chain->elements->data;
5239 demuxer = gst_object_ref (delem->element);
5240 }
5241 CHAIN_MUTEX_UNLOCK (dbin->decode_chain);
5242
5243 if (demuxer) {
5244 gboolean ret;
5245
5246 GST_DEBUG_OBJECT (dbin,
5247 "Sending SEEK event directly to adaptive streaming demuxer %s",
5248 GST_OBJECT_NAME (demuxer));
5249 ret = gst_element_send_event (demuxer, event);
5250 gst_object_unref (demuxer);
5251 return ret;
5252 }
5253 }
5254
5255 return gst_pad_event_default (pad, parent, event);
5256 }
5257
5258 static gboolean
gst_decode_pad_query(GstPad * pad,GstObject * parent,GstQuery * query)5259 gst_decode_pad_query (GstPad * pad, GstObject * parent, GstQuery * query)
5260 {
5261 GstDecodePad *dpad = GST_DECODE_PAD (parent);
5262 gboolean ret = FALSE;
5263
5264 CHAIN_MUTEX_LOCK (dpad->chain);
5265 if (!dpad->exposed && !dpad->dbin->shutdown && !dpad->chain->deadend
5266 && dpad->chain->elements) {
5267 GstDecodeElement *delem = dpad->chain->elements->data;
5268
5269 ret = FALSE;
5270 GST_DEBUG_OBJECT (dpad->dbin,
5271 "calling autoplug-query for %s (element %s): %" GST_PTR_FORMAT,
5272 GST_PAD_NAME (dpad), GST_ELEMENT_NAME (delem->element), query);
5273 g_signal_emit (G_OBJECT (dpad->dbin),
5274 gst_decode_bin_signals[SIGNAL_AUTOPLUG_QUERY], 0, dpad, delem->element,
5275 query, &ret);
5276
5277 if (ret)
5278 GST_DEBUG_OBJECT (dpad->dbin,
5279 "autoplug-query returned %d: %" GST_PTR_FORMAT, ret, query);
5280 else
5281 GST_DEBUG_OBJECT (dpad->dbin, "autoplug-query returned %d", ret);
5282 }
5283 CHAIN_MUTEX_UNLOCK (dpad->chain);
5284
5285 /* If exposed or nothing handled the query use the default handler */
5286 if (!ret)
5287 ret = gst_pad_query_default (pad, parent, query);
5288
5289 return ret;
5290 }
5291
5292 static gboolean
gst_decode_pad_is_exposable(GstDecodePad * endpad)5293 gst_decode_pad_is_exposable (GstDecodePad * endpad)
5294 {
5295 if (endpad->blocked || endpad->exposed)
5296 return TRUE;
5297
5298 return gst_pad_has_current_caps (GST_PAD_CAST (endpad));
5299 }
5300
5301 /*gst_decode_pad_new:
5302 *
5303 * Creates a new GstDecodePad for the given pad.
5304 */
5305 static GstDecodePad *
gst_decode_pad_new(GstDecodeBin * dbin,GstDecodeChain * chain)5306 gst_decode_pad_new (GstDecodeBin * dbin, GstDecodeChain * chain)
5307 {
5308 GstDecodePad *dpad;
5309 GstProxyPad *ppad;
5310 GstPadTemplate *pad_tmpl;
5311
5312 GST_DEBUG_OBJECT (dbin, "making new decodepad");
5313 pad_tmpl = gst_static_pad_template_get (&decoder_bin_src_template);
5314 dpad =
5315 g_object_new (GST_TYPE_DECODE_PAD, "direction", GST_PAD_SRC,
5316 "template", pad_tmpl, NULL);
5317 gst_ghost_pad_construct (GST_GHOST_PAD_CAST (dpad));
5318 dpad->chain = chain;
5319 dpad->dbin = dbin;
5320 gst_object_unref (pad_tmpl);
5321
5322 ppad = gst_proxy_pad_get_internal (GST_PROXY_PAD (dpad));
5323 gst_pad_set_query_function (GST_PAD_CAST (ppad), gst_decode_pad_query);
5324 gst_pad_set_event_function (GST_PAD_CAST (dpad), gst_decode_pad_event);
5325 gst_object_unref (ppad);
5326
5327 return dpad;
5328 }
5329
5330 static void
gst_pending_pad_free(GstPendingPad * ppad)5331 gst_pending_pad_free (GstPendingPad * ppad)
5332 {
5333 g_assert (ppad);
5334 g_assert (ppad->pad);
5335
5336 if (ppad->event_probe_id != 0)
5337 gst_pad_remove_probe (ppad->pad, ppad->event_probe_id);
5338 if (ppad->notify_caps_id)
5339 g_signal_handler_disconnect (ppad->pad, ppad->notify_caps_id);
5340 gst_object_unref (ppad->pad);
5341 g_slice_free (GstPendingPad, ppad);
5342 }
5343
5344 /*****
5345 * Element add/remove
5346 *****/
5347
5348 static void
do_async_start(GstDecodeBin * dbin)5349 do_async_start (GstDecodeBin * dbin)
5350 {
5351 GstMessage *message;
5352
5353 dbin->async_pending = TRUE;
5354
5355 message = gst_message_new_async_start (GST_OBJECT_CAST (dbin));
5356 parent_class->handle_message (GST_BIN_CAST (dbin), message);
5357 }
5358
5359 static void
do_async_done(GstDecodeBin * dbin)5360 do_async_done (GstDecodeBin * dbin)
5361 {
5362 GstMessage *message;
5363
5364 if (dbin->async_pending) {
5365 message =
5366 gst_message_new_async_done (GST_OBJECT_CAST (dbin),
5367 GST_CLOCK_TIME_NONE);
5368 parent_class->handle_message (GST_BIN_CAST (dbin), message);
5369
5370 dbin->async_pending = FALSE;
5371 }
5372 }
5373
5374 /*****
5375 * convenience functions
5376 *****/
5377
5378 /* find_sink_pad
5379 *
5380 * Returns the first sink pad of the given element, or NULL if it doesn't have
5381 * any.
5382 */
5383
5384 static GstPad *
find_sink_pad(GstElement * element)5385 find_sink_pad (GstElement * element)
5386 {
5387 GstIterator *it;
5388 GstPad *pad = NULL;
5389 GValue item = { 0, };
5390
5391 it = gst_element_iterate_sink_pads (element);
5392
5393 if ((gst_iterator_next (it, &item)) == GST_ITERATOR_OK)
5394 pad = g_value_dup_object (&item);
5395 g_value_unset (&item);
5396 gst_iterator_free (it);
5397
5398 return pad;
5399 }
5400
5401 /* call with dyn_lock held */
5402 static void
unblock_pads(GstDecodeBin * dbin)5403 unblock_pads (GstDecodeBin * dbin)
5404 {
5405 GST_LOG_OBJECT (dbin, "unblocking pads");
5406
5407 while (dbin->blocked_pads) {
5408 GList *tmp = dbin->blocked_pads;
5409 GstDecodePad *dpad = (GstDecodePad *) tmp->data;
5410 GstPad *opad;
5411
5412 dbin->blocked_pads = g_list_delete_link (dbin->blocked_pads, tmp);
5413 opad = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (dpad));
5414 if (opad) {
5415
5416 GST_DEBUG_OBJECT (dpad, "unblocking");
5417 if (dpad->block_id != 0) {
5418 gst_pad_remove_probe (opad, dpad->block_id);
5419 dpad->block_id = 0;
5420 }
5421 gst_object_unref (opad);
5422 }
5423
5424 dpad->blocked = FALSE;
5425
5426 /* We release the dyn lock since we want to allow the streaming threads
5427 * to properly stop and not be blocked in our various probes */
5428 DYN_UNLOCK (dbin);
5429 /* make flushing, prevent NOT_LINKED */
5430 gst_pad_set_active (GST_PAD_CAST (dpad), FALSE);
5431 DYN_LOCK (dbin);
5432
5433 GST_DEBUG_OBJECT (dpad, "unblocked");
5434 gst_object_unref (dpad);
5435 }
5436 }
5437
5438 static void
gst_decode_chain_stop(GstDecodeBin * dbin,GstDecodeChain * chain,GQueue * elements)5439 gst_decode_chain_stop (GstDecodeBin * dbin, GstDecodeChain * chain,
5440 GQueue * elements)
5441 {
5442 GQueue *internal_elements, internal_elements_ = G_QUEUE_INIT;
5443 GList *l;
5444
5445 CHAIN_MUTEX_LOCK (chain);
5446 if (elements) {
5447 internal_elements = elements;
5448 } else {
5449 internal_elements = &internal_elements_;
5450 }
5451
5452 for (l = chain->next_groups; l; l = l->next) {
5453 GstDecodeGroup *group = l->data;
5454 GList *m;
5455
5456 for (m = group->children; m; m = m->next) {
5457 GstDecodeChain *chain2 = m->data;
5458 gst_decode_chain_stop (dbin, chain2, internal_elements);
5459 }
5460 if (group->multiqueue)
5461 g_queue_push_head (internal_elements, gst_object_ref (group->multiqueue));
5462 }
5463
5464 if (chain->active_group) {
5465 for (l = chain->active_group->children; l; l = l->next) {
5466 GstDecodeChain *chain2 = l->data;
5467 gst_decode_chain_stop (dbin, chain2, internal_elements);
5468 }
5469 if (chain->active_group->multiqueue)
5470 g_queue_push_head (internal_elements,
5471 gst_object_ref (chain->active_group->multiqueue));
5472 }
5473
5474 for (l = chain->old_groups; l; l = l->next) {
5475 GstDecodeGroup *group = l->data;
5476 GList *m;
5477
5478 for (m = group->children; m; m = m->next) {
5479 GstDecodeChain *chain2 = m->data;
5480 gst_decode_chain_stop (dbin, chain2, internal_elements);
5481 }
5482 if (group->multiqueue)
5483 g_queue_push_head (internal_elements, gst_object_ref (group->multiqueue));
5484 }
5485
5486 for (l = chain->elements; l; l = l->next) {
5487 GstDecodeElement *delem = l->data;
5488
5489 if (delem->capsfilter)
5490 g_queue_push_head (internal_elements, gst_object_ref (delem->capsfilter));
5491 g_queue_push_head (internal_elements, gst_object_ref (delem->element));
5492 }
5493
5494 CHAIN_MUTEX_UNLOCK (chain);
5495
5496 if (!elements) {
5497 GstElement *element;
5498
5499 EXPOSE_UNLOCK (dbin);
5500 /* Shut down from bottom to top */
5501 while ((element = g_queue_pop_tail (internal_elements))) {
5502 /* The bin must never ever change the state of this element anymore */
5503 gst_element_set_locked_state (element, TRUE);
5504 gst_element_set_state (element, GST_STATE_NULL);
5505 gst_object_unref (element);
5506 }
5507 g_queue_clear (internal_elements);
5508 EXPOSE_LOCK (dbin);
5509 }
5510 }
5511
5512 static GstStateChangeReturn
gst_decode_bin_change_state(GstElement * element,GstStateChange transition)5513 gst_decode_bin_change_state (GstElement * element, GstStateChange transition)
5514 {
5515 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5516 GstDecodeBin *dbin = GST_DECODE_BIN (element);
5517 GstDecodeChain *chain_to_free = NULL;
5518
5519 switch (transition) {
5520 case GST_STATE_CHANGE_NULL_TO_READY:
5521 if (dbin->typefind == NULL)
5522 goto missing_typefind;
5523 break;
5524 case GST_STATE_CHANGE_READY_TO_PAUSED:
5525 /* Make sure we've cleared all existing chains */
5526 EXPOSE_LOCK (dbin);
5527 if (dbin->decode_chain) {
5528 gst_decode_chain_free (dbin->decode_chain);
5529 dbin->decode_chain = NULL;
5530 }
5531 EXPOSE_UNLOCK (dbin);
5532 DYN_LOCK (dbin);
5533 GST_LOG_OBJECT (dbin, "clearing shutdown flag");
5534 dbin->shutdown = FALSE;
5535 DYN_UNLOCK (dbin);
5536 dbin->have_type = FALSE;
5537 ret = GST_STATE_CHANGE_ASYNC;
5538 do_async_start (dbin);
5539
5540
5541 /* connect a signal to find out when the typefind element found
5542 * a type */
5543 dbin->have_type_id =
5544 g_signal_connect (dbin->typefind, "have-type",
5545 G_CALLBACK (type_found), dbin);
5546 break;
5547 case GST_STATE_CHANGE_PAUSED_TO_READY:
5548 case GST_STATE_CHANGE_READY_TO_NULL:
5549 if (dbin->have_type_id)
5550 g_signal_handler_disconnect (dbin->typefind, dbin->have_type_id);
5551 dbin->have_type_id = 0;
5552 DYN_LOCK (dbin);
5553 GST_LOG_OBJECT (dbin, "setting shutdown flag");
5554 dbin->shutdown = TRUE;
5555 unblock_pads (dbin);
5556 DYN_UNLOCK (dbin);
5557
5558 /* Make sure we don't have cleanup races where
5559 * we might be trying to deactivate pads (in the cleanup thread)
5560 * at the same time as the default element deactivation
5561 * (in PAUSED=>READY) */
5562 g_mutex_lock (&dbin->cleanup_lock);
5563 if (dbin->cleanup_thread) {
5564 g_thread_join (dbin->cleanup_thread);
5565 dbin->cleanup_thread = NULL;
5566 }
5567 g_mutex_unlock (&dbin->cleanup_lock);
5568 default:
5569 break;
5570 }
5571
5572 {
5573 GstStateChangeReturn bret;
5574
5575 bret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5576 if (G_UNLIKELY (bret == GST_STATE_CHANGE_FAILURE))
5577 goto activate_failed;
5578 else if (G_UNLIKELY (bret == GST_STATE_CHANGE_NO_PREROLL)) {
5579 do_async_done (dbin);
5580 ret = bret;
5581 }
5582 }
5583 switch (transition) {
5584 case GST_STATE_CHANGE_PAUSED_TO_READY:
5585 do_async_done (dbin);
5586 EXPOSE_LOCK (dbin);
5587 if (dbin->decode_chain) {
5588 gst_decode_chain_stop (dbin, dbin->decode_chain, NULL);
5589 chain_to_free = dbin->decode_chain;
5590 gst_decode_chain_free_internal (dbin->decode_chain, TRUE);
5591 dbin->decode_chain = NULL;
5592 }
5593 EXPOSE_UNLOCK (dbin);
5594 if (chain_to_free)
5595 gst_decode_chain_free (chain_to_free);
5596 g_list_free_full (dbin->buffering_status,
5597 (GDestroyNotify) gst_message_unref);
5598 dbin->buffering_status = NULL;
5599 /* Let's do a final check of leftover groups to free */
5600 g_mutex_lock (&dbin->cleanup_lock);
5601 if (dbin->cleanup_groups) {
5602 gst_decode_chain_free_hidden_groups (dbin->cleanup_groups);
5603 dbin->cleanup_groups = NULL;
5604 }
5605 g_mutex_unlock (&dbin->cleanup_lock);
5606 break;
5607 case GST_STATE_CHANGE_READY_TO_NULL:
5608 /* Let's do a final check of leftover groups to free */
5609 g_mutex_lock (&dbin->cleanup_lock);
5610 if (dbin->cleanup_groups) {
5611 gst_decode_chain_free_hidden_groups (dbin->cleanup_groups);
5612 dbin->cleanup_groups = NULL;
5613 }
5614 g_mutex_unlock (&dbin->cleanup_lock);
5615 break;
5616 default:
5617 break;
5618 }
5619
5620 return ret;
5621
5622 /* ERRORS */
5623 missing_typefind:
5624 {
5625 gst_element_post_message (element,
5626 gst_missing_element_message_new (element, "typefind"));
5627 GST_ELEMENT_ERROR (dbin, CORE, MISSING_PLUGIN, (NULL), ("no typefind!"));
5628 return GST_STATE_CHANGE_FAILURE;
5629 }
5630 activate_failed:
5631 {
5632 GST_DEBUG_OBJECT (element,
5633 "element failed to change states -- activation problem?");
5634 do_async_done (dbin);
5635 return GST_STATE_CHANGE_FAILURE;
5636 }
5637 }
5638
5639 static void
gst_decode_bin_handle_message(GstBin * bin,GstMessage * msg)5640 gst_decode_bin_handle_message (GstBin * bin, GstMessage * msg)
5641 {
5642 GstDecodeBin *dbin = GST_DECODE_BIN (bin);
5643 gboolean drop = FALSE;
5644
5645 if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) {
5646 /* Don't pass errors when shutting down. Sometimes,
5647 * elements can generate spurious errors because we set the
5648 * output pads to flushing, and they can't detect that if they
5649 * send an event at exactly the wrong moment */
5650 DYN_LOCK (dbin);
5651 drop = dbin->shutdown;
5652 DYN_UNLOCK (dbin);
5653
5654 if (!drop) {
5655 GST_OBJECT_LOCK (dbin);
5656 drop = (g_list_find (dbin->filtered, GST_MESSAGE_SRC (msg)) != NULL);
5657 if (drop)
5658 dbin->filtered_errors =
5659 g_list_prepend (dbin->filtered_errors, gst_message_ref (msg));
5660 GST_OBJECT_UNLOCK (dbin);
5661 }
5662 } else if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_BUFFERING) {
5663 gint perc, msg_perc;
5664 gint smaller_perc = 100;
5665 GstMessage *smaller = NULL;
5666 GList *found = NULL;
5667 GList *iter;
5668
5669 /* buffering messages must be aggregated as there might be multiple
5670 * multiqueue in the pipeline and their independent buffering messages
5671 * will confuse the application
5672 *
5673 * decodebin keeps a list of messages received from elements that are
5674 * buffering.
5675 * Rules are:
5676 * 1) Always post the smaller buffering %
5677 * 2) If an element posts a 100% buffering message, remove it from the list
5678 * 3) When there are no more messages on the list, post 100% message
5679 * 4) When an element posts a new buffering message, update the one
5680 * on the list to this new value
5681 */
5682
5683 BUFFERING_LOCK (dbin);
5684 gst_message_parse_buffering (msg, &msg_perc);
5685
5686 GST_DEBUG_OBJECT (dbin, "Got buffering msg %" GST_PTR_FORMAT, msg);
5687
5688 g_mutex_lock (&dbin->buffering_post_lock);
5689
5690 /*
5691 * Single loop for 2 things:
5692 * 1) Look for a message with the same source
5693 * 1.1) If the received message is 100%, remove it from the list
5694 * 2) Find the minimum buffering from the list
5695 */
5696 for (iter = dbin->buffering_status; iter;) {
5697 GstMessage *bufstats = iter->data;
5698 if (GST_MESSAGE_SRC (bufstats) == GST_MESSAGE_SRC (msg)) {
5699 found = iter;
5700 if (msg_perc < 100) {
5701 GST_DEBUG_OBJECT (dbin, "Replacing old buffering msg %"
5702 GST_PTR_FORMAT, iter->data);
5703 gst_message_unref (iter->data);
5704 bufstats = iter->data = gst_message_ref (msg);
5705 } else {
5706 GList *current = iter;
5707
5708 /* remove the element here and avoid confusing the loop */
5709 iter = g_list_next (iter);
5710
5711 GST_DEBUG_OBJECT (dbin, "Deleting old buffering msg %"
5712 GST_PTR_FORMAT, current->data);
5713
5714 gst_message_unref (current->data);
5715 dbin->buffering_status =
5716 g_list_delete_link (dbin->buffering_status, current);
5717
5718 continue;
5719 }
5720 }
5721
5722 gst_message_parse_buffering (bufstats, &perc);
5723 if (perc < smaller_perc) {
5724 smaller_perc = perc;
5725 smaller = bufstats;
5726 }
5727 iter = g_list_next (iter);
5728 }
5729
5730 if (found == NULL && msg_perc < 100) {
5731 if (msg_perc < smaller_perc) {
5732 smaller_perc = msg_perc;
5733 smaller = msg;
5734 }
5735 GST_DEBUG_OBJECT (dbin, "Storing buffering msg %" GST_PTR_FORMAT, msg);
5736 dbin->buffering_status =
5737 g_list_prepend (dbin->buffering_status, gst_message_ref (msg));
5738 }
5739
5740 /* now compute the buffering message that should be posted */
5741 if (smaller_perc == 100) {
5742 g_assert (dbin->buffering_status == NULL);
5743 /* we are posting the original received msg */
5744 } else {
5745 gst_message_replace (&msg, smaller);
5746 }
5747 BUFFERING_UNLOCK (dbin);
5748
5749 GST_DEBUG_OBJECT (dbin, "Forwarding buffering msg %" GST_PTR_FORMAT, msg);
5750 GST_BIN_CLASS (parent_class)->handle_message (bin, msg);
5751
5752 g_mutex_unlock (&dbin->buffering_post_lock);
5753 return;
5754 }
5755
5756 if (drop) {
5757 gst_message_unref (msg);
5758 } else {
5759 GST_DEBUG_OBJECT (dbin, "Forwarding msg %" GST_PTR_FORMAT, msg);
5760 GST_BIN_CLASS (parent_class)->handle_message (bin, msg);
5761 }
5762 }
5763
5764 static gboolean
gst_decode_bin_remove_element(GstBin * bin,GstElement * element)5765 gst_decode_bin_remove_element (GstBin * bin, GstElement * element)
5766 {
5767 GstDecodeBin *dbin = GST_DECODE_BIN (bin);
5768 gboolean removed = FALSE, post = FALSE;
5769 GList *iter;
5770
5771 BUFFERING_LOCK (bin);
5772 g_mutex_lock (&dbin->buffering_post_lock);
5773 for (iter = dbin->buffering_status; iter; iter = iter->next) {
5774 GstMessage *bufstats = iter->data;
5775
5776 if (GST_MESSAGE_SRC (bufstats) == GST_OBJECT_CAST (element) ||
5777 gst_object_has_as_ancestor (GST_MESSAGE_SRC (bufstats),
5778 GST_OBJECT_CAST (element))) {
5779 gst_message_unref (bufstats);
5780 dbin->buffering_status =
5781 g_list_delete_link (dbin->buffering_status, iter);
5782 removed = TRUE;
5783 break;
5784 }
5785 }
5786
5787 if (removed && dbin->buffering_status == NULL)
5788 post = TRUE;
5789 BUFFERING_UNLOCK (bin);
5790
5791 if (post) {
5792 gst_element_post_message (GST_ELEMENT_CAST (bin),
5793 gst_message_new_buffering (GST_OBJECT_CAST (dbin), 100));
5794 }
5795 g_mutex_unlock (&dbin->buffering_post_lock);
5796
5797 return GST_BIN_CLASS (parent_class)->remove_element (bin, element);
5798 }
5799
5800 gboolean
gst_decode_bin_plugin_init(GstPlugin * plugin)5801 gst_decode_bin_plugin_init (GstPlugin * plugin)
5802 {
5803 GST_DEBUG_CATEGORY_INIT (gst_decode_bin_debug, "decodebin", 0, "decoder bin");
5804
5805 /* Register some quarks here for the stream topology message */
5806 topology_structure_name = g_quark_from_static_string ("stream-topology");
5807 topology_caps = g_quark_from_static_string ("caps");
5808 topology_next = g_quark_from_static_string ("next");
5809 topology_pad = g_quark_from_static_string ("pad");
5810 topology_element_srcpad = g_quark_from_static_string ("element-srcpad");
5811
5812 return gst_element_register (plugin, "decodebin", GST_RANK_NONE,
5813 GST_TYPE_DECODE_BIN);
5814 }
5815