mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-27 00:16:37 +00:00
decodebin3: rename/clarify eos and draining usage around multiqueue
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7002>
This commit is contained in:
parent
8794918607
commit
b6263febe0
1 changed files with 64 additions and 48 deletions
|
@ -841,7 +841,7 @@ gst_decodebin3_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
|
|
||||||
/* WITH SELECTION_LOCK TAKEN! */
|
/* WITH SELECTION_LOCK TAKEN! */
|
||||||
static gboolean
|
static gboolean
|
||||||
all_inputs_are_eos (GstDecodebin3 * dbin)
|
all_input_streams_are_eos (GstDecodebin3 * dbin)
|
||||||
{
|
{
|
||||||
GList *tmp;
|
GList *tmp;
|
||||||
|
|
||||||
|
@ -856,15 +856,27 @@ all_inputs_are_eos (GstDecodebin3 * dbin)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* WITH SELECTION_LOCK TAKEN! */
|
/** check_all_input_streams_for_eos:
|
||||||
static void
|
* @dbin: A #GstDecodebin3
|
||||||
check_all_input_streams_for_eos (GstDecodebin3 * dbin, GstEvent * event)
|
* @eos_event: (transfer none): The GST_EVENT_EOS that triggered this check
|
||||||
|
*
|
||||||
|
* Check if all inputs streams are EOS. If they are propagates the @eos_event to all
|
||||||
|
* #DecodebinInputstream pads.
|
||||||
|
*
|
||||||
|
* Returns: #TRUE if all pads are EOS and the event was propagated, else #FALSE.
|
||||||
|
*/
|
||||||
|
static gboolean
|
||||||
|
check_all_input_streams_for_eos (GstDecodebin3 * dbin, GstEvent * eos_event)
|
||||||
{
|
{
|
||||||
GList *tmp;
|
GList *tmp;
|
||||||
GList *outputpads = NULL;
|
GList *outputpads = NULL;
|
||||||
|
|
||||||
if (!all_inputs_are_eos (dbin))
|
SELECTION_LOCK (dbin);
|
||||||
return;
|
|
||||||
|
if (!all_input_streams_are_eos (dbin)) {
|
||||||
|
SELECTION_UNLOCK (dbin);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* We know all streams are EOS, properly clean up everything */
|
/* We know all streams are EOS, properly clean up everything */
|
||||||
|
|
||||||
|
@ -885,13 +897,14 @@ check_all_input_streams_for_eos (GstDecodebin3 * dbin, GstEvent * event)
|
||||||
GstPad *peer = (GstPad *) tmp->data;
|
GstPad *peer = (GstPad *) tmp->data;
|
||||||
|
|
||||||
/* Send EOS and then remove elements */
|
/* Send EOS and then remove elements */
|
||||||
gst_pad_send_event (peer, gst_event_ref (event));
|
gst_pad_send_event (peer, gst_event_ref (eos_event));
|
||||||
GST_FIXME_OBJECT (peer, "Remove input stream");
|
GST_FIXME_OBJECT (peer, "Remove input stream");
|
||||||
gst_object_unref (peer);
|
gst_object_unref (peer);
|
||||||
}
|
}
|
||||||
SELECTION_LOCK (dbin);
|
|
||||||
|
|
||||||
g_list_free (outputpads);
|
g_list_free (outputpads);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the intersection of parser caps and available (sorted) decoders */
|
/* Get the intersection of parser caps and available (sorted) decoders */
|
||||||
|
@ -1049,13 +1062,13 @@ gst_decodebin_input_stream_src_probe (GstPad * pad, GstPadProbeInfo * info,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_EOS:
|
case GST_EVENT_EOS:
|
||||||
|
{
|
||||||
|
GST_DEBUG_OBJECT (pad, "Marking input as EOS");
|
||||||
input->saw_eos = TRUE;
|
input->saw_eos = TRUE;
|
||||||
if (all_inputs_are_eos (input->dbin)) {
|
|
||||||
GST_DEBUG_OBJECT (pad, "real input pad, marking as EOS");
|
/* If not all pads are EOS yet, we send our custom EOS (which will be
|
||||||
SELECTION_LOCK (input->dbin);
|
* handled/dropped downstream of multiqueue) */
|
||||||
check_all_input_streams_for_eos (input->dbin, ev);
|
if (!check_all_input_streams_for_eos (input->dbin, ev)) {
|
||||||
SELECTION_UNLOCK (input->dbin);
|
|
||||||
} else {
|
|
||||||
GstPad *peer = gst_pad_get_peer (input->srcpad);
|
GstPad *peer = gst_pad_get_peer (input->srcpad);
|
||||||
if (peer) {
|
if (peer) {
|
||||||
/* Send custom-eos event to multiqueue slot */
|
/* Send custom-eos event to multiqueue slot */
|
||||||
|
@ -1074,6 +1087,7 @@ gst_decodebin_input_stream_src_probe (GstPad * pad, GstPadProbeInfo * info,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret = GST_PAD_PROBE_DROP;
|
ret = GST_PAD_PROBE_DROP;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_FLUSH_STOP:
|
case GST_EVENT_FLUSH_STOP:
|
||||||
GST_DEBUG_OBJECT (pad, "Clear saw_eos flag");
|
GST_DEBUG_OBJECT (pad, "Clear saw_eos flag");
|
||||||
|
@ -3016,13 +3030,16 @@ is_selection_done (GstDecodebin3 * dbin)
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Must be called with SELECTION_LOCK taken
|
/** check_and_drain_multiqueue_locked:
|
||||||
|
* @dbin: A #GstDecodebin3
|
||||||
|
* @eos_event: The GST_EVENT_EOS that triggered this check.
|
||||||
*
|
*
|
||||||
* This code is used to propagate the final EOS if all slots and inputs are
|
* Check if all #DecodebinInputstream and #MultiqueueSlot are
|
||||||
* drained.
|
* emptied/drained. If that is the case, send the final sequence of final EOS
|
||||||
**/
|
* events based on the provided @eos_event.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
check_inputs_and_slots_for_eos (GstDecodebin3 * dbin, GstEvent * ev)
|
check_and_drain_multiqueue_locked (GstDecodebin3 * dbin, GstEvent * eos_event)
|
||||||
{
|
{
|
||||||
GList *iter;
|
GList *iter;
|
||||||
|
|
||||||
|
@ -3038,43 +3055,42 @@ check_inputs_and_slots_for_eos (GstDecodebin3 * dbin, GstEvent * ev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Also check with the inputs, data might be pending */
|
/* Also check with the inputs, data might be pending */
|
||||||
if (!all_inputs_are_eos (dbin))
|
if (!all_input_streams_are_eos (dbin))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (dbin,
|
GST_DEBUG_OBJECT (dbin,
|
||||||
"All active slots are drained, and no pending input, push EOS");
|
"All active slots are drained, and no pending input, push EOS");
|
||||||
|
|
||||||
for (iter = dbin->input_streams; iter; iter = iter->next) {
|
for (iter = dbin->input_streams; iter; iter = iter->next) {
|
||||||
|
GstEvent *stream_start, *eos;
|
||||||
DecodebinInputStream *input = (DecodebinInputStream *) iter->data;
|
DecodebinInputStream *input = (DecodebinInputStream *) iter->data;
|
||||||
GstPad *peer = gst_pad_get_peer (input->srcpad);
|
GstPad *peer = gst_pad_get_peer (input->srcpad);
|
||||||
|
|
||||||
|
if (!peer) {
|
||||||
|
GST_DEBUG_OBJECT (input->srcpad, "Not linked to multiqueue");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* First forward a custom STREAM_START event to reset the EOS status (if
|
||||||
|
* any) */
|
||||||
|
stream_start =
|
||||||
|
gst_pad_get_sticky_event (input->srcpad, GST_EVENT_STREAM_START, 0);
|
||||||
|
if (stream_start) {
|
||||||
|
GstStructure *s;
|
||||||
|
GstEvent *custom_stream_start = gst_event_copy (stream_start);
|
||||||
|
gst_event_unref (stream_start);
|
||||||
|
s = (GstStructure *) gst_event_get_structure (custom_stream_start);
|
||||||
|
gst_structure_set (s, "decodebin3-flushing-stream-start",
|
||||||
|
G_TYPE_BOOLEAN, TRUE, NULL);
|
||||||
|
gst_pad_send_event (peer, custom_stream_start);
|
||||||
|
}
|
||||||
/* Send EOS to all slots */
|
/* Send EOS to all slots */
|
||||||
if (peer) {
|
eos = gst_event_new_eos ();
|
||||||
GstEvent *stream_start, *eos;
|
gst_event_set_seqnum (eos, gst_event_get_seqnum (eos_event));
|
||||||
|
gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (eos),
|
||||||
stream_start =
|
CUSTOM_FINAL_EOS_QUARK, (gchar *) CUSTOM_FINAL_EOS_QUARK_DATA, NULL);
|
||||||
gst_pad_get_sticky_event (input->srcpad, GST_EVENT_STREAM_START, 0);
|
gst_pad_send_event (peer, eos);
|
||||||
|
gst_object_unref (peer);
|
||||||
/* First forward a custom STREAM_START event to reset the EOS status (if
|
|
||||||
* any) */
|
|
||||||
if (stream_start) {
|
|
||||||
GstStructure *s;
|
|
||||||
GstEvent *custom_stream_start = gst_event_copy (stream_start);
|
|
||||||
gst_event_unref (stream_start);
|
|
||||||
s = (GstStructure *) gst_event_get_structure (custom_stream_start);
|
|
||||||
gst_structure_set (s, "decodebin3-flushing-stream-start",
|
|
||||||
G_TYPE_BOOLEAN, TRUE, NULL);
|
|
||||||
gst_pad_send_event (peer, custom_stream_start);
|
|
||||||
}
|
|
||||||
|
|
||||||
eos = gst_event_new_eos ();
|
|
||||||
gst_event_set_seqnum (eos, gst_event_get_seqnum (ev));
|
|
||||||
gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (eos),
|
|
||||||
CUSTOM_FINAL_EOS_QUARK, (gchar *) CUSTOM_FINAL_EOS_QUARK_DATA, NULL);
|
|
||||||
gst_pad_send_event (peer, eos);
|
|
||||||
gst_object_unref (peer);
|
|
||||||
} else
|
|
||||||
GST_DEBUG_OBJECT (dbin, "no output");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3243,7 +3259,7 @@ multiqueue_src_probe (GstPad * pad, GstPadProbeInfo * info,
|
||||||
free_multiqueue_slot_async (dbin, slot);
|
free_multiqueue_slot_async (dbin, slot);
|
||||||
ret = GST_PAD_PROBE_REMOVE;
|
ret = GST_PAD_PROBE_REMOVE;
|
||||||
} else if (!was_drained) {
|
} else if (!was_drained) {
|
||||||
check_inputs_and_slots_for_eos (dbin, ev);
|
check_and_drain_multiqueue_locked (dbin, ev);
|
||||||
}
|
}
|
||||||
if (ret == GST_PAD_PROBE_HANDLED)
|
if (ret == GST_PAD_PROBE_HANDLED)
|
||||||
gst_event_unref (ev);
|
gst_event_unref (ev);
|
||||||
|
@ -3290,7 +3306,7 @@ multiqueue_src_probe (GstPad * pad, GstPadProbeInfo * info,
|
||||||
* when all output streams are also eos */
|
* when all output streams are also eos */
|
||||||
ret = GST_PAD_PROBE_DROP;
|
ret = GST_PAD_PROBE_DROP;
|
||||||
SELECTION_LOCK (dbin);
|
SELECTION_LOCK (dbin);
|
||||||
check_inputs_and_slots_for_eos (dbin, ev);
|
check_and_drain_multiqueue_locked (dbin, ev);
|
||||||
SELECTION_UNLOCK (dbin);
|
SELECTION_UNLOCK (dbin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue