baseaudiodecoder: improve glitch resilience
Provide a replacement for GST_ELEMENT_ERROR to avoid aborting at the first atom out of place, while on the other hand not failing indefinitely.
This commit is contained in:
parent
79b41f59f6
commit
d46006b198
@ -215,6 +215,8 @@ struct _GstBaseAudioDecoderPrivate
|
|||||||
guint64 samples_out;
|
guint64 samples_out;
|
||||||
/* bytes flushed during parsing */
|
/* bytes flushed during parsing */
|
||||||
guint sync_flush;
|
guint sync_flush;
|
||||||
|
/* error count */
|
||||||
|
gint error_count;
|
||||||
/* codec id tag */
|
/* codec id tag */
|
||||||
GstTagList *taglist;
|
GstTagList *taglist;
|
||||||
|
|
||||||
@ -386,6 +388,7 @@ gst_base_audio_decoder_reset (GstBaseAudioDecoder * dec, gboolean full)
|
|||||||
dec->priv->bytes_in = 0;
|
dec->priv->bytes_in = 0;
|
||||||
dec->priv->samples_out = 0;
|
dec->priv->samples_out = 0;
|
||||||
dec->priv->agg = -1;
|
dec->priv->agg = -1;
|
||||||
|
dec->priv->error_count = 0;
|
||||||
gst_base_audio_decoder_clear_queues (dec);
|
gst_base_audio_decoder_clear_queues (dec);
|
||||||
|
|
||||||
g_free (dec->ctx->state.channel_pos);
|
g_free (dec->ctx->state.channel_pos);
|
||||||
@ -786,6 +789,10 @@ gst_base_audio_decoder_finish_frame (GstBaseAudioDecoder * dec, GstBuffer * buf,
|
|||||||
}
|
}
|
||||||
priv->samples += samples;
|
priv->samples += samples;
|
||||||
priv->samples_out += samples;
|
priv->samples_out += samples;
|
||||||
|
|
||||||
|
/* we got data, so note things are looking up */
|
||||||
|
if (G_UNLIKELY (dec->priv->error_count))
|
||||||
|
dec->priv->error_count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
return gst_base_audio_decoder_output (dec, buf);
|
return gst_base_audio_decoder_output (dec, buf);
|
||||||
@ -985,6 +992,7 @@ gst_base_audio_decoder_flush (GstBaseAudioDecoder * dec, gboolean hard)
|
|||||||
ret = gst_base_audio_decoder_drain (dec);
|
ret = gst_base_audio_decoder_drain (dec);
|
||||||
} else {
|
} else {
|
||||||
gst_segment_init (&dec->segment, GST_FORMAT_TIME);
|
gst_segment_init (&dec->segment, GST_FORMAT_TIME);
|
||||||
|
dec->priv->error_count = 0;
|
||||||
}
|
}
|
||||||
/* only bother subclass with flushing if known it is already alive
|
/* only bother subclass with flushing if known it is already alive
|
||||||
* and kicking out stuff */
|
* and kicking out stuff */
|
||||||
@ -1844,3 +1852,23 @@ stop_failed:
|
|||||||
return GST_STATE_CHANGE_FAILURE;
|
return GST_STATE_CHANGE_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GstFlowReturn
|
||||||
|
_gst_base_audio_decoder_error (GstBaseAudioDecoder * dec, gint weight,
|
||||||
|
GQuark domain, gint code, gchar * txt, gchar * dbg, const gchar * file,
|
||||||
|
const gchar * function, gint line)
|
||||||
|
{
|
||||||
|
if (txt)
|
||||||
|
GST_WARNING_OBJECT (dec, "error: %s", txt);
|
||||||
|
if (dbg)
|
||||||
|
GST_WARNING_OBJECT (dec, "error: %s", dbg);
|
||||||
|
dec->priv->error_count += weight;
|
||||||
|
dec->priv->discont = TRUE;
|
||||||
|
if (dec->ctx->max_errors < dec->priv->error_count) {
|
||||||
|
gst_element_message_full (GST_ELEMENT (dec), GST_MESSAGE_ERROR,
|
||||||
|
domain, code, txt, dbg, file, function, line);
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
|
} else {
|
||||||
|
return GST_FLOW_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -83,6 +83,44 @@ typedef struct _GstBaseAudioDecoderClass GstBaseAudioDecoderClass;
|
|||||||
typedef struct _GstBaseAudioDecoderPrivate GstBaseAudioDecoderPrivate;
|
typedef struct _GstBaseAudioDecoderPrivate GstBaseAudioDecoderPrivate;
|
||||||
typedef struct _GstBaseAudioDecoderContext GstBaseAudioDecoderContext;
|
typedef struct _GstBaseAudioDecoderContext GstBaseAudioDecoderContext;
|
||||||
|
|
||||||
|
/* do not use this one, use macro below */
|
||||||
|
GstFlowReturn _gst_base_audio_decoder_error (GstBaseAudioDecoder *dec, gint weight,
|
||||||
|
GQuark domain, gint code,
|
||||||
|
gchar *txt, gchar *debug,
|
||||||
|
const gchar *file, const gchar *function,
|
||||||
|
gint line);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GST_BASE_AUDIO_DECODER_ERROR:
|
||||||
|
* @el: the base audio decoder element that generates the error
|
||||||
|
* @weight: element defined weight of the error, added to error count
|
||||||
|
* @domain: like CORE, LIBRARY, RESOURCE or STREAM (see #gstreamer-GstGError)
|
||||||
|
* @code: error code defined for that domain (see #gstreamer-GstGError)
|
||||||
|
* @text: the message to display (format string and args enclosed in
|
||||||
|
* parentheses)
|
||||||
|
* @debug: debugging information for the message (format string and args
|
||||||
|
* enclosed in parentheses)
|
||||||
|
* @ret: variable to receive return value
|
||||||
|
*
|
||||||
|
* Utility function that audio decoder elements can use in case they encountered
|
||||||
|
* a data processing error that may be fatal for the current "data unit" but
|
||||||
|
* need not prevent subsequent decoding. Such errors are counted and if there
|
||||||
|
* are too many, as configured in the context's max_errors, the pipeline will
|
||||||
|
* post an error message and the application will be requested to stop further
|
||||||
|
* media processing. Otherwise, it is considered a "glitch" and only a warning
|
||||||
|
* is logged. In either case, @ret is set to the proper value to
|
||||||
|
* return to upstream/caller (indicating either GST_FLOW_ERROR or GST_FLOW_OK).
|
||||||
|
*/
|
||||||
|
#define GST_BASE_AUDIO_DECODER_ERROR(el, w, domain, code, text, debug, ret) \
|
||||||
|
G_STMT_START { \
|
||||||
|
gchar *__txt = _gst_element_error_printf text; \
|
||||||
|
gchar *__dbg = _gst_element_error_printf debug; \
|
||||||
|
GstBaseAudioDecoder *dec = GST_BASE_AUDIO_DECODER (el); \
|
||||||
|
ret = _gst_base_audio_decoder_error (dec, w, GST_ ## domain ## _ERROR, \
|
||||||
|
GST_ ## domain ## _ERROR_ ## code, __txt, __dbg, __FILE__, \
|
||||||
|
GST_FUNCTION, __LINE__); \
|
||||||
|
} G_STMT_END
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstBaseAudioDecoderContext:
|
* GstBaseAudioDecoderContext:
|
||||||
* @state: a #GstAudioState describing input audio format
|
* @state: a #GstAudioState describing input audio format
|
||||||
@ -111,6 +149,7 @@ struct _GstBaseAudioDecoderContext {
|
|||||||
/* output */
|
/* output */
|
||||||
gboolean do_plc;
|
gboolean do_plc;
|
||||||
gboolean do_byte_time;
|
gboolean do_byte_time;
|
||||||
|
gint max_errors;
|
||||||
/* MT-protected (with LOCK) */
|
/* MT-protected (with LOCK) */
|
||||||
GstClockTime min_latency;
|
GstClockTime min_latency;
|
||||||
GstClockTime max_latency;
|
GstClockTime max_latency;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user