This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch release/8.1
in repository ffmpeg.

commit c96d402ff135f20afe27390fcf61e85538b3819b
Author:     Frank Plowman <[email protected]>
AuthorDate: Sat Aug 29 09:46:56 2026 +0100
Commit:     Michael Niedermayer <[email protected]>
CommitDate: Sat Sep 19 14:27:18 2026 +0200

    avcodec/vvc: Skip over the current picture in find_ref_idx
    
    In VVC, there are two schemes for addressing reference pictures in
    the DPB:
    1. Normally, the POC of the reference picture is signaled using a delta
       from the current picture POC.
    2. In the case of long-term reference pictures (LTRPs), which may be far
       away from the current POC, the absolute value of the LTRP POC is
       signalled.  This scheme has two sub-schemes:
       a. Signalling the entirety of the absolute value of the LTRP
          POC would be expensive, so in most cases we only signal the
          sps_log2_max_pic_order_cnt_lsb_minus4 + 4 least-significant bits
          of the LTRP POC.
       b. In the case of a collision in the least-significant bits,
          the full POC is signalled.
    
    Both schemes are implemented in find_ref_idx.  The use_msb parameter
    of find_ref_idx is nonzero in the case of schemes 1 and 2b, and zero in
    the case of scheme 2a.
    
    This commit fixes a bug in scheme 2a.  The issue arises from the fact
    that the current picture is stored in the DPB at the time find_ref_idx
    is invoked in FFmpeg's implementation, whereas in the specification the
    current picture is not yet considered part of the DPB.  The current
    picture may have a POC which shares least-significant bits with an LTRP.
    The specification does not identify this as a collision however (see the
    condition in 7.4.10, under the semantics of
    delta_poc_msb_cycle_present_flag), and so scheme 2a is used rather than
    scheme 2b.  If the current frame precedes the correct LTRP in the DPB,
    FFmpeg's implementation then interprets the signalling to mean a frame
    which references itself.  The problematic callsite identifies this as an
    issue and returns an AVERROR_INVALIDDATA, but this scenario can occur in
    valid bitstreams.  For example, the conformance bitstream
    LTRP_A_ERICSSON_3 has one such instance.  FFmpeg gets away with decoding
    it currently because the LTRP precedes the current picture in the DPB,
    but this is by chance rather than design.
    
    The commit addresses this issue by skipping over the current picture
    inside the main loop of find_ref_idx.  An unambiguous reference to the
    current picture is still syntactically possible but illegal when using
    scheme 2b.  The handling of this case is moved from find_ref_idx to the
    caller, which allows for simplifying find_ref_idx.
    
    Signed-off-by: Frank Plowman <[email protected]>
    (cherry picked from commit 2b3609ab615065700939426509bea08779bcd681)
    Signed-off-by: Michael Niedermayer <[email protected]>
---
 libavcodec/vvc/refs.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/libavcodec/vvc/refs.c b/libavcodec/vvc/refs.c
index c1f027aed5..77391abd7b 100644
--- a/libavcodec/vvc/refs.c
+++ b/libavcodec/vvc/refs.c
@@ -381,6 +381,12 @@ static VVCFrame *find_ref_idx(VVCContext *s, 
VVCFrameContext *fc, int poc, uint8
 
     for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
         VVCFrame *ref = &fc->DPB[i];
+
+        // In the specification, the current frame is not considered part of
+        // the DPB at this stage, therefore we treat it as if it's not there.
+        if (ref == fc->ref)
+            continue;
+
         if (ref->frame->buf[0] && ref->sequence == s->seq_decode) {
             if ((ref->poc & mask) == poc)
                 return ref;
@@ -451,12 +457,14 @@ static int check_candidate_ref(const VVCFrame *frame, 
const VVCRefPic *refp)
 static int add_candidate_ref(VVCContext *s, VVCFrameContext *fc, RefPicList 
*list,
                              int poc, int ref_flag, uint8_t use_msb)
 {
-    VVCFrame *ref   = find_ref_idx(s, fc, poc, use_msb);
     VVCRefPic *refp = &list->refs[list->nb_refs];
+    VVCFrame *ref;
 
-    if (ref == fc->ref || list->nb_refs >= VVC_MAX_REF_ENTRIES)
+    if (use_msb && poc == fc->ref->poc || list->nb_refs >= VVC_MAX_REF_ENTRIES)
         return AVERROR_INVALIDDATA;
 
+    ref = find_ref_idx(s, fc, poc, use_msb);
+
     if (!IS_CVSS(s)) {
         const bool ref_corrupt = !ref || (ref->flags & VVC_FRAME_FLAG_CORRUPT);
         const bool recovering  = s->no_output_before_recovery_flag &&

-- 
To stop receiving notification emails like this one, please contact
[email protected].
_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to