/*
 *  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 std::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 std::nullopt;                                               \
    }                                                                    \
  } while (0)

namespace {
using OptionalSps = std::optional<webrtc::H265SpsParser::SpsState>;
using OptionalShortTermRefPicSet =
    std::optional<webrtc::H265SpsParser::ShortTermRefPicSet>;
using OptionalProfileTierLevel =
    std::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.
std::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();
}

std::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 std::nullopt;
  }

  return OptionalShortTermRefPicSet(st_ref_pic_set);
}

std::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 std::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 std::nullopt;
  }

  return OptionalProfileTierLevel(pf_tier_level);
}

std::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 std::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 std::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 std::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 std::nullopt;
  }

  return OptionalSps(sps);
}

}  // namespace webrtc
