ref: 293734b755e5e9167e33480f419c348d217585da
parent: 5b558592f564be258671f73175d5a4f987cf321c
parent: c3a6943c16f701f5f344692e1a1af3a90f23d791
author: Hui Su <huisu@google.com>
date: Thu Sep 14 17:02:38 EDT 2017
Merge "VP9 level targeting: add a new AUTO mode"
--- a/test/level_test.cc
+++ b/test/level_test.cc
@@ -130,7 +130,7 @@
if (level == 10 || level == 11 || level == 20 || level == 21 ||
level == 30 || level == 31 || level == 40 || level == 41 ||
level == 50 || level == 51 || level == 52 || level == 60 ||
- level == 61 || level == 62 || level == 0 || level == 255)
+ level == 61 || level == 62 || level == 0 || level == 1 || level == 255)
EXPECT_EQ(VPX_CODEC_OK,
vpx_codec_control(&enc, VP9E_SET_TARGET_LEVEL, level));
else
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -1209,6 +1209,14 @@
clamp(cpi->oxcf.tile_columns, min_log2_tile_cols, max_log2_tile_cols);
cm->log2_tile_rows = cpi->oxcf.tile_rows;
}
+
+ 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);
+ if (cm->log2_tile_cols > level_tile_cols) {
+ cm->log2_tile_cols = VPXMAX(level_tile_cols, min_log2_tile_cols);
+ }
+ }
}
static void update_frame_size(VP9_COMP *cpi) {
--- a/vp9/encoder/vp9_encoder.h
+++ b/vp9/encoder/vp9_encoder.h
@@ -360,6 +360,7 @@
typedef enum {
LEVEL_UNKNOWN = 0,
+ LEVEL_AUTO = 1,
LEVEL_1 = 10,
LEVEL_1_1 = 11,
LEVEL_2 = 20,
@@ -911,6 +912,18 @@
if (level == vp9_level_defs[i].level) return i;
}
return -1;
+}
+
+// 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) {
+ int i;
+ for (i = LEVEL_1; i < LEVEL_MAX; ++i) {
+ if (vp9_level_defs[i].max_luma_picture_size > pic_size) {
+ return get_msb(vp9_level_defs[i].max_col_tiles);
+ }
+ }
+ return INT_MAX;
}
VP9_LEVEL vp9_get_level(const Vp9LevelSpec *const level_spec);
--- a/vp9/encoder/vp9_ethread.c
+++ b/vp9/encoder/vp9_ethread.c
@@ -64,6 +64,13 @@
vp9_get_tile_n_bits(mi_cols, &min_log2_tile_cols, &max_log2_tile_cols);
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);
+ if (log2_tile_cols > level_tile_cols) {
+ log2_tile_cols = VPXMAX(level_tile_cols, min_log2_tile_cols);
+ }
+ }
return (1 << log2_tile_cols);
}
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -1851,6 +1851,23 @@
// Clamp min to max
rc->min_gf_interval = VPXMIN(rc->min_gf_interval, rc->max_gf_interval);
+
+ if (oxcf->target_level == LEVEL_AUTO) {
+ const uint32_t pic_size = 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 (rc->min_gf_interval <=
+ (int)vp9_level_defs[i].min_altref_distance) {
+ rc->min_gf_interval =
+ (int)vp9_level_defs[i].min_altref_distance + 1;
+ rc->max_gf_interval =
+ VPXMAX(rc->max_gf_interval, rc->min_gf_interval);
+ }
+ break;
+ }
+ }
+ }
}
}
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -213,7 +213,7 @@
level != LEVEL_4 && level != LEVEL_4_1 && level != LEVEL_5 &&
level != LEVEL_5_1 && level != LEVEL_5_2 && level != LEVEL_6 &&
level != LEVEL_6_1 && level != LEVEL_6_2 && level != LEVEL_UNKNOWN &&
- level != LEVEL_MAX)
+ level != LEVEL_AUTO && level != LEVEL_MAX)
ERROR("target_level is invalid");
}
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -468,8 +468,14 @@
static const arg_def_t target_level = ARG_DEF(
NULL, "target-level", 1,
- "Target level (255: off (default); 0: only keep level stats; 10: level 1.0;"
- " 11: level 1.1; ... 62: level 6.2)");
+ "Target level\n"
+ " 255: off (default)\n"
+ " 0: only keep level stats\n"
+ " 1: adaptively set alt-ref "
+ "distance and column tile limit based on picture size, and keep"
+ " level stats\n"
+ " 10: level 1.0 11: level 1.1 "
+ "... 62: level 6.2");
static const arg_def_t row_mt =
ARG_DEF(NULL, "row-mt", 1,