diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index d5afbb884..087b492ba 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -437,34 +437,37 @@ static int is_psnr_calc_enabled(VP9_COMP *cpi) { /* clang-format off */ const Vp9LevelSpec vp9_level_defs[VP9_LEVELS] = { - { LEVEL_1, 829440, 36864, 200, 400, 2, 1, 4, 8 }, - { LEVEL_1_1, 2764800, 73728, 800, 1000, 2, 1, 4, 8 }, - { LEVEL_2, 4608000, 122880, 1800, 1500, 2, 1, 4, 8 }, - { LEVEL_2_1, 9216000, 245760, 3600, 2800, 2, 2, 4, 8 }, - { LEVEL_3, 20736000, 552960, 7200, 6000, 2, 4, 4, 8 }, - { LEVEL_3_1, 36864000, 983040, 12000, 10000, 2, 4, 4, 8 }, - { LEVEL_4, 83558400, 2228224, 18000, 16000, 4, 4, 4, 8 }, - { LEVEL_4_1, 160432128, 2228224, 30000, 18000, 4, 4, 5, 6 }, - { LEVEL_5, 311951360, 8912896, 60000, 36000, 6, 8, 6, 4 }, - { LEVEL_5_1, 588251136, 8912896, 120000, 46000, 8, 8, 10, 4 }, + // sample rate size breadth bitrate cpb + { LEVEL_1, 829440, 36864, 512, 200, 400, 2, 1, 4, 8 }, + { LEVEL_1_1, 2764800, 73728, 768, 800, 1000, 2, 1, 4, 8 }, + { LEVEL_2, 4608000, 122880, 960, 1800, 1500, 2, 1, 4, 8 }, + { LEVEL_2_1, 9216000, 245760, 1344, 3600, 2800, 2, 2, 4, 8 }, + { LEVEL_3, 20736000, 552960, 2048, 7200, 6000, 2, 4, 4, 8 }, + { LEVEL_3_1, 36864000, 983040, 2752, 12000, 10000, 2, 4, 4, 8 }, + { LEVEL_4, 83558400, 2228224, 4160, 18000, 16000, 4, 4, 4, 8 }, + { LEVEL_4_1, 160432128, 2228224, 4160, 30000, 18000, 4, 4, 5, 6 }, + { LEVEL_5, 311951360, 8912896, 8384, 60000, 36000, 6, 8, 6, 4 }, + { LEVEL_5_1, 588251136, 8912896, 8384, 120000, 46000, 8, 8, 10, 4 }, // TODO(huisu): update max_cpb_size for level 5_2 ~ 6_2 when // they are finalized (currently tentative). - { LEVEL_5_2, 1176502272, 8912896, 180000, 90000, 8, 8, 10, 4 }, - { LEVEL_6, 1176502272, 35651584, 180000, 90000, 8, 16, 10, 4 }, - { LEVEL_6_1, 2353004544u, 35651584, 240000, 180000, 8, 16, 10, 4 }, - { LEVEL_6_2, 4706009088u, 35651584, 480000, 360000, 8, 16, 10, 4 }, + { LEVEL_5_2, 1176502272, 8912896, 8384, 180000, 90000, 8, 8, 10, 4 }, + { LEVEL_6, 1176502272, 35651584, 16832, 180000, 90000, 8, 16, 10, 4 }, + { LEVEL_6_1, 2353004544u, 35651584, 16832, 240000, 180000, 8, 16, 10, 4 }, + { LEVEL_6_2, 4706009088u, 35651584, 16832, 480000, 360000, 8, 16, 10, 4 }, }; /* clang-format on */ -static const char *level_fail_messages[TARGET_LEVEL_FAIL_IDS] = - { "The average bit-rate is too high.", - "The picture size is too large.", - "The luma sample rate is too large.", - "The CPB size is too large.", - "The compression ratio is too small", - "Too many column tiles are used.", - "The alt-ref distance is too small.", - "Too many reference buffers are used." }; +static const char *level_fail_messages[TARGET_LEVEL_FAIL_IDS] = { + "The average bit-rate is too high.", + "The picture size is too large.", + "The picture width/height is too large.", + "The luma sample rate is too large.", + "The CPB size is too large.", + "The compression ratio is too small", + "Too many column tiles are used.", + "The alt-ref distance is too small.", + "Too many reference buffers are used." +}; static INLINE void Scale2Ratio(VPX_SCALING mode, int *hr, int *hs) { switch (mode) { @@ -566,6 +569,8 @@ VP9_LEVEL vp9_get_level(const Vp9LevelSpec *const level_spec) { (double)this_level->max_luma_sample_rate * (1 + SAMPLE_RATE_GRACE_P) || level_spec->max_luma_picture_size > this_level->max_luma_picture_size || + level_spec->max_luma_picture_breadth > + this_level->max_luma_picture_breadth || level_spec->average_bitrate > this_level->average_bitrate || level_spec->max_cpb_size > this_level->max_cpb_size || level_spec->compression_ratio < this_level->compression_ratio || @@ -1219,8 +1224,8 @@ static void set_tile_limits(VP9_COMP *cpi) { } if (cpi->oxcf.target_level == LEVEL_AUTO) { - const uint32_t pic_size = cpi->common.width * cpi->common.height; - const int level_tile_cols = log_tile_cols_from_picsize_level(pic_size); + const int level_tile_cols = + log_tile_cols_from_picsize_level(cpi->common.width, cpi->common.height); if (cm->log2_tile_cols > level_tile_cols) { cm->log2_tile_cols = VPXMAX(level_tile_cols, min_log2_tile_cols); } @@ -4829,6 +4834,7 @@ static void update_level_info(VP9_COMP *cpi, size_t *size, int arf_src_index) { int i, idx; uint64_t luma_samples, dur_end; const uint32_t luma_pic_size = cm->width * cm->height; + const uint32_t luma_pic_breadth = VPXMAX(cm->width, cm->height); LevelConstraint *const level_constraint = &cpi->level_constraint; const int8_t level_index = level_constraint->level_index; double cpb_data_size; @@ -4932,6 +4938,11 @@ static void update_level_info(VP9_COMP *cpi, size_t *size, int arf_src_index) { level_spec->max_luma_picture_size = luma_pic_size; } + // update max_luma_picture_breadth + if (luma_pic_breadth > level_spec->max_luma_picture_breadth) { + level_spec->max_luma_picture_breadth = luma_pic_breadth; + } + // update compression_ratio level_spec->compression_ratio = (double)level_stats->total_uncompressed_size * cm->bit_depth / @@ -4952,6 +4963,15 @@ static void update_level_info(VP9_COMP *cpi, size_t *size, int arf_src_index) { level_fail_messages[LUMA_PIC_SIZE_TOO_LARGE]); } + if (level_spec->max_luma_picture_breadth > + vp9_level_defs[level_index].max_luma_picture_breadth) { + level_constraint->fail_flag |= (1 << LUMA_PIC_BREADTH_TOO_LARGE); + vpx_internal_error(&cm->error, VPX_CODEC_ERROR, + "Failed to encode to the target level %d. %s", + vp9_level_defs[level_index].level, + level_fail_messages[LUMA_PIC_BREADTH_TOO_LARGE]); + } + if ((double)level_spec->max_luma_sample_rate > (double)vp9_level_defs[level_index].max_luma_sample_rate * (1 + SAMPLE_RATE_GRACE_P)) { diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h index 303194a3b..1b3f49833 100644 --- a/vp9/encoder/vp9_encoder.h +++ b/vp9/encoder/vp9_encoder.h @@ -383,6 +383,7 @@ typedef struct { VP9_LEVEL level; uint64_t max_luma_sample_rate; uint32_t max_luma_picture_size; + uint32_t max_luma_picture_breadth; double average_bitrate; // in kilobits per second double max_cpb_size; // in kilobits double compression_ratio; @@ -422,14 +423,15 @@ typedef struct { typedef enum { BITRATE_TOO_LARGE = 0, - LUMA_PIC_SIZE_TOO_LARGE = 1, - LUMA_SAMPLE_RATE_TOO_LARGE = 2, - CPB_TOO_LARGE = 3, - COMPRESSION_RATIO_TOO_SMALL = 4, - TOO_MANY_COLUMN_TILE = 5, - ALTREF_DIST_TOO_SMALL = 6, - TOO_MANY_REF_BUFFER = 7, - TARGET_LEVEL_FAIL_IDS = 8 + LUMA_PIC_SIZE_TOO_LARGE, + LUMA_PIC_BREADTH_TOO_LARGE, + LUMA_SAMPLE_RATE_TOO_LARGE, + CPB_TOO_LARGE, + COMPRESSION_RATIO_TOO_SMALL, + TOO_MANY_COLUMN_TILE, + ALTREF_DIST_TOO_SMALL, + TOO_MANY_REF_BUFFER, + TARGET_LEVEL_FAIL_IDS } TARGET_LEVEL_FAIL_ID; typedef struct { @@ -920,10 +922,14 @@ static INLINE int get_level_index(VP9_LEVEL level) { // Return the log2 value of max column tiles corresponding to the level that // the picture size fits into. -static INLINE int log_tile_cols_from_picsize_level(uint32_t pic_size) { +static INLINE int log_tile_cols_from_picsize_level(uint32_t width, + uint32_t height) { int i; + const uint32_t pic_size = width * height; + const uint32_t pic_breadth = VPXMAX(width, height); for (i = LEVEL_1; i < LEVEL_MAX; ++i) { - if (vp9_level_defs[i].max_luma_picture_size > pic_size) { + if (vp9_level_defs[i].max_luma_picture_size >= pic_size && + vp9_level_defs[i].max_luma_picture_breadth >= pic_breadth) { return get_msb(vp9_level_defs[i].max_col_tiles); } } diff --git a/vp9/encoder/vp9_ethread.c b/vp9/encoder/vp9_ethread.c index 6c5004c6c..0bd2e2145 100644 --- a/vp9/encoder/vp9_ethread.c +++ b/vp9/encoder/vp9_ethread.c @@ -66,8 +66,8 @@ static int get_max_tile_cols(VP9_COMP *cpi) { log2_tile_cols = clamp(cpi->oxcf.tile_columns, min_log2_tile_cols, max_log2_tile_cols); if (cpi->oxcf.target_level == LEVEL_AUTO) { - const uint32_t pic_size = cpi->common.width * cpi->common.height; - const int level_tile_cols = log_tile_cols_from_picsize_level(pic_size); + const int level_tile_cols = + log_tile_cols_from_picsize_level(cpi->common.width, cpi->common.height); if (log2_tile_cols > level_tile_cols) { log2_tile_cols = VPXMAX(level_tile_cols, min_log2_tile_cols); } diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index 767ae6dd6..3f7fb1e88 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -1873,9 +1873,12 @@ void vp9_rc_set_gf_interval_range(const VP9_COMP *const cpi, if (oxcf->target_level == LEVEL_AUTO) { const uint32_t pic_size = cpi->common.width * cpi->common.height; + const uint32_t pic_breadth = + VPXMAX(cpi->common.width, cpi->common.height); int i; for (i = LEVEL_1; i < LEVEL_MAX; ++i) { - if (vp9_level_defs[i].max_luma_picture_size > pic_size) { + if (vp9_level_defs[i].max_luma_picture_size >= pic_size && + vp9_level_defs[i].max_luma_picture_breadth >= pic_breadth) { if (rc->min_gf_interval <= (int)vp9_level_defs[i].min_altref_distance) { rc->min_gf_interval =