Keep level info. for every operating point AV1 level is defined per operating point. BUG=aomedia:2332 Change-Id: I7c70a7f3c4aa387c128041f060b1dce476ad6973
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c index b53e191..9366660 100644 --- a/av1/encoder/encoder.c +++ b/av1/encoder/encoder.c
@@ -2544,9 +2544,9 @@ } static void init_level_info(AV1LevelInfo *level_info) { - av1_zero(*level_info); - - level_info->level_spec.level = SEQ_LEVEL_MAX; + memset(level_info, 0, MAX_NUM_OPERATING_POINTS * sizeof(*level_info)); + for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) + level_info[i].level_spec.level = SEQ_LEVEL_MAX; } AV1_COMP *av1_create_compressor(AV1EncoderConfig *oxcf, @@ -2610,7 +2610,7 @@ cpi->refresh_alt_ref_frame = 0; - init_level_info(&cpi->level_info); + init_level_info(cpi->level_info); cpi->b_calculate_psnr = CONFIG_INTERNAL_STATS; #if CONFIG_INTERNAL_STATS
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h index 67d6315..9729e08 100644 --- a/av1/encoder/encoder.h +++ b/av1/encoder/encoder.h
@@ -997,7 +997,7 @@ // level info and flags AV1_LEVEL target_seq_level_idx; int keep_level_stats; - AV1LevelInfo level_info; + AV1LevelInfo level_info[MAX_NUM_OPERATING_POINTS]; } AV1_COMP; typedef struct {
diff --git a/av1/encoder/level.c b/av1/encoder/level.c index abab067..fdaab76 100644 --- a/av1/encoder/level.c +++ b/av1/encoder/level.c
@@ -278,13 +278,18 @@ } } +static INLINE int is_in_operating_point(int operating_point, + int temporal_layer_id, + int spatial_layer_id) { + if (!operating_point) return 1; + + return ((operating_point >> temporal_layer_id) & 1) && + ((operating_point >> (spatial_layer_id + 8)) & 1); +} + void av1_update_level_info(AV1_COMP *cpi, size_t size, int64_t ts_start, int64_t ts_end) { const AV1_COMMON *const cm = &cpi->common; - AV1LevelInfo *const level_info = &cpi->level_info; - AV1LevelSpec *const level_spec = &level_info->level_spec; - AV1LevelStats *const level_stats = &level_info->level_stats; - const uint32_t luma_pic_size = cm->superres_upscaled_width * cm->height; const uint32_t pic_size_profile_factor = cm->seq_params.profile == PROFILE_0 @@ -296,43 +301,56 @@ const double compression_ratio = frame_uncompressed_size / (double)frame_compressed_size; + const SequenceHeader *const seq = &cm->seq_params; + const int temporal_layer_id = cm->temporal_layer_id; + const int spatial_layer_id = cm->spatial_layer_id; // update level_stats // TODO(kyslov@) fix the implementation according to buffer model - level_stats->total_compressed_size += frame_compressed_size; - if (cm->show_frame) { - level_stats->total_time_encoded = - (cpi->last_end_time_stamp_seen - cpi->first_time_stamp_ever) / - (double)TICKS_PER_SEC; + for (int i = 0; i < seq->operating_points_cnt_minus_1 + 1; ++i) { + if (!is_in_operating_point(seq->operating_point_idc[i], temporal_layer_id, + spatial_layer_id)) { + continue; + } + + AV1LevelInfo *const level_info = &cpi->level_info[i]; + AV1LevelStats *const level_stats = &level_info->level_stats; + level_stats->total_compressed_size += frame_compressed_size; + if (cm->show_frame) { + level_stats->total_time_encoded = + (cpi->last_end_time_stamp_seen - cpi->first_time_stamp_ever) / + (double)TICKS_PER_SEC; + } + + // update level_spec + // TODO(kyslov@) update all spec fields + AV1LevelSpec *const level_spec = &level_info->level_spec; + if (luma_pic_size > level_spec->max_picture_size) { + level_spec->max_picture_size = luma_pic_size; + } + + if (cm->superres_upscaled_width > (int)level_spec->max_h_size) { + level_spec->max_h_size = cm->superres_upscaled_width; + } + + if (cm->height > (int)level_spec->max_v_size) { + level_spec->max_v_size = cm->height; + } + + if (level_spec->max_tile_cols < (1 << cm->log2_tile_cols)) { + level_spec->max_tile_cols = (1 << cm->log2_tile_cols); + } + + if (level_spec->max_tiles < + (1 << cm->log2_tile_cols) * (1 << cm->log2_tile_rows)) { + level_spec->max_tiles = + (1 << cm->log2_tile_cols) * (1 << cm->log2_tile_rows); + } + + // TODO(kyslov@) These are needed for further level stat calculations + (void)compression_ratio; + (void)ts_start; + (void)ts_end; + + check_level_constraints(cpi, level_spec); } - - // update level_spec - // TODO(kyslov@) update all spec fields - if (luma_pic_size > level_spec->max_picture_size) { - level_spec->max_picture_size = luma_pic_size; - } - - if (cm->superres_upscaled_width > (int)level_spec->max_h_size) { - level_spec->max_h_size = cm->superres_upscaled_width; - } - - if (cm->height > (int)level_spec->max_v_size) { - level_spec->max_v_size = cm->height; - } - - if (level_spec->max_tile_cols < (1 << cm->log2_tile_cols)) { - level_spec->max_tile_cols = (1 << cm->log2_tile_cols); - } - - if (level_spec->max_tiles < - (1 << cm->log2_tile_cols) * (1 << cm->log2_tile_rows)) { - level_spec->max_tiles = - (1 << cm->log2_tile_cols) * (1 << cm->log2_tile_rows); - } - - // TODO(kyslov@) These are needed for further level stat calculations - (void)compression_ratio; - (void)ts_start; - (void)ts_end; - - check_level_constraints(cpi, level_spec); }