[FFmpeg-devel,02/20] hevc: Improve stream constraint values in common header

Submitted by Mark Thompson on Sept. 12, 2017, 11:43 p.m.

Details

Message ID 20170912234410.14093-3-sw@jkqxz.net
State New
Headers show

Commit Message

Mark Thompson Sept. 12, 2017, 11:43 p.m.
Add comments to describe the sources of the constraint values expressed here,
and add some more related values which will be used in following patches.

Fix the incorrect values for SPS and PPS count (they are not the same as those
used for H.264), and remove HEVC_MAX_CU_SIZE because it is not used anywhere.

(cherry picked from commit b88da98b34809dedf8882d43ed543632ed233538)
---
 libavcodec/hevc.h    | 65 ++++++++++++++++++++++++++++++++++++++++++----------
 libavcodec/hevc_ps.c |  2 +-
 libavcodec/hevc_ps.h |  6 ++---
 libavformat/hevc.c   |  6 ++---
 4 files changed, 60 insertions(+), 19 deletions(-)

Patch hide | download patch | download mbox

diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h
index f0fb919a7f..2f20db8285 100644
--- a/libavcodec/hevc.h
+++ b/libavcodec/hevc.h
@@ -74,19 +74,60 @@  enum HEVCSliceType {
     HEVC_SLICE_I = 2,
 };
 
-/**
- * 7.4.2.1
- */
-#define HEVC_MAX_SUB_LAYERS 7
-#define HEVC_MAX_VPS_COUNT 16
-#define HEVC_MAX_SPS_COUNT 32
-#define HEVC_MAX_PPS_COUNT 256
-#define HEVC_MAX_SHORT_TERM_RPS_COUNT 64
-#define HEVC_MAX_CU_SIZE 128
+enum {
+    // 7.4.3.1: vps_max_layers_minus1 is in [0, 62].
+    HEVC_MAX_LAYERS     = 63,
+    // 7.4.3.1: vps_max_sub_layers_minus1 is in [0, 6].
+    HEVC_MAX_SUB_LAYERS = 7,
+    // 7.4.3.1: vps_num_layer_sets_minus1 is in [0, 1023].
+    HEVC_MAX_LAYER_SETS = 1024,
+
+    // 7.4.2.1: vps_video_parameter_set_id is u(4).
+    HEVC_MAX_VPS_COUNT = 16,
+    // 7.4.3.2.1: sps_seq_parameter_set_id is in [0, 15].
+    HEVC_MAX_SPS_COUNT = 16,
+    // 7.4.3.3.1: pps_pic_parameter_set_id is in [0, 63].
+    HEVC_MAX_PPS_COUNT = 64,
+
+    // A.4.2: MaxDpbSize is bounded above by 16.
+    HEVC_MAX_DPB_SIZE = 16,
+    // 7.4.3.1: vps_max_dec_pic_buffering_minus1[i] is in [0, MaxDpbSize - 1].
+    HEVC_MAX_REFS     = HEVC_MAX_DPB_SIZE,
+
+    // 7.4.3.2.1: num_short_term_ref_pic_sets is in [0, 64].
+    HEVC_MAX_SHORT_TERM_REF_PIC_SETS = 64,
+    // 7.4.3.2.1: num_long_term_ref_pics_sps is in [0, 32].
+    HEVC_MAX_LONG_TERM_REF_PICS      = 32,
 
-#define HEVC_MAX_REFS 16
-#define HEVC_MAX_DPB_SIZE 16 // A.4.1
+    // A.3: all profiles require that CtbLog2SizeY is in [4, 6].
+    HEVC_MIN_LOG2_CTB_SIZE = 4,
+    HEVC_MAX_LOG2_CTB_SIZE = 6,
+
+    // E.3.2: cpb_cnt_minus1[i] is in [0, 31].
+    HEVC_MAX_CPB_CNT = 32,
+
+    // A.4.1: in table A.6 the highest level allows a MaxLumaPs of 35 651 584.
+    HEVC_MAX_LUMA_PS = 35651584,
+    // A.4.1: pic_width_in_luma_samples and pic_height_in_luma_samples are
+    // constrained to be not greater than sqrt(MaxLumaPs * 8).  Hence height/
+    // width are bounded above by sqrt(8 * 35651584) = 16888.2 samples.
+    HEVC_MAX_WIDTH  = 16888,
+    HEVC_MAX_HEIGHT = 16888,
+
+    // A.4.1: table A.6 allows at most 22 tile rows for any level.
+    HEVC_MAX_TILE_ROWS    = 22,
+    // A.4.1: table A.6 allows at most 20 tile columns for any level.
+    HEVC_MAX_TILE_COLUMNS = 20,
+
+    // 7.4.7.1: in the worst case (tiles_enabled_flag and
+    // entropy_coding_sync_enabled_flag are both set), entry points can be
+    // placed at the beginning of every Ctb row in every tile, giving an
+    // upper bound of (num_tile_columns_minus1 + 1) * PicHeightInCtbsY - 1.
+    // Only a stream with very high resolution and perverse parameters could
+    // get near that, though, so set a lower limit here with the maximum
+    // possible value for 4K video (at most 135 16x16 Ctb rows).
+    HEVC_MAX_ENTRY_POINT_OFFSETS = HEVC_MAX_TILE_COLUMNS * 135,
+};
 
