From: Zhao Zhili <zhiliz...@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 <zhiliz...@tencent.com>
---
v2: Don't check 'output' twice in ff_hevc_output_frames

 libavcodec/hevc/hevcdec.h |  1 +
 libavcodec/hevc/refs.c    | 13 +++++++++++++
 tests/fate/hevc.mak       |  5 +++--
 3 files changed, 17 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..33d34833a4 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);
@@ -266,6 +268,8 @@ int ff_hevc_output_frames(HEVCContext *s,
             int output = !discard && (layers_active_output & (1 << min_layer));
 
             if (output) {
+                if (frame->flags & HEVC_FRAME_FLAG_CORRUPT)
+                    f->flags |= AV_FRAME_FLAG_CORRUPT;
                 f->pkt_dts = s->pkt_dts;
                 ret = av_container_fifo_write(s->output_fifo, f, 
AV_CONTAINER_FIFO_FLAG_REF);
             }
@@ -462,6 +466,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

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to