[PR] avcodec/hevc: don't error out on remaining slices of a skipped picture (PR #24257)
Kacper Michajłow via ffmpeg-devel <[email protected]>
| Newsgroups | gmane.comp.video.ffmpeg.devel |
|---|---|
| Message-ID | <[email protected]> |
PR #24257 opened by Kacper Michajłow (kasper93) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24257 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24257.patch When the first slice of a picture is skipped, an undecodable RASL after a seek or avctx->skip_frame, the remaining slices failed the PPS change check against the stale context and logged an decoding error per slice. Skip them cleanly, instead of erroring out. From 4503f15d2b23062915186627d0ebbde327902da5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= <[email protected]> Date: Tue, 25 Aug 2026 01:37:59 +0200 Subject: [PATCH] avcodec/hevc: don't error out on remaining slices of a skipped picture When the first slice of a picture is skipped, an undecodable RASL after a seek or avctx->skip_frame, the remaining slices failed the PPS change check against the stale context and logged an decoding error per slice. Skip them cleanly, instead of erroring out. --- libavcodec/hevc/hevcdec.c | 9 ++++++++- libavcodec/hevc/hevcdec.h | 4 ++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c index 475c2738b1..88da337a7d 100644 --- a/libavcodec/hevc/hevcdec.c +++ b/libavcodec/hevc/hevcdec.c @@ -791,7 +791,8 @@ static int hls_slice_header(SliceHeader *sh, const HEVCContext *s, GetBitContext av_log(s->avctx, AV_LOG_ERROR, "PPS id out of range: %d\n", pps_id); return AVERROR_INVALIDDATA; } - if (!sh->first_slice_in_pic_flag && s->ps.pps_list[pps_id] != s->pps) { + if (!sh->first_slice_in_pic_flag && !s->skipping_frame && + s->ps.pps_list[pps_id] != s->pps) { av_log(s->avctx, AV_LOG_ERROR, "PPS changed between slices.\n"); return AVERROR_INVALIDDATA; } @@ -3573,8 +3574,12 @@ static int decode_slice(HEVCContext *s, unsigned nal_idx, GetBitContext *gb) (s->avctx->skip_frame >= AVDISCARD_NONKEY && !IS_IRAP(s)) || ((s->nal_unit_type == HEVC_NAL_RASL_R || s->nal_unit_type == HEVC_NAL_RASL_N) && s->no_rasl_output_flag)) { + if (s->sh.first_slice_in_pic_flag) + s->skipping_frame = 1; return 0; } + if (s->sh.first_slice_in_pic_flag) + s->skipping_frame = 0; // switching to a new layer, mark previous layer's frame (if any) as done if (s->cur_layer != layer_idx && @@ -4076,6 +4081,7 @@ static int hevc_update_thread_context(AVCodecContext *dst, s->poc_tid0 = s0->poc_tid0; s->eos = s0->eos; s->no_rasl_output_flag = s0->no_rasl_output_flag; + s->skipping_frame = s0->skipping_frame; s->is_nalff = s0->is_nalff; s->nal_length_size = s0->nal_length_size; @@ -4221,6 +4227,7 @@ static av_cold void hevc_decode_flush(AVCodecContext *avctx) ff_dovi_ctx_flush(&s->dovi_ctx); av_buffer_unref(&s->rpu_buf); s->eos = 1; + s->skipping_frame = 0; if (FF_HW_HAS_CB(avctx, flush)) FF_HW_SIMPLE_CALL(avctx, flush); diff --git a/libavcodec/hevc/hevcdec.h b/libavcodec/hevc/hevcdec.h index 8394740c4b..b21d82b5c6 100644 --- a/libavcodec/hevc/hevcdec.h +++ b/libavcodec/hevc/hevcdec.h @@ -531,6 +531,10 @@ typedef struct HEVCContext { // NoRaslOutputFlag associated with the last IRAP frame int no_rasl_output_flag; + // The first slice of the current picture was skipped (undecodable RASL + // or avctx->skip_frame), so drop its remaining slices too + int skipping_frame; + HEVCPredContext hpc; HEVCDSPContext hevcdsp; VideoDSPContext vdsp; -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]