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

Git pushed a commit to branch master
in repository ffmpeg.

commit ef533ef3a3ea063eb72edbf510d006684f260f7f
Author:     Wu Jianhua <[email protected]>
AuthorDate: Thu Aug 27 04:08:10 2026 +0800
Commit:     jianhuaw <[email protected]>
CommitDate: Sun Sep 6 20:55:01 2026 +0000

    avcodec/vvc/ps: allow out-of-range ph_recovery_poc_cnt in non-strict mode
    
    The GDR stream in ticket #24265 carries ph_recovery_poc_cnt equal to
    128 even though MaxPicOrderCntLsb is 16. H.266 7.4.3.8 requires the
    value to be in the range [0, MaxPicOrderCntLsb - 1].
    
    CBS currently rejects it before the decoder can proceed. The former
    CBS upper bound also admitted MaxPicOrderCntLsb itself. The syntax
    element does not affect entropy decoding, however, so treating it as a
    fatal error in normal operation prevents decoding a stream beyond this
    non-conforming value.
    
    Store the raw ue(v) value as uint32_t and defer the conformance check
    until the recovery POC is derived. In non-strict mode, accept values
    whose derived POC is representable as an int and emit a warning. In
    strict mode, reject values above MaxPicOrderCntLsb - 1.
    
    Fixes #24265.
    
    Signed-off-by: Wu Jianhua <[email protected]>
---
 libavcodec/cbs_h266.h                 |  2 +-
 libavcodec/cbs_h266_syntax_template.c |  9 ++++++++-
 libavcodec/vvc/ps.c                   | 38 ++++++++++++++++++++++++++++++-----
 3 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/libavcodec/cbs_h266.h b/libavcodec/cbs_h266.h
index 0dc7d96828..d315f6b64a 100644
--- a/libavcodec/cbs_h266.h
+++ b/libavcodec/cbs_h266.h
@@ -681,7 +681,7 @@ typedef struct  H266RawPictureHeader {
     uint8_t  ph_intra_slice_allowed_flag;
     uint8_t  ph_pic_parameter_set_id;
     uint16_t ph_pic_order_cnt_lsb;
-    uint8_t  ph_recovery_poc_cnt;
+    uint32_t ph_recovery_poc_cnt;
     uint8_t  ph_extra_bit[16];
     uint8_t  ph_poc_msb_cycle_present_flag;
     uint8_t  ph_poc_msb_cycle_val;
diff --git a/libavcodec/cbs_h266_syntax_template.c 
b/libavcodec/cbs_h266_syntax_template.c
index fa90aba1de..55178db1ea 100644
--- a/libavcodec/cbs_h266_syntax_template.c
+++ b/libavcodec/cbs_h266_syntax_template.c
@@ -2687,9 +2687,16 @@ static int FUNC(picture_header) (CodedBitstreamContext 
*ctx, RWContext *rw,
     }
 
     ub(sps->sps_log2_max_pic_order_cnt_lsb_minus4 + 4, ph_pic_order_cnt_lsb);
-    if (current->ph_gdr_pic_flag)
+    if (current->ph_gdr_pic_flag) {
+#ifdef READ
+        // H.266 7.4.3.8: ph_recovery_poc_cnt shall be in [0, 
MaxPicOrderCntLsb - 1].
+        // The range check is deferred to decode_recovery_poc().
+        ue(ph_recovery_poc_cnt, 0, UINT32_MAX - 1);
+#else
         ue(ph_recovery_poc_cnt, 0,
            (1 << (sps->sps_log2_max_pic_order_cnt_lsb_minus4 + 4)) - 1);
+#endif
+    }
 
     for (i = 0; i < sps->sps_num_extra_ph_bytes * 8; i++) {
         if (sps->sps_extra_ph_bit_present_flag[i])
diff --git a/libavcodec/vvc/ps.c b/libavcodec/vvc/ps.c
index a591851238..c27c8a43c2 100644
--- a/libavcodec/vvc/ps.c
+++ b/libavcodec/vvc/ps.c
@@ -20,6 +20,7 @@
  * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
+#include <limits.h>
 #include <stdbool.h>
 
 #include "libavcodec/cbs_h266.h"
@@ -1045,14 +1046,39 @@ static void decode_recovery_flag(VVCContext *s)
         s->no_output_before_recovery_flag = s->last_eos;
 }
 
-static void decode_recovery_poc(VVCContext *s, const VVCPH *ph)
+static int decode_recovery_poc(VVCContext *s, const VVCFrameParamSets *fps)
 {
+    const VVCPH *ph = &fps->ph;
+
+    if (IS_GDR(s)) {
+        const uint32_t recovery_poc_cnt     = ph->r->ph_recovery_poc_cnt;
+        const uint32_t max_recovery_poc_cnt = fps->sps->max_pic_order_cnt_lsb 
- 1;
+
+        const int64_t recovery_poc = (int64_t)ph->poc + recovery_poc_cnt;
+        if (recovery_poc < INT_MIN || recovery_poc > INT_MAX) {
+            av_log(s->avctx, AV_LOG_ERROR, "Recovery point POC out of range: 
%"PRId64".\n", recovery_poc);
+            return AVERROR_INVALIDDATA;
+        }
+
+        if (recovery_poc_cnt > max_recovery_poc_cnt) {
+            const int strict = s->avctx->strict_std_compliance >= 
FF_COMPLIANCE_STRICT;
+            av_log(s->avctx, strict ? AV_LOG_ERROR : AV_LOG_WARNING,
+                   "ph_recovery_poc_cnt out of range: %"PRIu32
+                   ", expected [0, %"PRIu32"].\n", recovery_poc_cnt, 
max_recovery_poc_cnt);
+            if (strict)
+                return AVERROR_INVALIDDATA;
+        }
+
+        if (s->no_output_before_recovery_flag)
+            s->gdr_recovery_point_poc = recovery_poc;
+    }
+
     if (s->no_output_before_recovery_flag) {
-        if (IS_GDR(s))
-            s->gdr_recovery_point_poc = ph->poc + ph->r->ph_recovery_poc_cnt;
         if (!GDR_IS_RECOVERED(s) && s->gdr_recovery_point_poc <= ph->poc)
             GDR_SET_RECOVERED(s);
     }
+
+    return 0;
 }
 
 int ff_vvc_decode_frame_ps(struct VVCFrameContext *fc, struct VVCContext *s)
@@ -1071,8 +1097,10 @@ int ff_vvc_decode_frame_ps(struct VVCFrameContext *fc, 
struct VVCContext *s)
         return ret;
 
     ret = decode_frame_ps(fps, ps, sc, s->poc_tid0, is_clvss, s);
-    decode_recovery_poc(s, &fps->ph);
-    return ret;
+    if (ret < 0)
+        return ret;
+
+    return decode_recovery_poc(s, fps);
 }
 
 void ff_vvc_frame_ps_free(VVCFrameParamSets *fps)

-- 
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