// Copyright 2020 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.

#include "media/gpu/mac/vp9_super_frame_bitstream_filter.h"

#include "base/bits.h"
#include "base/check.h"
#include "base/logging.h"
#include "base/mac/mac_logging.h"
#include "media/filters/vp9_raw_bits_reader.h"

namespace {

void ReleaseDecoderBuffer(void* refcon,
                          void* doomed_memory_block,
                          size_t size_in_bytes) {
  if (refcon)
    static_cast<media::DecoderBuffer*>(refcon)->Release();
}

// See Annex B of the VP9 specification for details.
// https://www.webmproject.org/vp9/
constexpr uint8_t kSuperFrameMarker = 0b11000000;

}  // namespace

namespace media {

VP9SuperFrameBitstreamFilter::VP9SuperFrameBitstreamFilter() = default;
VP9SuperFrameBitstreamFilter::~VP9SuperFrameBitstreamFilter() = default;

bool VP9SuperFrameBitstreamFilter::EnqueueBuffer(
    scoped_refptr<DecoderBuffer> buffer) {
  DCHECK(!buffer->end_of_stream());

  Vp9RawBitsReader reader;
  reader.Initialize(buffer->data(), buffer->data_size());
  const bool show_frame = ShouldShowFrame(&reader);
  if (!reader.IsValid()) {
    DLOG(ERROR) << "Bitstream reading failed.";
    return false;
  }

  // See Vp9Parser::ParseSuperframe() for more details.
  const bool is_superframe =
      (buffer->data()[buffer->data_size() - 1] & 0xE0) == kSuperFrameMarker;
  if (is_superframe && data_) {
    DLOG(WARNING) << "Mixing of superframe and raw frames not supported";
    return false;
  }

  // Passthrough.
  if ((show_frame || is_superframe) && partial_buffers_.empty()) {
    DCHECK(!data_);
    return PreparePassthroughBuffer(std::move(buffer));
  }

  partial_buffers_.emplace_back(std::move(buffer));
  if (!show_frame)
    return true;

  // Time to merge buffers into one superframe.
  return BuildSuperFrame();
}

void VP9SuperFrameBitstreamFilter::Flush() {
  partial_buffers_.clear();
  data_.reset();
}

bool VP9SuperFrameBitstreamFilter::ShouldShowFrame(Vp9RawBitsReader* reader) {
  // See section 6.2 of the VP9 specification.
  reader->ReadLiteral(2);  // frame_marker

  uint8_t profile = 0;
  if (reader->ReadBool())  // profile_low_bit
    profile |= 1;
  if (reader->ReadBool())  // profile_high_bit
    profile |= 2;
  if (profile > 2 && reader->ReadBool())  // reserved_zero
    profile += 1;

  if (reader->ReadBool())  // show_existing_frame
    return true;

  reader->ReadBool();         // frame_type
  return reader->ReadBool();  // show_frame
}

bool VP9SuperFrameBitstreamFilter::PreparePassthroughBuffer(
    scoped_refptr<DecoderBuffer> buffer) {
  // The created CMBlockBuffer owns a ref on DecoderBuffer to avoid a copy.
  CMBlockBufferCustomBlockSource source = {0};
  source.refCon = buffer.get();
  source.FreeBlock = &ReleaseDecoderBuffer;

  // Create a memory-backed CMBlockBuffer for the translated data.
  OSStatus status = CMBlockBufferCreateWithMemoryBlock(
      kCFAllocatorDefault, static_cast<void*>(buffer->writable_data()),
      buffer->data_size(), kCFAllocatorDefault, &source, 0, buffer->data_size(),
      0, data_.InitializeInto());
  if (status != noErr) {
    OSSTATUS_DLOG(ERROR, status)
        << "CMBlockBufferCreateWithMemoryBlock failed.";
    return false;
  }

  buffer->AddRef();
  return true;
}

bool VP9SuperFrameBitstreamFilter::AllocateCombinedBlock(size_t total_size) {
  DCHECK(!data_);

  OSStatus status = CMBlockBufferCreateWithMemoryBlock(
      kCFAllocatorDefault, nullptr, total_size, kCFAllocatorDefault, nullptr, 0,
      total_size, 0, data_.InitializeInto());
  if (status != noErr) {
    OSSTATUS_DLOG(ERROR, status)
        << "CMBlockBufferCreateWithMemoryBlock failed.";
    return false;
  }

  status = CMBlockBufferAssureBlockMemory(data_);
  if (status != noErr) {
    OSSTATUS_DLOG(ERROR, status) << "CMBlockBufferAssureBlockMemory failed.";
    return false;
  }

  return true;
}

bool VP9SuperFrameBitstreamFilter::MergeBuffer(const DecoderBuffer& buffer,
                                               size_t offset) {
  OSStatus status = CMBlockBufferReplaceDataBytes(buffer.data(), data_, offset,
                                                  buffer.data_size());
  if (status != noErr) {
    OSSTATUS_DLOG(ERROR, status) << "CMBlockBufferReplaceDataBytes failed.";
    return false;
  }

  return true;
}

bool VP9SuperFrameBitstreamFilter::BuildSuperFrame() {
  DCHECK(!partial_buffers_.empty());

  // See Annex B of the VP9 specification for details on this process.

  // Calculate maximum and total size.
  size_t total_size = 0, max_size = 0;
  for (const auto& b : partial_buffers_) {
    total_size += b->data_size();
    if (b->data_size() > max_size)
      max_size = b->data_size();
  }

  const uint8_t bytes_per_frame_size =
      base::bits::AlignUp(
          base::bits::Log2Ceiling(base::checked_cast<uint32_t>(max_size)), 8) /
      8;
  DCHECK_GT(bytes_per_frame_size, 0);
  DCHECK_LE(bytes_per_frame_size, 4u);

  // A leading and trailing marker byte plus storage for each frame size.
  total_size += 2 + bytes_per_frame_size * partial_buffers_.size();

  // Allocate a block to hold the superframe.
  if (!AllocateCombinedBlock(total_size))
    return false;

  // Merge each buffer into our superframe.
  size_t offset = 0;
  for (const auto& b : partial_buffers_) {
    if (!MergeBuffer(*b, offset))
      return false;
    offset += b->data_size();
  }

  // Write superframe trailer which has size information for each buffer.
  size_t trailer_offset = 0;
  const size_t trailer_size = total_size - offset;
  std::unique_ptr<uint8_t[]> trailer(new uint8_t[trailer_size]);

  const uint8_t marker = kSuperFrameMarker + ((bytes_per_frame_size - 1) << 3) +
                         (partial_buffers_.size() - 1);

  trailer[trailer_offset++] = marker;
  for (const auto& b : partial_buffers_) {
    const uint32_t s = base::checked_cast<uint32_t>(b->data_size());
    DCHECK_LE(s, (1ULL << (bytes_per_frame_size * 8)) - 1);

    memcpy(&trailer[trailer_offset], &s, bytes_per_frame_size);
    trailer_offset += bytes_per_frame_size;
  }
  DCHECK_EQ(trailer_offset, trailer_size - 1);
  trailer[trailer_offset] = marker;

  OSStatus status =
      CMBlockBufferReplaceDataBytes(trailer.get(), data_, offset, trailer_size);
  if (status != noErr) {
    OSSTATUS_DLOG(ERROR, status) << "CMBlockBufferReplaceDataBytes failed.";
    return false;
  }

  partial_buffers_.clear();
  return true;
}

}  // namespace media
