// Copyright 2018 The Fuchsia 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 "vp9_utils.h"

#include <byteswap.h>
#include <lib/ddk/debug.h>
#include <zircon/assert.h>
#include <zircon/compiler.h>

#include "macros.h"

namespace amlogic_decoder {

std::vector<uint32_t> TryParseSuperframeHeader(const uint8_t* data, uint32_t frame_size) {
  std::vector<uint32_t> frame_sizes;
  if (frame_size < 1)
    return frame_sizes;
  uint8_t superframe_header = data[frame_size - 1];

  // Split out superframes into separate frames - see
  // https://storage.googleapis.com/downloads.webmproject.org/docs/vp9/vp9-bitstream-specification-v0.6-20160331-draft.pdf
  // Annex B.
  if ((superframe_header & 0xe0) != 0xc0)
    return frame_sizes;
  uint8_t bytes_per_framesize = ((superframe_header >> 3) & 3) + 1;
  uint8_t superframe_count = (superframe_header & 7) + 1;
  uint32_t superframe_index_size = 2 + bytes_per_framesize * superframe_count;
  if (superframe_index_size > frame_size)
    return frame_sizes;
  if (data[frame_size - superframe_index_size] != superframe_header) {
    return frame_sizes;
  }
  const uint8_t* index_data = &data[frame_size - superframe_index_size + 1];
  uint32_t total_size = 0;
  for (uint32_t i = 0; i < superframe_count; i++) {
    uint32_t sub_frame_size;
    switch (bytes_per_framesize) {
      case 1:
        sub_frame_size = index_data[i];
        break;
      case 2:
        sub_frame_size = reinterpret_cast<const uint16_t*>(index_data)[i];
        break;
      case 3:
        sub_frame_size = 0;
        for (uint32_t j = 0; j < 3; ++j) {
          sub_frame_size |= static_cast<uint32_t>(index_data[i * 3 + j]) << (j * 8);
        }
        break;
      case 4:
        sub_frame_size = reinterpret_cast<const uint32_t*>(index_data)[i];
        break;
      default:
        zxlogf(ERROR, "Unsupported bytes_per_framesize: %d", bytes_per_framesize);
        frame_sizes.clear();
        return frame_sizes;
    }
    total_size += sub_frame_size;
    if (total_size > frame_size) {
      zxlogf(ERROR, "Total superframe size too large: %u > %u", total_size, frame_size);
      frame_sizes.clear();
      return frame_sizes;
    }
    frame_sizes.push_back(sub_frame_size);
  }
  return frame_sizes;
}

void SplitSuperframe(const uint8_t* data, uint32_t frame_size, std::vector<uint8_t>* output_vector,
                     std::vector<uint32_t>* superframe_byte_sizes, bool like_secmem) {
  std::vector<uint32_t> frame_sizes = TryParseSuperframeHeader(data, frame_size);

  if (frame_sizes.empty())
    frame_sizes.push_back(frame_size);
  uint32_t frame_offset = 0;
  uint32_t total_frame_bytes = 0;
  for (auto& size : frame_sizes) {
    total_frame_bytes += size;
  }
  ZX_DEBUG_ASSERT_MSG(total_frame_bytes <= frame_size, "total_frame_bytes: 0x%x frame_size: 0x%x",
                      total_frame_bytes, frame_size);
  uint64_t output_offset = output_vector->size();
  // This can be called multiple times on the same output_vector overall, but
  // should be amortized O(1), since resizing larger inserts elements at the end
  // and inserting elements at the end is amortized O(1) for std::vector.
  uint64_t output_vector_size_increase = kVp9AmlvHeaderSize * frame_sizes.size();
  if (like_secmem) {
    output_vector_size_increase += frame_size;
  } else {
    output_vector_size_increase += total_frame_bytes;
  }
  output_vector->resize(output_offset + output_vector_size_increase);
  uint8_t* output = &(*output_vector)[output_offset];
  for (auto& size : frame_sizes) {
    ZX_DEBUG_ASSERT(output + kVp9AmlvHeaderSize - output_vector->data() <=
                    static_cast<int64_t>(output_vector->size()));
    *reinterpret_cast<uint32_t*>(output) = bswap_32(size + 4);
    output += 4;
    *reinterpret_cast<uint32_t*>(output) = ~bswap_32(size + 4);
    output += 4;
    *output++ = 0;
    *output++ = 0;
    *output++ = 0;
    *output++ = 1;
    *output++ = 'A';
    *output++ = 'M';
    *output++ = 'L';
    *output++ = 'V';

    ZX_DEBUG_ASSERT(output + size - output_vector->data() <=
                    static_cast<int64_t>(output_vector->size()));
    memcpy(output, &data[frame_offset], size);
    output += size;
    frame_offset += size;
    if (superframe_byte_sizes) {
      superframe_byte_sizes->push_back(size + kVp9AmlvHeaderSize);
    }
  }
  if (like_secmem) {
    ZX_DEBUG_ASSERT(output - output_vector->data() + frame_size - total_frame_bytes ==
                    static_cast<int64_t>(output_vector->size()));
  } else {
    ZX_DEBUG_ASSERT(output - output_vector->data() == static_cast<int64_t>(output_vector->size()));
  }
}

fpromise::result<bool, fuchsia::media::StreamError> IsVp9KeyFrame(uint8_t frame_header_byte_0) {
  // We could make a bit-shifter class, but ... not really parsing that much here...
  uint8_t byte_0_shifter = frame_header_byte_0;
  uint8_t frame_marker = byte_0_shifter >> 6;
  byte_0_shifter <<= 2;
  if (frame_marker != kVp9FrameMarker) {
    LOG(ERROR, "frame marker not 2");
    return fpromise::error(fuchsia::media::StreamError::DECODER_DATA_PARSING);
  }
  uint8_t profile_low_bit = byte_0_shifter >> 7;
  byte_0_shifter <<= 1;
  uint8_t profile_high_bit = byte_0_shifter >> 7;
  byte_0_shifter <<= 1;
  uint8_t profile = static_cast<uint8_t>((profile_high_bit << 1) | profile_low_bit);
  if (profile == 3) {
    uint8_t reserved_zero = byte_0_shifter >> 7;
    byte_0_shifter <<= 1;
    if (reserved_zero != 0) {
      LOG(ERROR, "reserved_zero not zero");
      return fpromise::error(fuchsia::media::StreamError::DECODER_DATA_PARSING);
    }
  }

  uint8_t show_existing_frame = byte_0_shifter >> 7;
  byte_0_shifter <<= 1;
  if (show_existing_frame) {
    // without having seen a keyframe, a show_existing_frame isn't going to find the frame it
    // wants to show.
    LOG(DEBUG, "show_existing_frame");
    return fpromise::ok(false);
  }
  ZX_DEBUG_ASSERT(!show_existing_frame);

  uint8_t frame_type = byte_0_shifter >> 7;
  byte_0_shifter <<= 1;
  if (frame_type != kVp9FrameTypeKeyFrame) {
    // without having seen a keyframe, a non-keyframe isn't going to be able to decode
    // properly, so skip.
    LOG(DEBUG, "frame_type != kVp9FrameTypeKeyFrame");
    return fpromise::ok(false);
  }
  ZX_DEBUG_ASSERT(frame_type == kVp9FrameTypeKeyFrame);

  return fpromise::ok(true);
}

}  // namespace amlogic_decoder
