// Copyright (c) 2012 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 "cobalt/media/base/video_frame.h"

#include <algorithm>
#include <climits>

#include "base/atomic_sequence_num.h"
#include "base/basictypes.h"
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/logging.h"
#include "base/memory/aligned_memory.h"
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "cobalt/media/base/limits.h"
#include "cobalt/media/base/timestamp_constants.h"
#include "cobalt/media/base/video_util.h"
#include "starboard/memory.h"
#include "ui/gfx/geometry/point.h"

namespace cobalt {
namespace media {

// Static POD class for generating unique identifiers for each VideoFrame.
static base::AtomicSequenceNumber g_unique_id_generator;

static bool IsPowerOfTwo(size_t x) { return x != 0 && (x & (x - 1)) == 0; }

static inline size_t RoundUp(size_t value, size_t alignment) {
  DCHECK(IsPowerOfTwo(alignment));
  return ((value + (alignment - 1)) & ~(alignment - 1));
}

static inline size_t RoundDown(size_t value, size_t alignment) {
  DCHECK(IsPowerOfTwo(alignment));
  return value & ~(alignment - 1);
}

static std::string StorageTypeToString(
    const VideoFrame::StorageType storage_type) {
  switch (storage_type) {
    case VideoFrame::STORAGE_UNKNOWN:
      return "UNKNOWN";
    case VideoFrame::STORAGE_OPAQUE:
      return "OPAQUE";
    case VideoFrame::STORAGE_UNOWNED_MEMORY:
      return "UNOWNED_MEMORY";
    case VideoFrame::STORAGE_OWNED_MEMORY:
      return "OWNED_MEMORY";
    case VideoFrame::STORAGE_SHMEM:
      return "SHMEM";
#if defined(OS_LINUX)
    case VideoFrame::STORAGE_DMABUFS:
      return "DMABUFS";
#endif
    case VideoFrame::STORAGE_GPU_MEMORY_BUFFERS:
      return "GPU_MEMORY_BUFFERS";
    case VideoFrame::STORAGE_MOJO_SHARED_BUFFER:
      return "MOJO_SHARED_BUFFER";
  }

  NOTREACHED() << "Invalid StorageType provided: " << storage_type;
  return "INVALID";
}

// Returns true if |frame| is accesible mapped in the VideoFrame memory space.
// static
static bool IsStorageTypeMappable(VideoFrame::StorageType storage_type) {
  return
#if defined(OS_LINUX)
      // This is not strictly needed but makes explicit that, at VideoFrame
      // level, DmaBufs are not mappable from userspace.
      storage_type != VideoFrame::STORAGE_DMABUFS &&
#endif
      (storage_type == VideoFrame::STORAGE_UNOWNED_MEMORY ||
       storage_type == VideoFrame::STORAGE_OWNED_MEMORY ||
       storage_type == VideoFrame::STORAGE_SHMEM ||
       storage_type == VideoFrame::STORAGE_GPU_MEMORY_BUFFERS ||
       storage_type == VideoFrame::STORAGE_MOJO_SHARED_BUFFER);
}

// Checks if |source_format| can be wrapped into a |target_format| frame.
static bool AreValidPixelFormatsForWrap(VideoPixelFormat source_format,
                                        VideoPixelFormat target_format) {
  if (source_format == target_format) return true;

  // It is possible to add other planar to planar format conversions here if the
  // use case is there.
  return source_format == PIXEL_FORMAT_YV12A &&
         target_format == PIXEL_FORMAT_I420;
}

// static
bool VideoFrame::IsValidConfig(VideoPixelFormat format,
                               StorageType storage_type,
                               const gfx::Size& coded_size,
                               const gfx::Rect& visible_rect,
                               const gfx::Size& natural_size) {
  // Check maximum limits for all formats.
  int coded_size_area = coded_size.GetCheckedArea().ValueOrDefault(INT_MAX);
  int natural_size_area = natural_size.GetCheckedArea().ValueOrDefault(INT_MAX);
  static_assert(limits::kMaxCanvas < INT_MAX, "");
  if (coded_size_area > limits::kMaxCanvas ||
      coded_size.width() > limits::kMaxDimension ||
      coded_size.height() > limits::kMaxDimension || visible_rect.x() < 0 ||
      visible_rect.y() < 0 || visible_rect.right() > coded_size.width() ||
      visible_rect.bottom() > coded_size.height() ||
      natural_size_area > limits::kMaxCanvas ||
      natural_size.width() > limits::kMaxDimension ||
      natural_size.height() > limits::kMaxDimension)
    return false;

  // TODO(mcasas): Remove parameter |storage_type| when the opaque storage types
  // comply with the checks below. Right now we skip them.
  if (!IsStorageTypeMappable(storage_type)) return true;

  // Make sure new formats are properly accounted for in the method.
  static_assert(PIXEL_FORMAT_MAX == 26,
                "Added pixel format, please review IsValidConfig()");

  if (format == PIXEL_FORMAT_UNKNOWN) {
    return coded_size.IsEmpty() && visible_rect.IsEmpty() &&
           natural_size.IsEmpty();
  }

  // Check that software-allocated buffer formats are not empty.
  return !coded_size.IsEmpty() && !visible_rect.IsEmpty() &&
         !natural_size.IsEmpty();
}

// static
scoped_refptr<VideoFrame> VideoFrame::CreateFrame(VideoPixelFormat format,
                                                  const gfx::Size& coded_size,
                                                  const gfx::Rect& visible_rect,
                                                  const gfx::Size& natural_size,
                                                  base::TimeDelta timestamp) {
  return CreateFrameInternal(format, coded_size, visible_rect, natural_size,
                             timestamp, false);
}

// static
scoped_refptr<VideoFrame> VideoFrame::CreateZeroInitializedFrame(
    VideoPixelFormat format, const gfx::Size& coded_size,
    const gfx::Rect& visible_rect, const gfx::Size& natural_size,
    base::TimeDelta timestamp) {
  return CreateFrameInternal(format, coded_size, visible_rect, natural_size,
                             timestamp, true);
}

// static
scoped_refptr<VideoFrame> VideoFrame::WrapNativeTextures(
    VideoPixelFormat format,
    const gpu::MailboxHolder (&mailbox_holders)[kMaxPlanes],
    const ReleaseMailboxCB& mailbox_holder_release_cb,
    const gfx::Size& coded_size, const gfx::Rect& visible_rect,
    const gfx::Size& natural_size, base::TimeDelta timestamp) {
  if (format != PIXEL_FORMAT_ARGB && format != PIXEL_FORMAT_XRGB &&
      format != PIXEL_FORMAT_UYVY && format != PIXEL_FORMAT_NV12 &&
      format != PIXEL_FORMAT_I420) {
    LOG(DFATAL) << "Unsupported pixel format supported, got "
                << VideoPixelFormatToString(format);
    return NULL;
  }
  const StorageType storage = STORAGE_OPAQUE;
  if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) {
    LOG(DFATAL) << __func__ << " Invalid config."
                << ConfigToString(format, storage, coded_size, visible_rect,
                                  natural_size);
    return NULL;
  }

