/*
 *  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_pps_parser.h"

#include <memory>
#include <vector>

#include "absl/types/optional.h"
#include "common_video/h265/h265_common.h"
#include "rtc_base/bit_buffer.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 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 {
constexpr int kMaxNumTileColumnWidth = 19;
constexpr int kMaxNumTileRowHeight = 21;
constexpr int kMaxRefIdxActive = 15;
}  // namespace

namespace webrtc {

// 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

absl::optional<H265PpsParser::PpsState> H265PpsParser::ParsePps(
    const uint8_t* data,
    size_t length,
    const H265SpsParser::SpsState* sps) {
  // First, parse out rbsp, which is basically the source buffer minus emulation
  // bytes (the last byte of a 0x00 0x00 0x03 sequence). RBSP is defined in
  // section 7.3.1.1 of the H.265 standard.
  return ParseInternal(H265::ParseRbsp(data, length), sps);
}

bool H265PpsParser::ParsePpsIds(const uint8_t* data,
                                size_t length,
                                uint32_t* pps_id,
                                uint32_t* sps_id) {
  RTC_DCHECK(pps_id);
  RTC_DCHECK(sps_id);
  // First, parse out rbsp, which is basically the source buffer minus emulation
  // bytes (the last byte of a 0x00 0x00 0x03 sequence). RBSP is defined in
  // section 7.3.1.1 of the H.265 standard.
  std::vector<uint8_t> unpacked_buffer = H265::ParseRbsp(data, length);
  BitstreamReader reader(unpacked_buffer);
  *pps_id = reader.ReadExponentialGolomb();
  IN_RANGE_OR_RETURN_FALSE(*pps_id, 0, 63);
  *sps_id = reader.ReadExponentialGolomb();
  IN_RANGE_OR_RETURN_FALSE(*sps_id, 0, 15);
  return reader.Ok();
}

absl::optional<H265PpsParser::PpsState> H265PpsParser::ParseInternal(
    rtc::ArrayView<const uint8_t> buffer,
    const H265SpsParser::SpsState* sps) {
  BitstreamReader reader(buffer);
  PpsState pps;

  if (!sps) {
    return absl::nullopt;
  }

  if (!ParsePpsIdsInternal(reader, pps.pps_id, pps.sps_id)) {
    return absl::nullopt;
  }

  // dependent_slice_segments_enabled_flag: u(1)
  pps.dependent_slice_segments_enabled_flag = reader.Read<bool>();
  // output_flag_present_flag: u(1)
  pps.output_flag_present_flag = reader.Read<bool>();
  // num_extra_slice_header_bits: u(3)
  pps.num_extra_slice_header_bits = reader.ReadBits(3);
  IN_RANGE_OR_RETURN_NULL(pps.num_extra_slice_header_bits, 0, 2);
  // sign_data_hiding_enabled_flag: u(1)
  reader.ConsumeBits(1);
  // cabac_init_present_flag: u(1)
  pps.cabac_init_present_flag = reader.Read<bool>();
  // num_ref_idx_l0_default_active_minus1: ue(v)
  pps.num_ref_idx_l0_default_active_minus1 = reader.ReadExponentialGolomb();
  IN_RANGE_OR_RETURN_NULL(pps.num_ref_idx_l0_default_active_minus1, 0,
                          kMaxRefIdxActive - 1);
  // num_ref_idx_l1_default_active_minus1: ue(v)
  pps.num_ref_idx_l1_default_active_minus1 = reader.ReadExponentialGolomb();
  IN_RANGE_OR_RETURN_NULL(pps.num_ref_idx_l1_default_active_minus1, 0,
                          kMaxRefIdxActive - 1);
  // init_qp_minus26: se(v)
  pps.init_qp_minus26 = reader.ReadSignedExponentialGolomb();
  pps.qp_bd_offset_y = 6 * sps->bit_depth_luma_minus8;
  // Sanity-check parsed value
  IN_RANGE_OR_RETURN_NULL(pps.init_qp_minus26, -(26 + pps.qp_bd_offset_y), 25);
  // constrained_intra_pred_flag: u(1)log2_min_pcm_luma_coding_block_size_minus3
  reader.ConsumeBits(1);
  // transform_skip_enabled_flag: u(1)
  reader.ConsumeBits(1);
  // cu_qp_delta_enabled_flag: u(1)
  bool cu_qp_delta_enabled_flag = reader.Read<bool>();
  if (cu_qp_delta_enabled_flag) {
    // diff_cu_qp_delta_depth: ue(v)
    uint32_t diff_cu_qp_delta_depth = reader.ReadExponentialGolomb();
    IN_RANGE_OR_RETURN_NULL(diff_cu_qp_delta_depth, 0,
                            sps->log2_diff_max_min_luma_coding_block_size);
  }
  // pps_cb_qp_offset: se(v)
  int32_t pps_cb_qp_offset = reader.ReadSignedExponentialGolomb();
  IN_RANGE_OR_RETURN_NULL(pps_cb_qp_offset, -12, 12);
  // pps_cr_qp_offset: se(v)
  int32_t pps_cr_qp_offset = reader.ReadSignedExponentialGolomb();
  IN_RANGE_OR_RETURN_NULL(pps_cr_qp_offset, -12, 12);
  // pps_slice_chroma_qp_offsets_present_flag: u(1)
  reader.ConsumeBits(1);
  // weighted_pred_flag: u(1)
  pps.weighted_pred_flag = reader.Read<bool>();
  // weighted_bipred_flag: u(1)
  pps.weighted_bipred_flag = reader.Read<bool>();
  // transquant_bypass_enabled_flag: u(1)
  reader.ConsumeBits(1);
  // tiles_enabled_flag: u(1)
  bool tiles_enabled_flag = reader.Read<bool>();
  // entropy_coding_sync_enabled_flag: u(1)
  reader.ConsumeBits(1);
  if (tiles_enabled_flag) {
    // num_tile_columns_minus1: ue(v)
    uint32_t num_tile_columns_minus1 = reader.ReadExponentialGolomb();
    IN_RANGE_OR_RETURN_NULL(num_tile_columns_minus1, 0,
                            sps->pic_width_in_ctbs_y - 1);
    TRUE_OR_RETURN(num_tile_columns_minus1 < kMaxNumTileColumnWidth);
    // num_tile_rows_minus1: ue(v)
    uint32_t num_tile_rows_minus1 = reader.ReadExponentialGolomb();
    IN_RANGE_OR_RETURN_NULL(num_tile_rows_minus1, 0,
                            sps->pic_height_in_ctbs_y - 1);
    TRUE_OR_RETURN((num_tile_columns_minus1 != 0) ||
                   (num_tile_rows_minus1 != 0));
    TRUE_OR_RETURN(num_tile_rows_minus1 < kMaxNumTileRowHeight);
    // uniform_spacing_flag: u(1)
    bool uniform_spacing_flag = reader.Read<bool>();
    if (!uniform_spacing_flag) {
      int column_width_minus1[kMaxNumTileColumnWidth];
      column_width_minus1[num_tile_columns_minus1] =
          sps->pic_width_in_ctbs_y - 1;
      for (uint32_t i = 0; i < num_tile_columns_minus1; i++) {
        // column_width_minus1: ue(v)
        column_width_minus1[i] = reader.ReadExponentialGolomb();
        IN_RANGE_OR_RETURN_NULL(
            column_width_minus1[i], 0,
            column_width_minus1[num_tile_columns_minus1] - 1);
        column_width_minus1[num_tile_columns_minus1] -=
            column_width_minus1[i] + 1;
      }
      int row_height_minus1[kMaxNumTileRowHeight];
      row_height_minus1[num_tile_rows_minus1] = sps->pic_height_in_ctbs_y - 1;
      for (uint32_t i = 0; i < num_tile_rows_minus1; i++) {
        // row_height_minus1: ue(v)
        row_height_minus1[i] = reader.ReadExponentialGolomb();
        IN_RANGE_OR_RETURN_NULL(row_height_minus1[i], 0,
                                row_height_minus1[num_tile_rows_minus1] - 1);
        row_height_minus1[num_tile_rows_minus1] -= row_height_minus1[i] + 1;
      }
      // loop_filter_across_tiles_enabled_flag: u(1)
      reader.ConsumeBits(1);
    }
  }
  // pps_loop_filter_across_slices_enabled_flag: u(1)
  reader.ConsumeBits(1);
  // deblocking_filter_control_present_flag: u(1)
  bool deblocking_filter_control_present_flag = reader.Read<bool>();
  if (deblocking_filter_control_present_flag) {
    // deblocking_filter_override_enabled_flag: u(1)
    reader.ConsumeBits(1);
    // pps_deblocking_filter_disabled_flag: u(1)
    bool pps_deblocking_filter_disabled_flag = reader.Read<bool>();
    if (!pps_deblocking_filter_disabled_flag) {
      // pps_beta_offset_div2: se(v)
      int pps_beta_offset_div2 = reader.ReadSignedExponentialGolomb();
      IN_RANGE_OR_RETURN_NULL(pps_beta_offset_div2, -6, 6);
      // pps_tc_offset_div2: se(v)
      int pps_tc_offset_div2 = reader.ReadSignedExponentialGolomb();
      IN_RANGE_OR_RETURN_NULL(pps_tc_offset_div2, -6, 6);
    }
  }
  // pps_scaling_list_data_present_flag: u(1)
  bool pps_scaling_list_data_present_flag = 0;
  pps_scaling_list_data_present_flag = reader.Read<bool>();
  if (pps_scaling_list_data_present_flag) {
    // scaling_list_data()
    if (!H265SpsParser::ParseScalingListData(reader)) {
      return absl::nullopt;
    }
  }
  // lists_modification_present_flag: u(1)
  pps.lists_modification_present_flag = reader.Read<bool>();

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

  return pps;
}

bool H265PpsParser::ParsePpsIdsInternal(BitstreamReader& reader,
                                        uint32_t& pps_id,
                                        uint32_t& sps_id) {
  // pic_parameter_set_id: ue(v)
  pps_id = reader.ReadExponentialGolomb();
  IN_RANGE_OR_RETURN_FALSE(pps_id, 0, 63);
  // seq_parameter_set_id: ue(v)
  sps_id = reader.ReadExponentialGolomb();
  IN_RANGE_OR_RETURN_FALSE(sps_id, 0, 15);
  return true;
}

}  // namespace webrtc
