Add check for product of tile size and header rate
BUG=aomedia:2332
Change-Id: I4d4f0e3cfa438a5d9849f3210c4cd294cf5eb45e
diff --git a/av1/common/enums.h b/av1/common/enums.h
index fbacc89..b9767eb 100644
--- a/av1/common/enums.h
+++ b/av1/common/enums.h
@@ -625,6 +625,25 @@
RESTORE_TYPES = 4,
} UENUM1BYTE(RestorationType);
+// Picture prediction structures (0-12 are predefined) in scalability metadata.
+enum {
+ SCALABILITY_L1T2 = 0,
+ SCALABILITY_L1T3 = 1,
+ SCALABILITY_L2T1 = 2,
+ SCALABILITY_L2T2 = 3,
+ SCALABILITY_L2T3 = 4,
+ SCALABILITY_S2T1 = 5,
+ SCALABILITY_S2T2 = 6,
+ SCALABILITY_S2T3 = 7,
+ SCALABILITY_L2T1h = 8,
+ SCALABILITY_L2T2h = 9,
+ SCALABILITY_L2T3h = 10,
+ SCALABILITY_S2T1h = 11,
+ SCALABILITY_S2T2h = 12,
+ SCALABILITY_S2T3h = 13,
+ SCALABILITY_SS = 14
+} UENUM1BYTE(SCALABILITY_STRUCTURES);
+
#define SUPERRES_SCALE_BITS 3
#define SUPERRES_SCALE_DENOMINATOR_MIN (SCALE_NUMERATOR + 1)
diff --git a/av1/decoder/obu.c b/av1/decoder/obu.c
index aaea572..f4ea4af 100644
--- a/av1/decoder/obu.c
+++ b/av1/decoder/obu.c
@@ -25,25 +25,6 @@
#include "av1/decoder/decodeframe.h"
#include "av1/decoder/obu.h"
-// Picture prediction structures (0-12 are predefined) in scalability metadata.
-enum {
- SCALABILITY_L1T2 = 0,
- SCALABILITY_L1T3 = 1,
- SCALABILITY_L2T1 = 2,
- SCALABILITY_L2T2 = 3,
- SCALABILITY_L2T3 = 4,
- SCALABILITY_S2T1 = 5,
- SCALABILITY_S2T2 = 6,
- SCALABILITY_S2T3 = 7,
- SCALABILITY_L2T1h = 8,
- SCALABILITY_L2T2h = 9,
- SCALABILITY_L2T3h = 10,
- SCALABILITY_S2T1h = 11,
- SCALABILITY_S2T2h = 12,
- SCALABILITY_S2T3h = 13,
- SCALABILITY_SS = 14
-} UENUM1BYTE(SCALABILITY_STRUCTURES);
-
aom_codec_err_t aom_get_num_layers_from_operating_point_idc(
int operating_point_idc, unsigned int *number_spatial_layers,
unsigned int *number_temporal_layers) {
diff --git a/av1/encoder/level.c b/av1/encoder/level.c
index 1668bdf..48bb20e 100644
--- a/av1/encoder/level.c
+++ b/av1/encoder/level.c
@@ -235,6 +235,7 @@
DISPLAY_RATE_TOO_HIGH,
DECODE_RATE_TOO_HIGH,
CR_TOO_SMALL,
+ TILE_SIZE_HEADER_RATE_TOO_HIGH,
TARGET_LEVEL_FAIL_IDS,
TARGET_LEVEL_OK,
@@ -258,6 +259,7 @@
"The display luma sample rate is too high.",
"The decoded luma sample rate is too high.",
"The compression ratio is too small.",
+ "The product of max tile size and header rate is too high.",
};
static double get_min_cr(const AV1LevelSpec *const level_spec, int tier,
@@ -269,6 +271,30 @@
return AOMMAX(min_cr_basis * speed_adj, 0.8);
}
+static void get_temporal_parallel_params(int scalability_mode_idc,
+ int *temporal_parallel_num,
+ int *temporal_parallel_denom) {
+ if (scalability_mode_idc < 0) {
+ *temporal_parallel_num = 1;
+ *temporal_parallel_denom = 1;
+ return;
+ }
+
+ // TODO(huisu@): handle scalability cases.
+ if (scalability_mode_idc == SCALABILITY_SS) {
+ (void)scalability_mode_idc;
+ } else {
+ (void)scalability_mode_idc;
+ }
+}
+
+#define MAX_TILE_SIZE (4096 * 2304)
+#define MIN_CROPPED_TILE_WIDTH 8
+#define MIN_CROPPED_TILE_HEIGHT 8
+#define MIN_FRAME_WIDTH 16
+#define MIN_FRAME_HEIGHT 16
+#define MAX_TILE_SIZE_HEADER_RATE_PRODUCT 588251136
+
static TARGET_LEVEL_FAIL_ID check_level_constraints(
const AV1LevelSpec *const target_level_spec,
const AV1LevelSpec *const level_spec,
@@ -323,7 +349,7 @@
break;
}
- if (level_stats->max_tile_size > 4096 * 2304) {
+ if (level_stats->max_tile_size > MAX_TILE_SIZE) {
fail_id = TILE_TOO_LARGE;
break;
}
@@ -333,22 +359,22 @@
break;
}
- if (level_stats->min_cropped_tile_width < 8) {
+ if (level_stats->min_cropped_tile_width < MIN_CROPPED_TILE_WIDTH) {
fail_id = CROPPED_TILE_WIDTH_TOO_SMALL;
break;
}
- if (level_stats->min_cropped_tile_height < 8) {
+ if (level_stats->min_cropped_tile_height < MIN_CROPPED_TILE_HEIGHT) {
fail_id = CROPPED_TILE_HEIGHT_TOO_SMALL;
break;
}
- if (level_stats->min_frame_width < 16) {
+ if (level_stats->min_frame_width < MIN_FRAME_WIDTH) {
fail_id = LUMA_PIC_H_SIZE_TOO_SMALL;
break;
}
- if (level_stats->min_frame_height < 16) {
+ if (level_stats->min_frame_height < MIN_FRAME_HEIGHT) {
fail_id = LUMA_PIC_V_SIZE_TOO_SMALL;
break;
}
@@ -362,6 +388,20 @@
fail_id = CR_TOO_SMALL;
break;
}
+
+ if (target_level_spec->level > SEQ_LEVEL_5_1) {
+ int temporal_parallel_num;
+ int temporal_parallel_denom;
+ const int scalability_mode_idc = -1;
+ get_temporal_parallel_params(scalability_mode_idc, &temporal_parallel_num,
+ &temporal_parallel_denom);
+ const int val = level_stats->max_tile_size * level_spec->max_header_rate *
+ temporal_parallel_denom / temporal_parallel_num;
+ if (val > MAX_TILE_SIZE_HEADER_RATE_PRODUCT) {
+ fail_id = TILE_SIZE_HEADER_RATE_TOO_HIGH;
+ break;
+ }
+ }
} while (0);
return fail_id;