  return new VideoFrame(format, storage, coded_size, visible_rect, natural_size,
                        mailbox_holders, mailbox_holder_release_cb, timestamp);
}

// static
scoped_refptr<VideoFrame> VideoFrame::WrapExternalData(
    VideoPixelFormat format, const gfx::Size& coded_size,
    const gfx::Rect& visible_rect, const gfx::Size& natural_size, uint8_t* data,
    size_t data_size, base::TimeDelta timestamp) {
  return WrapExternalStorage(format, STORAGE_UNOWNED_MEMORY, coded_size,
                             visible_rect, natural_size, data, data_size,
                             timestamp, base::SharedMemory::NULLHandle(), 0);
}

// static
scoped_refptr<VideoFrame> VideoFrame::WrapExternalSharedMemory(
    VideoPixelFormat format, const gfx::Size& coded_size,
    const gfx::Rect& visible_rect, const gfx::Size& natural_size, uint8_t* data,
    size_t data_size, base::SharedMemoryHandle handle, size_t data_offset,
    base::TimeDelta timestamp) {
  return WrapExternalStorage(format, STORAGE_SHMEM, coded_size, visible_rect,
                             natural_size, data, data_size, timestamp, handle,
                             data_offset);
}

// static
scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvData(
    VideoPixelFormat format, const gfx::Size& coded_size,
    const gfx::Rect& visible_rect, const gfx::Size& natural_size,
    int32_t y_stride, int32_t u_stride, int32_t v_stride, uint8_t* y_data,
    uint8_t* u_data, uint8_t* v_data, base::TimeDelta timestamp) {
  const StorageType storage = STORAGE_UNOWNED_MEMORY;
  if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) {
    LOG(DFATAL) << __func__ << " Invalid config."
                << ConfigToString(format, storage, coded_size, visible_rect,
                                  natural_size);
    return NULL;
  }

  scoped_refptr<VideoFrame> frame(new VideoFrame(
      format, storage, coded_size, visible_rect, natural_size, timestamp));
  frame->strides_[kYPlane] = y_stride;
  frame->strides_[kUPlane] = u_stride;
  frame->strides_[kVPlane] = v_stride;
  frame->data_[kYPlane] = y_data;
  frame->data_[kUPlane] = u_data;
  frame->data_[kVPlane] = v_data;
  return frame;
}

// static
scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvGpuMemoryBuffers(
    VideoPixelFormat format, const gfx::Size& coded_size,
    const gfx::Rect& visible_rect, const gfx::Size& natural_size,
    int32_t y_stride, int32_t u_stride, int32_t v_stride, uint8_t* y_data,
    uint8_t* u_data, uint8_t* v_data,
    const gfx::GpuMemoryBufferHandle& y_handle,
    const gfx::GpuMemoryBufferHandle& u_handle,
    const gfx::GpuMemoryBufferHandle& v_handle, base::TimeDelta timestamp) {
  const StorageType storage = STORAGE_GPU_MEMORY_BUFFERS;
  if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) {
    LOG(DFATAL) << __func__ << " Invalid config."
                << ConfigToString(format, storage, coded_size, visible_rect,
                                  natural_size);
    return NULL;
  }

  scoped_refptr<VideoFrame> frame(new VideoFrame(
      format, storage, coded_size, visible_rect, natural_size, timestamp));
  frame->strides_[kYPlane] = y_stride;
  frame->strides_[kUPlane] = u_stride;
  frame->strides_[kVPlane] = v_stride;
  frame->data_[kYPlane] = y_data;
  frame->data_[kUPlane] = u_data;
  frame->data_[kVPlane] = v_data;
  frame->gpu_memory_buffer_handles_.push_back(y_handle);
  frame->gpu_memory_buffer_handles_.push_back(u_handle);
  frame->gpu_memory_buffer_handles_.push_back(v_handle);
  return frame;
}

