// 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 "media/base/video_util.h"

#include <cmath>

#include "base/bind.h"
#include "base/bits.h"
#include "base/callback_helpers.h"
#include "base/check_op.h"
#include "base/logging.h"
#include "base/notreached.h"
#include "base/numerics/safe_conversions.h"
#include "base/numerics/safe_math.h"
#include "base/time/time.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/raster_interface.h"
#include "media/base/status_codes.h"
#include "media/base/video_frame.h"
#include "media/base/video_frame_pool.h"
#include "third_party/libyuv/include/libyuv.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/core/SkYUVAPixmaps.h"
#include "third_party/skia/include/gpu/GrDirectContext.h"
#include "third_party/skia/include/gpu/gl/GrGLTypes.h"
#include "ui/gfx/gpu_memory_buffer.h"

namespace media {

namespace {

// Helper to apply padding to the region outside visible rect up to the coded
// size with the repeated last column / row of the visible rect.
void FillRegionOutsideVisibleRect(uint8_t* data,
                                  size_t stride,
                                  const gfx::Size& coded_size,
                                  const gfx::Size& visible_size) {
  if (visible_size.IsEmpty()) {
    if (!coded_size.IsEmpty())
      memset(data, 0, coded_size.height() * stride);
    return;
  }

  const int coded_width = coded_size.width();
  if (visible_size.width() < coded_width) {
    const int pad_length = coded_width - visible_size.width();
    uint8_t* dst = data + visible_size.width();
    for (int i = 0; i < visible_size.height(); ++i, dst += stride)
      std::memset(dst, *(dst - 1), pad_length);
  }

  if (visible_size.height() < coded_size.height()) {
    uint8_t* dst = data + visible_size.height() * stride;
    uint8_t* src = dst - stride;
    for (int i = visible_size.height(); i < coded_size.height();
         ++i, dst += stride)
      std::memcpy(dst, src, coded_width);
  }
}

VideoPixelFormat ReadbackFormat(const media::VideoFrame& frame) {
  switch (frame.format()) {
    case PIXEL_FORMAT_I420:
    case PIXEL_FORMAT_I420A:
    case PIXEL_FORMAT_I422:
    case PIXEL_FORMAT_I444:
    case PIXEL_FORMAT_ARGB:
    case PIXEL_FORMAT_XRGB:
    case PIXEL_FORMAT_ABGR:
    case PIXEL_FORMAT_XBGR:
      return frame.format();
    case PIXEL_FORMAT_NV12:
      // |frame| may be backed by a graphics buffer that is NV12, but sampled as
      // a single RGB texture.
      return frame.NumTextures() == 1 ? PIXEL_FORMAT_XRGB : PIXEL_FORMAT_NV12;
    default:
      // Currently unsupported.
      return PIXEL_FORMAT_UNKNOWN;
  }
}

// TODO(eugene): There is some strange channel switch during RGB readback.
// When frame's pixel format matches GL and Skia color types we get reversed
// channels. But why?
SkColorType SkColorTypeForPlane(VideoPixelFormat format, size_t plane) {
  switch (format) {
    case PIXEL_FORMAT_I420:
    case PIXEL_FORMAT_I420A:
    case PIXEL_FORMAT_I422:
    case PIXEL_FORMAT_I444:
      // kGray_8_SkColorType would make more sense but doesn't work on Windows.
      return kAlpha_8_SkColorType;
    case PIXEL_FORMAT_NV12:
      return plane == media::VideoFrame::kYPlane ? kAlpha_8_SkColorType
                                                 : kR8G8_unorm_SkColorType;
    case PIXEL_FORMAT_XBGR:
    case PIXEL_FORMAT_ABGR:
      return kRGBA_8888_SkColorType;
    case PIXEL_FORMAT_XRGB:
    case PIXEL_FORMAT_ARGB:
      return kBGRA_8888_SkColorType;
    default:
      NOTREACHED();
      return kUnknown_SkColorType;
  }
}

GrGLenum GLFormatForPlane(VideoPixelFormat format, size_t plane) {
  switch (SkColorTypeForPlane(format, plane)) {
    case kAlpha_8_SkColorType:
      return GL_R8_EXT;
    case kR8G8_unorm_SkColorType:
      return GL_RG8_EXT;
    case kRGBA_8888_SkColorType:
      return GL_RGBA8_OES;
    case kBGRA_8888_SkColorType:
      return GL_BGRA8_EXT;
    default:
      NOTREACHED();
      return 0;
  }
}

bool ReadbackTexturePlaneToMemorySyncSkImage(const VideoFrame& src_frame,
                                             size_t src_plane,
                                             gfx::Rect& src_rect,
                                             uint8_t* dest_pixels,
                                             size_t dest_stride,
                                             gpu::raster::RasterInterface* ri,
                                             GrDirectContext* gr_context) {
  DCHECK(gr_context);

  VideoPixelFormat format = ReadbackFormat(src_frame);
  int width = src_frame.columns(src_plane);
  int height = src_frame.rows(src_plane);
  bool has_alpha = !IsOpaque(format) && src_frame.NumTextures() == 1;

  const gpu::MailboxHolder& holder = src_frame.mailbox_holder(src_plane);
  DCHECK(!holder.mailbox.IsZero());
  ri->WaitSyncTokenCHROMIUM(holder.sync_token.GetConstData());
  auto texture_id = ri->CreateAndConsumeForGpuRaster(holder.mailbox);
  if (holder.mailbox.IsSharedImage()) {
    ri->BeginSharedImageAccessDirectCHROMIUM(
        texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM);
  }
  base::ScopedClosureRunner cleanup(base::BindOnce(
      [](GLuint texture_id, bool shared, gpu::raster::RasterInterface* ri) {
        if (shared)
          ri->EndSharedImageAccessDirectCHROMIUM(texture_id);
        ri->DeleteGpuRasterTexture(texture_id);
      },
      texture_id, holder.mailbox.IsSharedImage(), ri));

  GrGLenum texture_format = GLFormatForPlane(format, src_plane);
  SkColorType sk_color_type = SkColorTypeForPlane(format, src_plane);
  SkAlphaType sk_alpha_type =
      has_alpha ? kUnpremul_SkAlphaType : kOpaque_SkAlphaType;

  GrGLTextureInfo gl_texture_info;
  gl_texture_info.fID = texture_id;
  gl_texture_info.fTarget = holder.texture_target;
  gl_texture_info.fFormat = texture_format;
  GrBackendTexture texture(width, height, GrMipMapped::kNo, gl_texture_info);

  auto image =
      SkImage::MakeFromTexture(gr_context, texture,
                               src_frame.metadata().texture_origin_is_top_left
                                   ? kTopLeft_GrSurfaceOrigin
                                   : kBottomLeft_GrSurfaceOrigin,
                               sk_color_type, sk_alpha_type,
                               /*colorSpace=*/nullptr);
  if (!image) {
    DLOG(ERROR) << "Can't create SkImage from texture plane " << src_plane;
    return false;
  }

  auto dest_info = SkImageInfo::Make(src_rect.width(), src_rect.height(),
                                     sk_color_type, sk_alpha_type);
  SkPixmap dest_pixmap(dest_info, dest_pixels, dest_stride);
  if (!image->readPixels(gr_context, dest_pixmap, src_rect.x(), src_rect.y(),
                         SkImage::kDisallow_CachingHint)) {
    DLOG(ERROR) << "Plane readback failed."
                << " plane:" << src_plane << " width: " << width
                << " height: " << height;
    return false;
  }

  return true;
}

bool ReadbackTexturePlaneToMemorySyncOOP(const VideoFrame& src_frame,
                                         size_t src_plane,
                                         gfx::Rect& src_rect,
                                         uint8_t* dest_pixels,
                                         size_t dest_stride,
                                         gpu::raster::RasterInterface* ri) {
  VideoPixelFormat format = ReadbackFormat(src_frame);
  bool has_alpha = !IsOpaque(format) && src_frame.NumTextures() == 1;

  const gpu::MailboxHolder& holder = src_frame.mailbox_holder(src_plane);
  DCHECK(!holder.mailbox.IsZero());
  ri->WaitSyncTokenCHROMIUM(holder.sync_token.GetConstData());

  SkColorType sk_color_type = SkColorTypeForPlane(format, src_plane);
  SkAlphaType sk_alpha_type =
      has_alpha ? kUnpremul_SkAlphaType : kOpaque_SkAlphaType;

  auto info = SkImageInfo::Make(src_rect.width(), src_rect.height(),
                                sk_color_type, sk_alpha_type);
  ri->ReadbackImagePixels(holder.mailbox, info, dest_stride, src_rect.x(),
                          src_rect.y(), dest_pixels);
  DCHECK_EQ(ri->GetError(), static_cast<GLenum>(GL_NO_ERROR));
  return true;
}

}  // namespace

void FillYUV(VideoFrame* frame, uint8_t y, uint8_t u, uint8_t v) {
  // Fill the Y plane.
  uint8_t* y_plane = frame->data(VideoFrame::kYPlane);
  int y_rows = frame->rows(VideoFrame::kYPlane);
  int y_row_bytes = frame->row_bytes(VideoFrame::kYPlane);
  for (int i = 0; i < y_rows; ++i) {
    memset(y_plane, y, y_row_bytes);
    y_plane += frame->stride(VideoFrame::kYPlane);
  }

  // Fill the U and V planes.
  uint8_t* u_plane = frame->data(VideoFrame::kUPlane);
  uint8_t* v_plane = frame->data(VideoFrame::kVPlane);
  int uv_rows = frame->rows(VideoFrame::kUPlane);
  int u_row_bytes = frame->row_bytes(VideoFrame::kUPlane);
  int v_row_bytes = frame->row_bytes(VideoFrame::kVPlane);
  for (int i = 0; i < uv_rows; ++i) {
    memset(u_plane, u, u_row_bytes);
    memset(v_plane, v, v_row_bytes);
    u_plane += frame->stride(VideoFrame::kUPlane);
    v_plane += frame->stride(VideoFrame::kVPlane);
  }
}

void FillYUVA(VideoFrame* frame, uint8_t y, uint8_t u, uint8_t v, uint8_t a) {
  // Fill Y, U and V planes.
  FillYUV(frame, y, u, v);

  // Fill the A plane.
  uint8_t* a_plane = frame->data(VideoFrame::kAPlane);
  int a_rows = frame->rows(VideoFrame::kAPlane);
  int a_row_bytes = frame->row_bytes(VideoFrame::kAPlane);
  for (int i = 0; i < a_rows; ++i) {
    memset(a_plane, a, a_row_bytes);
    a_plane += frame->stride(VideoFrame::kAPlane);
  }
}

static void LetterboxPlane(VideoFrame* frame,
                           int plane,
                           const gfx::Rect& view_area_in_pixels,
                           uint8_t fill_byte) {
  uint8_t* ptr = frame->data(plane);
  const int rows = frame->rows(plane);
  const int row_bytes = frame->row_bytes(plane);
  const int stride = frame->stride(plane);
  const int bytes_per_element =
      VideoFrame::BytesPerElement(frame->format(), plane);
  gfx::Rect view_area(view_area_in_pixels.x() * bytes_per_element,
                      view_area_in_pixels.y(),
                      view_area_in_pixels.width() * bytes_per_element,
                      view_area_in_pixels.height());

  CHECK_GE(stride, row_bytes);
  CHECK_GE(view_area.x(), 0);
  CHECK_GE(view_area.y(), 0);
  CHECK_LE(view_area.right(), row_bytes);
  CHECK_LE(view_area.bottom(), rows);

  int y = 0;
  for (; y < view_area.y(); y++) {
    memset(ptr, fill_byte, row_bytes);
    ptr += stride;
  }
  if (view_area.width() < row_bytes) {
    for (; y < view_area.bottom(); y++) {
      if (view_area.x() > 0) {
        memset(ptr, fill_byte, view_area.x());
      }
      if (view_area.right() < row_bytes) {
        memset(ptr + view_area.right(),
               fill_byte,
               row_bytes - view_area.right());
      }
      ptr += stride;
    }
  } else {
    y += view_area.height();
    ptr += stride * view_area.height();
  }
  for (; y < rows; y++) {
    memset(ptr, fill_byte, row_bytes);
    ptr += stride;
  }
}

void LetterboxVideoFrame(VideoFrame* frame, const gfx::Rect& view_area) {
  switch (frame->format()) {
    case PIXEL_FORMAT_ARGB:
      LetterboxPlane(frame, VideoFrame::kARGBPlane, view_area, 0x00);
      break;
    case PIXEL_FORMAT_YV12:
    case PIXEL_FORMAT_I420: {
      DCHECK(!(view_area.x() & 1));
      DCHECK(!(view_area.y() & 1));
      DCHECK(!(view_area.width() & 1));
      DCHECK(!(view_area.height() & 1));
      LetterboxPlane(frame, VideoFrame::kYPlane, view_area, 0x00);
      gfx::Rect half_view_area(view_area.x() / 2, view_area.y() / 2,
                               view_area.width() / 2, view_area.height() / 2);
      LetterboxPlane(frame, VideoFrame::kUPlane, half_view_area, 0x80);
      LetterboxPlane(frame, VideoFrame::kVPlane, half_view_area, 0x80);
      break;
    }
    default:
      NOTREACHED();
  }
}

void RotatePlaneByPixels(const uint8_t* src,
                         uint8_t* dest,
                         int width,
                         int height,
                         int rotation,  // Clockwise.
                         bool flip_vert,
                         bool flip_horiz) {
  DCHECK((width > 0) && (height > 0) &&
         ((width & 1) == 0) && ((height & 1) == 0) &&
         (rotation >= 0) && (rotation < 360) && (rotation % 90 == 0));

  // Consolidate cases. Only 0 and 90 are left.
  if (rotation == 180 || rotation == 270) {
    rotation -= 180;
    flip_vert = !flip_vert;
    flip_horiz = !flip_horiz;
  }

  int num_rows = height;
  int num_cols = width;
  int src_stride = width;
  // During pixel copying, the corresponding incremental of dest pointer
  // when src pointer moves to next row.
  int dest_row_step = width;
  // During pixel copying, the corresponding incremental of dest pointer
  // when src pointer moves to next column.
  int dest_col_step = 1;

  if (rotation == 0) {
    if (flip_horiz) {
      // Use pixel copying.
      dest_col_step = -1;
      if (flip_vert) {
        // Rotation 180.
        dest_row_step = -width;
        dest += height * width - 1;
      } else {
        dest += width - 1;
      }
    } else {
      if (flip_vert) {
        // Fast copy by rows.
        dest += width * (height - 1);
        for (int row = 0; row < height; ++row) {
          memcpy(dest, src, width);
          src += width;
          dest -= width;
        }
      } else {
        memcpy(dest, src, width * height);
      }
      return;
    }
  } else if (rotation == 90) {
    int offset;
    if (width > height) {
      offset = (width - height) / 2;
      src += offset;
      num_rows = num_cols = height;
    } else {
      offset = (height - width) / 2;
      src += width * offset;
      num_rows = num_cols = width;
    }

    dest_col_step = (flip_vert ? -width : width);
    dest_row_step = (flip_horiz ? 1 : -1);
    if (flip_horiz) {
      if (flip_vert) {
        dest += (width > height ? width * (height - 1) + offset :
                                  width * (height - offset - 1));
      } else {
        dest += (width > height ? offset : width * offset);
      }
    } else {
      if (flip_vert) {
        dest += (width > height ?  width * height - offset - 1 :
                                   width * (height - offset) - 1);
      } else {
        dest += (width > height ? width - offset - 1 :
                                  width * (offset + 1) - 1);
      }
    }
  } else {
    NOTREACHED();
  }

  // Copy pixels.
  for (int row = 0; row < num_rows; ++row) {
    const uint8_t* src_ptr = src;
    uint8_t* dest_ptr = dest;
    for (int col = 0; col < num_cols; ++col) {
      *dest_ptr = *src_ptr++;
      dest_ptr += dest_col_step;
    }
    src += src_stride;
    dest += dest_row_step;
  }
}

// Helper function to return |a| divided by |b|, rounded to the nearest integer.
static int RoundedDivision(int64_t a, int b) {
  DCHECK_GE(a, 0);
  DCHECK_GT(b, 0);
  base::CheckedNumeric<uint64_t> result(a);
  result += b / 2;
  result /= b;
  return base::ValueOrDieForType<int>(result);
}

// Common logic for the letterboxing and scale-within/scale-encompassing
// functions.  Scales |size| to either fit within or encompass |target|,
// depending on whether |fit_within_target| is true.
static gfx::Size ScaleSizeToTarget(const gfx::Size& size,
                                   const gfx::Size& target,
                                   bool fit_within_target) {
  if (size.IsEmpty())
    return gfx::Size();  // Corner case: Aspect ratio is undefined.

  const int64_t x = static_cast<int64_t>(size.width()) * target.height();
  const int64_t y = static_cast<int64_t>(size.height()) * target.width();
  const bool use_target_width = fit_within_target ? (y < x) : (x < y);
  return use_target_width ?
      gfx::Size(target.width(), RoundedDivision(y, size.width())) :
      gfx::Size(RoundedDivision(x, size.height()), target.height());
}

gfx::Rect ComputeLetterboxRegion(const gfx::Rect& bounds,
                                 const gfx::Size& content) {
  // If |content| has an undefined aspect ratio, let's not try to divide by
  // zero.
  if (content.IsEmpty())
    return gfx::Rect();

  gfx::Rect result = bounds;
  result.ClampToCenteredSize(ScaleSizeToTarget(content, bounds.size(), true));
  return result;
}

gfx::Rect ComputeLetterboxRegionForI420(const gfx::Rect& bounds,
                                        const gfx::Size& content) {
  DCHECK_EQ(bounds.x() % 2, 0);
  DCHECK_EQ(bounds.y() % 2, 0);
  DCHECK_EQ(bounds.width() % 2, 0);
  DCHECK_EQ(bounds.height() % 2, 0);

  gfx::Rect result = ComputeLetterboxRegion(bounds, content);

  if (result.x() & 1) {
    // This is always legal since bounds.x() was even and result.x() must always
    // be greater or equal to bounds.x().
    result.set_x(result.x() - 1);

    // The result.x() was nudged to the left, so if the width is odd, it should
    // be perfectly legal to nudge it up by one to make it even.
    if (result.width() & 1)
      result.set_width(result.width() + 1);
  } else /* if (result.x() is even) */ {
    if (result.width() & 1)
      result.set_width(result.width() - 1);
  }

  if (result.y() & 1) {
    // These operations are legal for the same reasons mentioned above for
    // result.x().
    result.set_y(result.y() - 1);
    if (result.height() & 1)
      result.set_height(result.height() + 1);
  } else /* if (result.y() is even) */ {
    if (result.height() & 1)
      result.set_height(result.height() - 1);
  }

  return result;
}

gfx::Size ScaleSizeToFitWithinTarget(const gfx::Size& size,
                                     const gfx::Size& target) {
  return ScaleSizeToTarget(size, target, true);
}

gfx::Size ScaleSizeToEncompassTarget(const gfx::Size& size,
                                     const gfx::Size& target) {
  return ScaleSizeToTarget(size, target, false);
}

gfx::Rect CropSizeForScalingToTarget(const gfx::Size& size,
                                     const gfx::Size& target,
                                     size_t alignment) {
  DCHECK_GT(alignment, 0u);
  if (size.IsEmpty() || target.IsEmpty())
    return gfx::Rect();

  gfx::Rect crop(ScaleSizeToFitWithinTarget(target, size));
  crop.set_width(base::checked_cast<int>(base::bits::AlignDown(
      base::checked_cast<size_t>(crop.width()), alignment)));
  crop.set_height(base::checked_cast<int>(base::bits::AlignDown(
      base::checked_cast<size_t>(crop.height()), alignment)));
  crop.set_x(base::checked_cast<int>(base::bits::AlignDown(
      base::checked_cast<size_t>((size.width() - crop.width()) / 2),
      alignment)));
  crop.set_y(base::checked_cast<int>(base::bits::AlignDown(
      base::checked_cast<size_t>((size.height() - crop.height()) / 2),
      alignment)));
  DCHECK(gfx::Rect(size).Contains(crop));
  return crop;
}

gfx::Size GetRectSizeFromOrigin(const gfx::Rect& rect) {
  return gfx::Size(rect.right(), rect.bottom());
}

gfx::Size PadToMatchAspectRatio(const gfx::Size& size,
                                const gfx::Size& target) {
  if (target.IsEmpty())
    return gfx::Size();  // Aspect ratio is undefined.

  const int64_t x = static_cast<int64_t>(size.width()) * target.height();
  const int64_t y = static_cast<int64_t>(size.height()) * target.width();
  if (x < y)
    return gfx::Size(RoundedDivision(y, target.height()), size.height());
  return gfx::Size(size.width(), RoundedDivision(x, target.width()));
}

scoped_refptr<VideoFrame> ConvertToMemoryMappedFrame(
    scoped_refptr<VideoFrame> video_frame) {
  DCHECK(video_frame);
  DCHECK(video_frame->HasGpuMemoryBuffer());

  auto* gmb = video_frame->GetGpuMemoryBuffer();
  if (!gmb->Map())
    return nullptr;

  const size_t num_planes = VideoFrame::NumPlanes(video_frame->format());
  uint8_t* plane_addrs[VideoFrame::kMaxPlanes] = {};
  for (size_t i = 0; i < num_planes; i++)
    plane_addrs[i] = static_cast<uint8_t*>(gmb->memory(i));

  auto mapped_frame = VideoFrame::WrapExternalYuvDataWithLayout(
      video_frame->layout(), video_frame->visible_rect(),
      video_frame->natural_size(), plane_addrs[0], plane_addrs[1],
      plane_addrs[2], video_frame->timestamp());

  if (!mapped_frame) {
    gmb->Unmap();
    return nullptr;
  }

  mapped_frame->set_color_space(video_frame->ColorSpace());
  mapped_frame->metadata().MergeMetadataFrom(video_frame->metadata());

  // Pass |video_frame| so that it outlives |mapped_frame| and the mapped buffer
  // is unmapped on destruction.
  mapped_frame->AddDestructionObserver(base::BindOnce(
      [](scoped_refptr<VideoFrame> frame) {
        DCHECK(frame->HasGpuMemoryBuffer());
        frame->GetGpuMemoryBuffer()->Unmap();
      },
      std::move(video_frame)));
  return mapped_frame;
}

scoped_refptr<VideoFrame> WrapAsI420VideoFrame(
    scoped_refptr<VideoFrame> frame) {
  DCHECK_EQ(VideoFrame::STORAGE_OWNED_MEMORY, frame->storage_type());
  DCHECK_EQ(PIXEL_FORMAT_I420A, frame->format());

  scoped_refptr<VideoFrame> wrapped_frame = VideoFrame::WrapVideoFrame(
      frame, PIXEL_FORMAT_I420, frame->visible_rect(), frame->natural_size());
  return wrapped_frame;
}

bool I420CopyWithPadding(const VideoFrame& src_frame, VideoFrame* dst_frame) {
  if (!dst_frame || !dst_frame->IsMappable())
    return false;

  DCHECK_GE(dst_frame->coded_size().width(), src_frame.visible_rect().width());
  DCHECK_GE(dst_frame->coded_size().height(),
            src_frame.visible_rect().height());
  DCHECK(dst_frame->visible_rect().origin().IsOrigin());

  if (libyuv::I420Copy(src_frame.visible_data(VideoFrame::kYPlane),
                       src_frame.stride(VideoFrame::kYPlane),
                       src_frame.visible_data(VideoFrame::kUPlane),
                       src_frame.stride(VideoFrame::kUPlane),
                       src_frame.visible_data(VideoFrame::kVPlane),
                       src_frame.stride(VideoFrame::kVPlane),
                       dst_frame->data(VideoFrame::kYPlane),
                       dst_frame->stride(VideoFrame::kYPlane),
                       dst_frame->data(VideoFrame::kUPlane),
                       dst_frame->stride(VideoFrame::kUPlane),
                       dst_frame->data(VideoFrame::kVPlane),
                       dst_frame->stride(VideoFrame::kVPlane),
                       src_frame.visible_rect().width(),
                       src_frame.visible_rect().height()))
    return false;

  // Padding the region outside the visible rect with the repeated last
  // column / row of the visible rect. This can improve the coding efficiency.
  FillRegionOutsideVisibleRect(dst_frame->data(VideoFrame::kYPlane),
                               dst_frame->stride(VideoFrame::kYPlane),
                               dst_frame->coded_size(),
                               src_frame.visible_rect().size());
  FillRegionOutsideVisibleRect(
      dst_frame->data(VideoFrame::kUPlane),
      dst_frame->stride(VideoFrame::kUPlane),
      VideoFrame::PlaneSize(PIXEL_FORMAT_I420, VideoFrame::kUPlane,
                            dst_frame->coded_size()),
      VideoFrame::PlaneSize(PIXEL_FORMAT_I420, VideoFrame::kUPlane,
                            src_frame.visible_rect().size()));
  FillRegionOutsideVisibleRect(
      dst_frame->data(VideoFrame::kVPlane),
      dst_frame->stride(VideoFrame::kVPlane),
      VideoFrame::PlaneSize(PIXEL_FORMAT_I420, VideoFrame::kVPlane,
                            dst_frame->coded_size()),
      VideoFrame::PlaneSize(PIXEL_FORMAT_I420, VideoFrame::kVPlane,
                            src_frame.visible_rect().size()));

  return true;
}

scoped_refptr<VideoFrame> ReadbackTextureBackedFrameToMemorySync(
    const VideoFrame& txt_frame,
    gpu::raster::RasterInterface* ri,
    GrDirectContext* gr_context,
    VideoFramePool* pool) {
  DCHECK(ri);

  VideoPixelFormat format = ReadbackFormat(txt_frame);
  if (format == PIXEL_FORMAT_UNKNOWN) {
    DLOG(ERROR) << "Readback is not possible for this frame: "
                << txt_frame.AsHumanReadableString();
    return nullptr;
  }

  scoped_refptr<VideoFrame> result =
      pool ? pool->CreateFrame(format, txt_frame.coded_size(),
                               txt_frame.visible_rect(),
                               txt_frame.natural_size(), txt_frame.timestamp())
           : VideoFrame::CreateFrame(
                 format, txt_frame.coded_size(), txt_frame.visible_rect(),
                 txt_frame.natural_size(), txt_frame.timestamp());
  result->set_color_space(txt_frame.ColorSpace());
  result->metadata().MergeMetadataFrom(txt_frame.metadata());

  size_t planes = VideoFrame::NumPlanes(format);
  for (size_t plane = 0; plane < planes; plane++) {
    gfx::Rect src_rect(0, 0, txt_frame.columns(plane), txt_frame.rows(plane));
    if (!ReadbackTexturePlaneToMemorySync(
            txt_frame, plane, src_rect, result->data(plane),
            result->stride(plane), ri, gr_context)) {
      return nullptr;
    }
  }

  return result;
}

bool ReadbackTexturePlaneToMemorySync(const VideoFrame& src_frame,
                                      size_t src_plane,
                                      gfx::Rect& src_rect,
                                      uint8_t* dest_pixels,
                                      size_t dest_stride,
                                      gpu::raster::RasterInterface* ri,
                                      GrDirectContext* gr_context) {
  DCHECK(ri);

  if (gr_context) {
    return ReadbackTexturePlaneToMemorySyncSkImage(src_frame, src_plane,
                                                   src_rect, dest_pixels,
                                                   dest_stride, ri, gr_context);
  }

  return ReadbackTexturePlaneToMemorySyncOOP(src_frame, src_plane, src_rect,
                                             dest_pixels, dest_stride, ri);
}

Status ConvertAndScaleFrame(const VideoFrame& src_frame,
                            VideoFrame& dst_frame,
                            std::vector<uint8_t>& tmp_buf) {
  constexpr auto kDefaultFiltering = libyuv::kFilterBox;
  if (!src_frame.IsMappable() || !dst_frame.IsMappable())
    return Status(StatusCode::kUnsupportedFrameFormatError);

  if ((dst_frame.format() == PIXEL_FORMAT_I420 ||
       dst_frame.format() == PIXEL_FORMAT_NV12) &&
      (src_frame.format() == PIXEL_FORMAT_XBGR ||
       src_frame.format() == PIXEL_FORMAT_XRGB ||
       src_frame.format() == PIXEL_FORMAT_ABGR ||
       src_frame.format() == PIXEL_FORMAT_ARGB)) {
    // libyuv's RGB to YUV methods always output BT.601.
    dst_frame.set_color_space(gfx::ColorSpace::CreateREC601());

    size_t src_stride = src_frame.stride(VideoFrame::kARGBPlane);
    const uint8_t* src_data = src_frame.visible_data(VideoFrame::kARGBPlane);
    if (src_frame.visible_rect() != dst_frame.visible_rect()) {
      size_t tmp_buffer_size = VideoFrame::AllocationSize(
          src_frame.format(), dst_frame.coded_size());
      if (tmp_buf.size() < tmp_buffer_size)
        tmp_buf.resize(tmp_buffer_size);

      size_t stride =
          VideoFrame::RowBytes(VideoFrame::kARGBPlane, src_frame.format(),
                               dst_frame.visible_rect().width());
      int error = libyuv::ARGBScale(
          src_data, src_stride, src_frame.visible_rect().width(),
          src_frame.visible_rect().height(), tmp_buf.data(), stride,
          dst_frame.visible_rect().width(), dst_frame.visible_rect().height(),
          kDefaultFiltering);
      if (error)
        return Status(StatusCode::kInvalidArgument);
      src_data = tmp_buf.data();
      src_stride = stride;
    }

    if (dst_frame.format() == PIXEL_FORMAT_I420) {
      auto convert_fn = (src_frame.format() == PIXEL_FORMAT_XBGR ||
                         src_frame.format() == PIXEL_FORMAT_ABGR)
                            ? libyuv::ABGRToI420
                            : libyuv::ARGBToI420;
      int error = convert_fn(
          src_data, src_stride, dst_frame.visible_data(VideoFrame::kYPlane),
          dst_frame.stride(VideoFrame::kYPlane),
          dst_frame.visible_data(VideoFrame::kUPlane),
          dst_frame.stride(VideoFrame::kUPlane),
          dst_frame.visible_data(VideoFrame::kVPlane),
          dst_frame.stride(VideoFrame::kVPlane),
          dst_frame.visible_rect().width(), dst_frame.visible_rect().height());
      return error ? Status(StatusCode::kInvalidArgument) : Status();
    }

    auto convert_fn = (src_frame.format() == PIXEL_FORMAT_XBGR ||
                       src_frame.format() == PIXEL_FORMAT_ABGR)
                          ? libyuv::ABGRToNV12
                          : libyuv::ARGBToNV12;
    int error = convert_fn(
        src_data, src_stride, dst_frame.visible_data(VideoFrame::kYPlane),
        dst_frame.stride(VideoFrame::kYPlane),
        dst_frame.visible_data(VideoFrame::kUVPlane),
        dst_frame.stride(VideoFrame::kUVPlane),
        dst_frame.visible_rect().width(), dst_frame.visible_rect().height());
    return error ? Status(StatusCode::kInvalidArgument) : Status();
  }

  // Converting between YUV formats doesn't change the color space.
  dst_frame.set_color_space(src_frame.ColorSpace());

  // Both frames are I420, only scaling is required.
  if (dst_frame.format() == PIXEL_FORMAT_I420 &&
      src_frame.format() == PIXEL_FORMAT_I420) {
    int error = libyuv::I420Scale(
        src_frame.visible_data(VideoFrame::kYPlane),
        src_frame.stride(VideoFrame::kYPlane),
        src_frame.visible_data(VideoFrame::kUPlane),
        src_frame.stride(VideoFrame::kUPlane),
        src_frame.visible_data(VideoFrame::kVPlane),
        src_frame.stride(VideoFrame::kVPlane), src_frame.visible_rect().width(),
        src_frame.visible_rect().height(),
        dst_frame.visible_data(VideoFrame::kYPlane),
        dst_frame.stride(VideoFrame::kYPlane),
        dst_frame.visible_data(VideoFrame::kUPlane),
        dst_frame.stride(VideoFrame::kUPlane),
        dst_frame.visible_data(VideoFrame::kVPlane),
        dst_frame.stride(VideoFrame::kVPlane), dst_frame.visible_rect().width(),
        dst_frame.visible_rect().height(), kDefaultFiltering);
    return error ? Status(StatusCode::kInvalidArgument) : Status();
  }

  // Both frames are NV12, only scaling is required.
  if (dst_frame.format() == PIXEL_FORMAT_NV12 &&
      src_frame.format() == PIXEL_FORMAT_NV12) {
    int error = libyuv::NV12Scale(
        src_frame.visible_data(VideoFrame::kYPlane),
        src_frame.stride(VideoFrame::kYPlane),
        src_frame.visible_data(VideoFrame::kUVPlane),
        src_frame.stride(VideoFrame::kUVPlane),
        src_frame.visible_rect().width(), src_frame.visible_rect().height(),
        dst_frame.visible_data(VideoFrame::kYPlane),
        dst_frame.stride(VideoFrame::kYPlane),
        dst_frame.visible_data(VideoFrame::kUVPlane),
        dst_frame.stride(VideoFrame::kUVPlane),
        dst_frame.visible_rect().width(), dst_frame.visible_rect().height(),
        kDefaultFiltering);
    return error ? Status(StatusCode::kInvalidArgument) : Status();
  }

  if (dst_frame.format() == PIXEL_FORMAT_I420 &&
      src_frame.format() == PIXEL_FORMAT_NV12) {
    if (src_frame.visible_rect() == dst_frame.visible_rect()) {
      // Both frames have the same size, only NV12-to-I420 conversion is
      // required.
      int error = libyuv::NV12ToI420(
          src_frame.visible_data(VideoFrame::kYPlane),
          src_frame.stride(VideoFrame::kYPlane),
          src_frame.visible_data(VideoFrame::kUVPlane),
          src_frame.stride(VideoFrame::kUVPlane),
          dst_frame.visible_data(VideoFrame::kYPlane),
          dst_frame.stride(VideoFrame::kYPlane),
          dst_frame.visible_data(VideoFrame::kUPlane),
          dst_frame.stride(VideoFrame::kUPlane),
          dst_frame.visible_data(VideoFrame::kVPlane),
          dst_frame.stride(VideoFrame::kVPlane),
          dst_frame.visible_rect().width(), dst_frame.visible_rect().height());
      return error ? Status(StatusCode::kInvalidArgument) : Status();
    } else {
      // Both resize and NV12-to-I420 conversion are required.
      // First, split UV planes into two, basically producing a I420 frame.
      const int tmp_uv_width = (src_frame.visible_rect().width() + 1) / 2;
      const int tmp_uv_height = (src_frame.visible_rect().height() + 1) / 2;
      size_t tmp_buffer_size = tmp_uv_width * tmp_uv_height * 2;
      if (tmp_buf.size() < tmp_buffer_size)
        tmp_buf.resize(tmp_buffer_size);

      uint8_t* tmp_u = tmp_buf.data();
      uint8_t* tmp_v = tmp_u + tmp_uv_width * tmp_uv_height;
      DCHECK_EQ(tmp_buf.data() + tmp_buffer_size,
                tmp_v + (tmp_uv_width * tmp_uv_height));
      libyuv::SplitUVPlane(src_frame.visible_data(VideoFrame::kUVPlane),
                           src_frame.stride(VideoFrame::kUVPlane), tmp_u,
                           tmp_uv_width, tmp_v, tmp_uv_width, tmp_uv_width,
                           tmp_uv_height);

      // Second, scale resulting I420 frame into the destination.
      int error = libyuv::I420Scale(
          src_frame.visible_data(VideoFrame::kYPlane),
          src_frame.stride(VideoFrame::kYPlane),
          tmp_u,  // Temporary U-plane for src UV-plane.
          tmp_uv_width,
          tmp_v,  // Temporary V-plane for src UV-plane.
          tmp_uv_width, src_frame.visible_rect().width(),
          src_frame.visible_rect().height(),
          dst_frame.visible_data(VideoFrame::kYPlane),
          dst_frame.stride(VideoFrame::kYPlane),
          dst_frame.visible_data(VideoFrame::kUPlane),
          dst_frame.stride(VideoFrame::kUPlane),
          dst_frame.visible_data(VideoFrame::kVPlane),
          dst_frame.stride(VideoFrame::kVPlane),
          dst_frame.visible_rect().width(), dst_frame.visible_rect().height(),
          kDefaultFiltering);
      return error ? Status(StatusCode::kInvalidArgument) : Status();
    }
  }

  if (dst_frame.format() == PIXEL_FORMAT_NV12 &&
      src_frame.format() == PIXEL_FORMAT_I420) {
    if (src_frame.visible_rect() == dst_frame.visible_rect()) {
      // Both frames have the same size, only I420-to-NV12 conversion is
      // required.
      int error = libyuv::I420ToNV12(
          src_frame.visible_data(VideoFrame::kYPlane),
          src_frame.stride(VideoFrame::kYPlane),
          src_frame.visible_data(VideoFrame::kUPlane),
          src_frame.stride(VideoFrame::kUPlane),
          src_frame.visible_data(VideoFrame::kVPlane),
          src_frame.stride(VideoFrame::kVPlane),
          dst_frame.visible_data(VideoFrame::kYPlane),
          dst_frame.stride(VideoFrame::kYPlane),
          dst_frame.visible_data(VideoFrame::kUVPlane),
          dst_frame.stride(VideoFrame::kUVPlane),
          dst_frame.visible_rect().width(), dst_frame.visible_rect().height());
      return error ? Status(StatusCode::kInvalidArgument) : Status();
    } else {
      // Both resize and I420-to-NV12 conversion are required.
      // First, merge U and V planes into one, basically producing a NV12 frame.
      const int tmp_uv_width = (src_frame.visible_rect().width() + 1) / 2;
      const int tmp_uv_height = (src_frame.visible_rect().height() + 1) / 2;
      size_t tmp_buffer_size = tmp_uv_width * tmp_uv_height * 2;
      if (tmp_buf.size() < tmp_buffer_size)
        tmp_buf.resize(tmp_buffer_size);

      uint8_t* tmp_uv = tmp_buf.data();
      size_t stride_uv = tmp_uv_width * 2;
      libyuv::MergeUVPlane(src_frame.visible_data(VideoFrame::kUPlane),
                           src_frame.stride(VideoFrame::kUPlane),
                           src_frame.visible_data(VideoFrame::kVPlane),
                           src_frame.stride(VideoFrame::kVPlane),
                           tmp_uv,     // Temporary for merged UV-plane
                           stride_uv,  // Temporary stride
                           tmp_uv_width, tmp_uv_height);

      // Second, scale resulting NV12 frame into the destination.
      int error = libyuv::NV12Scale(
          src_frame.visible_data(VideoFrame::kYPlane),
          src_frame.stride(VideoFrame::kYPlane),
          tmp_uv,     // Temporary for merged UV-plane
          stride_uv,  // Temporary stride
          src_frame.visible_rect().width(), src_frame.visible_rect().height(),
          dst_frame.visible_data(VideoFrame::kYPlane),
          dst_frame.stride(VideoFrame::kYPlane),
          dst_frame.visible_data(VideoFrame::kUVPlane),
          dst_frame.stride(VideoFrame::kUVPlane),
          dst_frame.visible_rect().width(), dst_frame.visible_rect().height(),
          kDefaultFiltering);
      return error ? Status(StatusCode::kInvalidArgument) : Status();
    }
  }

  return Status(StatusCode::kUnsupportedFrameFormatError)
      .WithData("src", src_frame.AsHumanReadableString())
      .WithData("dst", dst_frame.AsHumanReadableString());
}

MEDIA_EXPORT VideoPixelFormat
VideoPixelFormatFromSkColorType(SkColorType sk_color_type, bool is_opaque) {
  switch (sk_color_type) {
    case kRGBA_8888_SkColorType:
      return is_opaque ? media::PIXEL_FORMAT_XBGR : media::PIXEL_FORMAT_ABGR;
    case kBGRA_8888_SkColorType:
      return is_opaque ? media::PIXEL_FORMAT_XRGB : media::PIXEL_FORMAT_ARGB;
    default:
      // TODO(crbug.com/1073995): Add F16 support.
      return media::PIXEL_FORMAT_UNKNOWN;
  }
}

scoped_refptr<VideoFrame> CreateFromSkImage(sk_sp<SkImage> sk_image,
                                            const gfx::Rect& visible_rect,
                                            const gfx::Size& natural_size,
                                            base::TimeDelta timestamp,
                                            bool force_opaque) {
  DCHECK(!sk_image->isTextureBacked());

  // A given SkImage may not exist until it's rasterized.
  if (sk_image->isLazyGenerated())
    sk_image = sk_image->makeRasterImage();

  const auto format = VideoPixelFormatFromSkColorType(
      sk_image->colorType(), sk_image->isOpaque() || force_opaque);
  if (VideoFrameLayout::NumPlanes(format) != 1) {
    DLOG(ERROR) << "Invalid SkColorType for CreateFromSkImage";
    return nullptr;
  }

  SkPixmap pm;
  const bool peek_result = sk_image->peekPixels(&pm);
  DCHECK(peek_result);

  auto coded_size = gfx::Size(sk_image->width(), sk_image->height());
  auto layout = VideoFrameLayout::CreateWithStrides(
      format, coded_size, std::vector<int32_t>(1, pm.rowBytes()));
  if (!layout)
    return nullptr;

  auto frame = VideoFrame::WrapExternalDataWithLayout(
      *layout, visible_rect, natural_size,
      // TODO(crbug.com/1161304): We should be able to wrap readonly memory in
      // a VideoFrame instead of using writable_addr() here.
      reinterpret_cast<uint8_t*>(pm.writable_addr()), pm.computeByteSize(),
      timestamp);
  if (!frame)
    return nullptr;

  frame->AddDestructionObserver(
      base::BindOnce([](sk_sp<SkImage>) {}, std::move(sk_image)));
  return frame;
}

}  // namespace media
