// Copyright 2014 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 "content/renderer/pepper/pepper_media_stream_video_track_host.h"

#include <stddef.h>

#include "base/base64.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/rand_util.h"
#include "base/strings/utf_string_conversions.h"
#include "content/renderer/media/media_stream_video_source.h"
#include "content/renderer/media/media_stream_video_track.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/video_util.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppb_media_stream_video_track.h"
#include "ppapi/c/ppb_video_frame.h"
#include "ppapi/host/dispatch_host_message.h"
#include "ppapi/host/host_message_context.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/shared_impl/media_stream_buffer.h"
#include "third_party/libyuv/include/libyuv.h"

using media::VideoFrame;
using ppapi::host::HostMessageContext;
using ppapi::MediaStreamVideoTrackShared;

namespace {

const int32_t kDefaultNumberOfBuffers = 4;
const int32_t kMaxNumberOfBuffers = 8;
// Filter mode for scaling frames.
const libyuv::FilterMode kFilterMode = libyuv::kFilterBox;

const char kPepperVideoSourceName[] = "PepperVideoSourceName";

// Default config for output mode.
const int kDefaultOutputFrameRate = 30;

media::VideoPixelFormat ToPixelFormat(PP_VideoFrame_Format format) {
  switch (format) {
    case PP_VIDEOFRAME_FORMAT_YV12:
      return media::PIXEL_FORMAT_YV12;
    case PP_VIDEOFRAME_FORMAT_I420:
      return media::PIXEL_FORMAT_I420;
    default:
      DVLOG(1) << "Unsupported pixel format " << format;
      return media::PIXEL_FORMAT_UNKNOWN;
  }
}

PP_VideoFrame_Format ToPpapiFormat(media::VideoPixelFormat format) {
  switch (format) {
    case media::PIXEL_FORMAT_YV12:
      return PP_VIDEOFRAME_FORMAT_YV12;
    case media::PIXEL_FORMAT_I420:
      return PP_VIDEOFRAME_FORMAT_I420;
    default:
      DVLOG(1) << "Unsupported pixel format " << format;
      return PP_VIDEOFRAME_FORMAT_UNKNOWN;
  }
}

media::VideoPixelFormat FromPpapiFormat(PP_VideoFrame_Format format) {
  switch (format) {
    case PP_VIDEOFRAME_FORMAT_YV12:
      return media::PIXEL_FORMAT_YV12;
    case PP_VIDEOFRAME_FORMAT_I420:
      return media::PIXEL_FORMAT_I420;
    default:
      DVLOG(1) << "Unsupported pixel format " << format;
      return media::PIXEL_FORMAT_UNKNOWN;
  }
}

// Compute size base on the size of frame received from MediaStreamVideoSink
// and size specified by plugin.
gfx::Size GetTargetSize(const gfx::Size& source, const gfx::Size& plugin) {
  return gfx::Size(plugin.width() ? plugin.width() : source.width(),
                   plugin.height() ? plugin.height() : source.height());
}

// Compute format base on the format of frame received from MediaStreamVideoSink
// and format specified by plugin.
PP_VideoFrame_Format GetTargetFormat(PP_VideoFrame_Format source,
                                     PP_VideoFrame_Format plugin) {
  return plugin != PP_VIDEOFRAME_FORMAT_UNKNOWN ? plugin : source;
}

void ConvertFromMediaVideoFrame(const scoped_refptr<media::VideoFrame>& src,
                                PP_VideoFrame_Format dst_format,
                                const gfx::Size& dst_size,
                                uint8_t* dst) {
  CHECK(src->format() == media::PIXEL_FORMAT_YV12 ||
        src->format() == media::PIXEL_FORMAT_I420);
  if (dst_format == PP_VIDEOFRAME_FORMAT_BGRA) {
    if (src->visible_rect().size() == dst_size) {
      libyuv::I420ToARGB(src->visible_data(VideoFrame::kYPlane),
                         src->stride(VideoFrame::kYPlane),
                         src->visible_data(VideoFrame::kUPlane),
                         src->stride(VideoFrame::kUPlane),
                         src->visible_data(VideoFrame::kVPlane),
                         src->stride(VideoFrame::kVPlane),
                         dst,
                         dst_size.width() * 4,
                         dst_size.width(),
                         dst_size.height());
    } else {
      libyuv::YUVToARGBScaleClip(
          src->visible_data(VideoFrame::kYPlane),
          src->stride(VideoFrame::kYPlane),
          src->visible_data(VideoFrame::kUPlane),
          src->stride(VideoFrame::kUPlane),
          src->visible_data(VideoFrame::kVPlane),
          src->stride(VideoFrame::kVPlane), libyuv::FOURCC_YV12,
          src->visible_rect().width(), src->visible_rect().height(), dst,
          dst_size.width() * 4, libyuv::FOURCC_ARGB, dst_size.width(),
          dst_size.height(), 0, 0, dst_size.width(), dst_size.height(),
          kFilterMode);
    }
  } else if (dst_format == PP_VIDEOFRAME_FORMAT_YV12 ||
             dst_format == PP_VIDEOFRAME_FORMAT_I420) {
    static const size_t kPlanesOrder[][3] = {
        {VideoFrame::kYPlane, VideoFrame::kVPlane,
         VideoFrame::kUPlane},  // YV12
        {VideoFrame::kYPlane, VideoFrame::kUPlane,
         VideoFrame::kVPlane},  // I420
    };
    const int plane_order = (dst_format == PP_VIDEOFRAME_FORMAT_YV12) ? 0 : 1;
    int dst_width = dst_size.width();
    int dst_height = dst_size.height();
    libyuv::ScalePlane(src->visible_data(kPlanesOrder[plane_order][0]),
                       src->stride(kPlanesOrder[plane_order][0]),
                       src->visible_rect().width(),
                       src->visible_rect().height(),
                       dst,
                       dst_width,
                       dst_width,
                       dst_height,
                       kFilterMode);
    dst += dst_width * dst_height;
    const int src_halfwidth = (src->visible_rect().width() + 1) >> 1;
    const int src_halfheight = (src->visible_rect().height() + 1) >> 1;
    const int dst_halfwidth = (dst_width + 1) >> 1;
    const int dst_halfheight = (dst_height + 1) >> 1;
    libyuv::ScalePlane(src->visible_data(kPlanesOrder[plane_order][1]),
                       src->stride(kPlanesOrder[plane_order][1]),
                       src_halfwidth,
                       src_halfheight,
                       dst,
                       dst_halfwidth,
                       dst_halfwidth,
                       dst_halfheight,
                       kFilterMode);
    dst += dst_halfwidth * dst_halfheight;
    libyuv::ScalePlane(src->visible_data(kPlanesOrder[plane_order][2]),
                       src->stride(kPlanesOrder[plane_order][2]),
                       src_halfwidth,
                       src_halfheight,
                       dst,
                       dst_halfwidth,
                       dst_halfwidth,
                       dst_halfheight,
                       kFilterMode);
  } else {
    NOTREACHED();
  }
}

}  // namespace

