// 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/filters/skcanvas_video_renderer.h"

#include "base/logging.h"
#include "media/base/video_frame.h"
#include "media/base/yuv_convert.h"
#include "third_party/libyuv/include/libyuv.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "ui/gfx/skbitmap_operations.h"

// Skia internal format depends on a platform. On Android it is ABGR, on others
// it is ARGB.
#if SK_B32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_R32_SHIFT == 16 && \
    SK_A32_SHIFT == 24
#define LIBYUV_I420_TO_ARGB libyuv::I420ToARGB
#define LIBYUV_I422_TO_ARGB libyuv::I422ToARGB
#elif SK_R32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 16 && \
    SK_A32_SHIFT == 24
#define LIBYUV_I420_TO_ARGB libyuv::I420ToABGR
#define LIBYUV_I422_TO_ARGB libyuv::I422ToABGR
#else
#error Unexpected Skia ARGB_8888 layout!
#endif

namespace media {

static bool IsYUV(media::VideoFrame::Format format) {
  return format == media::VideoFrame::YV12 ||
         format == media::VideoFrame::YV16 ||
         format == media::VideoFrame::I420 ||
         format == media::VideoFrame::YV12A ||
         format == media::VideoFrame::YV12J ||
         format == media::VideoFrame::YV24;
}

static bool IsYUVOrNative(media::VideoFrame::Format format) {
  return IsYUV(format) || format == media::VideoFrame::NATIVE_TEXTURE;
}

// Converts a VideoFrame containing YUV data to a SkBitmap containing RGB data.
//
// |bitmap| will be (re)allocated to match the dimensions of |video_frame|.
static void ConvertVideoFrameToBitmap(
    const scoped_refptr<media::VideoFrame>& video_frame,
    SkBitmap* bitmap) {
  DCHECK(IsYUVOrNative(video_frame->format()))
      << video_frame->format();
  if (IsYUV(video_frame->format())) {
    DCHECK_EQ(video_frame->stride(media::VideoFrame::kUPlane),
              video_frame->stride(media::VideoFrame::kVPlane));
  }

  // Check if |bitmap| needs to be (re)allocated.
  if (bitmap->isNull() ||
      bitmap->width() != video_frame->visible_rect().width() ||
      bitmap->height() != video_frame->visible_rect().height()) {
    bitmap->allocN32Pixels(video_frame->visible_rect().width(),
                           video_frame->visible_rect().height());
    bitmap->setIsVolatile(true);
  }

  bitmap->lockPixels();

  size_t y_offset = 0;
  size_t uv_offset = 0;
  if (IsYUV(video_frame->format())) {
    int y_shift = (video_frame->format() == media::VideoFrame::YV16) ? 0 : 1;
    // Use the "left" and "top" of the destination rect to locate the offset
    // in Y, U and V planes.
    y_offset = (video_frame->stride(media::VideoFrame::kYPlane) *
                video_frame->visible_rect().y()) +
                video_frame->visible_rect().x();
    // For format YV12, there is one U, V value per 2x2 block.
    // For format YV16, there is one U, V value per 2x1 block.
    uv_offset = (video_frame->stride(media::VideoFrame::kUPlane) *
                (video_frame->visible_rect().y() >> y_shift)) +
                (video_frame->visible_rect().x() >> 1);
  }

  switch (video_frame->format()) {
    case media::VideoFrame::YV12:
    case media::VideoFrame::I420:
      LIBYUV_I420_TO_ARGB(
          video_frame->data(media::VideoFrame::kYPlane) + y_offset,
          video_frame->stride(media::VideoFrame::kYPlane),
          video_frame->data(media::VideoFrame::kUPlane) + uv_offset,
          video_frame->stride(media::VideoFrame::kUPlane),
          video_frame->data(media::VideoFrame::kVPlane) + uv_offset,
          video_frame->stride(media::VideoFrame::kVPlane),
          static_cast<uint8*>(bitmap->getPixels()),
          bitmap->rowBytes(),
          video_frame->visible_rect().width(),
          video_frame->visible_rect().height());
      break;

    case media::VideoFrame::YV12J:
      media::ConvertYUVToRGB32(
          video_frame->data(media::VideoFrame::kYPlane) + y_offset,
          video_frame->data(media::VideoFrame::kUPlane) + uv_offset,
          video_frame->data(media::VideoFrame::kVPlane) + uv_offset,
          static_cast<uint8*>(bitmap->getPixels()),
          video_frame->visible_rect().width(),
          video_frame->visible_rect().height(),
          video_frame->stride(media::VideoFrame::kYPlane),
          video_frame->stride(media::VideoFrame::kUPlane),
          bitmap->rowBytes(),
          media::YV12J);
      break;

    case media::VideoFrame::YV16:
      LIBYUV_I422_TO_ARGB(
          video_frame->data(media::VideoFrame::kYPlane) + y_offset,
          video_frame->stride(media::VideoFrame::kYPlane),
          video_frame->data(media::VideoFrame::kUPlane) + uv_offset,
          video_frame->stride(media::VideoFrame::kUPlane),
          video_frame->data(media::VideoFrame::kVPlane) + uv_offset,
          video_frame->stride(media::VideoFrame::kVPlane),
          static_cast<uint8*>(bitmap->getPixels()),
          bitmap->rowBytes(),
          video_frame->visible_rect().width(),
          video_frame->visible_rect().height());
      break;

    case media::VideoFrame::YV12A:
      // Since libyuv doesn't support YUVA, fallback to media, which is not ARM
      // optimized.
      // TODO(fbarchard, mtomasz): Use libyuv, then copy the alpha channel.
      media::ConvertYUVAToARGB(
          video_frame->data(media::VideoFrame::kYPlane) + y_offset,
          video_frame->data(media::VideoFrame::kUPlane) + uv_offset,
          video_frame->data(media::VideoFrame::kVPlane) + uv_offset,
          video_frame->data(media::VideoFrame::kAPlane),
          static_cast<uint8*>(bitmap->getPixels()),
          video_frame->visible_rect().width(),
          video_frame->visible_rect().height(),
          video_frame->stride(media::VideoFrame::kYPlane),
          video_frame->stride(media::VideoFrame::kUPlane),
          video_frame->stride(media::VideoFrame::kAPlane),
          bitmap->rowBytes(),
          media::YV12);
      break;

    case media::VideoFrame::YV24:
      libyuv::I444ToARGB(
          video_frame->data(media::VideoFrame::kYPlane) + y_offset,
          video_frame->stride(media::VideoFrame::kYPlane),
          video_frame->data(media::VideoFrame::kUPlane) + uv_offset,
          video_frame->stride(media::VideoFrame::kUPlane),
          video_frame->data(media::VideoFrame::kVPlane) + uv_offset,
          video_frame->stride(media::VideoFrame::kVPlane),
          static_cast<uint8*>(bitmap->getPixels()),
          bitmap->rowBytes(),
          video_frame->visible_rect().width(),
          video_frame->visible_rect().height());
#if SK_R32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 16 && \
    SK_A32_SHIFT == 24
      libyuv::ARGBToABGR(
          static_cast<uint8*>(bitmap->getPixels()),
          bitmap->rowBytes(),
          static_cast<uint8*>(bitmap->getPixels()),
          bitmap->rowBytes(),
          video_frame->visible_rect().width(),
          video_frame->visible_rect().height());
#endif
      break;

    case media::VideoFrame::NATIVE_TEXTURE:
      DCHECK_EQ(video_frame->format(), media::VideoFrame::NATIVE_TEXTURE);
      video_frame->ReadPixelsFromNativeTexture(*bitmap);
      break;

    default:
      NOTREACHED();
      break;
  }
  bitmap->notifyPixelsChanged();
  bitmap->unlockPixels();
}

SkCanvasVideoRenderer::SkCanvasVideoRenderer()
    : last_frame_timestamp_(media::kNoTimestamp()) {
}

SkCanvasVideoRenderer::~SkCanvasVideoRenderer() {}

void SkCanvasVideoRenderer::Paint(media::VideoFrame* video_frame,
                                  SkCanvas* canvas,
                                  const gfx::RectF& dest_rect,
                                  uint8 alpha,
                                  SkXfermode::Mode mode,
                                  VideoRotation video_rotation) {
  if (alpha == 0) {
    return;
  }

  SkRect dest;
  dest.set(dest_rect.x(), dest_rect.y(), dest_rect.right(), dest_rect.bottom());

  SkPaint paint;
  paint.setAlpha(alpha);

  // Paint black rectangle if there isn't a frame available or the
  // frame has an unexpected format.
  if (!video_frame || !IsYUVOrNative(video_frame->format())) {
    canvas->drawRect(dest, paint);
    return;
  }

  // Check if we should convert and update |last_frame_|.
  if (last_frame_.isNull() ||
      video_frame->timestamp() != last_frame_timestamp_) {
    ConvertVideoFrameToBitmap(video_frame, &last_frame_);

    switch (video_rotation) {
      case VIDEO_ROTATION_0:
        break;
      case VIDEO_ROTATION_90:
        last_frame_ = SkBitmapOperations::Rotate(
            last_frame_, SkBitmapOperations::ROTATION_90_CW);
        break;
      case VIDEO_ROTATION_180:
        last_frame_ = SkBitmapOperations::Rotate(
            last_frame_, SkBitmapOperations::ROTATION_180_CW);
        break;
      case VIDEO_ROTATION_270:
        last_frame_ = SkBitmapOperations::Rotate(
            last_frame_, SkBitmapOperations::ROTATION_270_CW);
        break;
    }

    last_frame_timestamp_ = video_frame->timestamp();
  }

  paint.setXfermodeMode(mode);

  // Paint using |last_frame_|.
  paint.setFilterLevel(SkPaint::kLow_FilterLevel);
  canvas->drawBitmapRect(last_frame_, NULL, dest, &paint);
}

void SkCanvasVideoRenderer::Copy(media::VideoFrame* video_frame,
                                 SkCanvas* canvas) {
  Paint(video_frame,
        canvas,
        video_frame->visible_rect(),
        0xff,
        SkXfermode::kSrc_Mode,
        media::VIDEO_ROTATION_0);
}

}  // namespace media