// static
scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvaData(
    VideoPixelFormat format, const gfx::Size& coded_size,
    const gfx::Rect& visible_rect, const gfx::Size& natural_size,
    int32_t y_stride, int32_t u_stride, int32_t v_stride, int32_t a_stride,
    uint8_t* y_data, uint8_t* u_data, uint8_t* v_data, uint8_t* a_data,
    base::TimeDelta timestamp) {
  const StorageType storage = STORAGE_UNOWNED_MEMORY;
  if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) {
    LOG(DFATAL) << __func__ << " Invalid config."
                << ConfigToString(format, storage, coded_size, visible_rect,
                                  natural_size);
    return NULL;
  }

  if (NumPlanes(format) != 4) {
    LOG(DFATAL) << "Expecting Y, U, V and A planes to be present for the video"
                << " format.";
    return NULL;
  }

  scoped_refptr<VideoFrame> frame(new VideoFrame(
      format, storage, coded_size, visible_rect, natural_size, timestamp));
  frame->strides_[kYPlane] = y_stride;
  frame->strides_[kUPlane] = u_stride;
  frame->strides_[kVPlane] = v_stride;
  frame->strides_[kAPlane] = a_stride;
  frame->data_[kYPlane] = y_data;
  frame->data_[kUPlane] = u_data;
  frame->data_[kVPlane] = v_data;
  frame->data_[kAPlane] = a_data;
  return frame;
}

#if defined(OS_LINUX)
// static
scoped_refptr<VideoFrame> VideoFrame::WrapExternalDmabufs(
    VideoPixelFormat format, const gfx::Size& coded_size,
    const gfx::Rect& visible_rect, const gfx::Size& natural_size,
    const std::vector<int>& dmabuf_fds, base::TimeDelta timestamp) {
  const StorageType storage = STORAGE_DMABUFS;
  if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) {
    LOG(DFATAL) << __func__ << " Invalid config."
                << ConfigToString(format, storage, coded_size, visible_rect,
                                  natural_size);
    return NULL;
  }

  gpu::MailboxHolder mailbox_holders[kMaxPlanes];
  scoped_refptr<VideoFrame> frame =
      new VideoFrame(format, storage, coded_size, visible_rect, natural_size,
                     mailbox_holders, ReleaseMailboxCB(), timestamp);
  if (!frame || !frame->DuplicateFileDescriptors(dmabuf_fds)) {
    LOG(DFATAL) << __func__ << " Couldn't duplicate fds.";
    return NULL;
  }
  return frame;
}
#endif

#if defined(OS_MACOSX)
// static
scoped_refptr<VideoFrame> VideoFrame::WrapCVPixelBuffer(
    CVPixelBufferRef cv_pixel_buffer, base::TimeDelta timestamp) {
  DCHECK(cv_pixel_buffer);
  DCHECK(CFGetTypeID(cv_pixel_buffer) == CVPixelBufferGetTypeID());

  const OSType cv_format = CVPixelBufferGetPixelFormatType(cv_pixel_buffer);
  VideoPixelFormat format;
  // There are very few compatible CV pixel formats, so just check each.
  if (cv_format == kCVPixelFormatType_420YpCbCr8Planar) {
    format = PIXEL_FORMAT_I420;
  } else if (cv_format == kCVPixelFormatType_444YpCbCr8) {
    format = PIXEL_FORMAT_YV24;
  } else if (cv_format == '420v') {
    // TODO(jfroy): Use kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange when the
    // minimum OS X and iOS SDKs permits it.
    format = PIXEL_FORMAT_NV12;
  } else {
    LOG(DFATAL) << "CVPixelBuffer format not supported: " << cv_format;
    return NULL;
  }

  const gfx::Size coded_size(CVImageBufferGetEncodedSize(cv_pixel_buffer));
  const gfx::Rect visible_rect(CVImageBufferGetCleanRect(cv_pixel_buffer));
  const gfx::Size natural_size(CVImageBufferGetDisplaySize(cv_pixel_buffer));
  const StorageType storage = STORAGE_UNOWNED_MEMORY;

  if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) {
    LOG(DFATAL) << __func__ << " Invalid config."
                << ConfigToString(format, storage, coded_size, visible_rect,
                                  natural_size);
    return NULL;
  }

  scoped_refptr<VideoFrame> frame(new VideoFrame(
      format, storage, coded_size, visible_rect, natural_size, timestamp));

  frame->cv_pixel_buffer_.reset(cv_pixel_buffer, base::scoped_policy::RETAIN);
  return frame;
}
#endif

// static
scoped_refptr<VideoFrame> VideoFrame::WrapVideoFrame(
    const scoped_refptr<VideoFrame>& frame, VideoPixelFormat format,
    const gfx::Rect& visible_rect, const gfx::Size& natural_size) {
  // Frames with textures need mailbox info propagated, and there's no support
  // for that here yet, see http://crbug/362521.
  CHECK(!frame->HasTextures());
  DCHECK(frame->visible_rect().Contains(visible_rect));

  if (!AreValidPixelFormatsForWrap(frame->format(), format)) {
    LOG(DFATAL) << __func__ << " Invalid format conversion."
                << VideoPixelFormatToString(frame->format()) << " to "
                << VideoPixelFormatToString(format);
    return NULL;
  }

  if (!IsValidConfig(format, frame->storage_type(), frame->coded_size(),
                     visible_rect, natural_size)) {
    LOG(DFATAL) << __func__ << " Invalid config."
                << ConfigToString(format, frame->storage_type(),
                                  frame->coded_size(), visible_rect,
                                  natural_size);
    return NULL;
  }

  scoped_refptr<VideoFrame> wrapping_frame(
      new VideoFrame(format, frame->storage_type(), frame->coded_size(),
                     visible_rect, natural_size, frame->timestamp()));

  // Copy all metadata to the wrapped frame.
  wrapping_frame->metadata()->MergeMetadataFrom(frame->metadata());

  for (size_t i = 0; i < NumPlanes(format); ++i) {
    wrapping_frame->strides_[i] = frame->stride(i);
    wrapping_frame->data_[i] = frame->data(i);
  }

#if defined(OS_LINUX)
  // If there are any |dmabuf_fds_| plugged in, we should duplicate them.
  if (frame->storage_type() == STORAGE_DMABUFS) {
    std::vector<int> original_fds;
    for (size_t i = 0; i < kMaxPlanes; ++i)
      original_fds.push_back(frame->dmabuf_fd(i));
    if (!wrapping_frame->DuplicateFileDescriptors(original_fds)) {
      LOG(DFATAL) << __func__ << " Couldn't duplicate fds.";
      return NULL;
    }
  }
#endif

  if (frame->storage_type() == STORAGE_SHMEM)
    wrapping_frame->AddSharedMemoryHandle(frame->shared_memory_handle_);

  return wrapping_frame;
}

