[FFmpeg-devel] [PATCHv2] [RFC] libavcodec/hevc_refs: Clear DPB of old frames

Kieran Kunhya kierank at obe.tv
Mon Sep 14 19:37:53 EEST 2020


>From 21bf6e5eac61d34f270534dd5a2a7229967c1ee9 Mon Sep 17 00:00:00 2001
From: Kieran Kunhya <kierank at obe.tv>
Date: Thu, 16 Jul 2020 20:29:24 +0100
Subject: [PATCHv2] [RFC] libavcodec/hevc_refs: Clear DPB of old frames

During glitching or looping streams, old frames remain in the DPB.
The decoder incorrectly thinks that the DPB contains the right number
of buffered frames to output and reordering breaks badly
---
 libavcodec/hevc_refs.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c
index 4f6d985..6af0f6e 100644
--- a/libavcodec/hevc_refs.c
+++ b/libavcodec/hevc_refs.c
@@ -277,6 +277,10 @@ static int init_slice_rpl(HEVCContext *s)
     int ctb_addr_ts  = s->ps.pps->ctb_addr_rs_to_ts[s->sh.slice_segment_addr];
     int i;

+    if(frame && !frame->rpl_buf) {
+        return AVERROR_INVALIDDATA;
+    }
+
     if (s->slice_idx >= frame->rpl_buf->size / sizeof(RefPicListTab))
         return AVERROR_INVALIDDATA;

@@ -462,6 +466,21 @@ int ff_hevc_frame_rps(HEVCContext *s)
         mark_ref(frame, 0);
     }

+    /* Clear the DPB of any junk frames */
+    for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
+        HEVCFrame *frame = &s->DPB[i];
+        if ((frame->flags & HEVC_FRAME_FLAG_OUTPUT) &&
+            frame->sequence == s->seq_output) {
+            int dpb_size = FF_ARRAY_ELEMS(s->DPB);
+            if (frame->frame->buf[0] && ((frame->poc > s->poc +
dpb_size) || (frame->poc < s->poc - dpb_size))) {
+                if(frame->poc == s->poc)
+                    continue;
+
+                ff_hevc_unref_frame(s, frame, ~0);
+            }
+        }
+    }
+
     for (i = 0; i < NB_RPS_TYPE; i++)
         rps[i].nb_refs = 0;

--
1.9.1


More information about the ffmpeg-devel mailing list