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

Git pushed a commit to branch master
in repository ffmpeg.

commit 2b3609ab615065700939426509bea08779bcd681
Author:     Frank Plowman <[email protected]>
AuthorDate: Sat Aug 29 09:46:56 2026 +0100
Commit:     Frank Plowman <[email protected]>
CommitDate: Sun Sep 13 10:37:40 2026 +0100

    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]>
---
 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 15024d7b68..6939a22732 100644
--- a/libavcodec/vvc/refs.c
+++ b/libavcodec/vvc/refs.c
@@ -380,6 +380,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;
@@ -450,12 +456,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