// static
scoped_refptr<VideoFrame> VideoFrame::CreateEOSFrame() {
  scoped_refptr<VideoFrame> frame =
      new VideoFrame(PIXEL_FORMAT_UNKNOWN, STORAGE_UNKNOWN, gfx::Size(),
                     gfx::Rect(), gfx::Size(), kNoTimestamp);
  frame->metadata()->SetBoolean(VideoFrameMetadata::END_OF_STREAM, true);
  return frame;
}

// static
scoped_refptr<VideoFrame> VideoFrame::CreateColorFrame(
    const gfx::Size& size, uint8_t y, uint8_t u, uint8_t v,
    base::TimeDelta timestamp) {
  scoped_refptr<VideoFrame> frame =
      CreateFrame(PIXEL_FORMAT_YV12, size, gfx::Rect(size), size, timestamp);
  FillYUV(frame.get(), y, u, v);
  return frame;
}

// static
scoped_refptr<VideoFrame> VideoFrame::CreateBlackFrame(const gfx::Size& size) {
  const uint8_t kBlackY = 0x00;
  const uint8_t kBlackUV = 0x80;
  const base::TimeDelta kZero;
  return CreateColorFrame(size, kBlackY, kBlackUV, kBlackUV, kZero);
}

// static
scoped_refptr<VideoFrame> VideoFrame::CreateTransparentFrame(
    const gfx::Size& size) {
  const uint8_t kBlackY = 0x00;
  const uint8_t kBlackUV = 0x00;
  const uint8_t kTransparentA = 0x00;
  const base::TimeDelta kZero;
  scoped_refptr<VideoFrame> frame =
      CreateFrame(PIXEL_FORMAT_YV12A, size, gfx::Rect(size), size, kZero);
  FillYUVA(frame.get(), kBlackY, kBlackUV, kBlackUV, kTransparentA);
  return frame;
}

// static
size_t VideoFrame::NumPlanes(VideoPixelFormat format) {
  switch (format) {
    case PIXEL_FORMAT_UYVY:
    case PIXEL_FORMAT_YUY2:
    case PIXEL_FORMAT_ARGB:
    case PIXEL_FORMAT_XRGB:
    case PIXEL_FORMAT_RGB24:
    case PIXEL_FORMAT_RGB32:
    case PIXEL_FORMAT_MJPEG:
    case PIXEL_FORMAT_Y8:
    case PIXEL_FORMAT_Y16:
      return 1;
    case PIXEL_FORMAT_NV12:
    case PIXEL_FORMAT_NV21:
    case PIXEL_FORMAT_MT21:
      return 2;
    case PIXEL_FORMAT_I420:
    case PIXEL_FORMAT_YV12:
    case PIXEL_FORMAT_YV16:
    case PIXEL_FORMAT_YV24:
    case PIXEL_FORMAT_YUV420P9:
    case PIXEL_FORMAT_YUV422P9:
    case PIXEL_FORMAT_YUV444P9:
    case PIXEL_FORMAT_YUV420P10:
    case PIXEL_FORMAT_YUV422P10:
    case PIXEL_FORMAT_YUV444P10:
    case PIXEL_FORMAT_YUV420P12:
    case PIXEL_FORMAT_YUV422P12:
    case PIXEL_FORMAT_YUV444P12:
      return 3;
    case PIXEL_FORMAT_YV12A:
      return 4;
    case PIXEL_FORMAT_UNKNOWN:
      break;
  }
  NOTREACHED() << "Unsupported video frame format: " << format;
  return 0;
}

// static
size_t VideoFrame::AllocationSize(VideoPixelFormat format,
                                  const gfx::Size& coded_size) {
  size_t total = 0;
  for (size_t i = 0; i < NumPlanes(format); ++i)
    total += PlaneSize(format, i, coded_size).GetArea();
  return total;
}

// static
gfx::Size VideoFrame::PlaneSize(VideoPixelFormat format, size_t plane,
                                const gfx::Size& coded_size) {
  DCHECK(IsValidPlane(plane, format));

  int width = coded_size.width();
  int height = coded_size.height();
  if (format != PIXEL_FORMAT_ARGB) {
    // Align to multiple-of-two size overall. This ensures that non-subsampled
    // planes can be addressed by pixel with the same scaling as the subsampled
    // planes.
    width = RoundUp(width, 2);
    height = RoundUp(height, 2);
  }

  const gfx::Size subsample = SampleSize(format, plane);
  DCHECK_EQ(width % subsample.width(), 0);
  DCHECK_EQ(height % subsample.height(), 0);
  return gfx::Size(BytesPerElement(format, plane) * width / subsample.width(),
                   height / subsample.height());
}

