* it has fully transitioned to active */
gboolean selection_updated;
/* End of variables protected by selection_lock */
+ gboolean upstream_selected;
/* List of pending collections.
* FIXME : Is this really needed ? */
GstPad *parsebin_sink;
GstStreamCollection *collection; /* Active collection */
+ gboolean upstream_selected;
guint group_id;
GST_DEBUG_OBJECT (sinkpad, "event %" GST_PTR_FORMAT, event);
switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_STREAM_START:
+ {
+ GstQuery *q = gst_query_new_selectable ();
+
+ /* Query whether upstream can handle stream selection or not */
+ if (gst_pad_peer_query (sinkpad, q)) {
+ gst_query_parse_selectable (q, &input->upstream_selected);
+ GST_DEBUG_OBJECT (sinkpad, "Upstream is selectable : %d",
+ input->upstream_selected);
+ } else {
+ input->upstream_selected = FALSE;
+ GST_DEBUG_OBJECT (sinkpad, "Upstream does not handle SELECTABLE query");
+ }
+ gst_query_unref (q);
+
+ /* FIXME : We force `decodebin3` to upstream selection mode if *any* of the
+ inputs is. This means things might break if there's a mix */
+ if (input->upstream_selected)
+ dbin->upstream_selected = TRUE;
+ break;
+ }
case GST_EVENT_CAPS:
{
GST_DEBUG_OBJECT (sinkpad,
input->ghost_sink = gst_ghost_pad_new_no_target (pad_name, GST_PAD_SINK);
g_free (pad_name);
}
+ input->upstream_selected = FALSE;
g_object_set_data (G_OBJECT (input->ghost_sink), "decodebin.input", input);
gst_pad_set_event_function (input->ghost_sink,
(GstPadEventFunction) sink_event_function);
/* Call with INPUT_LOCK taken */
static void
handle_stream_collection (GstDecodebin3 * dbin,
- GstStreamCollection * collection, GstElement * child)
+ GstStreamCollection * collection, DecodebinInput * input)
{
#ifndef GST_DISABLE_GST_DEBUG
const gchar *upstream_id;
guint i;
#endif
- DecodebinInput *input = find_message_parsebin (dbin, child);
-
if (!input) {
GST_DEBUG_OBJECT (dbin,
"Couldn't find corresponding input, most likely shutting down");
case GST_MESSAGE_STREAM_COLLECTION:
{
GstStreamCollection *collection = NULL;
+ DecodebinInput *input;
+
+ INPUT_LOCK (dbin);
+ input =
+ find_message_parsebin (dbin,
+ (GstElement *) GST_MESSAGE_SRC (message));
+ if (input == NULL) {
+ GST_DEBUG_OBJECT (dbin,
+ "Couldn't find corresponding input, most likely shutting down");
+ INPUT_UNLOCK (dbin);
+ break;
+ }
+ if (input->upstream_selected) {
+ GST_DEBUG_OBJECT (dbin,
+ "Upstream handles selection, not using/forwarding collection");
+ INPUT_UNLOCK (dbin);
+ goto drop_message;
+ }
gst_message_parse_stream_collection (message, &collection);
if (collection) {
- INPUT_LOCK (dbin);
- handle_stream_collection (dbin, collection,
- (GstElement *) GST_MESSAGE_SRC (message));
+ handle_stream_collection (dbin, collection, input);
posting_collection = TRUE;
- INPUT_UNLOCK (dbin);
}
+ INPUT_UNLOCK (dbin);
SELECTION_LOCK (dbin);
if (dbin->collection) {
/* Figure out a selection for that collection */
update_requested_selection (dbin);
}
+
+ return;
+
+drop_message:
+ {
+ GST_DEBUG_OBJECT (bin, "dropping message");
+ gst_message_unref (message);
+ }
}
static DecodebinOutputStream *
/* 3. In default mode check if we should expose */
id_in_list = (gchar *) stream_in_list (dbin->requested_selection, stream_id);
- if (id_in_list) {
+ if (id_in_list || dbin->upstream_selected) {
/* Check if we can steal an existing output stream we could re-use.
* that is:
* * an output stream whose slot->stream is not in requested
GList *streams = NULL;
guint32 seqnum = gst_event_get_seqnum (event);
+ if (dbin->upstream_selected) {
+ GST_DEBUG_OBJECT (pad, "Letting select-streams event flow upstream");
+ break;
+ }
+
SELECTION_LOCK (dbin);
if (seqnum == dbin->select_streams_seqnum) {
SELECTION_UNLOCK (dbin);
static gboolean
gst_decodebin3_send_event (GstElement * element, GstEvent * event)
{
+ GstDecodebin3 *dbin = (GstDecodebin3 *) element;
+
GST_DEBUG_OBJECT (element, "event %s", GST_EVENT_TYPE_NAME (event));
- if (GST_EVENT_TYPE (event) == GST_EVENT_SELECT_STREAMS) {
- GstDecodebin3 *dbin = (GstDecodebin3 *) element;
+ if (!dbin->upstream_selected
+ && GST_EVENT_TYPE (event) == GST_EVENT_SELECT_STREAMS) {
GList *streams = NULL;
guint32 seqnum = gst_event_get_seqnum (event);
g_object_set (dbin->multiqueue, "min-interleave-time",
dbin->default_mq_min_interleave, NULL);
dbin->current_mq_min_interleave = dbin->default_mq_min_interleave;
+ dbin->upstream_selected = FALSE;
}
break;
default: