Refactor check_level_constraints()

BUG=aomedia:2332

Change-Id: Iac018fc5e681888cf9ff0bfc09b2f110dcc5c605
diff --git a/av1/encoder/level.c b/av1/encoder/level.c
index be5099f..0527969 100644
--- a/av1/encoder/level.c
+++ b/av1/encoder/level.c
@@ -232,7 +232,8 @@
   DECODE_RATE_TOO_HIGH,
   CR_TOO_SMALL,
 
-  TARGET_LEVEL_FAIL_IDS
+  TARGET_LEVEL_FAIL_IDS,
+  TARGET_LEVEL_OK,
 } TARGET_LEVEL_FAIL_ID;
 
 static const char *level_fail_messages[TARGET_LEVEL_FAIL_IDS] = {
@@ -260,21 +261,13 @@
   return AOMMAX(min_cr_basis * speed_adj, 0.8);
 }
 
-static void check_level_constraints(AV1_COMP *cpi, int operating_point_idx,
-                                    const AV1LevelSpec *const level_spec,
-                                    const AV1LevelStats *const level_stats) {
-  const AV1_LEVEL target_seq_level_idx =
-      cpi->target_seq_level_idx[operating_point_idx];
-  if (target_seq_level_idx >= SEQ_LEVELS) return;
-  TARGET_LEVEL_FAIL_ID fail_id = TARGET_LEVEL_FAIL_IDS;
-  const AV1LevelSpec *const target_level_spec =
-      av1_level_defs + target_seq_level_idx;
-  const SequenceHeader *const seq_params = &cpi->common.seq_params;
-  const double min_cr =
-      get_min_cr(target_level_spec, seq_params->tier[operating_point_idx],
-                 seq_params->still_picture, level_spec->max_decode_rate);
-  // Check level conformance
-  // TODO(kyslov@) implement all constraints
+static TARGET_LEVEL_FAIL_ID check_level_constraints(
+    const AV1LevelSpec *const target_level_spec,
+    const AV1LevelSpec *const level_spec,
+    const AV1LevelStats *const level_stats, int tier, int is_still_picture) {
+  const double min_cr = get_min_cr(target_level_spec, tier, is_still_picture,
+                                   level_spec->max_decode_rate);
+  TARGET_LEVEL_FAIL_ID fail_id = TARGET_LEVEL_OK;
 
   do {
     if (level_spec->max_picture_size > target_level_spec->max_picture_size) {
@@ -343,15 +336,7 @@
     }
   } while (0);
 
-  if (fail_id != TARGET_LEVEL_FAIL_IDS) {
-    AV1_COMMON *const cm = &cpi->common;
-    const int target_level_major = 2 + (target_seq_level_idx >> 2);
-    const int target_level_minor = target_seq_level_idx & 3;
-    aom_internal_error(&cm->error, AOM_CODEC_ERROR,
-                       "Failed to encode to the target level %d_%d. %s",
-                       target_level_major, target_level_minor,
-                       level_fail_messages[fail_id]);
-  }
+  return fail_id;
 }
 
 static INLINE int is_in_operating_point(int operating_point,
@@ -482,7 +467,7 @@
 
 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;
+  AV1_COMMON *const cm = &cpi->common;
   const int upscaled_width = cm->superres_upscaled_width;
   const int height = cm->height;
   const int tile_cols = cm->tile_cols;
@@ -508,10 +493,10 @@
   get_tile_stats(cpi, &max_tile_size, &min_cropped_tile_width,
                  &min_cropped_tile_height, &tile_width_is_valid);
 
+  const SequenceHeader *const seq_params = &cm->seq_params;
+  const BITSTREAM_PROFILE profile = seq_params->profile;
   const int pic_size_profile_factor =
-      cm->seq_params.profile == PROFILE_0
-          ? 15
-          : (cm->seq_params.profile == PROFILE_1 ? 30 : 36);
+      profile == PROFILE_0 ? 15 : (profile == PROFILE_1 ? 30 : 36);
   const size_t frame_compressed_size = (size > 129 ? size - 128 : 1);
   const size_t frame_uncompressed_size =
       (luma_pic_size * pic_size_profile_factor) >> 3;
@@ -523,14 +508,14 @@
       (cpi->last_end_time_stamp_seen - cpi->first_time_stamp_ever) /
       (double)TICKS_PER_SEC;
 
-  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;
+  const int is_still_picture = seq_params->still_picture;
   // update level_stats
   // TODO(kyslov@) fix the implementation according to buffer model
-  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)) {
+  for (int i = 0; i < seq_params->operating_points_cnt_minus_1 + 1; ++i) {
+    if (!is_in_operating_point(seq_params->operating_point_idc[i],
+                               temporal_layer_id, spatial_layer_id)) {
       continue;
     }
 
@@ -563,7 +548,23 @@
       scan_past_frames(buffer, encoded_frames_in_last_second, level_spec);
     }
 
-    check_level_constraints(cpi, i, level_spec, level_stats);
+    // Check whether target level is met.
+    const AV1_LEVEL target_seq_level_idx = cpi->target_seq_level_idx[i];
+    if (target_seq_level_idx < SEQ_LEVELS) {
+      const AV1LevelSpec *const target_level_spec =
+          av1_level_defs + target_seq_level_idx;
+      const int tier = seq_params->tier[i];
+      const TARGET_LEVEL_FAIL_ID fail_id = check_level_constraints(
+          target_level_spec, level_spec, level_stats, tier, is_still_picture);
+      if (fail_id != TARGET_LEVEL_OK) {
+        const int target_level_major = 2 + (target_seq_level_idx >> 2);
+        const int target_level_minor = target_seq_level_idx & 3;
+        aom_internal_error(&cm->error, AOM_CODEC_ERROR,
+                           "Failed to encode to the target level %d_%d. %s",
+                           target_level_major, target_level_minor,
+                           level_fail_messages[fail_id]);
+      }
+    }
   }
 }