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/7044>
This commit is contained in:
Piotr Brzeziński 2024-03-26 15:24:31 +01:00 committed by Backport Bot
parent a9beac80da
commit a0b35d86f9

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");