// static
int VideoFrame::PlaneHorizontalBitsPerPixel(VideoPixelFormat format,
                                            size_t plane) {
  DCHECK(IsValidPlane(plane, format));
  const int bits_per_element = 8 * BytesPerElement(format, plane);
  const int horiz_pixels_per_element = SampleSize(format, plane).width();
  DCHECK_EQ(bits_per_element % horiz_pixels_per_element, 0);
  return bits_per_element / horiz_pixels_per_element;
}

// static
int VideoFrame::PlaneBitsPerPixel(VideoPixelFormat format, size_t plane) {
  DCHECK(IsValidPlane(plane, format));
  return PlaneHorizontalBitsPerPixel(format, plane) /
         SampleSize(format, plane).height();
}

// static
size_t VideoFrame::RowBytes(size_t plane, VideoPixelFormat format, int width) {
  DCHECK(IsValidPlane(plane, format));
  return BytesPerElement(format, plane) * Columns(plane, format, width);
}

// static
size_t VideoFrame::Rows(size_t plane, VideoPixelFormat format, int height) {
  DCHECK(IsValidPlane(plane, format));
  const int sample_height = SampleSize(format, plane).height();
  return RoundUp(height, sample_height) / sample_height;
}

// static
size_t VideoFrame::Columns(size_t plane, VideoPixelFormat format, int width) {
  DCHECK(IsValidPlane(plane, format));
  const int sample_width = SampleSize(format, plane).width();
  return RoundUp(width, sample_width) / sample_width;
}

// static
void VideoFrame::HashFrameForTesting(base::MD5Context* context,
                                     const scoped_refptr<VideoFrame>& frame) {
  DCHECK(context);
  for (size_t plane = 0; plane < NumPlanes(frame->format()); ++plane) {
    for (int row = 0; row < frame->rows(plane); ++row) {
      base::MD5Update(
          context,
          base::StringPiece(reinterpret_cast<char*>(frame->data(plane) +
                                                    frame->stride(plane) * row),
                            frame->row_bytes(plane)));
    }
  }
}

bool VideoFrame::IsMappable() const {
  return IsStorageTypeMappable(storage_type_);
}

bool VideoFrame::HasTextures() const {
  return !mailbox_holders_[0].mailbox.IsZero();
}

gfx::ColorSpace VideoFrame::ColorSpace() const {
  if (color_space_ == gfx::ColorSpace()) {
    int videoframe_color_space;
    if (metadata()->GetInteger(media::VideoFrameMetadata::COLOR_SPACE,
                               &videoframe_color_space)) {
      switch (videoframe_color_space) {
        case media::COLOR_SPACE_JPEG:
          return gfx::ColorSpace::CreateJpeg();
        case media::COLOR_SPACE_HD_REC709:
          return gfx::ColorSpace::CreateREC709();
        case media::COLOR_SPACE_SD_REC601:
          return gfx::ColorSpace::CreateREC601();
        default:
          break;
      }
    }
  }
  return color_space_;
}

void VideoFrame::set_color_space(const gfx::ColorSpace& color_space) {
  color_space_ = color_space;
}

int VideoFrame::stride(size_t plane) const {
  DCHECK(IsValidPlane(plane, format_));
  return strides_[plane];
}

int VideoFrame::row_bytes(size_t plane) const {
  return RowBytes(plane, format_, coded_size_.width());
}

int VideoFrame::rows(size_t plane) const {
  return Rows(plane, format_, coded_size_.height());
}

const uint8_t* VideoFrame::data(size_t plane) const {
  DCHECK(IsValidPlane(plane, format_));
  DCHECK(IsMappable());
  return data_[plane];
}

uint8_t* VideoFrame::data(size_t plane) {
  DCHECK(IsValidPlane(plane, format_));
  DCHECK(IsMappable());
  return data_[plane];
}

const uint8_t* VideoFrame::visible_data(size_t plane) const {
  DCHECK(IsValidPlane(plane, format_));
  DCHECK(IsMappable());

  // Calculate an offset that is properly aligned for all planes.
  const gfx::Size alignment = CommonAlignment(format_);
  const gfx::Point offset(RoundDown(visible_rect_.x(), alignment.width()),
                          RoundDown(visible_rect_.y(), alignment.height()));

  const gfx::Size subsample = SampleSize(format_, plane);
  DCHECK_EQ(offset.x() % subsample.width(), 0);
  DCHECK_EQ(offset.y() % subsample.height(), 0);
  return data(plane) +
         stride(plane) * (offset.y() / subsample.height()) +  // Row offset.
         BytesPerElement(format_, plane) *                    // Column offset.
             (offset.x() / subsample.width());
}

uint8_t* VideoFrame::visible_data(size_t plane) {
  return const_cast<uint8_t*>(
      static_cast<const VideoFrame*>(this)->visible_data(plane));
}

const gpu::MailboxHolder& VideoFrame::mailbox_holder(
    size_t texture_index) const {
  DCHECK(HasTextures());
  DCHECK(IsValidPlane(texture_index, format_));
  return mailbox_holders_[texture_index];
}

base::SharedMemoryHandle VideoFrame::shared_memory_handle() const {
  DCHECK_EQ(storage_type_, STORAGE_SHMEM);
  DCHECK(shared_memory_handle_ != base::SharedMemory::NULLHandle());
  return shared_memory_handle_;
}

size_t VideoFrame::shared_memory_offset() const {
  DCHECK_EQ(storage_type_, STORAGE_SHMEM);
  DCHECK(shared_memory_handle_ != base::SharedMemory::NULLHandle());
  return shared_memory_offset_;
}

const std::vector<gfx::GpuMemoryBufferHandle>&
VideoFrame::gpu_memory_buffer_handles() const {
  DCHECK_EQ(storage_type_, STORAGE_GPU_MEMORY_BUFFERS);
  DCHECK(!gpu_memory_buffer_handles_.empty());
  return gpu_memory_buffer_handles_;
}