-#define HEVC_MAX_LOG2_CTB_SIZE 6
 
 #endif /* AVCODEC_HEVC_H */
diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c
index 500fee03d8..b2b6f343eb 100644
--- a/libavcodec/hevc_ps.c
+++ b/libavcodec/hevc_ps.c
@@ -1060,7 +1060,7 @@  int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id,
     }
 
     sps->nb_st_rps = get_ue_golomb_long(gb);
-    if (sps->nb_st_rps > HEVC_MAX_SHORT_TERM_RPS_COUNT) {
+    if (sps->nb_st_rps > HEVC_MAX_SHORT_TERM_REF_PIC_SETS) {
         av_log(avctx, AV_LOG_ERROR, "Too many short term RPS: %d.\n",
                sps->nb_st_rps);
         return AVERROR_INVALIDDATA;
diff --git a/libavcodec/hevc_ps.h b/libavcodec/hevc_ps.h
index 4e6c3bc849..2507c34098 100644
--- a/libavcodec/hevc_ps.h
+++ b/libavcodec/hevc_ps.h
@@ -252,14 +252,14 @@  typedef struct HEVCSPS {
     ScalingList scaling_list;
 
     unsigned int nb_st_rps;
-    ShortTermRPS st_rps[HEVC_MAX_SHORT_TERM_RPS_COUNT];
+    ShortTermRPS st_rps[HEVC_MAX_SHORT_TERM_REF_PIC_SETS];
 
     uint8_t amp_enabled_flag;
     uint8_t sao_enabled;
 
     uint8_t long_term_ref_pics_present_flag;
-    uint16_t lt_ref_pic_poc_lsb_sps[32];
-    uint8_t used_by_curr_pic_lt_sps_flag[32];
+    uint16_t lt_ref_pic_poc_lsb_sps[HEVC_MAX_LONG_TERM_REF_PICS];
+    uint8_t used_by_curr_pic_lt_sps_flag[HEVC_MAX_LONG_TERM_REF_PICS];
     uint8_t num_long_term_ref_pics_sps;
 
     struct {
diff --git a/libavformat/hevc.c b/libavformat/hevc.c
index 1a2d6cdd2b..e45d2c08d2 100644
--- a/libavformat/hevc.c
+++ b/libavformat/hevc.c
@@ -417,7 +417,7 @@  static void skip_scaling_list_data(GetBitContext *gb)
 
 static int parse_rps(GetBitContext *gb, unsigned int rps_idx,
                      unsigned int num_rps,
-                     unsigned int num_delta_pocs[HEVC_MAX_SHORT_TERM_RPS_COUNT])
+                     unsigned int num_delta_pocs[HEVC_MAX_SHORT_TERM_REF_PIC_SETS])
 {
     unsigned int i;
 
@@ -486,7 +486,7 @@  static int hvcc_parse_sps(GetBitContext *gb,
                           HEVCDecoderConfigurationRecord *hvcc)
 {
     unsigned int i, sps_max_sub_layers_minus1, log2_max_pic_order_cnt_lsb_minus4;
-    unsigned int num_short_term_ref_pic_sets, num_delta_pocs[HEVC_MAX_SHORT_TERM_RPS_COUNT];
+    unsigned int num_short_term_ref_pic_sets, num_delta_pocs[HEVC_MAX_SHORT_TERM_REF_PIC_SETS];
 
     skip_bits(gb, 4); // sps_video_parameter_set_id
 
@@ -556,7 +556,7 @@  static int hvcc_parse_sps(GetBitContext *gb,
     }
 
     num_short_term_ref_pic_sets = get_ue_golomb_long(gb);
-    if (num_short_term_ref_pic_sets > HEVC_MAX_SHORT_TERM_RPS_COUNT)
+    if (num_short_term_ref_pic_sets > HEVC_MAX_SHORT_TERM_REF_PIC_SETS)
         return AVERROR_INVALIDDATA;
 
     for (i = 0; i < num_short_term_ref_pic_sets; i++) {