mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-23 06:26:23 +00:00
basevideodecoder: 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
1588ed321c
commit
a1825bd5e2
2 changed files with 68 additions and 1 deletions
|
@ -318,6 +318,7 @@ gst_base_video_decoder_flush (GstBaseVideoDecoder * dec, gboolean hard)
|
|||
gst_segment_init (&GST_BASE_VIDEO_CODEC (dec)->segment,
|
||||
GST_FORMAT_UNDEFINED);
|
||||
gst_base_video_decoder_clear_queues (dec);
|
||||
dec->error_count = 0;
|
||||
}
|
||||
/* and get (re)set for the sequel */
|
||||
gst_base_video_decoder_reset (dec, FALSE);
|
||||
|
@ -887,6 +888,7 @@ gst_base_video_decoder_reset (GstBaseVideoDecoder * base_video_decoder,
|
|||
gst_segment_init (&GST_BASE_VIDEO_CODEC (base_video_decoder)->segment,
|
||||
GST_FORMAT_UNDEFINED);
|
||||
gst_base_video_decoder_clear_queues (base_video_decoder);
|
||||
base_video_decoder->error_count = 0;
|
||||
}
|
||||
|
||||
GST_BASE_VIDEO_CODEC (base_video_decoder)->discont = TRUE;
|
||||
|
@ -1482,6 +1484,10 @@ gst_base_video_decoder_finish_frame (GstBaseVideoDecoder * base_video_decoder,
|
|||
}
|
||||
}
|
||||
|
||||
/* we got data, so note things are looking up again */
|
||||
if (G_UNLIKELY (base_video_decoder->error_count))
|
||||
base_video_decoder->error_count--;
|
||||
|
||||
if (GST_BASE_VIDEO_CODEC (base_video_decoder)->segment.rate < 0.0) {
|
||||
GST_LOG_OBJECT (base_video_decoder, "queued buffer");
|
||||
base_video_decoder->queued =
|
||||
|
@ -1950,3 +1956,23 @@ gst_base_video_decoder_class_set_capture_pattern (GstBaseVideoDecoderClass *
|
|||
base_video_decoder_class->capture_mask = mask;
|
||||
base_video_decoder_class->capture_pattern = pattern;
|
||||
}
|
||||
|
||||
GstFlowReturn
|
||||
_gst_base_video_decoder_error (GstBaseVideoDecoder * 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->error_count += weight;
|
||||
GST_BASE_VIDEO_CODEC (dec)->discont = TRUE;
|
||||
if (dec->max_errors < dec->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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,10 +65,49 @@ G_BEGIN_DECLS
|
|||
**/
|
||||
#define GST_BASE_VIDEO_DECODER_FLOW_NEED_DATA GST_FLOW_CUSTOM_SUCCESS
|
||||
|
||||
|
||||
typedef struct _GstBaseVideoDecoder GstBaseVideoDecoder;
|
||||
typedef struct _GstBaseVideoDecoderClass GstBaseVideoDecoderClass;
|
||||
|
||||
|
||||
/* do not use this one, use macro below */
|
||||
GstFlowReturn _gst_base_video_decoder_error (GstBaseVideoDecoder *dec, gint weight,
|
||||
GQuark domain, gint code,
|
||||
gchar *txt, gchar *debug,
|
||||
const gchar *file, const gchar *function,
|
||||
gint line);
|
||||
|
||||
/**
|
||||
* GST_BASE_VIDEO_DECODER_ERROR:
|
||||
* @el: the base video 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; \
|
||||
GstBaseVideoDecoder *dec = GST_BASE_VIDEO_DECODER (el); \
|
||||
ret = _gst_base_video_decoder_error (dec, w, GST_ ## domain ## _ERROR, \
|
||||
GST_ ## domain ## _ERROR_ ## code, __txt, __dbg, __FILE__, \
|
||||
GST_FUNCTION, __LINE__); \
|
||||
} G_STMT_END
|
||||
|
||||
|
||||
/**
|
||||
* GstBaseVideoDecoder:
|
||||
*
|
||||
|
@ -82,6 +121,7 @@ struct _GstBaseVideoDecoder
|
|||
gboolean sink_clipping;
|
||||
gboolean do_byte_time;
|
||||
gboolean packetized;
|
||||
gint max_errors;
|
||||
|
||||
/* parse tracking */
|
||||
/* input data */
|
||||
|
@ -113,6 +153,7 @@ struct _GstBaseVideoDecoder
|
|||
|
||||
/* last outgoing ts */
|
||||
GstClockTime last_timestamp;
|
||||
gint error_count;
|
||||
|
||||
/* reverse playback */
|
||||
/* collect input */
|
||||
|
|
Loading…
Reference in a new issue