#if defined(OS_LINUX)
int VideoFrame::dmabuf_fd(size_t plane) const {
  DCHECK_EQ(storage_type_, STORAGE_DMABUFS);
  DCHECK(IsValidPlane(plane, format_));
  return dmabuf_fds_[plane].get();
}

bool VideoFrame::DuplicateFileDescriptors(const std::vector<int>& in_fds) {
  // TODO(mcasas): Support offsets for e.g. multiplanar inside a single |in_fd|.

  storage_type_ = STORAGE_DMABUFS;
  // TODO(posciak): This is not exactly correct, it's possible for one
  // buffer to contain more than one plane.
  if (in_fds.size() != NumPlanes(format_)) {
    LOG(FATAL) << "Not enough dmabuf fds provided, got: " << in_fds.size()
               << ", expected: " << NumPlanes(format_);
    return false;
  }

  // Make sure that all fds are closed if any dup() fails,
  base::ScopedFD temp_dmabuf_fds[kMaxPlanes];
  for (size_t i = 0; i < in_fds.size(); ++i) {
    temp_dmabuf_fds[i] = base::ScopedFD(HANDLE_EINTR(dup(in_fds[i])));
    if (!temp_dmabuf_fds[i].is_valid()) {
      DPLOG(ERROR) << "Failed duplicating a dmabuf fd";
      return false;
    }
  }
  for (size_t i = 0; i < kMaxPlanes; ++i)
    dmabuf_fds_[i] = std::move(temp_dmabuf_fds[i]);

  return true;
}
#endif

void VideoFrame::AddSharedMemoryHandle(base::SharedMemoryHandle handle) {
  storage_type_ = STORAGE_SHMEM;
  shared_memory_handle_ = handle;
}

#if defined(OS_MACOSX)
CVPixelBufferRef VideoFrame::cv_pixel_buffer() const {
  return cv_pixel_buffer_.get();
}
#endif

void VideoFrame::AddDestructionObserver(const base::Closure& callback) {
  DCHECK(!callback.is_null());
  done_callbacks_.push_back(callback);
}

void VideoFrame::UpdateReleaseSyncToken(SyncTokenClient* client) {
  DCHECK(HasTextures());
  base::AutoLock locker(release_sync_token_lock_);
  // Must wait on the previous sync point before inserting a new sync point so
  // that |mailbox_holders_release_cb_| guarantees the previous sync point
  // occurred when it waits on |release_sync_token_|.
  if (release_sync_token_.HasData()) client->WaitSyncToken(release_sync_token_);
  client->GenerateSyncToken(&release_sync_token_);
}

std::string VideoFrame::AsHumanReadableString() {
  if (metadata()->IsTrue(media::VideoFrameMetadata::END_OF_STREAM))
    return "end of stream";

  std::ostringstream s;
  s << ConfigToString(format_, storage_type_, coded_size_, visible_rect_,
                      natural_size_)
    << " timestamp:" << timestamp_.InMicroseconds();
  return s.str();
}

// static
scoped_refptr<VideoFrame> VideoFrame::WrapExternalStorage(
    VideoPixelFormat format, StorageType storage_type,
    const gfx::Size& coded_size, const gfx::Rect& visible_rect,
    const gfx::Size& natural_size, uint8_t* data, size_t data_size,
    base::TimeDelta timestamp, base::SharedMemoryHandle handle,
    size_t data_offset) {
  DCHECK(IsStorageTypeMappable(storage_type));

  // TODO(miu): This function should support any pixel format.
  // http://crbug.com/555909
  if (format != PIXEL_FORMAT_I420) {
    LOG(DFATAL) << "Only PIXEL_FORMAT_I420 format supported: "
                << VideoPixelFormatToString(format);
    return NULL;
  }

  if (!IsValidConfig(format, storage_type, coded_size, visible_rect,
                     natural_size)) {
    LOG(DFATAL) << __func__ << " Invalid config."
                << ConfigToString(format, storage_type, coded_size,
                                  visible_rect, natural_size);
    return NULL;
  }

  scoped_refptr<VideoFrame> frame;
  if (storage_type == STORAGE_SHMEM) {
    frame = new VideoFrame(format, storage_type, coded_size, visible_rect,
                           natural_size, timestamp, handle, data_offset);
  } else {
    frame = new VideoFrame(format, storage_type, coded_size, visible_rect,
                           natural_size, timestamp);
  }
  frame->strides_[kYPlane] = coded_size.width();
  // TODO(miu): This always rounds widths down, whereas VideoFrame::RowBytes()
  // always rounds up.  This inconsistency must be resolved.  Perhaps a
  // CommonAlignment() check should be made in IsValidConfig()?
  // http://crbug.com/555909
  frame->strides_[kUPlane] = coded_size.width() / 2;
  frame->strides_[kVPlane] = coded_size.width() / 2;
  frame->data_[kYPlane] = data;
  frame->data_[kUPlane] = data + coded_size.GetArea();
  frame->data_[kVPlane] = data + (coded_size.GetArea() * 5 / 4);
  return frame;
}

VideoFrame::VideoFrame(VideoPixelFormat format, StorageType storage_type,
                       const gfx::Size& coded_size,
                       const gfx::Rect& visible_rect,
                       const gfx::Size& natural_size, base::TimeDelta timestamp)
    : format_(format),
      storage_type_(storage_type),
      coded_size_(coded_size),
      visible_rect_(visible_rect),
      natural_size_(natural_size),
      shared_memory_handle_(base::SharedMemory::NULLHandle()),
      shared_memory_offset_(0),
      timestamp_(timestamp),
      unique_id_(g_unique_id_generator.GetNext()) {
  DCHECK(IsValidConfig(format_, storage_type, coded_size_, visible_rect_,
                       natural_size_));
  SbMemorySet(&mailbox_holders_, 0, sizeof(mailbox_holders_));
  SbMemorySet(&strides_, 0, sizeof(strides_));
  SbMemorySet(&data_, 0, sizeof(data_));
}

