vtdec: Handle some errors without stopping the decoder

ReferenceMissingErr is not critical and the simplest solution is to just ignore it. The frame has
the FrameDropped flag set when it occurs, so we can just drop it as usual.
BadDataErr is also not immediately critical, but in its case let's set the ERROR flag,
so the output loop can use GST_VIDEO_DECODER_ERROR to count and error out if it happens too many times.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6446>
This commit is contained in:
Piotr Brzeziński 2024-03-26 15:24:31 +01:00 committed by GStreamer Marge Bot
parent 223b63b1d2
commit a5c437c643

View file

@ -1215,8 +1215,30 @@ gst_vtdec_session_output_callback (void *decompression_output_ref_con,
frame->output_buffer = NULL;
if (status != noErr) {
GST_ERROR_OBJECT (vtdec, "Error decoding frame %d", (int) status);
frame->flags |= VTDEC_FRAME_FLAG_ERROR;
switch (status) {
case kVTVideoDecoderReferenceMissingErr:
/* ReferenceMissingErr is not critical, when it occurs the frame
* usually has the kVTDecodeInfo_FrameDropped flag set. Log only for debugging purposes. */
GST_DEBUG_OBJECT (vtdec, "ReferenceMissingErr when decoding frame %d",
frame->decode_frame_number);
break;
#ifndef HAVE_IOS
case codecBadDataErr: /* SW decoder on macOS uses a different code from the hardware one... */
#endif
case kVTVideoDecoderBadDataErr:
/* BadDataErr also shouldn't cause an error to be displayed immediately.
* Set the error flag so the output loop will log a warning
* and only error out if this happens too many times. */
GST_DEBUG_OBJECT (vtdec, "BadDataErr when decoding frame %d",
frame->decode_frame_number);
frame->flags |= VTDEC_FRAME_FLAG_ERROR;
break;
default:
GST_ERROR_OBJECT (vtdec, "Error decoding frame %d: %d",
frame->decode_frame_number, (int) status);
frame->flags |= VTDEC_FRAME_FLAG_ERROR;
break;
}
}
if (image_buffer) {
@ -1238,8 +1260,8 @@ gst_vtdec_session_output_callback (void *decompression_output_ref_con,
}
} else {
if (info_flags & kVTDecodeInfo_FrameDropped) {
GST_DEBUG_OBJECT (vtdec, "Frame dropped by video toolbox %p %d",
frame, frame->decode_frame_number);
GST_DEBUG_OBJECT (vtdec, "Frame %d dropped by VideoToolbox (%p)",
frame->decode_frame_number, frame);
frame->flags |= VTDEC_FRAME_FLAG_DROP;
} else {
GST_DEBUG_OBJECT (vtdec, "Decoded frame is NULL");