namespace content {

// Internal class used for delivering video frames on the IO-thread to
// the MediaStreamVideoSource implementation.
class PepperMediaStreamVideoTrackHost::FrameDeliverer
    : public base::RefCountedThreadSafe<FrameDeliverer> {
 public:
  FrameDeliverer(scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
                 const VideoCaptureDeliverFrameCB& new_frame_callback);

  void DeliverVideoFrame(const scoped_refptr<media::VideoFrame>& frame);

 private:
  friend class base::RefCountedThreadSafe<FrameDeliverer>;
  virtual ~FrameDeliverer();

  void DeliverFrameOnIO(const scoped_refptr<media::VideoFrame>& frame);

  scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
  VideoCaptureDeliverFrameCB new_frame_callback_;

  DISALLOW_COPY_AND_ASSIGN(FrameDeliverer);
};

PepperMediaStreamVideoTrackHost::FrameDeliverer::FrameDeliverer(
    scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
    const VideoCaptureDeliverFrameCB& new_frame_callback)
    : io_task_runner_(io_task_runner), new_frame_callback_(new_frame_callback) {
}

PepperMediaStreamVideoTrackHost::FrameDeliverer::~FrameDeliverer() {
}

void PepperMediaStreamVideoTrackHost::FrameDeliverer::DeliverVideoFrame(
    const scoped_refptr<media::VideoFrame>& frame) {
  io_task_runner_->PostTask(
      FROM_HERE, base::Bind(&FrameDeliverer::DeliverFrameOnIO, this, frame));
}

void PepperMediaStreamVideoTrackHost::FrameDeliverer::DeliverFrameOnIO(
     const scoped_refptr<media::VideoFrame>& frame) {
  DCHECK(io_task_runner_->BelongsToCurrentThread());
  // The time when this frame is generated is unknown so give a null value to
  // |estimated_capture_time|.
  new_frame_callback_.Run(frame, base::TimeTicks());
}

PepperMediaStreamVideoTrackHost::PepperMediaStreamVideoTrackHost(
    RendererPpapiHost* host,
    PP_Instance instance,
    PP_Resource resource,
    const blink::WebMediaStreamTrack& track)
    : PepperMediaStreamTrackHostBase(host, instance, resource),
      track_(track),
      number_of_buffers_(kDefaultNumberOfBuffers),
      source_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN),
      plugin_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN),
      frame_data_size_(0),
      type_(kRead),
      weak_factory_(this) {
  DCHECK(!track_.isNull());
}

