[FFmpeg-devel] [PATCH] lavc/vvc: Validate explicit subpic locations

Frank Plowman post at frankplowman.com
Sat Aug 24 12:28:07 EEST 2024


Implement the missing requirements from H.266 (V3) p. 106 on the width
and height of subpictures whose dimensions are provided explicitly.

Signed-off-by: Frank Plowman <post at frankplowman.com>
---
 libavcodec/cbs_h266_syntax_template.c | 35 +++++++++++++++++++++------
 1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/libavcodec/cbs_h266_syntax_template.c b/libavcodec/cbs_h266_syntax_template.c
index 9c37996947..6e5ff55e20 100644
--- a/libavcodec/cbs_h266_syntax_template.c
+++ b/libavcodec/cbs_h266_syntax_template.c
@@ -1061,7 +1061,7 @@ static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw,
     unsigned int ctb_log2_size_y, min_cb_log2_size_y,
                  min_qt_log2_size_intra_y, min_qt_log2_size_inter_y,
                  ctb_size_y, max_num_merge_cand, tmp_width_val, tmp_height_val;
-    uint8_t qp_bd_offset;
+    uint8_t qp_bd_offset, sub_width_c, sub_height_c;
 
     static const uint8_t h266_sub_width_c[] = {
         1, 2, 2, 1
@@ -1089,6 +1089,9 @@ static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw,
 
     u(3, sps_max_sublayers_minus1, 0, VVC_MAX_SUBLAYERS - 1);
     u(2, sps_chroma_format_idc, 0, 3);
+    sub_width_c = h266_sub_width_c[current->sps_chroma_format_idc];
+    sub_height_c = h266_sub_height_c[current->sps_chroma_format_idc];
+
     u(2, sps_log2_ctu_size_minus5, 0, 3);
     ctb_log2_size_y = current->sps_log2_ctu_size_minus5 + 5;
     ctb_size_y = 1 << ctb_log2_size_y;
@@ -1110,8 +1113,6 @@ static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw,
 
     flag(sps_conformance_window_flag);
     if (current->sps_conformance_window_flag) {
-        uint8_t sub_width_c = h266_sub_width_c[current->sps_chroma_format_idc];
-        uint8_t sub_height_c = h266_sub_height_c[current->sps_chroma_format_idc];
         uint16_t width = current->sps_pic_width_max_in_luma_samples / sub_width_c;
         uint16_t height = current->sps_pic_height_max_in_luma_samples / sub_height_c;
         ue(sps_conf_win_left_offset, 0, width);
@@ -1161,18 +1162,33 @@ static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw,
             for (i = 1; i <= current->sps_num_subpics_minus1; i++) {
                 if (!current->sps_subpic_same_size_flag) {
                     if (current->sps_pic_width_max_in_luma_samples > ctb_size_y)
-                        ubs(wlen, sps_subpic_ctu_top_left_x[i], 1, i);
+                        us(wlen, sps_subpic_ctu_top_left_x[i], 0,
+                           (current->sps_pic_width_max_in_luma_samples
+                              - current->sps_conf_win_right_offset * sub_width_c
+                              + ctb_size_y - 1)
+                           / ctb_size_y - 1,
+                           1, i);
                     else
                         infer(sps_subpic_ctu_top_left_x[i], 0);
                     if (current->sps_pic_height_max_in_luma_samples >
                         ctb_size_y)
-                        ubs(hlen, sps_subpic_ctu_top_left_y[i], 1, i);
+                        us(hlen, sps_subpic_ctu_top_left_y[i], 0,
+                           (current->sps_pic_height_max_in_luma_samples
+                              - current->sps_conf_win_bottom_offset * sub_height_c
+                              + ctb_size_y - 1)
+                           / ctb_size_y - 1,
+                           1, i);
                     else
                         infer(sps_subpic_ctu_top_left_y[i], 0);
                     if (i < current->sps_num_subpics_minus1 &&
                         current->sps_pic_width_max_in_luma_samples >
                         ctb_size_y) {
-                        ubs(wlen, sps_subpic_width_minus1[i], 1, i);
+                        us(wlen, sps_subpic_width_minus1[i], 0,
+                           (current->sps_conf_win_left_offset * sub_width_c
+                              + ctb_size_y - 1)
+                           / ctb_size_y
+                           - current->sps_subpic_ctu_top_left_x[i] - 2,
+                           1, i);
                     } else {
                         infer(sps_subpic_width_minus1[i],
                               tmp_width_val -
@@ -1181,7 +1197,12 @@ static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw,
                     if (i < current->sps_num_subpics_minus1 &&
                         current->sps_pic_height_max_in_luma_samples >
                         ctb_size_y) {
-                        ubs(hlen, sps_subpic_height_minus1[i], 1, i);
+                        us(hlen, sps_subpic_height_minus1[i], 0,
+                           (current->sps_conf_win_top_offset * sub_height_c
+                              + ctb_size_y - 1)
+                           / ctb_size_y
+                           - current->sps_subpic_ctu_top_left_y[i] - 2,
+                           1, i);
                     } else {
                         infer(sps_subpic_height_minus1[i],
                               tmp_height_val -
-- 
2.46.0



More information about the ffmpeg-devel mailing list