VideoFrame::~VideoFrame() {
  if (!mailbox_holders_release_cb_.is_null()) {
    gpu::SyncToken release_sync_token;
    {
      // To ensure that changes to |release_sync_token_| are visible on this
      // thread (imply a memory barrier).
      base::AutoLock locker(release_sync_token_lock_);
      release_sync_token = release_sync_token_;
    }
    base::ResetAndReturn(&mailbox_holders_release_cb_).Run(release_sync_token);
  }

  for (auto& callback : done_callbacks_) base::ResetAndReturn(&callback).Run();
}

// static
std::string VideoFrame::ConfigToString(const VideoPixelFormat format,
                                       const StorageType storage_type,
                                       const gfx::Size& coded_size,
                                       const gfx::Rect& visible_rect,
                                       const gfx::Size& natural_size) {
  return base::StringPrintf(
      "format:%s storage_type:%s coded_size:%s visible_rect:%s natural_size:%s",
      VideoPixelFormatToString(format).c_str(),
      StorageTypeToString(storage_type).c_str(), coded_size.ToString().c_str(),
      visible_rect.ToString().c_str(), natural_size.ToString().c_str());
}

// static
bool VideoFrame::IsValidPlane(size_t plane, VideoPixelFormat format) {
  DCHECK_LE(NumPlanes(format), static_cast<size_t>(kMaxPlanes));
  return (plane < NumPlanes(format));
}

// static
gfx::Size VideoFrame::DetermineAlignedSize(VideoPixelFormat format,
                                           const gfx::Size& dimensions) {
  const gfx::Size alignment = CommonAlignment(format);
  const gfx::Size adjusted =
      gfx::Size(RoundUp(dimensions.width(), alignment.width()),
                RoundUp(dimensions.height(), alignment.height()));
  DCHECK((adjusted.width() % alignment.width() == 0) &&
         (adjusted.height() % alignment.height() == 0));
  return adjusted;
}

void VideoFrame::set_data(size_t plane, uint8_t* ptr) {
  DCHECK(IsValidPlane(plane, format_));
  DCHECK(ptr);
  data_[plane] = ptr;
}

void VideoFrame::set_stride(size_t plane, int stride) {
  DCHECK(IsValidPlane(plane, format_));
  DCHECK_GT(stride, 0);
  strides_[plane] = stride;
}

VideoFrame::VideoFrame(VideoPixelFormat format, StorageType storage_type,
                       const gfx::Size& coded_size,
                       const gfx::Rect& visible_rect,
                       const gfx::Size& natural_size, base::TimeDelta timestamp,
                       base::SharedMemoryHandle handle,
                       size_t shared_memory_offset)
    : VideoFrame(format, storage_type, coded_size, visible_rect, natural_size,
                 timestamp) {
  DCHECK_EQ(storage_type, STORAGE_SHMEM);
  AddSharedMemoryHandle(handle);
  shared_memory_offset_ = shared_memory_offset;
}

VideoFrame::VideoFrame(VideoPixelFormat format, StorageType storage_type,
                       const gfx::Size& coded_size,
                       const gfx::Rect& visible_rect,
                       const gfx::Size& natural_size,
                       const gpu::MailboxHolder (&mailbox_holders)[kMaxPlanes],
                       const ReleaseMailboxCB& mailbox_holder_release_cb,
                       base::TimeDelta timestamp)
    : VideoFrame(format, storage_type, coded_size, visible_rect, natural_size,
                 timestamp) {
  SbMemoryCopy(&mailbox_holders_, mailbox_holders, sizeof(mailbox_holders_));
  mailbox_holders_release_cb_ = mailbox_holder_release_cb;
}

// static
scoped_refptr<VideoFrame> VideoFrame::CreateFrameInternal(
    VideoPixelFormat format, const gfx::Size& coded_size,
    const gfx::Rect& visible_rect, const gfx::Size& natural_size,
    base::TimeDelta timestamp, bool zero_initialize_memory) {
  if (!IsYuvPlanar(format)) {
    NOTIMPLEMENTED();
    return NULL;
  }

  // Since we're creating a new YUV frame (and allocating memory for it
  // ourselves), we can pad the requested |coded_size| if necessary if the
  // request does not line up on sample boundaries. See discussion at
  // http://crrev.com/1240833003
  const gfx::Size new_coded_size = DetermineAlignedSize(format, coded_size);
  const StorageType storage = STORAGE_OWNED_MEMORY;
  if (!IsValidConfig(format, storage, new_coded_size, visible_rect,
                     natural_size)) {
    LOG(DFATAL) << __func__ << " Invalid config."
                << ConfigToString(format, storage, coded_size, visible_rect,
                                  natural_size);
    return NULL;
  }

  scoped_refptr<VideoFrame> frame(new VideoFrame(
      format, storage, new_coded_size, visible_rect, natural_size, timestamp));
  frame->AllocateYUV(zero_initialize_memory);
  return frame;
}

