From 21bf6e5eac61d34f270534dd5a2a7229967c1ee9 Mon Sep 17 00:00:00 2001
From: Kieran Kunhya <kier...@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
_______________________________________________
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