/*
 *  Copyright (c) 2017 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 "modules/video_coding/utility/vp9_uncompressed_header_parser.h"

#include "absl/numeric/bits.h"
#include "absl/strings/string_view.h"
#include "rtc_base/bitstream_reader.h"
#include "rtc_base/logging.h"
#include "rtc_base/strings/string_builder.h"

namespace webrtc {
namespace {
const size_t kVp9NumRefsPerFrame = 3;
const size_t kVp9MaxRefLFDeltas = 4;
const size_t kVp9MaxModeLFDeltas = 2;
const size_t kVp9MinTileWidthB64 = 4;
const size_t kVp9MaxTileWidthB64 = 64;

void Vp9ReadColorConfig(BitstreamReader& br,
                        Vp9UncompressedHeader* frame_info) {
  if (frame_info->profile == 2 || frame_info->profile == 3) {
    frame_info->bit_detph =
        br.Read<bool>() ? Vp9BitDept::k12Bit : Vp9BitDept::k10Bit;
  } else {
    frame_info->bit_detph = Vp9BitDept::k8Bit;
  }

  frame_info->color_space = static_cast<Vp9ColorSpace>(br.ReadBits(3));

  if (frame_info->color_space != Vp9ColorSpace::CS_RGB) {
    frame_info->color_range =
        br.Read<bool>() ? Vp9ColorRange::kFull : Vp9ColorRange::kStudio;

    if (frame_info->profile == 1 || frame_info->profile == 3) {
      static constexpr Vp9YuvSubsampling kSubSamplings[] = {
          Vp9YuvSubsampling::k444, Vp9YuvSubsampling::k440,
          Vp9YuvSubsampling::k422, Vp9YuvSubsampling::k420};
      frame_info->sub_sampling = kSubSamplings[br.ReadBits(2)];

      if (br.Read<bool>()) {
        RTC_LOG(LS_WARNING) << "Failed to parse header. Reserved bit set.";
        br.Invalidate();
        return;
      }
    } else {
      // Profile 0 or 2.
      frame_info->sub_sampling = Vp9YuvSubsampling::k420;
    }
  } else {
    // SRGB
    frame_info->color_range = Vp9ColorRange::kFull;
    if (frame_info->profile == 1 || frame_info->profile == 3) {
      frame_info->sub_sampling = Vp9YuvSubsampling::k444;
      if (br.Read<bool>()) {
        RTC_LOG(LS_WARNING) << "Failed to parse header. Reserved bit set.";
        br.Invalidate();
      }
    } else {
      RTC_LOG(LS_WARNING) << "Failed to parse header. 4:4:4 color not supported"
                             " in profile 0 or 2.";
      br.Invalidate();
    }
  }
}

void ReadRefreshFrameFlags(BitstreamReader& br,
                           Vp9UncompressedHeader* frame_info) {
  // Refresh frame flags.
  uint8_t flags = br.Read<uint8_t>();
  for (int i = 0; i < 8; ++i) {
    frame_info->updated_buffers.set(i, (flags & (0x01 << (7 - i))) != 0);
  }
}

void Vp9ReadFrameSize(BitstreamReader& br, Vp9UncompressedHeader* frame_info) {
  // 16 bits: frame (width|height) - 1.
  frame_info->frame_width = br.Read<uint16_t>() + 1;
  frame_info->frame_height = br.Read<uint16_t>() + 1;
}

void Vp9ReadRenderSize(size_t total_buffer_size_bits,
                       BitstreamReader& br,
                       Vp9UncompressedHeader* frame_info) {
  // render_and_frame_size_different
  if (br.Read<bool>()) {
    frame_info->render_size_offset_bits =
        total_buffer_size_bits - br.RemainingBitCount();
    // 16 bits: render (width|height) - 1.
    frame_info->render_width = br.Read<uint16_t>() + 1;
    frame_info->render_height = br.Read<uint16_t>() + 1;
  } else {
    frame_info->render_height = frame_info->frame_height;
    frame_info->render_width = frame_info->frame_width;
  }
}

void Vp9ReadFrameSizeFromRefs(BitstreamReader& br,
                              Vp9UncompressedHeader* frame_info) {
  for (size_t i = 0; i < kVp9NumRefsPerFrame; i++) {
    // Size in refs.
    if (br.Read<bool>()) {
      frame_info->infer_size_from_reference = frame_info->reference_buffers[i];
      return;
    }
  }

  Vp9ReadFrameSize(br, frame_info);
}

void Vp9ReadLoopfilter(BitstreamReader& br) {
  // 6 bits: filter level.
  // 3 bits: sharpness level.
  br.ConsumeBits(9);

  if (!br.Read<bool>()) {  // mode_ref_delta_enabled
    return;
  }
  if (!br.Read<bool>()) {  // mode_ref_delta_update
    return;
  }

  for (size_t i = 0; i < kVp9MaxRefLFDeltas; i++) {
    if (br.Read<bool>()) {  // update_ref_delta
      br.ConsumeBits(7);
    }
  }
  for (size_t i = 0; i < kVp9MaxModeLFDeltas; i++) {
    if (br.Read<bool>()) {  // update_mode_delta
      br.ConsumeBits(7);
    }
  }
}

void Vp9ReadQp(BitstreamReader& br, Vp9UncompressedHeader* frame_info) {
  frame_info->base_qp = br.Read<uint8_t>();

  // yuv offsets
  frame_info->is_lossless = frame_info->base_qp == 0;
  for (int i = 0; i < 3; ++i) {
    if (br.Read<bool>()) {  // if delta_coded
      // delta_q is a signed integer with leading 4 bits containing absolute
      // value and last bit containing sign. There are are two ways to represent
      // zero with such encoding.
      if ((br.ReadBits(5) & 0b1111'0) != 0) {  // delta_q
        frame_info->is_lossless = false;
      }
    }
  }
}

void Vp9ReadSegmentationParams(BitstreamReader& br,
                               Vp9UncompressedHeader* frame_info) {
  constexpr int kSegmentationFeatureBits[kVp9SegLvlMax] = {8, 6, 2, 0};
  constexpr bool kSegmentationFeatureSigned[kVp9SegLvlMax] = {true, true, false,
                                                              false};

  frame_info->segmentation_enabled = br.Read<bool>();
  if (!frame_info->segmentation_enabled) {
    return;
  }

  if (br.Read<bool>()) {  // update_map
    frame_info->segmentation_tree_probs.emplace();
    for (int i = 0; i < 7; ++i) {
      if (br.Read<bool>()) {
        (*frame_info->segmentation_tree_probs)[i] = br.Read<uint8_t>();
      } else {
        (*frame_info->segmentation_tree_probs)[i] = 255;
      }
    }

    // temporal_update
    frame_info->segmentation_pred_prob.emplace();
    if (br.Read<bool>()) {
      for (int i = 0; i < 3; ++i) {
        if (br.Read<bool>()) {
          (*frame_info->segmentation_pred_prob)[i] = br.Read<uint8_t>();
        } else {
          (*frame_info->segmentation_pred_prob)[i] = 255;
        }
      }
    } else {
      frame_info->segmentation_pred_prob->fill(255);
    }
  }

  if (br.Read<bool>()) {  // segmentation_update_data
    frame_info->segmentation_is_delta = br.Read<bool>();
    for (size_t i = 0; i < kVp9MaxSegments; ++i) {
      for (size_t j = 0; j < kVp9SegLvlMax; ++j) {
        if (!br.Read<bool>()) {  // feature_enabled
          continue;
        }
        if (kSegmentationFeatureBits[j] == 0) {
          // No feature bits used and no sign, just mark it and return.
          frame_info->segmentation_features[i][j] = 1;
          continue;
        }
        frame_info->segmentation_features[i][j] =
            br.ReadBits(kSegmentationFeatureBits[j]);
        if (kSegmentationFeatureSigned[j] && br.Read<bool>()) {
          (*frame_info->segmentation_features[i][j]) *= -1;
        }
      }
    }
  }
}

void Vp9ReadTileInfo(BitstreamReader& br, Vp9UncompressedHeader* frame_info) {
  size_t mi_cols = (frame_info->frame_width + 7) >> 3;
  size_t sb64_cols = (mi_cols + 7) >> 3;

  size_t min_log2 = 0;
  while ((kVp9MaxTileWidthB64 << min_log2) < sb64_cols) {
    ++min_log2;
  }

  size_t max_log2 = 1;
  while ((sb64_cols >> max_log2) >= kVp9MinTileWidthB64) {
    ++max_log2;
  }
  --max_log2;

  frame_info->tile_cols_log2 = min_log2;
  while (frame_info->tile_cols_log2 < max_log2) {
    if (br.Read<bool>()) {
      ++frame_info->tile_cols_log2;
    } else {
      break;
    }
  }
  frame_info->tile_rows_log2 = 0;
  if (br.Read<bool>()) {
    ++frame_info->tile_rows_log2;
    if (br.Read<bool>()) {
      ++frame_info->tile_rows_log2;
    }
  }
}

const Vp9InterpolationFilter kLiteralToType[4] = {
    Vp9InterpolationFilter::kEightTapSmooth, Vp9InterpolationFilter::kEightTap,
    Vp9InterpolationFilter::kEightTapSharp, Vp9InterpolationFilter::kBilinear};
}  // namespace

std::string Vp9UncompressedHeader::ToString() const {
  char buf[1024];
  SimpleStringBuilder oss(buf);

  oss << "Vp9UncompressedHeader { " << "profile = " << profile;

  if (show_existing_frame) {
    oss << ", show_existing_frame = " << *show_existing_frame << " }";
    return oss.str();
  }

  oss << ", frame type = " << (is_keyframe ? "key" : "delta")
      << ", show_frame = " << (show_frame ? "true" : "false")
      << ", error_resilient = " << (error_resilient ? "true" : "false");

  oss << ", bit_depth = ";
  switch (bit_detph) {
    case Vp9BitDept::k8Bit:
      oss << "8bit";
      break;
    case Vp9BitDept::k10Bit:
      oss << "10bit";
      break;
    case Vp9BitDept::k12Bit:
      oss << "12bit";
      break;
  }

  if (color_space) {
    oss << ", color_space = ";
    switch (*color_space) {
      case Vp9ColorSpace::CS_UNKNOWN:
        oss << "unknown";
        break;
      case Vp9ColorSpace::CS_BT_601:
        oss << "CS_BT_601 Rec. ITU-R BT.601-7";
        break;
      case Vp9ColorSpace::CS_BT_709:
        oss << "Rec. ITU-R BT.709-6";
        break;
      case Vp9ColorSpace::CS_SMPTE_170:
        oss << "SMPTE-170";
        break;
      case Vp9ColorSpace::CS_SMPTE_240:
        oss << "SMPTE-240";
        break;
      case Vp9ColorSpace::CS_BT_2020:
        oss << "Rec. ITU-R BT.2020-2";
        break;
      case Vp9ColorSpace::CS_RESERVED:
        oss << "Reserved";
        break;
      case Vp9ColorSpace::CS_RGB:
        oss << "sRGB (IEC 61966-2-1)";
        break;
    }
  }

  if (color_range) {
    oss << ", color_range = ";
    switch (*color_range) {
      case Vp9ColorRange::kFull:
        oss << "full";
        break;
      case Vp9ColorRange::kStudio:
        oss << "studio";
        break;
    }
  }

  if (sub_sampling) {
    oss << ", sub_sampling = ";
    switch (*sub_sampling) {
      case Vp9YuvSubsampling::k444:
        oss << "444";
        break;
      case Vp9YuvSubsampling::k440:
        oss << "440";
        break;
      case Vp9YuvSubsampling::k422:
        oss << "422";
        break;
      case Vp9YuvSubsampling::k420:
        oss << "420";
        break;
    }
  }

  if (infer_size_from_reference) {
    oss << ", infer_frame_resolution_from = " << *infer_size_from_reference;
  } else {
    oss << ", frame_width = " << frame_width
        << ", frame_height = " << frame_height;
  }
  if (render_width != 0 && render_height != 0) {
    oss << ", render_width = " << render_width
        << ", render_height = " << render_height;
  }

  oss << ", base qp = " << base_qp;
  if (reference_buffers[0] != -1) {
    oss << ", last_buffer = " << reference_buffers[0];
  }
  if (reference_buffers[1] != -1) {
    oss << ", golden_buffer = " << reference_buffers[1];
  }
  if (reference_buffers[2] != -1) {
    oss << ", altref_buffer = " << reference_buffers[2];
  }

  oss << ", updated buffers = { ";
  bool first = true;
  for (int i = 0; i < 8; ++i) {
    if (updated_buffers.test(i)) {
      if (first) {
        first = false;
      } else {
        oss << ", ";
      }
      oss << i;
    }
  }
  oss << " }";

  oss << ", compressed_header_size_bytes = " << compressed_header_size;

  oss << " }";
  return oss.str();
}

void Parse(BitstreamReader& br,
           Vp9UncompressedHeader* frame_info,
           bool qp_only) {
  const size_t total_buffer_size_bits = br.RemainingBitCount();

  // Frame marker.
  if (br.ReadBits(2) != 0b10) {
    RTC_LOG(LS_WARNING) << "Failed to parse header. Frame marker should be 2.";
    br.Invalidate();
    return;
  }

  // Profile has low bit first.
  frame_info->profile = br.ReadBit();
  frame_info->profile |= br.ReadBit() << 1;
  if (frame_info->profile > 2 && br.Read<bool>()) {
    RTC_LOG(LS_WARNING)
        << "Failed to parse header. Unsupported bitstream profile.";
    br.Invalidate();
    return;
  }

  // Show existing frame.
  if (br.Read<bool>()) {
    frame_info->show_existing_frame = br.ReadBits(3);
    return;
  }

  // Frame type: KEY_FRAME(0), INTER_FRAME(1).
  frame_info->is_keyframe = !br.Read<bool>();
  frame_info->show_frame = br.Read<bool>();
  frame_info->error_resilient = br.Read<bool>();

  if (frame_info->is_keyframe) {
    if (br.ReadBits(24) != 0x498342) {
      RTC_LOG(LS_WARNING) << "Failed to parse header. Invalid sync code.";
      br.Invalidate();
      return;
    }

    Vp9ReadColorConfig(br, frame_info);
    Vp9ReadFrameSize(br, frame_info);
    Vp9ReadRenderSize(total_buffer_size_bits, br, frame_info);

    // Key-frames implicitly update all buffers.
    frame_info->updated_buffers.set();
  } else {
    // Non-keyframe.
    bool is_intra_only = false;
    if (!frame_info->show_frame) {
      is_intra_only = br.Read<bool>();
    }
    if (!frame_info->error_resilient) {
      br.ConsumeBits(2);  // Reset frame context.
    }

    if (is_intra_only) {
      if (br.ReadBits(24) != 0x498342) {
        RTC_LOG(LS_WARNING) << "Failed to parse header. Invalid sync code.";
        br.Invalidate();
        return;
      }

      if (frame_info->profile > 0) {
        Vp9ReadColorConfig(br, frame_info);
      } else {
        frame_info->color_space = Vp9ColorSpace::CS_BT_601;
        frame_info->sub_sampling = Vp9YuvSubsampling::k420;
        frame_info->bit_detph = Vp9BitDept::k8Bit;
      }
      frame_info->reference_buffers.fill(-1);
      ReadRefreshFrameFlags(br, frame_info);
      Vp9ReadFrameSize(br, frame_info);
      Vp9ReadRenderSize(total_buffer_size_bits, br, frame_info);
    } else {
      ReadRefreshFrameFlags(br, frame_info);

      frame_info->reference_buffers_sign_bias[0] = false;
      for (size_t i = 0; i < kVp9NumRefsPerFrame; i++) {
        frame_info->reference_buffers[i] = br.ReadBits(3);
        frame_info->reference_buffers_sign_bias[Vp9ReferenceFrame::kLast + i] =
            br.Read<bool>();
      }

      Vp9ReadFrameSizeFromRefs(br, frame_info);
      Vp9ReadRenderSize(total_buffer_size_bits, br, frame_info);

      frame_info->allow_high_precision_mv = br.Read<bool>();

      // Interpolation filter.
      if (br.Read<bool>()) {
        frame_info->interpolation_filter = Vp9InterpolationFilter::kSwitchable;
      } else {
        frame_info->interpolation_filter = kLiteralToType[br.ReadBits(2)];
      }
    }
  }

  if (!frame_info->error_resilient) {
    // 1 bit: Refresh frame context.
    // 1 bit: Frame parallel decoding mode.
    br.ConsumeBits(2);
  }

  // Frame context index.
  frame_info->frame_context_idx = br.ReadBits(2);

  frame_info->loop_filter_params_offset_bits =
      total_buffer_size_bits - br.RemainingBitCount();
  Vp9ReadLoopfilter(br);

  // Read base QP.
  Vp9ReadQp(br, frame_info);

  if (qp_only) {
    // Not interested in the rest of the header, return early.
    return;
  }

  Vp9ReadSegmentationParams(br, frame_info);
  Vp9ReadTileInfo(br, frame_info);
  frame_info->compressed_header_size = br.Read<uint16_t>();
  frame_info->uncompressed_header_size =
      (total_buffer_size_bits / 8) - (br.RemainingBitCount() / 8);
}

std::optional<Vp9UncompressedHeader> ParseUncompressedVp9Header(
    rtc::ArrayView<const uint8_t> buf) {
  BitstreamReader reader(buf);
  Vp9UncompressedHeader frame_info;
  Parse(reader, &frame_info, /*qp_only=*/false);
  if (reader.Ok() && frame_info.frame_width > 0) {
    return frame_info;
  }
  return std::nullopt;
}

namespace vp9 {

bool GetQp(const uint8_t* buf, size_t length, int* qp) {
  BitstreamReader reader(rtc::MakeArrayView(buf, length));
  Vp9UncompressedHeader frame_info;
  Parse(reader, &frame_info, /*qp_only=*/true);
  if (!reader.Ok()) {
    return false;
  }
  *qp = frame_info.base_qp;
  return true;
}

}  // namespace vp9
}  // namespace webrtc
