mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 04:36:20 +00:00
decodebin2: Fix group switching algorithm
There were two issues with the previous decodebin2 group switching algorithm: Issue 1: It operated with no memory of what has been drained or not, leading to multiple checks for chains/groups that were already drained. Issue 2: When receiving an EOS, it only detected that a higher-level chain was drained if it contained the pad receiving the EOS. The following modifications have been applied: - a new drained property has been added to GstDecodeChain - both drained properties of chain/group are set as soon as they are detected - the algorithm now tests agains these values See https://bugzilla.gnome.org/show_bug.cgi?id=685938
This commit is contained in:
parent
336842d35c
commit
87fd43aaaa
1 changed files with 16 additions and 8 deletions
|
@ -401,6 +401,7 @@ struct _GstDecodeChain
|
||||||
|
|
||||||
GstPad *pad; /* srcpad that caused creation of this chain */
|
GstPad *pad; /* srcpad that caused creation of this chain */
|
||||||
|
|
||||||
|
gboolean drained; /* TRUE if the all children are drained */
|
||||||
gboolean demuxer; /* TRUE if elements->data is a demuxer */
|
gboolean demuxer; /* TRUE if elements->data is a demuxer */
|
||||||
gboolean seekable; /* TRUE if this chain ends on a demuxer and is seekable */
|
gboolean seekable; /* TRUE if this chain ends on a demuxer and is seekable */
|
||||||
GList *elements; /* All elements in this group, first
|
GList *elements; /* All elements in this group, first
|
||||||
|
@ -3237,7 +3238,6 @@ drain_and_switch_group (GstDecodeGroup * group, GstDecodePad * drainpad,
|
||||||
gboolean * last_group, gboolean * drained, gboolean * switched)
|
gboolean * last_group, gboolean * drained, gboolean * switched)
|
||||||
{
|
{
|
||||||
gboolean handled = FALSE;
|
gboolean handled = FALSE;
|
||||||
gboolean alldrained = TRUE;
|
|
||||||
GList *tmp;
|
GList *tmp;
|
||||||
|
|
||||||
GST_DEBUG ("Checking group %p (target pad %s:%s)",
|
GST_DEBUG ("Checking group %p (target pad %s:%s)",
|
||||||
|
@ -3250,6 +3250,7 @@ drain_and_switch_group (GstDecodeGroup * group, GstDecodePad * drainpad,
|
||||||
|
|
||||||
/* Figure out if all our chains are drained with the
|
/* Figure out if all our chains are drained with the
|
||||||
* new information */
|
* new information */
|
||||||
|
group->drained = TRUE;
|
||||||
for (tmp = group->children; tmp; tmp = tmp->next) {
|
for (tmp = group->children; tmp; tmp = tmp->next) {
|
||||||
GstDecodeChain *chain = (GstDecodeChain *) tmp->data;
|
GstDecodeChain *chain = (GstDecodeChain *) tmp->data;
|
||||||
gboolean subdrained = FALSE;
|
gboolean subdrained = FALSE;
|
||||||
|
@ -3258,13 +3259,13 @@ drain_and_switch_group (GstDecodeGroup * group, GstDecodePad * drainpad,
|
||||||
drain_and_switch_chains (chain, drainpad, last_group, &subdrained,
|
drain_and_switch_chains (chain, drainpad, last_group, &subdrained,
|
||||||
switched);
|
switched);
|
||||||
if (!subdrained)
|
if (!subdrained)
|
||||||
alldrained = FALSE;
|
group->drained = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
beach:
|
beach:
|
||||||
GST_DEBUG ("group %p (last_group:%d, drained:%d, switched:%d, handled:%d)",
|
GST_DEBUG ("group %p (last_group:%d, drained:%d, switched:%d, handled:%d)",
|
||||||
group, *last_group, alldrained, *switched, handled);
|
group, *last_group, group->drained, *switched, handled);
|
||||||
*drained = alldrained;
|
*drained = group->drained;
|
||||||
return handled;
|
return handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3280,6 +3281,11 @@ drain_and_switch_chains (GstDecodeChain * chain, GstDecodePad * drainpad,
|
||||||
|
|
||||||
CHAIN_MUTEX_LOCK (chain);
|
CHAIN_MUTEX_LOCK (chain);
|
||||||
|
|
||||||
|
/* Definitely can't be in drained chains */
|
||||||
|
if (G_UNLIKELY (chain->drained)) {
|
||||||
|
goto beach;
|
||||||
|
}
|
||||||
|
|
||||||
if (chain->endpad) {
|
if (chain->endpad) {
|
||||||
/* Check if we're reached the target endchain */
|
/* Check if we're reached the target endchain */
|
||||||
if (chain == drainpad->chain) {
|
if (chain == drainpad->chain) {
|
||||||
|
@ -3288,7 +3294,7 @@ drain_and_switch_chains (GstDecodeChain * chain, GstDecodePad * drainpad,
|
||||||
handled = TRUE;
|
handled = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
*drained = chain->endpad->drained;
|
chain->drained = chain->endpad->drained;
|
||||||
goto beach;
|
goto beach;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3316,11 +3322,11 @@ drain_and_switch_chains (GstDecodeChain * chain, GstDecodePad * drainpad,
|
||||||
chain->next_groups =
|
chain->next_groups =
|
||||||
g_list_delete_link (chain->next_groups, chain->next_groups);
|
g_list_delete_link (chain->next_groups, chain->next_groups);
|
||||||
*switched = TRUE;
|
*switched = TRUE;
|
||||||
*drained = FALSE;
|
chain->drained = FALSE;
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG ("Group %p was the last in chain %p", chain->active_group,
|
GST_DEBUG ("Group %p was the last in chain %p", chain->active_group,
|
||||||
chain);
|
chain);
|
||||||
*drained = TRUE;
|
chain->drained = TRUE;
|
||||||
/* We're drained ! */
|
/* We're drained ! */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3330,7 +3336,9 @@ beach:
|
||||||
CHAIN_MUTEX_UNLOCK (chain);
|
CHAIN_MUTEX_UNLOCK (chain);
|
||||||
|
|
||||||
GST_DEBUG ("Chain %p (handled:%d, last_group:%d, drained:%d, switched:%d)",
|
GST_DEBUG ("Chain %p (handled:%d, last_group:%d, drained:%d, switched:%d)",
|
||||||
chain, handled, *last_group, *drained, *switched);
|
chain, handled, *last_group, chain->drained, *switched);
|
||||||
|
|
||||||
|
*drained = chain->drained;
|
||||||
|
|
||||||
if (*drained)
|
if (*drained)
|
||||||
g_signal_emit (dbin, gst_decode_bin_signals[SIGNAL_DRAINED], 0, NULL);
|
g_signal_emit (dbin, gst_decode_bin_signals[SIGNAL_DRAINED], 0, NULL);
|
||||||
|
|
Loading…
Reference in a new issue