decodebin3: Refactor/rename slot/output
* Centralize associating an output to a slot in one function, including properly resetting those fields * Rename functions to be more explicit * Move code to "reset" an output stream into a dedicated function (will be used later) Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6774>
This commit is contained in:
parent
1185a560c2
commit
fc96e29606
@ -546,9 +546,9 @@ static void gst_decodebin_input_unblock_streams (DecodebinInput * input,
|
|||||||
|
|
||||||
static gboolean reconfigure_output_stream (DecodebinOutputStream * output,
|
static gboolean reconfigure_output_stream (DecodebinOutputStream * output,
|
||||||
MultiQueueSlot * slot, GstMessage ** msg);
|
MultiQueueSlot * slot, GstMessage ** msg);
|
||||||
static void free_output_stream (GstDecodebin3 * dbin,
|
static void db_output_stream_reset (DecodebinOutputStream * output);
|
||||||
DecodebinOutputStream * output);
|
static void db_output_stream_free (DecodebinOutputStream * output);
|
||||||
static DecodebinOutputStream *create_output_stream (GstDecodebin3 * dbin,
|
static DecodebinOutputStream *db_output_stream_new (GstDecodebin3 * dbin,
|
||||||
GstStreamType type);
|
GstStreamType type);
|
||||||
|
|
||||||
static GstPadProbeReturn slot_unassign_probe (GstPad * pad,
|
static GstPadProbeReturn slot_unassign_probe (GstPad * pad,
|
||||||
@ -695,11 +695,8 @@ gst_decodebin3_reset (GstDecodebin3 * dbin)
|
|||||||
GST_DEBUG_OBJECT (dbin, "Resetting");
|
GST_DEBUG_OBJECT (dbin, "Resetting");
|
||||||
|
|
||||||
/* Free output streams */
|
/* Free output streams */
|
||||||
for (tmp = dbin->output_streams; tmp; tmp = tmp->next) {
|
g_list_free_full (dbin->output_streams,
|
||||||
DecodebinOutputStream *output = (DecodebinOutputStream *) tmp->data;
|
(GDestroyNotify) db_output_stream_free);
|
||||||
free_output_stream (dbin, output);
|
|
||||||
}
|
|
||||||
g_list_free (dbin->output_streams);
|
|
||||||
dbin->output_streams = NULL;
|
dbin->output_streams = NULL;
|
||||||
|
|
||||||
/* Free multiqueue slots */
|
/* Free multiqueue slots */
|
||||||
@ -1408,7 +1405,7 @@ remove_slot_from_streaming_thread (GstDecodebin3 * dbin, MultiQueueSlot * slot)
|
|||||||
"Multiqueue slot is drained, Remove output stream");
|
"Multiqueue slot is drained, Remove output stream");
|
||||||
|
|
||||||
dbin->output_streams = g_list_remove (dbin->output_streams, output);
|
dbin->output_streams = g_list_remove (dbin->output_streams, output);
|
||||||
free_output_stream (dbin, output);
|
db_output_stream_free (output);
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (slot->src_pad, "No pending pad, Remove multiqueue slot");
|
GST_DEBUG_OBJECT (slot->src_pad, "No pending pad, Remove multiqueue slot");
|
||||||
@ -2917,11 +2914,73 @@ find_free_compatible_output (GstDecodebin3 * dbin, GstStream * stream)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Give a certain slot, figure out if it should be linked to an
|
/** mq_slot_set_output:
|
||||||
* output stream
|
* @slot: A #MultiQueueSlot
|
||||||
* CALL WITH SELECTION LOCK TAKEN !*/
|
* @output: (allow none): A #DecodebinOutputStream
|
||||||
|
*
|
||||||
|
* Sets @output as the @slot output. The slot present previously will be
|
||||||
|
* returned.
|
||||||
|
*
|
||||||
|
* If the output previously associated was linked (via a decoder) to the slot,
|
||||||
|
* they will be unlinked.
|
||||||
|
*
|
||||||
|
* Returns: The output previously used on @slot.
|
||||||
|
*/
|
||||||
static DecodebinOutputStream *
|
static DecodebinOutputStream *
|
||||||
get_output_for_slot (MultiQueueSlot * slot)
|
mq_slot_set_output (MultiQueueSlot * slot, DecodebinOutputStream * output)
|
||||||
|
{
|
||||||
|
DecodebinOutputStream *old_output = slot->output;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (slot->src_pad, "output: %p", output);
|
||||||
|
|
||||||
|
if (old_output == output) {
|
||||||
|
GST_LOG_OBJECT (slot->src_pad, "Already targetting that output");
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_output) {
|
||||||
|
if (!old_output->slot)
|
||||||
|
GST_DEBUG_OBJECT (slot->src_pad,
|
||||||
|
"Old output %p was not associated to any slot", old_output);
|
||||||
|
else
|
||||||
|
GST_DEBUG_OBJECT (slot->src_pad,
|
||||||
|
"Old output %p was associated to %" GST_PTR_FORMAT, old_output,
|
||||||
|
old_output->slot->src_pad);
|
||||||
|
/* Check for inconsistencies in assigning */
|
||||||
|
g_assert (old_output->slot == slot);
|
||||||
|
GST_DEBUG_OBJECT (slot->src_pad, "Unassigning");
|
||||||
|
if (old_output->decoder_sink && old_output->decoder)
|
||||||
|
gst_pad_unlink (slot->src_pad, old_output->decoder_sink);
|
||||||
|
old_output->linked = FALSE;
|
||||||
|
old_output->slot = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (output) {
|
||||||
|
if (output->slot)
|
||||||
|
GST_DEBUG_OBJECT (slot->src_pad,
|
||||||
|
"New output was previously associated to slot %s:%s",
|
||||||
|
GST_DEBUG_PAD_NAME (output->slot->src_pad));
|
||||||
|
output->slot = slot;
|
||||||
|
}
|
||||||
|
slot->output = output;
|
||||||
|
|
||||||
|
return old_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** mq_slot_get_or_create_output:
|
||||||
|
* @slot: A #MultiQueueSlot
|
||||||
|
*
|
||||||
|
* Provides the #DecodebinOutputStream the @slot should use. This function will
|
||||||
|
* figure that out based on the current selection. The slot output will be
|
||||||
|
* updated accordingly.
|
||||||
|
*
|
||||||
|
* Call with SELECTION_LOCK taken
|
||||||
|
*
|
||||||
|
* Returns: The #DecodebinOutputStream to use, or #NULL if none can/should be
|
||||||
|
* used.
|
||||||
|
*/
|
||||||
|
static DecodebinOutputStream *
|
||||||
|
mq_slot_get_or_create_output (MultiQueueSlot * slot)
|
||||||
{
|
{
|
||||||
GstDecodebin3 *dbin = slot->dbin;
|
GstDecodebin3 *dbin = slot->dbin;
|
||||||
DecodebinOutputStream *output = NULL;
|
DecodebinOutputStream *output = NULL;
|
||||||
@ -2930,8 +2989,11 @@ get_output_for_slot (MultiQueueSlot * slot)
|
|||||||
gchar *id_in_list = NULL;
|
gchar *id_in_list = NULL;
|
||||||
|
|
||||||
/* If we already have a configured output, just use it */
|
/* If we already have a configured output, just use it */
|
||||||
if (slot->output != NULL)
|
if (slot->output != NULL) {
|
||||||
|
GST_LOG_OBJECT (slot->src_pad, "Returning current output %s:%s",
|
||||||
|
GST_DEBUG_PAD_NAME (slot->output->src_pad));
|
||||||
return slot->output;
|
return slot->output;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME
|
* FIXME
|
||||||
@ -2950,7 +3012,8 @@ get_output_for_slot (MultiQueueSlot * slot)
|
|||||||
|
|
||||||
stream_id = gst_stream_get_stream_id (slot->active_stream);
|
stream_id = gst_stream_get_stream_id (slot->active_stream);
|
||||||
caps = gst_stream_get_caps (slot->active_stream);
|
caps = gst_stream_get_caps (slot->active_stream);
|
||||||
GST_DEBUG_OBJECT (dbin, "stream %s , %" GST_PTR_FORMAT, stream_id, caps);
|
GST_DEBUG_OBJECT (slot->src_pad, "stream %s , %" GST_PTR_FORMAT, stream_id,
|
||||||
|
caps);
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
/* 0. Emit autoplug-continue signal for pending caps ? */
|
/* 0. Emit autoplug-continue signal for pending caps ? */
|
||||||
@ -2961,36 +3024,38 @@ get_output_for_slot (MultiQueueSlot * slot)
|
|||||||
|
|
||||||
/* 3. In default mode check if we should expose */
|
/* 3. In default mode check if we should expose */
|
||||||
id_in_list = (gchar *) stream_in_list (dbin->requested_selection, stream_id);
|
id_in_list = (gchar *) stream_in_list (dbin->requested_selection, stream_id);
|
||||||
if (id_in_list || dbin->upstream_handles_selection) {
|
if (!id_in_list && !dbin->upstream_handles_selection) {
|
||||||
/* Check if we can steal an existing output stream we could re-use.
|
GST_DEBUG_OBJECT (slot->src_pad, "Not selected, not creating any output");
|
||||||
* that is:
|
return NULL;
|
||||||
* * an output stream whose slot->stream is not in requested
|
}
|
||||||
* * and is of the same type as this stream
|
|
||||||
*/
|
|
||||||
output = find_free_compatible_output (dbin, slot->active_stream);
|
|
||||||
if (output) {
|
|
||||||
/* Move this output from its current slot to this slot */
|
|
||||||
dbin->to_activate =
|
|
||||||
g_list_append (dbin->to_activate, (gchar *) stream_id);
|
|
||||||
dbin->requested_selection =
|
|
||||||
g_list_remove (dbin->requested_selection, id_in_list);
|
|
||||||
g_free (id_in_list);
|
|
||||||
SELECTION_UNLOCK (dbin);
|
|
||||||
gst_pad_add_probe (output->slot->src_pad, GST_PAD_PROBE_TYPE_IDLE,
|
|
||||||
(GstPadProbeCallback) slot_unassign_probe, output->slot, NULL);
|
|
||||||
SELECTION_LOCK (dbin);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
output = create_output_stream (dbin, slot->type);
|
/* Check if we can steal an existing output stream we could re-use.
|
||||||
output->slot = slot;
|
* that is:
|
||||||
GST_DEBUG ("Linking slot %p to new output %p", slot, output);
|
* * an output stream whose slot->stream is not in requested
|
||||||
slot->output = output;
|
* * and is of the same type as this stream
|
||||||
GST_DEBUG ("Adding '%s' to active_selection", stream_id);
|
*/
|
||||||
dbin->active_selection =
|
output = find_free_compatible_output (dbin, slot->active_stream);
|
||||||
g_list_append (dbin->active_selection, (gchar *) g_strdup (stream_id));
|
if (output) {
|
||||||
} else
|
GST_DEBUG_OBJECT (slot->src_pad, "Reassigning to output %s:%s",
|
||||||
GST_DEBUG ("Not creating any output for slot %p", slot);
|
GST_DEBUG_PAD_NAME (output->src_pad));
|
||||||
|
/* Move this output from its current slot to this slot */
|
||||||
|
dbin->to_activate = g_list_append (dbin->to_activate, (gchar *) stream_id);
|
||||||
|
dbin->requested_selection =
|
||||||
|
g_list_remove (dbin->requested_selection, id_in_list);
|
||||||
|
g_free (id_in_list);
|
||||||
|
SELECTION_UNLOCK (dbin);
|
||||||
|
gst_pad_add_probe (output->slot->src_pad, GST_PAD_PROBE_TYPE_IDLE,
|
||||||
|
(GstPadProbeCallback) mq_slot_unassign_probe, output->slot, NULL);
|
||||||
|
SELECTION_LOCK (dbin);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
output = db_output_stream_new (dbin, slot->type);
|
||||||
|
mq_slot_set_output (slot, output);
|
||||||
|
|
||||||
|
GST_DEBUG ("Adding '%s' to active_selection", stream_id);
|
||||||
|
dbin->active_selection =
|
||||||
|
g_list_append (dbin->active_selection, (gchar *) g_strdup (stream_id));
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
@ -3222,17 +3287,18 @@ multiqueue_src_probe (GstPad * pad, GstPadProbeInfo * info,
|
|||||||
slot->active_stream = stream;
|
slot->active_stream = stream;
|
||||||
|
|
||||||
if (stream_type_changed) {
|
if (stream_type_changed) {
|
||||||
|
DecodebinOutputStream *previous_output;
|
||||||
/* The stream type has changed, we get rid of the current output. A
|
/* The stream type has changed, we get rid of the current output. A
|
||||||
* new one (targetting the new stream type) will be created once the
|
* new one (targetting the new stream type) will be created once the
|
||||||
* caps are received. */
|
* caps are received. */
|
||||||
GST_DEBUG_OBJECT (pad,
|
previous_output = mq_slot_set_output (slot, NULL);
|
||||||
"Stream type change, discarding current output stream");
|
if (previous_output) {
|
||||||
if (slot->output) {
|
GST_DEBUG_OBJECT (pad,
|
||||||
DecodebinOutputStream *output = slot->output;
|
"Stream type change, discarding current output stream");
|
||||||
SELECTION_LOCK (dbin);
|
SELECTION_LOCK (dbin);
|
||||||
dbin->output_streams =
|
dbin->output_streams =
|
||||||
g_list_remove (dbin->output_streams, output);
|
g_list_remove (dbin->output_streams, previous_output);
|
||||||
free_output_stream (dbin, output);
|
db_output_stream_free (previous_output);
|
||||||
SELECTION_UNLOCK (dbin);
|
SELECTION_UNLOCK (dbin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3884,15 +3950,9 @@ reassign_slot (GstDecodebin3 * dbin, MultiQueueSlot * slot)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Unlink slot from output */
|
/* Unlink slot from output */
|
||||||
/* FIXME : Handle flushing ? */
|
GST_DEBUG_OBJECT (slot->src_pad, "Unlinking from previous output");
|
||||||
/* FIXME : Handle outputs without decoders */
|
mq_slot_set_output (slot, NULL);
|
||||||
GST_DEBUG_OBJECT (slot->src_pad, "Unlinking from decoder %p",
|
|
||||||
output->decoder_sink);
|
|
||||||
if (output->decoder_sink)
|
|
||||||
gst_pad_unlink (slot->src_pad, output->decoder_sink);
|
|
||||||
output->linked = FALSE;
|
|
||||||
slot->output = NULL;
|
|
||||||
output->slot = NULL;
|
|
||||||
/* Remove sid from active selection */
|
/* Remove sid from active selection */
|
||||||
GST_DEBUG ("Removing '%s' from active_selection", sid);
|
GST_DEBUG ("Removing '%s' from active_selection", sid);
|
||||||
for (tmp = dbin->active_selection; tmp; tmp = tmp->next)
|
for (tmp = dbin->active_selection; tmp; tmp = tmp->next)
|
||||||
@ -3923,8 +3983,7 @@ reassign_slot (GstDecodebin3 * dbin, MultiQueueSlot * slot)
|
|||||||
if (target_slot) {
|
if (target_slot) {
|
||||||
GST_DEBUG_OBJECT (slot->src_pad, "Assigning output to slot %p '%s'",
|
GST_DEBUG_OBJECT (slot->src_pad, "Assigning output to slot %p '%s'",
|
||||||
target_slot, tsid);
|
target_slot, tsid);
|
||||||
target_slot->output = output;
|
mq_slot_set_output (target_slot, output);
|
||||||
output->slot = target_slot;
|
|
||||||
GST_DEBUG ("Adding '%s' to active_selection", tsid);
|
GST_DEBUG ("Adding '%s' to active_selection", tsid);
|
||||||
dbin->active_selection =
|
dbin->active_selection =
|
||||||
g_list_append (dbin->active_selection, (gchar *) g_strdup (tsid));
|
g_list_append (dbin->active_selection, (gchar *) g_strdup (tsid));
|
||||||
@ -3939,7 +3998,7 @@ reassign_slot (GstDecodebin3 * dbin, MultiQueueSlot * slot)
|
|||||||
GstMessage *msg;
|
GstMessage *msg;
|
||||||
|
|
||||||
dbin->output_streams = g_list_remove (dbin->output_streams, output);
|
dbin->output_streams = g_list_remove (dbin->output_streams, output);
|
||||||
free_output_stream (dbin, output);
|
db_output_stream_free (output);
|
||||||
msg = is_selection_done (slot->dbin);
|
msg = is_selection_done (slot->dbin);
|
||||||
SELECTION_UNLOCK (dbin);
|
SELECTION_UNLOCK (dbin);
|
||||||
|
|
||||||
@ -4282,11 +4341,17 @@ free_multiqueue_slot (GstDecodebin3 * dbin, MultiQueueSlot * slot)
|
|||||||
g_free (slot);
|
g_free (slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a DecodebinOutputStream for a given type
|
/** db_output_stream_new:
|
||||||
* Note: It will be empty initially, it needs to be configured
|
* @dbin: A #GstDecodebin3
|
||||||
* afterwards */
|
* @type: The #GstStreamType
|
||||||
|
*
|
||||||
|
* Creates a #DecodebinOutputStream for the given type and adds it to the list
|
||||||
|
* of available outputs.
|
||||||
|
*
|
||||||
|
* Returns: a #DecodebinOutputStream for the given @type.
|
||||||
|
*/
|
||||||
static DecodebinOutputStream *
|
static DecodebinOutputStream *
|
||||||
create_output_stream (GstDecodebin3 * dbin, GstStreamType type)
|
db_output_stream_new (GstDecodebin3 * dbin, GstStreamType type)
|
||||||
{
|
{
|
||||||
DecodebinOutputStream *res = g_new0 (DecodebinOutputStream, 1);
|
DecodebinOutputStream *res = g_new0 (DecodebinOutputStream, 1);
|
||||||
gchar *pad_name;
|
gchar *pad_name;
|
||||||
@ -4338,29 +4403,74 @@ create_output_stream (GstDecodebin3 * dbin, GstStreamType type)
|
|||||||
|
|
||||||
dbin->output_streams = g_list_append (dbin->output_streams, res);
|
dbin->output_streams = g_list_append (dbin->output_streams, res);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (dbin, "Created output stream %p (%s:%s)", res,
|
||||||
|
GST_DEBUG_PAD_NAME (res->src_pad));
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** db_output_stream_reset:
|
||||||
|
* @output: A #DecodebinOutputStream
|
||||||
|
*
|
||||||
|
* Resets the @output to be able to be re-used by another slot/format. If a
|
||||||
|
* decoder is present it will be disabled and removed
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
free_output_stream (GstDecodebin3 * dbin, DecodebinOutputStream * output)
|
db_output_stream_reset (DecodebinOutputStream * output)
|
||||||
{
|
{
|
||||||
if (output->slot) {
|
MultiQueueSlot *slot = output->slot;
|
||||||
if (output->decoder_sink && output->decoder)
|
|
||||||
gst_pad_unlink (output->slot->src_pad, output->decoder_sink);
|
|
||||||
|
|
||||||
output->slot->output = NULL;
|
GST_DEBUG_OBJECT (output->dbin, "Resetting %s:%s",
|
||||||
output->slot = NULL;
|
GST_DEBUG_PAD_NAME (output->src_pad));
|
||||||
|
|
||||||
|
/* Unlink decoder if needed */
|
||||||
|
if (output->linked && slot && output->decoder_sink) {
|
||||||
|
gst_pad_unlink (slot->src_pad, output->decoder_sink);
|
||||||
}
|
}
|
||||||
|
output->linked = FALSE;
|
||||||
|
|
||||||
|
if (slot && output->drop_probe_id) {
|
||||||
|
gst_pad_remove_probe (slot->src_pad, output->drop_probe_id);
|
||||||
|
output->drop_probe_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove/Reset pads */
|
||||||
gst_object_replace ((GstObject **) & output->decoder_sink, NULL);
|
gst_object_replace ((GstObject **) & output->decoder_sink, NULL);
|
||||||
decode_pad_set_target ((GstGhostPad *) output->src_pad, NULL);
|
decode_pad_set_target ((GstGhostPad *) output->src_pad, NULL);
|
||||||
gst_object_replace ((GstObject **) & output->decoder_src, NULL);
|
gst_object_replace ((GstObject **) & output->decoder_src, NULL);
|
||||||
if (output->src_exposed) {
|
|
||||||
gst_element_remove_pad ((GstElement *) dbin, output->src_pad);
|
/* Remove decoder */
|
||||||
}
|
|
||||||
if (output->decoder) {
|
if (output->decoder) {
|
||||||
gst_element_set_locked_state (output->decoder, TRUE);
|
gst_element_set_locked_state (output->decoder, TRUE);
|
||||||
gst_element_set_state (output->decoder, GST_STATE_NULL);
|
gst_element_set_state (output->decoder, GST_STATE_NULL);
|
||||||
gst_bin_remove ((GstBin *) dbin, output->decoder);
|
gst_bin_remove ((GstBin *) output->dbin, output->decoder);
|
||||||
|
|
||||||
|
output->decoder = NULL;
|
||||||
|
output->decoder_latency = GST_CLOCK_TIME_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** db_output_stream_free:
|
||||||
|
* @output: A #DecodebinOutputstream
|
||||||
|
*
|
||||||
|
* Releases the @output from the associated slot, removes the associated source
|
||||||
|
* ghost pad and frees any decoder
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
db_output_stream_free (DecodebinOutputStream * output)
|
||||||
|
{
|
||||||
|
GstDecodebin3 *dbin = output->dbin;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (output->src_pad, "Freeing");
|
||||||
|
|
||||||
|
db_output_stream_reset (output);
|
||||||
|
|
||||||
|
if (output->slot)
|
||||||
|
mq_slot_set_output (output->slot, NULL);
|
||||||
|
|
||||||
|
if (output->src_exposed) {
|
||||||
|
gst_element_remove_pad ((GstElement *) dbin, output->src_pad);
|
||||||
}
|
}
|
||||||
g_free (output);
|
g_free (output);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user