// static
gfx::Size VideoFrame::SampleSize(VideoPixelFormat format, size_t plane) {
  DCHECK(IsValidPlane(plane, format));

  switch (plane) {
    case kYPlane:  // and kARGBPlane:
    case kAPlane:
      return gfx::Size(1, 1);

    case kUPlane:  // and kUVPlane:
    case kVPlane:
      switch (format) {
        case PIXEL_FORMAT_YV24:
        case PIXEL_FORMAT_YUV444P9:
        case PIXEL_FORMAT_YUV444P10:
        case PIXEL_FORMAT_YUV444P12:
          return gfx::Size(1, 1);

        case PIXEL_FORMAT_YV16:
        case PIXEL_FORMAT_YUV422P9:
        case PIXEL_FORMAT_YUV422P10:
        case PIXEL_FORMAT_YUV422P12:
          return gfx::Size(2, 1);

        case PIXEL_FORMAT_YV12:
        case PIXEL_FORMAT_I420:
        case PIXEL_FORMAT_YV12A:
        case PIXEL_FORMAT_NV12:
        case PIXEL_FORMAT_NV21:
        case PIXEL_FORMAT_MT21:
        case PIXEL_FORMAT_YUV420P9:
        case PIXEL_FORMAT_YUV420P10:
        case PIXEL_FORMAT_YUV420P12:
          return gfx::Size(2, 2);

        case PIXEL_FORMAT_UNKNOWN:
        case PIXEL_FORMAT_UYVY:
        case PIXEL_FORMAT_YUY2:
        case PIXEL_FORMAT_ARGB:
        case PIXEL_FORMAT_XRGB:
        case PIXEL_FORMAT_RGB24:
        case PIXEL_FORMAT_RGB32:
        case PIXEL_FORMAT_MJPEG:
        case PIXEL_FORMAT_Y8:
        case PIXEL_FORMAT_Y16:
          break;
      }
  }
  NOTREACHED();
  return gfx::Size();
}

// static
int VideoFrame::BytesPerElement(VideoPixelFormat format, size_t plane) {
  DCHECK(IsValidPlane(plane, format));
  switch (format) {
    case PIXEL_FORMAT_ARGB:
    case PIXEL_FORMAT_XRGB:
    case PIXEL_FORMAT_RGB32:
      return 4;
    case PIXEL_FORMAT_RGB24:
      return 3;
    case PIXEL_FORMAT_Y16:
    case PIXEL_FORMAT_UYVY:
    case PIXEL_FORMAT_YUY2:
    case PIXEL_FORMAT_YUV420P9:
    case PIXEL_FORMAT_YUV422P9:
    case PIXEL_FORMAT_YUV444P9:
    case PIXEL_FORMAT_YUV420P10:
    case PIXEL_FORMAT_YUV422P10:
    case PIXEL_FORMAT_YUV444P10:
    case PIXEL_FORMAT_YUV420P12:
    case PIXEL_FORMAT_YUV422P12:
    case PIXEL_FORMAT_YUV444P12:
      return 2;
    case PIXEL_FORMAT_NV12:
    case PIXEL_FORMAT_NV21:
    case PIXEL_FORMAT_MT21: {
      static const int bytes_per_element[] = {1, 2};
      DCHECK_LT(plane, arraysize(bytes_per_element));
      return bytes_per_element[plane];
    }
    case PIXEL_FORMAT_YV12:
    case PIXEL_FORMAT_I420:
    case PIXEL_FORMAT_YV16:
    case PIXEL_FORMAT_YV12A:
    case PIXEL_FORMAT_YV24:
    case PIXEL_FORMAT_Y8:
      return 1;
    case PIXEL_FORMAT_MJPEG:
      return 0;
    case PIXEL_FORMAT_UNKNOWN:
      break;
  }
  NOTREACHED();
  return 0;
}

// static
gfx::Size VideoFrame::CommonAlignment(VideoPixelFormat format) {
  int max_sample_width = 0;
  int max_sample_height = 0;
  for (size_t plane = 0; plane < NumPlanes(format); ++plane) {
    const gfx::Size sample_size = SampleSize(format, plane);
    max_sample_width = std::max(max_sample_width, sample_size.width());
    max_sample_height = std::max(max_sample_height, sample_size.height());
  }
  return gfx::Size(max_sample_width, max_sample_height);
}

void VideoFrame::AllocateYUV(bool zero_initialize_memory) {
  DCHECK_EQ(storage_type_, STORAGE_OWNED_MEMORY);
  static_assert(0 == kYPlane, "y plane data must be index 0");

  size_t data_size = 0;
  size_t offset[kMaxPlanes];
  for (size_t plane = 0; plane < NumPlanes(format_); ++plane) {
    // The *2 in alignment for height is because some formats (e.g. h264) allow
    // interlaced coding, and then the size needs to be a multiple of two
    // macroblocks (vertically). See
    // libavcodec/utils.c:avcodec_align_dimensions2().
    const size_t height = RoundUp(rows(plane), kFrameSizeAlignment * 2);
    strides_[plane] = RoundUp(row_bytes(plane), kFrameSizeAlignment);
    offset[plane] = data_size;
    data_size += height * strides_[plane];
  }

  // The extra line of UV being allocated is because h264 chroma MC
  // overreads by one line in some cases, see libavcodec/utils.c:
  // avcodec_align_dimensions2() and libavcodec/x86/h264_chromamc.asm:
  // put_h264_chroma_mc4_ssse3().
  DCHECK(IsValidPlane(kUPlane, format_));
  data_size += strides_[kUPlane] + kFrameSizePadding;

  uint8_t* data = reinterpret_cast<uint8_t*>(
      base::AlignedAlloc(data_size, kFrameAddressAlignment));
  if (zero_initialize_memory) SbMemorySet(data, 0, data_size);

  for (size_t plane = 0; plane < NumPlanes(format_); ++plane)
    data_[plane] = data + offset[plane];

  AddDestructionObserver(base::Bind(&base::AlignedFree, data));
}

}  // namespace media
}  // namespace cobalt
