// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// This file contains an implementation of a VP9 bitstream parser.
//
// VERBOSE level:
//  1 something wrong in bitstream
//  2 parsing steps
//  3 parsed values (selected)

#include "cobalt/media/filters/vp9_parser.h"

#include <algorithm>

#include "base/basictypes.h"
#include "base/bind.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "cobalt/media/filters/vp9_compressed_header_parser.h"
#include "cobalt/media/filters/vp9_uncompressed_header_parser.h"
#include "starboard/memory.h"

namespace cobalt {
namespace media {

bool Vp9FrameHeader::IsKeyframe() const {
  // When show_existing_frame is true, the frame header does not precede an
  // actual frame to be decoded, so frame_type does not apply (and is not read
  // from the stream).
  return !show_existing_frame && frame_type == KEYFRAME;
}

bool Vp9FrameHeader::IsIntra() const {
  return !show_existing_frame && (frame_type == KEYFRAME || intra_only);
}

Vp9Parser::FrameInfo::FrameInfo(const uint8_t* ptr, off_t size)
    : ptr(ptr), size(size) {}

bool Vp9FrameContext::IsValid() const {
  // probs should be in [1, 255] range.
  static_assert(sizeof(Vp9Prob) == 1,
                "following checks assuming Vp9Prob is single byte");
  if (SbMemoryFindByte(tx_probs_8x8, 0, sizeof(tx_probs_8x8))) return false;
  if (SbMemoryFindByte(tx_probs_16x16, 0, sizeof(tx_probs_16x16))) return false;
  if (SbMemoryFindByte(tx_probs_32x32, 0, sizeof(tx_probs_32x32))) return false;

  for (auto& a : coef_probs) {
    for (auto& ai : a) {
      for (auto& aj : ai) {
        for (auto& ak : aj) {
          int max_l = (ak == aj[0]) ? 3 : 6;
          for (int l = 0; l < max_l; l++) {
            for (auto& x : ak[l]) {
              if (x == 0) return false;
            }
          }
        }
      }
    }
  }
  if (SbMemoryFindByte(skip_prob, 0, sizeof(skip_prob))) return false;
  if (SbMemoryFindByte(inter_mode_probs, 0, sizeof(inter_mode_probs)))
    return false;
  if (SbMemoryFindByte(interp_filter_probs, 0, sizeof(interp_filter_probs)))
    return false;
  if (SbMemoryFindByte(is_inter_prob, 0, sizeof(is_inter_prob))) return false;
  if (SbMemoryFindByte(comp_mode_prob, 0, sizeof(comp_mode_prob))) return false;
  if (SbMemoryFindByte(single_ref_prob, 0, sizeof(single_ref_prob)))
    return false;
  if (SbMemoryFindByte(comp_ref_prob, 0, sizeof(comp_ref_prob))) return false;
  if (SbMemoryFindByte(y_mode_probs, 0, sizeof(y_mode_probs))) return false;
  if (SbMemoryFindByte(uv_mode_probs, 0, sizeof(uv_mode_probs))) return false;
  if (SbMemoryFindByte(partition_probs, 0, sizeof(partition_probs)))
    return false;
  if (SbMemoryFindByte(mv_joint_probs, 0, sizeof(mv_joint_probs))) return false;
  if (SbMemoryFindByte(mv_sign_prob, 0, sizeof(mv_sign_prob))) return false;
  if (SbMemoryFindByte(mv_class_probs, 0, sizeof(mv_class_probs))) return false;
  if (SbMemoryFindByte(mv_class0_bit_prob, 0, sizeof(mv_class0_bit_prob)))
    return false;
  if (SbMemoryFindByte(mv_bits_prob, 0, sizeof(mv_bits_prob))) return false;
  if (SbMemoryFindByte(mv_class0_fr_probs, 0, sizeof(mv_class0_fr_probs)))
    return false;
  if (SbMemoryFindByte(mv_fr_probs, 0, sizeof(mv_fr_probs))) return false;
  if (SbMemoryFindByte(mv_class0_hp_prob, 0, sizeof(mv_class0_hp_prob)))
    return false;
  if (SbMemoryFindByte(mv_hp_prob, 0, sizeof(mv_hp_prob))) return false;

  return true;
}

Vp9Parser::Context::Vp9FrameContextManager::Vp9FrameContextManager()
    : weak_ptr_factory_(this) {}

Vp9Parser::Context::Vp9FrameContextManager::~Vp9FrameContextManager() {}

const Vp9FrameContext&
Vp9Parser::Context::Vp9FrameContextManager::frame_context() const {
  DCHECK(initialized_);
  DCHECK(!needs_client_update_);
  return frame_context_;
}

void Vp9Parser::Context::Vp9FrameContextManager::Reset() {
  initialized_ = false;
  needs_client_update_ = false;
  weak_ptr_factory_.InvalidateWeakPtrs();
}

void Vp9Parser::Context::Vp9FrameContextManager::SetNeedsClientUpdate() {
  DCHECK(!needs_client_update_);
  initialized_ = true;
  needs_client_update_ = true;
}

Vp9Parser::ContextRefreshCallback
Vp9Parser::Context::Vp9FrameContextManager::GetUpdateCb() {
  if (needs_client_update_)
    return base::Bind(&Vp9FrameContextManager::UpdateFromClient,
                      weak_ptr_factory_.GetWeakPtr());
  else
    return Vp9Parser::ContextRefreshCallback();
}

void Vp9Parser::Context::Vp9FrameContextManager::Update(
    const Vp9FrameContext& frame_context) {
  // DCHECK because we can trust values from our parser.
  DCHECK(frame_context.IsValid());
  initialized_ = true;
  frame_context_ = frame_context;

  // For frame context we are updating, it may be still awaiting previous
  // ContextRefreshCallback. Because we overwrite the value of context here and
  // previous ContextRefreshCallback no longer matters, invalidate the weak ptr
  // to prevent previous ContextRefreshCallback run.
  // With this optimization, we may be able to parse more frames while previous
  // are still decoding.
  weak_ptr_factory_.InvalidateWeakPtrs();
  needs_client_update_ = false;
}

void Vp9Parser::Context::Vp9FrameContextManager::UpdateFromClient(
    const Vp9FrameContext& frame_context) {
  DVLOG(2) << "Got external frame_context update";
  DCHECK(needs_client_update_);
  if (!frame_context.IsValid()) {
    DLOG(ERROR) << "Invalid prob value in frame_context";
    return;
  }
  needs_client_update_ = false;
  initialized_ = true;
  frame_context_ = frame_context;
}

void Vp9Parser::Context::Reset() {
  SbMemorySet(&segmentation_, 0, sizeof(segmentation_));
  SbMemorySet(&loop_filter_, 0, sizeof(loop_filter_));
  SbMemorySet(&ref_slots_, 0, sizeof(ref_slots_));
  for (auto& manager : frame_context_managers_) manager.Reset();
}

void Vp9Parser::Context::MarkFrameContextForUpdate(size_t frame_context_idx) {
  DCHECK_LT(frame_context_idx, arraysize(frame_context_managers_));
  frame_context_managers_[frame_context_idx].SetNeedsClientUpdate();
}

void Vp9Parser::Context::UpdateFrameContext(
    size_t frame_context_idx, const Vp9FrameContext& frame_context) {
  DCHECK_LT(frame_context_idx, arraysize(frame_context_managers_));
  frame_context_managers_[frame_context_idx].Update(frame_context);
}

const Vp9Parser::ReferenceSlot& Vp9Parser::Context::GetRefSlot(
    size_t ref_type) const {
  DCHECK_LT(ref_type, arraysize(ref_slots_));
  return ref_slots_[ref_type];
}

void Vp9Parser::Context::UpdateRefSlot(
    size_t ref_type, const Vp9Parser::ReferenceSlot& ref_slot) {
  DCHECK_LT(ref_type, arraysize(ref_slots_));
  ref_slots_[ref_type] = ref_slot;
}

Vp9Parser::Vp9Parser(bool parsing_compressed_header)
    : parsing_compressed_header_(parsing_compressed_header) {
  Reset();
}

Vp9Parser::~Vp9Parser() {}

void Vp9Parser::SetStream(const uint8_t* stream, off_t stream_size) {
  DCHECK(stream);
  stream_ = stream;
  bytes_left_ = stream_size;
  frames_.clear();
}

void Vp9Parser::Reset() {
  stream_ = NULL;
  bytes_left_ = 0;
  frames_.clear();
  curr_frame_info_.Reset();

  context_.Reset();
}

Vp9Parser::Result Vp9Parser::ParseNextFrame(Vp9FrameHeader* fhdr) {
  DCHECK(fhdr);
  DVLOG(2) << "ParseNextFrame";

  // If |curr_frame_info_| is valid, uncompressed header was parsed into
  // |curr_frame_header_| and we are awaiting context update to proceed with
  // compressed header parsing.
  if (!curr_frame_info_.IsValid()) {
    if (frames_.empty()) {
      // No frames to be decoded, if there is no more stream, request more.
      if (!stream_) return kEOStream;

      // New stream to be parsed, parse it and fill frames_.
      frames_ = ParseSuperframe();
      if (frames_.empty()) {
        DVLOG(1) << "Failed parsing superframes";
        return kInvalidStream;
      }
    }

    curr_frame_info_ = frames_.front();
    frames_.pop_front();

    SbMemorySet(&curr_frame_header_, 0, sizeof(curr_frame_header_));

    Vp9UncompressedHeaderParser uncompressed_parser(&context_);
    if (!uncompressed_parser.Parse(curr_frame_info_.ptr, curr_frame_info_.size,
                                   &curr_frame_header_))
      return kInvalidStream;

    if (curr_frame_header_.header_size_in_bytes == 0) {
      // Verify padding bits are zero.
      for (off_t i = curr_frame_header_.uncompressed_header_size;
           i < curr_frame_info_.size; i++) {
        if (curr_frame_info_.ptr[i] != 0) {
          DVLOG(1) << "Padding bits are not zeros.";
          return kInvalidStream;
        }
      }
      *fhdr = curr_frame_header_;
      curr_frame_info_.Reset();
      return kOk;
    }
    if (curr_frame_header_.uncompressed_header_size +
            curr_frame_header_.header_size_in_bytes >
        base::checked_cast<size_t>(curr_frame_info_.size)) {
      DVLOG(1) << "header_size_in_bytes="
               << curr_frame_header_.header_size_in_bytes
               << " is larger than bytes left in buffer: "
               << curr_frame_info_.size -
                      curr_frame_header_.uncompressed_header_size;
      return kInvalidStream;
    }
  }

  if (parsing_compressed_header_) {
    size_t frame_context_idx = curr_frame_header_.frame_context_idx;
    const Context::Vp9FrameContextManager& context_to_load =
        context_.frame_context_managers_[frame_context_idx];
    if (!context_to_load.initialized()) {
      // 8.2 Frame order constraints
      // must load an initialized set of probabilities.
      DVLOG(1) << "loading uninitialized frame context, index="
               << frame_context_idx;
      return kInvalidStream;
    }
    if (context_to_load.needs_client_update()) {
      DVLOG(3) << "waiting frame_context_idx=" << frame_context_idx
               << " to update";
      return kAwaitingRefresh;
    }
    curr_frame_header_.initial_frame_context =
        curr_frame_header_.frame_context = context_to_load.frame_context();

    Vp9CompressedHeaderParser compressed_parser;
    if (!compressed_parser.Parse(
            curr_frame_info_.ptr + curr_frame_header_.uncompressed_header_size,
            curr_frame_header_.header_size_in_bytes, &curr_frame_header_)) {
      return kInvalidStream;
    }

    if (curr_frame_header_.refresh_frame_context) {
      // In frame parallel mode, we can refresh the context without decoding
      // tile data.
      if (curr_frame_header_.frame_parallel_decoding_mode) {
        context_.UpdateFrameContext(frame_context_idx,
                                    curr_frame_header_.frame_context);
      } else {
        context_.MarkFrameContextForUpdate(frame_context_idx);
      }
    }
  }

  SetupSegmentationDequant();
  SetupLoopFilter();
  UpdateSlots();

  *fhdr = curr_frame_header_;
  curr_frame_info_.Reset();
  return kOk;
}

Vp9Parser::ContextRefreshCallback Vp9Parser::GetContextRefreshCb(
    size_t frame_context_idx) {
  DCHECK_LT(frame_context_idx, arraysize(context_.frame_context_managers_));
  auto& frame_context_manager =
      context_.frame_context_managers_[frame_context_idx];

  return frame_context_manager.GetUpdateCb();
}

// Annex B Superframes
std::deque<Vp9Parser::FrameInfo> Vp9Parser::ParseSuperframe() {
  const uint8_t* stream = stream_;
  off_t bytes_left = bytes_left_;

  // Make sure we don't parse stream_ more than once.
  stream_ = NULL;
  bytes_left_ = 0;

  if (bytes_left < 1) return std::deque<FrameInfo>();

  // If this is a superframe, the last byte in the stream will contain the
  // superframe marker. If not, the whole buffer contains a single frame.
  uint8_t marker = *(stream + bytes_left - 1);
  if ((marker & 0xe0) != 0xc0) {
    return {FrameInfo(stream, bytes_left)};
  }

  DVLOG(1) << "Parsing a superframe";

  // The bytes immediately before the superframe marker constitute superframe
  // index, which stores information about sizes of each frame in it.
  // Calculate its size and set index_ptr to the beginning of it.
  size_t num_frames = (marker & 0x7) + 1;
  size_t mag = ((marker >> 3) & 0x3) + 1;
  off_t index_size = 2 + mag * num_frames;

  if (bytes_left < index_size) return std::deque<FrameInfo>();

  const uint8_t* index_ptr = stream + bytes_left - index_size;
  if (marker != *index_ptr) return std::deque<FrameInfo>();

  ++index_ptr;
  bytes_left -= index_size;

  // Parse frame information contained in the index and add a pointer to and
  // size of each frame to frames.
  std::deque<FrameInfo> frames;
  for (size_t i = 0; i < num_frames; ++i) {
    uint32_t size = 0;
    for (size_t j = 0; j < mag; ++j) {
      size |= *index_ptr << (j * 8);
      ++index_ptr;
    }

    if (base::checked_cast<off_t>(size) > bytes_left) {
      DVLOG(1) << "Not enough data in the buffer for frame " << i;
      return std::deque<FrameInfo>();
    }

    frames.push_back(FrameInfo(stream, size));
    stream += size;
    bytes_left -= size;

    DVLOG(1) << "Frame " << i << ", size: " << size;
  }

  return frames;
}

// 8.6.1
const size_t QINDEX_RANGE = 256;
const int16_t kDcQLookup[QINDEX_RANGE] = {
    4,   8,    8,    9,    10,   11,   12,   12,   13,   14,  15,  16,  17,
    18,  19,   19,   20,   21,   22,   23,   24,   25,   26,  26,  27,  28,
    29,  30,   31,   32,   32,   33,   34,   35,   36,   37,  38,  38,  39,
    40,  41,   42,   43,   43,   44,   45,   46,   47,   48,  48,  49,  50,
    51,  52,   53,   53,   54,   55,   56,   57,   57,   58,  59,  60,  61,
    62,  62,   63,   64,   65,   66,   66,   67,   68,   69,  70,  70,  71,
    72,  73,   74,   74,   75,   76,   77,   78,   78,   79,  80,  81,  81,
    82,  83,   84,   85,   85,   87,   88,   90,   92,   93,  95,  96,  98,
    99,  101,  102,  104,  105,  107,  108,  110,  111,  113, 114, 116, 117,
    118, 120,  121,  123,  125,  127,  129,  131,  134,  136, 138, 140, 142,
    144, 146,  148,  150,  152,  154,  156,  158,  161,  164, 166, 169, 172,
    174, 177,  180,  182,  185,  187,  190,  192,  195,  199, 202, 205, 208,
    211, 214,  217,  220,  223,  226,  230,  233,  237,  240, 243, 247, 250,
    253, 257,  261,  265,  269,  272,  276,  280,  284,  288, 292, 296, 300,
    304, 309,  313,  317,  322,  326,  330,  335,  340,  344, 349, 354, 359,
    364, 369,  374,  379,  384,  389,  395,  400,  406,  411, 417, 423, 429,
    435, 441,  447,  454,  461,  467,  475,  482,  489,  497, 505, 513, 522,
    530, 539,  549,  559,  569,  579,  590,  602,  614,  626, 640, 654, 668,
    684, 700,  717,  736,  755,  775,  796,  819,  843,  869, 896, 925, 955,
    988, 1022, 1058, 1098, 1139, 1184, 1232, 1282, 1336,
};

const int16_t kAcQLookup[QINDEX_RANGE] = {
    4,    8,    9,    10,   11,   12,   13,   14,   15,   16,   17,   18,
    19,   20,   21,   22,   23,   24,   25,   26,   27,   28,   29,   30,
    31,   32,   33,   34,   35,   36,   37,   38,   39,   40,   41,   42,
    43,   44,   45,   46,   47,   48,   49,   50,   51,   52,   53,   54,
    55,   56,   57,   58,   59,   60,   61,   62,   63,   64,   65,   66,
    67,   68,   69,   70,   71,   72,   73,   74,   75,   76,   77,   78,
    79,   80,   81,   82,   83,   84,   85,   86,   87,   88,   89,   90,
    91,   92,   93,   94,   95,   96,   97,   98,   99,   100,  101,  102,
    104,  106,  108,  110,  112,  114,  116,  118,  120,  122,  124,  126,
    128,  130,  132,  134,  136,  138,  140,  142,  144,  146,  148,  150,
    152,  155,  158,  161,  164,  167,  170,  173,  176,  179,  182,  185,
    188,  191,  194,  197,  200,  203,  207,  211,  215,  219,  223,  227,
    231,  235,  239,  243,  247,  251,  255,  260,  265,  270,  275,  280,
    285,  290,  295,  300,  305,  311,  317,  323,  329,  335,  341,  347,
    353,  359,  366,  373,  380,  387,  394,  401,  408,  416,  424,  432,
    440,  448,  456,  465,  474,  483,  492,  501,  510,  520,  530,  540,
    550,  560,  571,  582,  593,  604,  615,  627,  639,  651,  663,  676,
    689,  702,  715,  729,  743,  757,  771,  786,  801,  816,  832,  848,
    864,  881,  898,  915,  933,  951,  969,  988,  1007, 1026, 1046, 1066,
    1087, 1108, 1129, 1151, 1173, 1196, 1219, 1243, 1267, 1292, 1317, 1343,
    1369, 1396, 1423, 1451, 1479, 1508, 1537, 1567, 1597, 1628, 1660, 1692,
    1725, 1759, 1793, 1828,
};

static_assert(arraysize(kDcQLookup) == arraysize(kAcQLookup),
              "quantizer lookup arrays of incorrect size");

static size_t ClampQ(size_t q) {
  return std::min(std::max(static_cast<size_t>(0), q),
                  arraysize(kDcQLookup) - 1);
}

// 8.6.1 Dequantization functions
size_t Vp9Parser::GetQIndex(const Vp9QuantizationParams& quant,
                            size_t segid) const {
  const Vp9SegmentationParams& segmentation = context_.segmentation();

  if (segmentation.FeatureEnabled(segid,
                                  Vp9SegmentationParams::SEG_LVL_ALT_Q)) {
    int16_t feature_data =
        segmentation.FeatureData(segid, Vp9SegmentationParams::SEG_LVL_ALT_Q);
    size_t q_index = segmentation.abs_or_delta_update
                         ? feature_data
                         : quant.base_q_idx + feature_data;
    return ClampQ(q_index);
  }

  return quant.base_q_idx;
}

// 8.6.1 Dequantization functions
void Vp9Parser::SetupSegmentationDequant() {
  const Vp9QuantizationParams& quant = curr_frame_header_.quant_params;
  Vp9SegmentationParams& segmentation = context_.segmentation_;

  DLOG_IF(ERROR, curr_frame_header_.bit_depth > 8)
      << "bit_depth > 8 is not supported "
         "yet, kDcQLookup and kAcQLookup "
         "need extended";
  if (segmentation.enabled) {
    for (size_t i = 0; i < Vp9SegmentationParams::kNumSegments; ++i) {
      const size_t q_index = GetQIndex(quant, i);
      segmentation.y_dequant[i][0] =
          kDcQLookup[ClampQ(q_index + quant.delta_q_y_dc)];
      segmentation.y_dequant[i][1] = kAcQLookup[ClampQ(q_index)];
      segmentation.uv_dequant[i][0] =
          kDcQLookup[ClampQ(q_index + quant.delta_q_uv_dc)];
      segmentation.uv_dequant[i][1] =
          kAcQLookup[ClampQ(q_index + quant.delta_q_uv_ac)];
    }
  } else {
    const size_t q_index = quant.base_q_idx;
    segmentation.y_dequant[0][0] =
        kDcQLookup[ClampQ(q_index + quant.delta_q_y_dc)];
    segmentation.y_dequant[0][1] = kAcQLookup[ClampQ(q_index)];
    segmentation.uv_dequant[0][0] =
        kDcQLookup[ClampQ(q_index + quant.delta_q_uv_dc)];
    segmentation.uv_dequant[0][1] =
        kAcQLookup[ClampQ(q_index + quant.delta_q_uv_ac)];
  }
}

static int ClampLf(int lf) {
  const int kMaxLoopFilterLevel = 63;
  return std::min(std::max(0, lf), kMaxLoopFilterLevel);
}

// 8.8.1 Loop filter frame init process
void Vp9Parser::SetupLoopFilter() {
  Vp9LoopFilterParams& loop_filter = context_.loop_filter_;
  if (!loop_filter.level) return;

  int scale = loop_filter.level < 32 ? 1 : 2;

  for (size_t i = 0; i < Vp9SegmentationParams::kNumSegments; ++i) {
    int level = loop_filter.level;
    const Vp9SegmentationParams& segmentation = context_.segmentation();

    if (segmentation.FeatureEnabled(i, Vp9SegmentationParams::SEG_LVL_ALT_LF)) {
      int feature_data =
          segmentation.FeatureData(i, Vp9SegmentationParams::SEG_LVL_ALT_LF);
      level = ClampLf(segmentation.abs_or_delta_update ? feature_data
                                                       : level + feature_data);
    }

    if (!loop_filter.delta_enabled) {
      SbMemorySet(loop_filter.lvl[i], level, sizeof(loop_filter.lvl[i]));
    } else {
      loop_filter.lvl[i][Vp9RefType::VP9_FRAME_INTRA][0] = ClampLf(
          level + loop_filter.ref_deltas[Vp9RefType::VP9_FRAME_INTRA] * scale);
      loop_filter.lvl[i][Vp9RefType::VP9_FRAME_INTRA][1] = 0;

      for (size_t type = Vp9RefType::VP9_FRAME_LAST;
           type < Vp9RefType::VP9_FRAME_MAX; ++type) {
        for (size_t mode = 0; mode < Vp9LoopFilterParams::kNumModeDeltas;
             ++mode) {
          loop_filter.lvl[i][type][mode] =
              ClampLf(level + loop_filter.ref_deltas[type] * scale +
                      loop_filter.mode_deltas[mode] * scale);
        }
      }
    }
  }
}

void Vp9Parser::UpdateSlots() {
  // 8.10 Reference frame update process
  for (size_t i = 0; i < kVp9NumRefFrames; i++) {
    if (curr_frame_header_.RefreshFlag(i)) {
      ReferenceSlot ref_slot;
      ref_slot.initialized = true;

      ref_slot.frame_width = curr_frame_header_.frame_width;
      ref_slot.frame_height = curr_frame_header_.frame_height;
      ref_slot.subsampling_x = curr_frame_header_.subsampling_x;
      ref_slot.subsampling_y = curr_frame_header_.subsampling_y;
      ref_slot.bit_depth = curr_frame_header_.bit_depth;

      ref_slot.profile = curr_frame_header_.profile;
      ref_slot.color_space = curr_frame_header_.color_space;
      context_.UpdateRefSlot(i, ref_slot);
    }
  }
}

}  // namespace media
}  // namespace cobalt
