/*
 *  Copyright (c) 2023 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "common_video/h265/h265_sps_parser.h"

#include <algorithm>
#include <memory>
#include <vector>

#include "common_video/h265/h265_common.h"
#include "rtc_base/bit_buffer.h"
#include "rtc_base/logging.h"

#define IN_RANGE_OR_RETURN_NULL(val, min, max)                                \
  do {                                                                        \
    if (!reader.Ok() || (val) < (min) || (val) > (max)) {                     \
      RTC_LOG(LS_WARNING) << "Error in stream: invalid value, expected " #val \
                             " to be"                                         \
                          << " in range [" << (min) << ":" << (max) << "]"    \
                          << " found " << (val) << " instead";                \
      return absl::nullopt;                                                   \
    }                                                                         \
  } while (0)

#define IN_RANGE_OR_RETURN_FALSE(val, min, max)                               \
  do {                                                                        \
    if (!reader.Ok() || (val) < (min) || (val) > (max)) {                     \
      RTC_LOG(LS_WARNING) << "Error in stream: invalid value, expected " #val \
                             " to be"                                         \
                          << " in range [" << (min) << ":" << (max) << "]"    \
                          << " found " << (val) << " instead";                \
      return false;                                                           \
    }                                                                         \
  } while (0)

#define TRUE_OR_RETURN(a)                                                \
  do {                                                                   \
    if (!reader.Ok() || !(a)) {                                          \
      RTC_LOG(LS_WARNING) << "Error in stream: invalid value, expected " \
                          << #a;                                         \
      return absl::nullopt;                                              \
    }                                                                    \
  } while (0)

namespace {
using OptionalSps = absl::optional<webrtc::H265SpsParser::SpsState>;
using OptionalShortTermRefPicSet =
    absl::optional<webrtc::H265SpsParser::ShortTermRefPicSet>;
using OptionalProfileTierLevel =
    absl::optional<webrtc::H265SpsParser::ProfileTierLevel>;

constexpr int kMaxNumSizeIds = 4;
constexpr int kMaxNumMatrixIds = 6;
constexpr int kMaxNumCoefs = 64;
}  // namespace

namespace webrtc {

H265SpsParser::ShortTermRefPicSet::ShortTermRefPicSet() = default;

H265SpsParser::ProfileTierLevel::ProfileTierLevel() = default;

int H265SpsParser::GetMaxLumaPs(int general_level_idc) {
  // From Table A.8 - General tier and level limits.
  // |general_level_idc| is 30x the actual level.
  if (general_level_idc <= 30)  // level 1
    return 36864;
  if (general_level_idc <= 60)  // level 2
    return 122880;
  if (general_level_idc <= 63)  // level 2.1
    return 245760;
  if (general_level_idc <= 90)  // level 3
    return 552960;
  if (general_level_idc <= 93)  // level 3.1
    return 983040;
  if (general_level_idc <= 123)  // level 4, 4.1
    return 2228224;
  if (general_level_idc <= 156)  // level 5, 5.1, 5.2
    return 8912896;
  // level 6, 6.1, 6.2 - beyond that there's no actual limit.
  return 35651584;
}

size_t H265SpsParser::GetDpbMaxPicBuf(int general_profile_idc) {
  // From A.4.2 - Profile-specific level limits for the video profiles.
  // If sps_curr_pic_ref_enabled_flag is required to be zero, than this is 6
  // otherwise it is 7.
  return (general_profile_idc >= kProfileIdcMain &&
          general_profile_idc <= kProfileIdcHighThroughput)
             ? 6
             : 7;
}

// General note: this is based off the 08/2021 version of the H.265 standard.
// You can find it on this page:
// http://www.itu.int/rec/T-REC-H.265

// Unpack RBSP and parse SPS state from the supplied buffer.
absl::optional<H265SpsParser::SpsState> H265SpsParser::ParseSps(
    rtc::ArrayView<const uint8_t> data) {
  return ParseSpsInternal(H265::ParseRbsp(data));
}

bool H265SpsParser::ParseScalingListData(BitstreamReader& reader) {
  int32_t scaling_list_dc_coef_minus8[kMaxNumSizeIds][kMaxNumMatrixIds] = {};
  for (int size_id = 0; size_id < kMaxNumSizeIds; size_id++) {
    for (int matrix_id = 0; matrix_id < kMaxNumMatrixIds;
         matrix_id += (size_id == 3) ? 3 : 1) {
      // scaling_list_pred_mode_flag: u(1)
      bool scaling_list_pred_mode_flag = reader.Read<bool>();
      if (!scaling_list_pred_mode_flag) {
        // scaling_list_pred_matrix_id_delta: ue(v)
        int scaling_list_pred_matrix_id_delta = reader.ReadExponentialGolomb();
        if (size_id <= 2) {
          IN_RANGE_OR_RETURN_FALSE(scaling_list_pred_matrix_id_delta, 0,
                                   matrix_id);
        } else {  // size_id == 3
          IN_RANGE_OR_RETURN_FALSE(scaling_list_pred_matrix_id_delta, 0,
                                   matrix_id / 3);
        }
      } else {
        uint32_t coef_num = std::min(kMaxNumCoefs, 1 << (4 + (size_id << 1)));
        if (size_id > 1) {
          // scaling_list_dc_coef_minus8: se(v)
          scaling_list_dc_coef_minus8[size_id - 2][matrix_id] =
              reader.ReadSignedExponentialGolomb();
          IN_RANGE_OR_RETURN_FALSE(
              scaling_list_dc_coef_minus8[size_id - 2][matrix_id], -7, 247);
        }
        for (uint32_t i = 0; i < coef_num; i++) {
          // scaling_list_delta_coef: se(v)
          int32_t scaling_list_delta_coef =
              reader.ReadSignedExponentialGolomb();
          IN_RANGE_OR_RETURN_FALSE(scaling_list_delta_coef, -128, 127);
        }
      }
    }
  }
  return reader.Ok();
}

absl::optional<H265SpsParser::ShortTermRefPicSet>
H265SpsParser::ParseShortTermRefPicSet(
    uint32_t st_rps_idx,
    uint32_t num_short_term_ref_pic_sets,
    const std::vector<H265SpsParser::ShortTermRefPicSet>&
        short_term_ref_pic_set,
    uint32_t sps_max_dec_pic_buffering_minus1,
    BitstreamReader& reader) {
  H265SpsParser::ShortTermRefPicSet st_ref_pic_set;

  bool inter_ref_pic_set_prediction_flag = false;
  if (st_rps_idx != 0) {
    // inter_ref_pic_set_prediction_flag: u(1)
    inter_ref_pic_set_prediction_flag = reader.Read<bool>();
  }

  if (inter_ref_pic_set_prediction_flag) {
    uint32_t delta_idx_minus1 = 0;
    if (st_rps_idx == num_short_term_ref_pic_sets) {
      // delta_idx_minus1: ue(v)
      delta_idx_minus1 = reader.ReadExponentialGolomb();
      IN_RANGE_OR_RETURN_NULL(delta_idx_minus1, 0, st_rps_idx - 1);
    }
    // delta_rps_sign: u(1)
    int delta_rps_sign = reader.ReadBits(1);
    // abs_delta_rps_minus1: ue(v)
    int abs_delta_rps_minus1 = reader.ReadExponentialGolomb();
    IN_RANGE_OR_RETURN_NULL(abs_delta_rps_minus1, 0, 0x7FFF);
    int delta_rps = (1 - 2 * delta_rps_sign) * (abs_delta_rps_minus1 + 1);
    uint32_t ref_rps_idx = st_rps_idx - (delta_idx_minus1 + 1);
    uint32_t num_delta_pocs =
        short_term_ref_pic_set[ref_rps_idx].num_delta_pocs;
    IN_RANGE_OR_RETURN_NULL(num_delta_pocs, 0, kMaxShortTermRefPicSets);
    const ShortTermRefPicSet& ref_set = short_term_ref_pic_set[ref_rps_idx];
    bool used_by_curr_pic_flag[kMaxShortTermRefPicSets] = {};
    bool use_delta_flag[kMaxShortTermRefPicSets] = {};
    // 7.4.8 - use_delta_flag defaults to 1 if not present.
    std::fill_n(use_delta_flag, kMaxShortTermRefPicSets, true);

    for (uint32_t j = 0; j <= num_delta_pocs; j++) {
      // used_by_curr_pic_flag: u(1)
      used_by_curr_pic_flag[j] = reader.Read<bool>();
      if (!used_by_curr_pic_flag[j]) {
        // use_delta_flag: u(1)
        use_delta_flag[j] = reader.Read<bool>();
      }
    }

    // Calculate delta_poc_s{0,1}, used_by_curr_pic_s{0,1}, num_negative_pics
    // and num_positive_pics.
    // Equation 7-61
    int i = 0;
    IN_RANGE_OR_RETURN_NULL(
        ref_set.num_negative_pics + ref_set.num_positive_pics, 0,
        kMaxShortTermRefPicSets);
    for (int j = ref_set.num_positive_pics - 1; j >= 0; --j) {
      int d_poc = ref_set.delta_poc_s1[j] + delta_rps;
      if (d_poc < 0 && use_delta_flag[ref_set.num_negative_pics + j]) {
        st_ref_pic_set.delta_poc_s0[i] = d_poc;
        st_ref_pic_set.used_by_curr_pic_s0[i++] =
            used_by_curr_pic_flag[ref_set.num_negative_pics + j];
      }
    }
    if (delta_rps < 0 && use_delta_flag[ref_set.num_delta_pocs]) {
      st_ref_pic_set.delta_poc_s0[i] = delta_rps;
      st_ref_pic_set.used_by_curr_pic_s0[i++] =
          used_by_curr_pic_flag[ref_set.num_delta_pocs];
    }
    for (uint32_t j = 0; j < ref_set.num_negative_pics; ++j) {
      int d_poc = ref_set.delta_poc_s0[j] + delta_rps;
      if (d_poc < 0 && use_delta_flag[j]) {
        st_ref_pic_set.delta_poc_s0[i] = d_poc;
        st_ref_pic_set.used_by_curr_pic_s0[i++] = used_by_curr_pic_flag[j];
      }
    }
    st_ref_pic_set.num_negative_pics = i;
    // Equation 7-62
    i = 0;
    for (int j = ref_set.num_negative_pics - 1; j >= 0; --j) {
      int d_poc = ref_set.delta_poc_s0[j] + delta_rps;
      if (d_poc > 0 && use_delta_flag[j]) {
        st_ref_pic_set.delta_poc_s1[i] = d_poc;
        st_ref_pic_set.used_by_curr_pic_s1[i++] = used_by_curr_pic_flag[j];
      }
    }
    if (delta_rps > 0 && use_delta_flag[ref_set.num_delta_pocs]) {
      st_ref_pic_set.delta_poc_s1[i] = delta_rps;
      st_ref_pic_set.used_by_curr_pic_s1[i++] =
          used_by_curr_pic_flag[ref_set.num_delta_pocs];
    }
    for (uint32_t j = 0; j < ref_set.num_positive_pics; ++j) {
      int d_poc = ref_set.delta_poc_s1[j] + delta_rps;
      if (d_poc > 0 && use_delta_flag[ref_set.num_negative_pics + j]) {
        st_ref_pic_set.delta_poc_s1[i] = d_poc;
        st_ref_pic_set.used_by_curr_pic_s1[i++] =
            used_by_curr_pic_flag[ref_set.num_negative_pics + j];
      }
    }
    st_ref_pic_set.num_positive_pics = i;
    IN_RANGE_OR_RETURN_NULL(st_ref_pic_set.num_negative_pics, 0,
                            sps_max_dec_pic_buffering_minus1);
    IN_RANGE_OR_RETURN_NULL(
        st_ref_pic_set.num_positive_pics, 0,
        sps_max_dec_pic_buffering_minus1 - st_ref_pic_set.num_negative_pics);

  } else {
    // num_negative_pics: ue(v)
    st_ref_pic_set.num_negative_pics = reader.ReadExponentialGolomb();
    // num_positive_pics: ue(v)
    st_ref_pic_set.num_positive_pics = reader.ReadExponentialGolomb();
    IN_RANGE_OR_RETURN_NULL(st_ref_pic_set.num_negative_pics, 0,
                            sps_max_dec_pic_buffering_minus1);
    IN_RANGE_OR_RETURN_NULL(
        st_ref_pic_set.num_positive_pics, 0,
        sps_max_dec_pic_buffering_minus1 - st_ref_pic_set.num_negative_pics);

    for (uint32_t i = 0; i < st_ref_pic_set.num_negative_pics; i++) {
      // delta_poc_s0_minus1: ue(v)
      int delta_poc_s0_minus1 = 0;
      delta_poc_s0_minus1 = reader.ReadExponentialGolomb();
      IN_RANGE_OR_RETURN_NULL(delta_poc_s0_minus1, 0, 0x7FFF);
      if (i == 0) {
        st_ref_pic_set.delta_poc_s0[i] = -(delta_poc_s0_minus1 + 1);
      } else {
        st_ref_pic_set.delta_poc_s0[i] =
            st_ref_pic_set.delta_poc_s0[i - 1] - (delta_poc_s0_minus1 + 1);
      }
      // used_by_curr_pic_s0_flag: u(1)
      st_ref_pic_set.used_by_curr_pic_s0[i] = reader.Read<bool>();
    }

    for (uint32_t i = 0; i < st_ref_pic_set.num_positive_pics; i++) {
      // delta_poc_s1_minus1: ue(v)
      int delta_poc_s1_minus1 = 0;
      delta_poc_s1_minus1 = reader.ReadExponentialGolomb();
      IN_RANGE_OR_RETURN_NULL(delta_poc_s1_minus1, 0, 0x7FFF);
      if (i == 0) {
        st_ref_pic_set.delta_poc_s1[i] = delta_poc_s1_minus1 + 1;
      } else {
        st_ref_pic_set.delta_poc_s1[i] =
            st_ref_pic_set.delta_poc_s1[i - 1] + delta_poc_s1_minus1 + 1;
      }
      // used_by_curr_pic_s1_flag: u(1)
      st_ref_pic_set.used_by_curr_pic_s1[i] = reader.Read<bool>();
    }
  }

  st_ref_pic_set.num_delta_pocs =
      st_ref_pic_set.num_negative_pics + st_ref_pic_set.num_positive_pics;

  if (!reader.Ok()) {
    return absl::nullopt;
  }

  return OptionalShortTermRefPicSet(st_ref_pic_set);
}

absl::optional<H265SpsParser::ProfileTierLevel>
H265SpsParser::ParseProfileTierLevel(bool profile_present,
                                     int max_num_sub_layers_minus1,
                                     BitstreamReader& reader) {
  H265SpsParser::ProfileTierLevel pf_tier_level;
  // 7.4.4
  if (profile_present) {
    int general_profile_space;
    general_profile_space = reader.ReadBits(2);
    TRUE_OR_RETURN(general_profile_space == 0);
    // general_tier_flag or reserved 0: u(1)
    reader.ConsumeBits(1);
    pf_tier_level.general_profile_idc = reader.ReadBits(5);
    IN_RANGE_OR_RETURN_NULL(pf_tier_level.general_profile_idc, 0, 11);
    uint16_t general_profile_compatibility_flag_high16 = reader.ReadBits(16);
    uint16_t general_profile_compatibility_flag_low16 = reader.ReadBits(16);
    pf_tier_level.general_profile_compatibility_flags =
        (general_profile_compatibility_flag_high16 << 16) +
        general_profile_compatibility_flag_low16;
    pf_tier_level.general_progressive_source_flag = reader.ReadBits(1);
    pf_tier_level.general_interlaced_source_flag = reader.ReadBits(1);
    if (!reader.Ok() || (!pf_tier_level.general_progressive_source_flag &&
                         pf_tier_level.general_interlaced_source_flag)) {
      RTC_LOG(LS_WARNING) << "Interlaced streams not supported";
      return absl::nullopt;
    }
    pf_tier_level.general_non_packed_constraint_flag = reader.ReadBits(1);
    pf_tier_level.general_frame_only_constraint_flag = reader.ReadBits(1);
    // general_reserved_zero_7bits
    reader.ConsumeBits(7);
    pf_tier_level.general_one_picture_only_constraint_flag = reader.ReadBits(1);
    // general_reserved_zero_35bits
    reader.ConsumeBits(35);
    // general_inbld_flag
    reader.ConsumeBits(1);
  }
  pf_tier_level.general_level_idc = reader.ReadBits(8);
  bool sub_layer_profile_present_flag[8] = {};
  bool sub_layer_level_present_flag[8] = {};
  for (int i = 0; i < max_num_sub_layers_minus1; ++i) {
    sub_layer_profile_present_flag[i] = reader.ReadBits(1);
    sub_layer_level_present_flag[i] = reader.ReadBits(1);
  }
  if (max_num_sub_layers_minus1 > 0) {
    for (int i = max_num_sub_layers_minus1; i < 8; i++) {
      reader.ConsumeBits(2);
    }
  }
  for (int i = 0; i < max_num_sub_layers_minus1; i++) {
    if (sub_layer_profile_present_flag[i]) {
      // sub_layer_profile_space
      reader.ConsumeBits(2);
      // sub_layer_tier_flag
      reader.ConsumeBits(1);
      // sub_layer_profile_idc
      reader.ConsumeBits(5);
      // sub_layer_profile_compatibility_flag
      reader.ConsumeBits(32);
      // sub_layer_{progressive,interlaced}_source_flag
      reader.ConsumeBits(2);
      // Ignore sub_layer_non_packed_constraint_flag and
      // sub_layer_frame_only_constraint_flag.
      reader.ConsumeBits(2);
      // Skip the compatibility flags, they are always 43 bits.
      reader.ConsumeBits(43);
      // sub_layer_inbld_flag
      reader.ConsumeBits(1);
    }
    if (sub_layer_level_present_flag[i]) {
      // sub_layer_level_idc
      reader.ConsumeBits(8);
    }
  }

  if (!reader.Ok()) {
    return absl::nullopt;
  }

  return OptionalProfileTierLevel(pf_tier_level);
}

absl::optional<H265SpsParser::SpsState> H265SpsParser::ParseSpsInternal(
    rtc::ArrayView<const uint8_t> buffer) {
  BitstreamReader reader(buffer);

  // Now, we need to use a bit buffer to parse through the actual H265 SPS
  // format. See Section 7.3.2.2.1 ("General sequence parameter set data
  // syntax") of the H.265 standard for a complete description.
  // Since we only care about resolution, we ignore the majority of fields, but
  // we still have to actively parse through a lot of the data, since many of
  // the fields have variable size.
  // We're particularly interested in:
  // chroma_format_idc -> affects crop units
  // pic_{width,height}_* -> resolution of the frame in macroblocks (16x16).
  // frame_crop_*_offset -> crop information
  SpsState sps;

  // sps_video_parameter_set_id: u(4)
  uint32_t sps_video_parameter_set_id = 0;
  sps_video_parameter_set_id = reader.ReadBits(4);
  IN_RANGE_OR_RETURN_NULL(sps_video_parameter_set_id, 0, 15);

  // sps_max_sub_layers_minus1: u(3)
  uint32_t sps_max_sub_layers_minus1 = 0;
  sps_max_sub_layers_minus1 = reader.ReadBits(3);
  IN_RANGE_OR_RETURN_NULL(sps_max_sub_layers_minus1, 0, kMaxSubLayers - 1);
  sps.sps_max_sub_layers_minus1 = sps_max_sub_layers_minus1;
  // sps_temporal_id_nesting_flag: u(1)
  reader.ConsumeBits(1);
  // profile_tier_level(1, sps_max_sub_layers_minus1).
  OptionalProfileTierLevel profile_tier_level =
      ParseProfileTierLevel(true, sps.sps_max_sub_layers_minus1, reader);
  if (!profile_tier_level) {
    return absl::nullopt;
  }
  // sps_seq_parameter_set_id: ue(v)
  sps.sps_id = reader.ReadExponentialGolomb();
  IN_RANGE_OR_RETURN_NULL(sps.sps_id, 0, 15);
  // chrome_format_idc: ue(v)
  sps.chroma_format_idc = reader.ReadExponentialGolomb();
  IN_RANGE_OR_RETURN_NULL(sps.chroma_format_idc, 0, 3);
  if (sps.chroma_format_idc == 3) {
    // seperate_colour_plane_flag: u(1)
    sps.separate_colour_plane_flag = reader.Read<bool>();
  }
  uint32_t pic_width_in_luma_samples = 0;
  uint32_t pic_height_in_luma_samples = 0;
  // pic_width_in_luma_samples: ue(v)
  pic_width_in_luma_samples = reader.ReadExponentialGolomb();
  TRUE_OR_RETURN(pic_width_in_luma_samples != 0);
  // pic_height_in_luma_samples: ue(v)
  pic_height_in_luma_samples = reader.ReadExponentialGolomb();
  TRUE_OR_RETURN(pic_height_in_luma_samples != 0);

  // Equation A-2: Calculate max_dpb_size.
  uint32_t max_luma_ps = GetMaxLumaPs(profile_tier_level->general_level_idc);
  uint32_t max_dpb_size = 0;
  uint32_t pic_size_in_samples_y = pic_height_in_luma_samples;
  pic_size_in_samples_y *= pic_width_in_luma_samples;
  size_t max_dpb_pic_buf =
      GetDpbMaxPicBuf(profile_tier_level->general_profile_idc);
  if (pic_size_in_samples_y <= (max_luma_ps >> 2))
    max_dpb_size = std::min(4 * max_dpb_pic_buf, size_t{16});
  else if (pic_size_in_samples_y <= (max_luma_ps >> 1))
    max_dpb_size = std::min(2 * max_dpb_pic_buf, size_t{16});
  else if (pic_size_in_samples_y <= ((3 * max_luma_ps) >> 2))
    max_dpb_size = std::min((4 * max_dpb_pic_buf) / 3, size_t{16});
  else
    max_dpb_size = max_dpb_pic_buf;

  // conformance_window_flag: u(1)
  bool conformance_window_flag = reader.Read<bool>();

  uint32_t conf_win_left_offset = 0;
  uint32_t conf_win_right_offset = 0;
  uint32_t conf_win_top_offset = 0;
  uint32_t conf_win_bottom_offset = 0;
  int sub_width_c =
      ((1 == sps.chroma_format_idc) || (2 == sps.chroma_format_idc)) &&
              (0 == sps.separate_colour_plane_flag)
          ? 2
          : 1;
  int sub_height_c =
      (1 == sps.chroma_format_idc) && (0 == sps.separate_colour_plane_flag) ? 2
                                                                            : 1;
  if (conformance_window_flag) {
    // conf_win_left_offset: ue(v)
    conf_win_left_offset = reader.ReadExponentialGolomb();
    // conf_win_right_offset: ue(v)
    conf_win_right_offset = reader.ReadExponentialGolomb();
    // conf_win_top_offset: ue(v)
    conf_win_top_offset = reader.ReadExponentialGolomb();
    // conf_win_bottom_offset: ue(v)
    conf_win_bottom_offset = reader.ReadExponentialGolomb();
    uint32_t width_crop = conf_win_left_offset;
    width_crop += conf_win_right_offset;
    width_crop *= sub_width_c;
    TRUE_OR_RETURN(width_crop < pic_width_in_luma_samples);
    uint32_t height_crop = conf_win_top_offset;
    height_crop += conf_win_bottom_offset;
    height_crop *= sub_height_c;
    TRUE_OR_RETURN(height_crop < pic_height_in_luma_samples);
  }

  // bit_depth_luma_minus8: ue(v)
  sps.bit_depth_luma_minus8 = reader.ReadExponentialGolomb();
  IN_RANGE_OR_RETURN_NULL(sps.bit_depth_luma_minus8, 0, 8);
  // bit_depth_chroma_minus8: ue(v)
  uint32_t bit_depth_chroma_minus8 = reader.ReadExponentialGolomb();
  IN_RANGE_OR_RETURN_NULL(bit_depth_chroma_minus8, 0, 8);
  // log2_max_pic_order_cnt_lsb_minus4: ue(v)
  sps.log2_max_pic_order_cnt_lsb_minus4 = reader.ReadExponentialGolomb();
  IN_RANGE_OR_RETURN_NULL(sps.log2_max_pic_order_cnt_lsb_minus4, 0, 12);
  uint32_t sps_sub_layer_ordering_info_present_flag = 0;
  // sps_sub_layer_ordering_info_present_flag: u(1)
  sps_sub_layer_ordering_info_present_flag = reader.Read<bool>();
  uint32_t sps_max_num_reorder_pics[kMaxSubLayers] = {};
  for (uint32_t i = (sps_sub_layer_ordering_info_present_flag != 0)
                        ? 0
                        : sps_max_sub_layers_minus1;
       i <= sps_max_sub_layers_minus1; i++) {
    // sps_max_dec_pic_buffering_minus1: ue(v)
    sps.sps_max_dec_pic_buffering_minus1[i] = reader.ReadExponentialGolomb();
    IN_RANGE_OR_RETURN_NULL(sps.sps_max_dec_pic_buffering_minus1[i], 0,
                            max_dpb_size - 1);
    // sps_max_num_reorder_pics: ue(v)
    sps_max_num_reorder_pics[i] = reader.ReadExponentialGolomb();
    IN_RANGE_OR_RETURN_NULL(sps_max_num_reorder_pics[i], 0,
                            sps.sps_max_dec_pic_buffering_minus1[i]);
    if (i > 0) {
      TRUE_OR_RETURN(sps.sps_max_dec_pic_buffering_minus1[i] >=
                     sps.sps_max_dec_pic_buffering_minus1[i - 1]);
      TRUE_OR_RETURN(sps_max_num_reorder_pics[i] >=
                     sps_max_num_reorder_pics[i - 1]);
    }
    // sps_max_latency_increase_plus1: ue(v)
    reader.ReadExponentialGolomb();
  }
  if (!sps_sub_layer_ordering_info_present_flag) {
    // Fill in the default values for the other sublayers.
    for (uint32_t i = 0; i < sps_max_sub_layers_minus1; ++i) {
      sps.sps_max_dec_pic_buffering_minus1[i] =
          sps.sps_max_dec_pic_buffering_minus1[sps_max_sub_layers_minus1];
    }
  }
  // log2_min_luma_coding_block_size_minus3: ue(v)
  sps.log2_min_luma_coding_block_size_minus3 = reader.ReadExponentialGolomb();
  IN_RANGE_OR_RETURN_NULL(sps.log2_min_luma_coding_block_size_minus3, 0, 27);
  // log2_diff_max_min_luma_coding_block_size: ue(v)
  sps.log2_diff_max_min_luma_coding_block_size = reader.ReadExponentialGolomb();
  int min_cb_log2_size_y = sps.log2_min_luma_coding_block_size_minus3 + 3;
  int ctb_log2_size_y = min_cb_log2_size_y;
  ctb_log2_size_y += sps.log2_diff_max_min_luma_coding_block_size;
  IN_RANGE_OR_RETURN_NULL(ctb_log2_size_y, 0, 30);
  int min_cb_size_y = 1 << min_cb_log2_size_y;
  int ctb_size_y = 1 << ctb_log2_size_y;
  sps.pic_width_in_ctbs_y =
      std::ceil(static_cast<float>(pic_width_in_luma_samples) / ctb_size_y);
  sps.pic_height_in_ctbs_y =
      std::ceil(static_cast<float>(pic_height_in_luma_samples) / ctb_size_y);
  TRUE_OR_RETURN(pic_width_in_luma_samples % min_cb_size_y == 0);
  TRUE_OR_RETURN(pic_height_in_luma_samples % min_cb_size_y == 0);
  // log2_min_luma_transform_block_size_minus2: ue(v)
  int log2_min_luma_transform_block_size_minus2 =
      reader.ReadExponentialGolomb();
  IN_RANGE_OR_RETURN_NULL(log2_min_luma_transform_block_size_minus2, 0,
                          min_cb_log2_size_y - 3);
  int min_tb_log2_size_y = log2_min_luma_transform_block_size_minus2 + 2;
  // log2_diff_max_min_luma_transform_block_size: ue(v)
  int log2_diff_max_min_luma_transform_block_size =
      reader.ReadExponentialGolomb();
  TRUE_OR_RETURN(log2_diff_max_min_luma_transform_block_size <=
                 std::min(ctb_log2_size_y, 5) - min_tb_log2_size_y);
  // max_transform_hierarchy_depth_inter: ue(v)
  int max_transform_hierarchy_depth_inter = reader.ReadExponentialGolomb();
  IN_RANGE_OR_RETURN_NULL(max_transform_hierarchy_depth_inter, 0,
                          ctb_log2_size_y - min_tb_log2_size_y);
  // max_transform_hierarchy_depth_intra: ue(v)
  int max_transform_hierarchy_depth_intra = reader.ReadExponentialGolomb();
  IN_RANGE_OR_RETURN_NULL(max_transform_hierarchy_depth_intra, 0,
                          ctb_log2_size_y - min_tb_log2_size_y);
  // scaling_list_enabled_flag: u(1)
  bool scaling_list_enabled_flag = reader.Read<bool>();
  if (scaling_list_enabled_flag) {
    // sps_scaling_list_data_present_flag: u(1)
    bool sps_scaling_list_data_present_flag = reader.Read<bool>();
    if (sps_scaling_list_data_present_flag) {
      // scaling_list_data()
      if (!ParseScalingListData(reader)) {
        return absl::nullopt;
      }
    }
  }

  // amp_enabled_flag: u(1)
  reader.ConsumeBits(1);
  // sample_adaptive_offset_enabled_flag: u(1)
  sps.sample_adaptive_offset_enabled_flag = reader.Read<bool>();
  // pcm_enabled_flag: u(1)
  bool pcm_enabled_flag = reader.Read<bool>();
  if (pcm_enabled_flag) {
    // pcm_sample_bit_depth_luma_minus1: u(4)
    reader.ConsumeBits(4);
    // pcm_sample_bit_depth_chroma_minus1: u(4)
    reader.ConsumeBits(4);
    // log2_min_pcm_luma_coding_block_size_minus3: ue(v)
    int log2_min_pcm_luma_coding_block_size_minus3 =
        reader.ReadExponentialGolomb();
    IN_RANGE_OR_RETURN_NULL(log2_min_pcm_luma_coding_block_size_minus3, 0, 2);
    int log2_min_ipcm_cb_size_y =
        log2_min_pcm_luma_coding_block_size_minus3 + 3;
    IN_RANGE_OR_RETURN_NULL(log2_min_ipcm_cb_size_y,
                            std::min(min_cb_log2_size_y, 5),
                            std::min(ctb_log2_size_y, 5));
    // log2_diff_max_min_pcm_luma_coding_block_size: ue(v)
    int log2_diff_max_min_pcm_luma_coding_block_size =
        reader.ReadExponentialGolomb();
    TRUE_OR_RETURN(log2_diff_max_min_pcm_luma_coding_block_size <=
                   std::min(ctb_log2_size_y, 5) - log2_min_ipcm_cb_size_y);
    // pcm_loop_filter_disabled_flag: u(1)
    reader.ConsumeBits(1);
  }

  // num_short_term_ref_pic_sets: ue(v)
  sps.num_short_term_ref_pic_sets = reader.ReadExponentialGolomb();
  IN_RANGE_OR_RETURN_NULL(sps.num_short_term_ref_pic_sets, 0,
                          kMaxShortTermRefPicSets);
  sps.short_term_ref_pic_set.resize(sps.num_short_term_ref_pic_sets);
  for (uint32_t st_rps_idx = 0; st_rps_idx < sps.num_short_term_ref_pic_sets;
       st_rps_idx++) {
    uint32_t sps_max_dec_pic_buffering_minus1 =
        sps.sps_max_dec_pic_buffering_minus1[sps.sps_max_sub_layers_minus1];
    // st_ref_pic_set()
    OptionalShortTermRefPicSet ref_pic_set = ParseShortTermRefPicSet(
        st_rps_idx, sps.num_short_term_ref_pic_sets, sps.short_term_ref_pic_set,
        sps_max_dec_pic_buffering_minus1, reader);
    if (ref_pic_set) {
      sps.short_term_ref_pic_set[st_rps_idx] = *ref_pic_set;
    } else {
      return absl::nullopt;
    }
  }

  // long_term_ref_pics_present_flag: u(1)
  sps.long_term_ref_pics_present_flag = reader.Read<bool>();
  if (sps.long_term_ref_pics_present_flag) {
    // num_long_term_ref_pics_sps: ue(v)
    sps.num_long_term_ref_pics_sps = reader.ReadExponentialGolomb();
    IN_RANGE_OR_RETURN_NULL(sps.num_long_term_ref_pics_sps, 0,
                            kMaxLongTermRefPicSets);
    sps.used_by_curr_pic_lt_sps_flag.resize(sps.num_long_term_ref_pics_sps, 0);
    for (uint32_t i = 0; i < sps.num_long_term_ref_pics_sps; i++) {
      // lt_ref_pic_poc_lsb_sps: u(v)
      uint32_t lt_ref_pic_poc_lsb_sps_bits =
          sps.log2_max_pic_order_cnt_lsb_minus4 + 4;
      reader.ConsumeBits(lt_ref_pic_poc_lsb_sps_bits);
      // used_by_curr_pic_lt_sps_flag: u(1)
      sps.used_by_curr_pic_lt_sps_flag[i] = reader.Read<bool>();
    }
  }

  // sps_temporal_mvp_enabled_flag: u(1)
  sps.sps_temporal_mvp_enabled_flag = reader.Read<bool>();

  // Far enough! We don't use the rest of the SPS.

  sps.vps_id = sps_video_parameter_set_id;

  sps.pic_width_in_luma_samples = pic_width_in_luma_samples;
  sps.pic_height_in_luma_samples = pic_height_in_luma_samples;

  // Start with the resolution determined by the pic_width/pic_height fields.
  sps.width = pic_width_in_luma_samples;
  sps.height = pic_height_in_luma_samples;

  if (conformance_window_flag) {
    int sub_width_c =
        ((1 == sps.chroma_format_idc) || (2 == sps.chroma_format_idc)) &&
                (0 == sps.separate_colour_plane_flag)
            ? 2
            : 1;
    int sub_height_c =
        (1 == sps.chroma_format_idc) && (0 == sps.separate_colour_plane_flag)
            ? 2
            : 1;
    // the offset includes the pixel within conformance window. so don't need to
    // +1 as per spec
    sps.width -= sub_width_c * (conf_win_right_offset + conf_win_left_offset);
    sps.height -= sub_height_c * (conf_win_top_offset + conf_win_bottom_offset);
  }

  if (!reader.Ok()) {
    return absl::nullopt;
  }

  return OptionalSps(sps);
}

}  // namespace webrtc
