/*
 *  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 <cstddef>
#include <cstdint>
#include <optional>
#include <string>

#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "modules/video_coding/utility/vp9_constants.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(
    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(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
