[FFmpeg-devel] [PATCH] avcodec/hevc: Add support for output_corrupt/showall flags
Zhao Zhili
quinkblack at foxmail.com
Sun Jan 5 10:00:15 EET 2025
From: Zhao Zhili <zhilizhao at tencent.com>
hevc decoder output corrupted frames when the reference frames
are missing. The output_corrupt flag has no effect. ffplay shows
artifacting after seek when playback TS stream.
This patch mark those frames with AV_FRAME_FLAG_CORRUPT flag when
output_corrupt flag is set, and drop those frames otherwise.
Signed-off-by: Zhao Zhili <zhilizhao at tencent.com>
---
libavcodec/hevc/hevcdec.h | 1 +
libavcodec/hevc/refs.c | 14 ++++++++++++++
tests/fate/hevc.mak | 5 +++--
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/libavcodec/hevc/hevcdec.h b/libavcodec/hevc/hevcdec.h
index 4e95035688..6d2aeb2815 100644
--- a/libavcodec/hevc/hevcdec.h
+++ b/libavcodec/hevc/hevcdec.h
@@ -353,6 +353,7 @@ typedef struct DBParams {
#define HEVC_FRAME_FLAG_SHORT_REF (1 << 1)
#define HEVC_FRAME_FLAG_LONG_REF (1 << 2)
#define HEVC_FRAME_FLAG_UNAVAILABLE (1 << 3)
+#define HEVC_FRAME_FLAG_CORRUPT (1 << 4)
typedef struct HEVCFrame {
union {
diff --git a/libavcodec/hevc/refs.c b/libavcodec/hevc/refs.c
index dd7f7f95a8..f60fa9c7d7 100644
--- a/libavcodec/hevc/refs.c
+++ b/libavcodec/hevc/refs.c
@@ -34,6 +34,8 @@
void ff_hevc_unref_frame(HEVCFrame *frame, int flags)
{
frame->flags &= ~flags;
+ if (!(frame->flags & ~HEVC_FRAME_FLAG_CORRUPT))
+ frame->flags = 0;
if (!frame->flags) {
ff_progress_frame_unref(&frame->tf);
av_frame_unref(frame->frame_grain);
@@ -265,6 +267,9 @@ int ff_hevc_output_frames(HEVCContext *s,
AVFrame *f = frame->needs_fg ? frame->frame_grain : frame->f;
int output = !discard && (layers_active_output & (1 << min_layer));
+ if (output && (frame->flags & HEVC_FRAME_FLAG_CORRUPT))
+ f->flags |= AV_FRAME_FLAG_CORRUPT;
+
if (output) {
f->pkt_dts = s->pkt_dts;
ret = av_container_fifo_write(s->output_fifo, f, AV_CONTAINER_FIFO_FLAG_REF);
@@ -462,6 +467,15 @@ static int add_candidate_ref(HEVCContext *s, HEVCLayerContext *l,
if (ref == s->cur_frame || list->nb_refs >= HEVC_MAX_REFS)
return AVERROR_INVALIDDATA;
+ if (!IS_IRAP(s) && (!ref || ref->flags & (HEVC_FRAME_FLAG_CORRUPT |
+ HEVC_FRAME_FLAG_UNAVAILABLE))) {
+ if (!(s->avctx->flags & AV_CODEC_FLAG_OUTPUT_CORRUPT) &&
+ !(s->avctx->flags2 & AV_CODEC_FLAG2_SHOW_ALL))
+ return AVERROR_INVALIDDATA;
+
+ s->cur_frame->flags |= HEVC_FRAME_FLAG_CORRUPT;
+ }
+
if (!ref) {
ref = generate_missing_ref(s, l, poc);
if (!ref)
diff --git a/tests/fate/hevc.mak b/tests/fate/hevc.mak
index 9e6fd72618..943045ac2c 100644
--- a/tests/fate/hevc.mak
+++ b/tests/fate/hevc.mak
@@ -207,7 +207,8 @@ $(HEVC_TESTS_444_8BIT): SCALE_OPTS := -pix_fmt yuv444p
$(HEVC_TESTS_10BIT): SCALE_OPTS := -pix_fmt yuv420p10le -vf scale
$(HEVC_TESTS_422_10BIT) $(HEVC_TESTS_422_10BIN): SCALE_OPTS := -pix_fmt yuv422p10le -vf scale
$(HEVC_TESTS_444_12BIT): SCALE_OPTS := -pix_fmt yuv444p12le -vf scale
-fate-hevc-conformance-%: CMD = framecrc -i $(TARGET_SAMPLES)/hevc-conformance/$(subst fate-hevc-conformance-,,$(@)).bit $(SCALE_OPTS)
+# Set output_corrupt flag for NUT_A_ericsson_5, since it missing some reference frames
+fate-hevc-conformance-%: CMD = framecrc -flags output_corrupt -i $(TARGET_SAMPLES)/hevc-conformance/$(subst fate-hevc-conformance-,,$(@)).bit $(SCALE_OPTS)
$(HEVC_TESTS_422_10BIN): CMD = framecrc -i $(TARGET_SAMPLES)/hevc-conformance/$(subst fate-hevc-conformance-,,$(@)).bin $(SCALE_OPTS)
$(HEVC_TESTS_MULTIVIEW): CMD = framecrc -i $(TARGET_SAMPLES)/hevc-conformance/$(subst fate-hevc-conformance-,,$(@)).bit \
-pix_fmt yuv420p -map "0:view:0" -map "0:view:1" -vf setpts=N
@@ -248,7 +249,7 @@ FATE_HEVC_FFPROBE-$(call DEMDEC, HEVC, HEVC) += fate-hevc-paired-fields
fate-hevc-monochrome-crop: CMD = probeframes -show_entries frame=width,height:stream=width,height $(TARGET_SAMPLES)/hevc/hevc-monochrome.hevc
FATE_HEVC_FFPROBE-$(call PARSERDEMDEC, HEVC, HEVC, HEVC) += fate-hevc-monochrome-crop
-fate-hevc-afd-tc-sei: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -bitexact -show_entries frame_side_data_list -select_streams v $(TARGET_SAMPLES)/mpegts/loewe.ts
+fate-hevc-afd-tc-sei: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -flags output_corrupt -bitexact -show_entries frame_side_data_list -select_streams v $(TARGET_SAMPLES)/mpegts/loewe.ts
FATE_HEVC_FFPROBE-$(call PARSERDEMDEC, HEVC, HEVC, HEVC) += fate-hevc-afd-tc-sei
fate-hevc-hdr10-plus-metadata: CMD = probeframes -show_entries frame=side_data_list $(TARGET_SAMPLES)/hevc/hdr10_plus_h265_sample.hevc
--
2.46.0
More information about the ffmpeg-devel
mailing list