PepperMediaStreamVideoTrackHost::PepperMediaStreamVideoTrackHost(
    RendererPpapiHost* host,
    PP_Instance instance,
    PP_Resource resource)
    : PepperMediaStreamTrackHostBase(host, instance, resource),
      number_of_buffers_(kDefaultNumberOfBuffers),
      source_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN),
      plugin_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN),
      frame_data_size_(0),
      type_(kWrite),
      weak_factory_(this) {
  InitBlinkTrack();
  DCHECK(!track_.isNull());
}

PepperMediaStreamVideoTrackHost::~PepperMediaStreamVideoTrackHost() {
  OnClose();
}

bool PepperMediaStreamVideoTrackHost::IsMediaStreamVideoTrackHost() {
  return true;
}

void PepperMediaStreamVideoTrackHost::InitBuffers() {
  gfx::Size size = GetTargetSize(source_frame_size_, plugin_frame_size_);
  DCHECK(!size.IsEmpty());

  PP_VideoFrame_Format format =
      GetTargetFormat(source_frame_format_, plugin_frame_format_);
  DCHECK_NE(format, PP_VIDEOFRAME_FORMAT_UNKNOWN);

  if (format == PP_VIDEOFRAME_FORMAT_BGRA) {
    frame_data_size_ = size.width() * size.height() * 4;
  } else {
    frame_data_size_ =
        VideoFrame::AllocationSize(FromPpapiFormat(format), size);
  }

  DCHECK_GT(frame_data_size_, 0U);
  int32_t buffer_size =
      sizeof(ppapi::MediaStreamBuffer::Video) + frame_data_size_;
  bool result = PepperMediaStreamTrackHostBase::InitBuffers(number_of_buffers_,
                                                            buffer_size,
                                                            type_);
  CHECK(result);

  if (type_ == kWrite) {
    for (int32_t i = 0; i < buffer_manager()->number_of_buffers(); ++i) {
      ppapi::MediaStreamBuffer::Video* buffer =
          &(buffer_manager()->GetBufferPointer(i)->video);
      buffer->header.size = buffer_manager()->buffer_size();
      buffer->header.type = ppapi::MediaStreamBuffer::TYPE_VIDEO;
      buffer->format = format;
      buffer->size.width = size.width();
      buffer->size.height = size.height();
      buffer->data_size = frame_data_size_;
    }

    // Make all the frames avaiable to the plugin.
    std::vector<int32_t> indices = buffer_manager()->DequeueBuffers();
    SendEnqueueBuffersMessageToPlugin(indices);
  }
}

void PepperMediaStreamVideoTrackHost::OnClose() {
  MediaStreamVideoSink::DisconnectFromTrack();
  weak_factory_.InvalidateWeakPtrs();
}

int32_t PepperMediaStreamVideoTrackHost::OnHostMsgEnqueueBuffer(
    ppapi::host::HostMessageContext* context, int32_t index) {
  if (type_ == kRead) {
    return PepperMediaStreamTrackHostBase::OnHostMsgEnqueueBuffer(context,
                                                                  index);
  } else {
    return SendFrameToTrack(index);
  }
}

