From a0b35d86f97318e173b267ee67668a32f1b629b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Brzezi=C5=84ski?= Date: Tue, 26 Mar 2024 15:24:31 +0100 Subject: [PATCH] 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: --- .../gst-plugins-bad/sys/applemedia/vtdec.c | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/subprojects/gst-plugins-bad/sys/applemedia/vtdec.c b/subprojects/gst-plugins-bad/sys/applemedia/vtdec.c index db8ebbce2a..625a50d7fb 100644 --- a/subprojects/gst-plugins-bad/sys/applemedia/vtdec.c +++ b/subprojects/gst-plugins-bad/sys/applemedia/vtdec.c @@ -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");