mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
splitmux: Handle a hang draining out at EOS
Make sure that all data is drained out when the reference pad goes EOS. Fixes a problem where data that arrives on other pads after the reference pad finishes can stall forever and never pass EOS. https://bugzilla.gnome.org/show_bug.cgi?id=763711
This commit is contained in:
parent
fb835c100a
commit
41d2b6f19e
1 changed files with 23 additions and 16 deletions
|
@ -718,8 +718,8 @@ restart_context (MqStreamCtx * ctx, GstSplitMuxSink * splitmux)
|
|||
gst_pad_sticky_events_foreach (ctx->srcpad,
|
||||
(GstPadStickyEventsForeachFunction) (resend_sticky), peer);
|
||||
|
||||
/* Clear EOS flag */
|
||||
ctx->out_eos = FALSE;
|
||||
/* Clear EOS flag if not actually EOS */
|
||||
ctx->out_eos = GST_PAD_IS_EOS (ctx->srcpad);
|
||||
|
||||
gst_object_unref (peer);
|
||||
}
|
||||
|
@ -743,11 +743,11 @@ start_next_fragment (GstSplitMuxSink * splitmux)
|
|||
g_list_foreach (splitmux->contexts, (GFunc) restart_context, splitmux);
|
||||
|
||||
/* Switch state and go back to processing */
|
||||
splitmux->state = SPLITMUX_STATE_COLLECTING_GOP_START;
|
||||
|
||||
if (!splitmux->reference_ctx->in_eos) {
|
||||
splitmux->state = SPLITMUX_STATE_COLLECTING_GOP_START;
|
||||
splitmux->max_out_running_time = splitmux->reference_ctx->in_running_time;
|
||||
} else {
|
||||
splitmux->state = SPLITMUX_STATE_WAITING_GOP_COMPLETE;
|
||||
splitmux->max_out_running_time = GST_CLOCK_TIME_NONE;
|
||||
splitmux->have_muxed_something = FALSE;
|
||||
}
|
||||
|
@ -811,6 +811,7 @@ handle_gathered_gop (GstSplitMuxSink * splitmux)
|
|||
GList *cur;
|
||||
gsize queued_bytes = 0;
|
||||
GstClockTime queued_time = 0;
|
||||
gboolean at_eos = TRUE;
|
||||
|
||||
/* Assess if the multiqueue contents overflowed the current file */
|
||||
for (cur = g_list_first (splitmux->contexts);
|
||||
|
@ -819,6 +820,7 @@ handle_gathered_gop (GstSplitMuxSink * splitmux)
|
|||
if (tmpctx->in_running_time > queued_time)
|
||||
queued_time = tmpctx->in_running_time;
|
||||
queued_bytes += tmpctx->in_bytes;
|
||||
at_eos &= tmpctx->in_eos;
|
||||
}
|
||||
|
||||
g_assert (queued_bytes >= splitmux->mux_start_bytes);
|
||||
|
@ -835,11 +837,11 @@ handle_gathered_gop (GstSplitMuxSink * splitmux)
|
|||
|
||||
/* Check for overrun - have we output at least one byte and overrun
|
||||
* either threshold? */
|
||||
if (splitmux->have_muxed_something &&
|
||||
((splitmux->threshold_bytes > 0 &&
|
||||
queued_bytes >= splitmux->threshold_bytes) ||
|
||||
(splitmux->threshold_time > 0 &&
|
||||
queued_time >= splitmux->threshold_time))) {
|
||||
if ((splitmux->have_muxed_something &&
|
||||
((splitmux->threshold_bytes > 0 &&
|
||||
queued_bytes >= splitmux->threshold_bytes) ||
|
||||
(splitmux->threshold_time > 0 &&
|
||||
queued_time >= splitmux->threshold_time))) || at_eos) {
|
||||
|
||||
splitmux->state = SPLITMUX_STATE_ENDING_FILE;
|
||||
|
||||
|
@ -857,13 +859,15 @@ handle_gathered_gop (GstSplitMuxSink * splitmux)
|
|||
queued_bytes, GST_TIME_ARGS (queued_time));
|
||||
|
||||
/* Wake everyone up to push this one GOP, then sleep */
|
||||
splitmux->state = SPLITMUX_STATE_COLLECTING_GOP_START;
|
||||
splitmux->have_muxed_something = TRUE;
|
||||
|
||||
if (!splitmux->reference_ctx->in_eos)
|
||||
if (!splitmux->reference_ctx->in_eos) {
|
||||
splitmux->state = SPLITMUX_STATE_COLLECTING_GOP_START;
|
||||
splitmux->max_out_running_time = splitmux->reference_ctx->in_running_time;
|
||||
else
|
||||
} else {
|
||||
splitmux->state = SPLITMUX_STATE_WAITING_GOP_COMPLETE;
|
||||
splitmux->max_out_running_time = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
|
||||
GST_LOG_OBJECT (splitmux, "Waking output for complete GOP, TS %"
|
||||
GST_TIME_FORMAT, GST_TIME_ARGS (splitmux->max_out_running_time));
|
||||
|
@ -887,9 +891,11 @@ check_completed_gop (GstSplitMuxSink * splitmux, MqStreamCtx * ctx)
|
|||
if (splitmux->state == SPLITMUX_STATE_WAITING_GOP_COMPLETE) {
|
||||
/* Iterate each pad, and check that the input running time is at least
|
||||
* up to the reference running time, and if so handle the collected GOP */
|
||||
GST_LOG_OBJECT (splitmux, "Checking GOP collected, ctx %p", ctx);
|
||||
for (cur = g_list_first (splitmux->contexts);
|
||||
cur != NULL; cur = g_list_next (cur)) {
|
||||
GST_LOG_OBJECT (splitmux, "Checking GOP collected, Max in running time %"
|
||||
GST_TIME_FORMAT " ctx %p",
|
||||
GST_TIME_ARGS (splitmux->max_in_running_time), ctx);
|
||||
for (cur = g_list_first (splitmux->contexts); cur != NULL;
|
||||
cur = g_list_next (cur)) {
|
||||
MqStreamCtx *tmpctx = (MqStreamCtx *) (cur->data);
|
||||
|
||||
GST_LOG_OBJECT (splitmux,
|
||||
|
@ -897,7 +903,8 @@ check_completed_gop (GstSplitMuxSink * splitmux, MqStreamCtx * ctx)
|
|||
" EOS %d", tmpctx, tmpctx->srcpad,
|
||||
GST_TIME_ARGS (tmpctx->in_running_time), tmpctx->in_eos);
|
||||
|
||||
if (tmpctx->in_running_time < splitmux->max_in_running_time &&
|
||||
if (splitmux->max_in_running_time != GST_CLOCK_TIME_NONE &&
|
||||
tmpctx->in_running_time < splitmux->max_in_running_time &&
|
||||
!tmpctx->in_eos) {
|
||||
GST_LOG_OBJECT (splitmux,
|
||||
"Context %p (src pad %" GST_PTR_FORMAT ") not ready. We'll sleep",
|
||||
|
|
Loading…
Reference in a new issue