int32_t PepperMediaStreamVideoTrackHost::SendFrameToTrack(int32_t index) {
  DCHECK_EQ(type_, kWrite);

  if (frame_deliverer_) {
    // Sends the frame to blink video track.
    ppapi::MediaStreamBuffer::Video* pp_frame =
        &(buffer_manager()->GetBufferPointer(index)->video);

    int32_t y_stride = plugin_frame_size_.width();
    int32_t uv_stride = (plugin_frame_size_.width() + 1) / 2;
    uint8_t* y_data = static_cast<uint8_t*>(pp_frame->data);
    // Default to I420
    uint8_t* u_data = y_data + plugin_frame_size_.GetArea();
    uint8_t* v_data = y_data + (plugin_frame_size_.GetArea() * 5 / 4);
    if (plugin_frame_format_ == PP_VIDEOFRAME_FORMAT_YV12) {
      // Swap u and v for YV12.
      uint8_t* tmp = u_data;
      u_data = v_data;
      v_data = tmp;
    }

    int64_t ts_ms = static_cast<int64_t>(pp_frame->timestamp *
                                         base::Time::kMillisecondsPerSecond);
    scoped_refptr<VideoFrame> frame = media::VideoFrame::WrapExternalYuvData(
        FromPpapiFormat(plugin_frame_format_),
        plugin_frame_size_,
        gfx::Rect(plugin_frame_size_),
        plugin_frame_size_,
        y_stride,
        uv_stride,
        uv_stride,
        y_data,
        u_data,
        v_data,
        base::TimeDelta::FromMilliseconds(ts_ms));
    if (!frame)
      return PP_ERROR_FAILED;

    frame_deliverer_->DeliverVideoFrame(frame);
  }

  // Makes the frame available again for plugin.
  SendEnqueueBufferMessageToPlugin(index);
  return PP_OK;
}

void PepperMediaStreamVideoTrackHost::OnVideoFrame(
    const scoped_refptr<VideoFrame>& video_frame,
    base::TimeTicks estimated_capture_time) {
  DCHECK(video_frame.get());
  // TODO(penghuang): Check |frame->end_of_stream()| and close the track.
  scoped_refptr<media::VideoFrame> frame = video_frame;
  // Drop alpha channel since we do not support it yet.
  if (frame->format() == media::PIXEL_FORMAT_YV12A)
    frame = media::WrapAsI420VideoFrame(video_frame);
  PP_VideoFrame_Format ppformat = ToPpapiFormat(frame->format());
  if (ppformat == PP_VIDEOFRAME_FORMAT_UNKNOWN)
    return;

  if (source_frame_size_.IsEmpty()) {
    source_frame_size_ = frame->visible_rect().size();
    source_frame_format_ = ppformat;
    InitBuffers();
  }

  int32_t index = buffer_manager()->DequeueBuffer();
  // Drop frames if the underlying buffer is full.
  if (index < 0) {
    DVLOG(1) << "A frame is dropped.";
    return;
  }

  CHECK_EQ(ppformat, source_frame_format_) << "Frame format is changed.";

  gfx::Size size = GetTargetSize(source_frame_size_, plugin_frame_size_);
  ppformat =
      GetTargetFormat(source_frame_format_, plugin_frame_format_);
  ppapi::MediaStreamBuffer::Video* buffer =
      &(buffer_manager()->GetBufferPointer(index)->video);
  buffer->header.size = buffer_manager()->buffer_size();
  buffer->header.type = ppapi::MediaStreamBuffer::TYPE_VIDEO;
  buffer->timestamp = frame->timestamp().InSecondsF();
  buffer->format = ppformat;
  buffer->size.width = size.width();
  buffer->size.height = size.height();
  buffer->data_size = frame_data_size_;
  ConvertFromMediaVideoFrame(frame, ppformat, size, buffer->data);

  SendEnqueueBufferMessageToPlugin(index);
}

class PepperMediaStreamVideoTrackHost::VideoSource final
    : public MediaStreamVideoSource {
 public:
  explicit VideoSource(base::WeakPtr<PepperMediaStreamVideoTrackHost> host)
      : host_(std::move(host)) {}

  ~VideoSource() final { StopSourceImpl(); }

  void GetCurrentSupportedFormats(
      int max_requested_width, int max_requested_height,
      double max_requested_frame_rate,
      const VideoCaptureDeviceFormatsCB& callback) final {
    media::VideoCaptureFormats formats;
    if (host_) {
      formats.push_back(media::VideoCaptureFormat(
          host_->plugin_frame_size_,
          kDefaultOutputFrameRate,
          ToPixelFormat(host_->plugin_frame_format_)));
    }
    callback.Run(formats);
  }

  void StartSourceImpl(
      const media::VideoCaptureFormat& format,
      const blink::WebMediaConstraints& constraints,
      const VideoCaptureDeliverFrameCB& frame_callback) final {
    if (host_) {
      host_->frame_deliverer_ =
          new FrameDeliverer(io_task_runner(), frame_callback);
    }
  }

  void StopSourceImpl() final {
    if (host_)
      host_->frame_deliverer_ = nullptr;
  }

 private:
  const base::WeakPtr<PepperMediaStreamVideoTrackHost> host_;

  DISALLOW_COPY_AND_ASSIGN(VideoSource);
};

