// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/shared/starboard/player/video_frame_internal.h"

#include "starboard/log.h"
#include "starboard/memory.h"

namespace starboard {
namespace shared {
namespace starboard {
namespace player {

namespace {

bool s_yuv_to_rgb_lookup_table_initialized = false;
int s_y_to_rgb[256];
int s_v_to_r[256];
int s_u_to_g[256];
int s_v_to_g[256];
int s_u_to_b[256];
uint8_t s_clamp_table[256 * 3];

void EnsureYUVToRGBLookupTableInitialized() {
  if (s_yuv_to_rgb_lookup_table_initialized) {
    return;
  }

  // The YUV to RGBA conversion is based on
  //   http://www.equasys.de/colorconversion.html.
  // The formula is:
  // r = 1.164f * y                      + 1.793f * (v - 128);
  // g = 1.164f * y - 0.213f * (u - 128) - 0.533f * (v - 128);
  // b = 1.164f * y + 2.112f * (u - 128);
  // And r/g/b has to be clamped to [0, 255].
  //
  // We optimize the conversion algorithm by creating two kinds of lookup
  // tables.  The color component table contains pre-calculated color component
  // values.  The clamp table contains a map between |v| + 256 to the clamped
  // |v| to avoid conditional operation.
  SbMemorySet(s_clamp_table, 0, 256);
  SbMemorySet(s_clamp_table + 512, 0xff, 256);

  for (int i = 0; i < 256; ++i) {
    s_y_to_rgb[i] = (static_cast<uint8_t>(i) - 16) * 1.164f;
    s_v_to_r[i] = (static_cast<uint8_t>(i) - 128) * 1.793f;
    s_u_to_g[i] = (static_cast<uint8_t>(i) - 128) * -0.213;
    s_v_to_g[i] = (static_cast<uint8_t>(i) - 128) * -0.533f;
    s_u_to_b[i] = (static_cast<uint8_t>(i) - 128) * 2.112f;
    s_clamp_table[256 + i] = i;
  }

  s_yuv_to_rgb_lookup_table_initialized = true;
}

uint8_t ClampColorComponent(int component) {
  return s_clamp_table[component + 256];
}

}  // namespace

VideoFrame::VideoFrame(const VideoFrame& that) {
  *this = that;
}

VideoFrame& VideoFrame::operator=(const VideoFrame& that) {
  this->format_ = that.format_;

  this->pts_ = that.pts_;
  this->planes_ = that.planes_;
  this->pixel_buffer_ = that.pixel_buffer_;

  for (int i = 0; i < GetPlaneCount(); ++i) {
    const uint8_t* data = that.GetPlane(i).data;
    const uint8_t* base = &that.pixel_buffer_[0];
    ptrdiff_t offset = data - base;
    SB_DCHECK(offset >= 0);
    SB_DCHECK(offset < static_cast<ptrdiff_t>(that.pixel_buffer_.size()));
    planes_[i].data = &pixel_buffer_[0] + offset;
  }

  return *this;
}

const VideoFrame::Plane& VideoFrame::GetPlane(int index) const {
  SB_DCHECK(index >= 0 && index < GetPlaneCount()) << "Invalid index: "
                                                   << index;
  return planes_[index];
}

VideoFrame VideoFrame::ConvertTo(Format target_format) const {
  SB_DCHECK(format_ == kYV12);
  SB_DCHECK(target_format == kBGRA32);

  EnsureYUVToRGBLookupTableInitialized();

  VideoFrame target_frame;

  target_frame.format_ = target_format;
  target_frame.pts_ = pts_;
  target_frame.pixel_buffer_.resize(width() * height() * 4);
  target_frame.planes_.push_back(
      Plane(width(), height(), width() * 4, &target_frame.pixel_buffer_[0]));

  const uint8_t* y_data = GetPlane(0).data;
  const uint8_t* u_data = GetPlane(1).data;
  const uint8_t* v_data = GetPlane(2).data;
  uint8_t* bgra_data = &target_frame.pixel_buffer_[0];

  int height = this->height();
  int width = this->width();

  for (int row = 0; row < height; ++row) {
    const uint8_t* y = &y_data[row * GetPlane(0).pitch_in_bytes];
    const uint8_t* u = &u_data[row / 2 * GetPlane(1).pitch_in_bytes];
    const uint8_t* v = &v_data[row / 2 * GetPlane(2).pitch_in_bytes];
    int v_to_r, u_to_g, v_to_g, u_to_b;

    for (int column = 0; column < width; ++column) {
      if (column % 2 == 0) {
        v_to_r = s_v_to_r[*v];
        u_to_g = s_u_to_g[*u];
        v_to_g = s_v_to_g[*v];
        u_to_b = s_u_to_b[*u];
      } else {
        ++u, ++v;
      }

      int y_to_rgb = s_y_to_rgb[*y];
      int r = y_to_rgb + v_to_r;
      int g = y_to_rgb + u_to_g + v_to_g;
      int b = y_to_rgb + u_to_b;

      *bgra_data++ = ClampColorComponent(b);
      *bgra_data++ = ClampColorComponent(g);
      *bgra_data++ = ClampColorComponent(r);
      *bgra_data++ = 0xff;

      ++y;
    }
  }

  return target_frame;
}

// static
VideoFrame VideoFrame::CreateEOSFrame() {
  return VideoFrame();
}

// static
VideoFrame VideoFrame::CreateYV12Frame(int width,
                                       int height,
                                       int pitch_in_bytes,
                                       SbMediaTime pts,
                                       const uint8_t* y,
                                       const uint8_t* u,
                                       const uint8_t* v) {
  VideoFrame frame;
  frame.format_ = kYV12;
  frame.pts_ = pts;

  // U/V planes generally have half resolution of the Y plane.  However, in the
  // extreme case that any dimension of Y plane is odd, we want to have an
  // extra pixel on U/V planes.
  int uv_height = height / 2 + height % 2;
  int uv_width = width / 2 + width % 2;
  int uv_pitch_in_bytes = pitch_in_bytes / 2 + pitch_in_bytes % 2;

  int y_plane_size_in_bytes = height * pitch_in_bytes;
  int uv_plane_size_in_bytes = uv_height * uv_pitch_in_bytes;
  frame.pixel_buffer_.assign(y, y + y_plane_size_in_bytes);
  frame.pixel_buffer_.insert(frame.pixel_buffer_.end(), u,
                             u + uv_plane_size_in_bytes);
  frame.pixel_buffer_.insert(frame.pixel_buffer_.end(), v,
                             v + uv_plane_size_in_bytes);

  frame.planes_.push_back(
      Plane(width, height, pitch_in_bytes, &frame.pixel_buffer_[0]));
  frame.planes_.push_back(
      Plane(uv_width, uv_height, uv_pitch_in_bytes,
            &frame.pixel_buffer_[0] + y_plane_size_in_bytes));
  frame.planes_.push_back(Plane(uv_width, uv_height, uv_pitch_in_bytes,
                                &frame.pixel_buffer_[0] +
                                    y_plane_size_in_bytes +
                                    uv_plane_size_in_bytes));
  return frame;
}

}  // namespace player
}  // namespace starboard
}  // namespace shared
}  // namespace starboard
