/*
 *  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 <cmath>
#include <cstddef>
#include <cstdint>
#include <optional>
#include <span>
#include <vector>

#include "common_video/h265/h265_common.h"
#include "rtc_base/bitstream_reader.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 webrtc {

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

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

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(
    std::span<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(
    std::span<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;
  const int sub_width_c =
      ((1 == sps.chroma_format_idc) || (2 == sps.chroma_format_idc)) &&
              (0 == sps.separate_colour_plane_flag)
          ? 2
          : 1;
  const 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) {
    // 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