void PepperMediaStreamVideoTrackHost::DidConnectPendingHostToResource() {
  if (!MediaStreamVideoSink::connected_track().isNull())
    return;
  MediaStreamVideoSink::ConnectToTrack(
      track_, media::BindToCurrentLoop(
                  base::Bind(&PepperMediaStreamVideoTrackHost::OnVideoFrame,
                             weak_factory_.GetWeakPtr())),
      false);
}

int32_t PepperMediaStreamVideoTrackHost::OnResourceMessageReceived(
    const IPC::Message& msg,
    HostMessageContext* context) {
  PPAPI_BEGIN_MESSAGE_MAP(PepperMediaStreamVideoTrackHost, msg)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL(
        PpapiHostMsg_MediaStreamVideoTrack_Configure, OnHostMsgConfigure)
  PPAPI_END_MESSAGE_MAP()
  return PepperMediaStreamTrackHostBase::OnResourceMessageReceived(msg,
                                                                   context);
}

int32_t PepperMediaStreamVideoTrackHost::OnHostMsgConfigure(
    HostMessageContext* context,
    const MediaStreamVideoTrackShared::Attributes& attributes) {
  CHECK(MediaStreamVideoTrackShared::VerifyAttributes(attributes));

  bool changed = false;
  gfx::Size new_size(attributes.width, attributes.height);
  if (GetTargetSize(source_frame_size_, plugin_frame_size_) !=
      GetTargetSize(source_frame_size_, new_size)) {
    changed = true;
  }
  plugin_frame_size_ = new_size;

  int32_t buffers = attributes.buffers
                        ? std::min(kMaxNumberOfBuffers, attributes.buffers)
                        : kDefaultNumberOfBuffers;
  if (buffers != number_of_buffers_)
    changed = true;
  number_of_buffers_ = buffers;

  if (GetTargetFormat(source_frame_format_, plugin_frame_format_) !=
      GetTargetFormat(source_frame_format_, attributes.format)) {
    changed = true;
  }
  plugin_frame_format_ = attributes.format;

  // If the first frame has been received, we will re-initialize buffers with
  // new settings. Otherwise, we will initialize buffer when we receive
  // the first frame, because plugin can only provide part of attributes
  // which are not enough to initialize buffers.
  if (changed && (type_ == kWrite || !source_frame_size_.IsEmpty()))
    InitBuffers();

  // TODO(ronghuawu): Ask the owner of DOMMediaStreamTrackToResource why
  // source id instead of track id is used there.
  const std::string id = track_.source().id().utf8();
  context->reply_msg = PpapiPluginMsg_MediaStreamVideoTrack_ConfigureReply(id);
  return PP_OK;
}

void PepperMediaStreamVideoTrackHost::InitBlinkTrack() {
  std::string source_id;
  base::Base64Encode(base::RandBytesAsString(64), &source_id);
  blink::WebMediaStreamSource webkit_source;
  webkit_source.initialize(blink::WebString::fromASCII(source_id),
                           blink::WebMediaStreamSource::TypeVideo,
                           blink::WebString::fromASCII(kPepperVideoSourceName));
  MediaStreamVideoSource* const source =
      new VideoSource(weak_factory_.GetWeakPtr());
  webkit_source.setExtraData(source);  // Takes ownership of |source|.

  const bool enabled = true;
  blink::WebMediaConstraints constraints;
  constraints.initialize();
  track_ = MediaStreamVideoTrack::CreateVideoTrack(
       source, constraints,
       base::Bind(
           &PepperMediaStreamVideoTrackHost::OnTrackStarted,
           base::Unretained(this)),
       enabled);
  // Note: The call to CreateVideoTrack() returned a track that holds a
  // ref-counted reference to |webkit_source| (and, implicitly, |source|).
}

void PepperMediaStreamVideoTrackHost::OnTrackStarted(
    MediaStreamSource* source,
    MediaStreamRequestResult result,
    const blink::WebString& result_name) {
  DVLOG(3) << "OnTrackStarted result: " << result;
}

}  // namespace content
