// Copyright 2013 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/common/gpu/media/gpu_video_encode_accelerator.h"

#include "base/callback.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/memory/shared_memory.h"
#include "base/numerics/safe_math.h"
#include "base/sys_info.h"
#include "build/build_config.h"
#include "content/common/gpu/client/gpu_memory_buffer_impl.h"
#include "content/common/gpu/gpu_channel.h"
#include "content/common/gpu/gpu_channel_manager.h"
#include "content/common/gpu/media/gpu_video_accelerator_util.h"
#include "content/common/gpu/media/media_messages.h"
#include "content/public/common/content_switches.h"
#include "ipc/ipc_message_macros.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/limits.h"
#include "media/base/video_frame.h"

#if defined(OS_CHROMEOS)
#if defined(USE_V4L2_CODEC)
#include "content/common/gpu/media/v4l2_video_encode_accelerator.h"
#endif
#if defined(ARCH_CPU_X86_FAMILY)
#include "content/common/gpu/media/vaapi_video_encode_accelerator.h"
#endif
#elif defined(OS_ANDROID) && defined(ENABLE_WEBRTC)
#include "content/common/gpu/media/android_video_encode_accelerator.h"
#endif

namespace content {

namespace {

// Allocation and destruction of buffer are done on the Browser process, so we
// don't need to handle synchronization here.
void DestroyGpuMemoryBuffer(const gpu::SyncToken& sync_token) {}

} // namespace

static bool MakeDecoderContextCurrent(
    const base::WeakPtr<GpuCommandBufferStub> stub) {
  if (!stub) {
    DLOG(ERROR) << "Stub is gone; won't MakeCurrent().";
    return false;
  }

  if (!stub->decoder()->MakeCurrent()) {
    DLOG(ERROR) << "Failed to MakeCurrent()";
    return false;
  }

  return true;
}

GpuVideoEncodeAccelerator::GpuVideoEncodeAccelerator(int32_t host_route_id,
                                                     GpuCommandBufferStub* stub)
    : host_route_id_(host_route_id),
      stub_(stub),
      input_format_(media::PIXEL_FORMAT_UNKNOWN),
      output_buffer_size_(0),
      weak_this_factory_(this) {
  stub_->AddDestructionObserver(this);
  make_context_current_ =
      base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr());
}

GpuVideoEncodeAccelerator::~GpuVideoEncodeAccelerator() {
  // This class can only be self-deleted from OnWillDestroyStub(), which means
  // the VEA has already been destroyed in there.
  DCHECK(!encoder_);
}

bool GpuVideoEncodeAccelerator::Initialize(
    media::VideoPixelFormat input_format,
    const gfx::Size& input_visible_size,
    media::VideoCodecProfile output_profile,
    uint32_t initial_bitrate) {
  DVLOG(2) << "GpuVideoEncodeAccelerator::Initialize(): "
              "input_format=" << input_format
           << ", input_visible_size=" << input_visible_size.ToString()
           << ", output_profile=" << output_profile
           << ", initial_bitrate=" << initial_bitrate;
  DCHECK(!encoder_);

  if (!stub_->channel()->AddRoute(host_route_id_, stub_->stream_id(), this)) {
    DLOG(ERROR) << "GpuVideoEncodeAccelerator::Initialize(): "
                   "failed to add route";
    return false;
  }

  if (input_visible_size.width() > media::limits::kMaxDimension ||
      input_visible_size.height() > media::limits::kMaxDimension ||
      input_visible_size.GetArea() > media::limits::kMaxCanvas) {
    DLOG(ERROR) << "GpuVideoEncodeAccelerator::Initialize(): "
                   "input_visible_size " << input_visible_size.ToString()
                << " too large";
    return false;
  }

  const gpu::GpuPreferences& gpu_preferences =
      stub_->channel()->gpu_channel_manager()->gpu_preferences();

  std::vector<GpuVideoEncodeAccelerator::CreateVEAFp> create_vea_fps =
      CreateVEAFps(gpu_preferences);
  // Try all possible encoders and use the first successful encoder.
  for (size_t i = 0; i < create_vea_fps.size(); ++i) {
    encoder_ = (*create_vea_fps[i])();
    if (encoder_ && encoder_->Initialize(input_format,
                                         input_visible_size,
                                         output_profile,
                                         initial_bitrate,
                                         this)) {
      input_format_ = input_format;
      input_visible_size_ = input_visible_size;
      return true;
    }
  }
  encoder_.reset();
  DLOG(ERROR)
      << "GpuVideoEncodeAccelerator::Initialize(): VEA initialization failed";
  return false;
}

bool GpuVideoEncodeAccelerator::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(GpuVideoEncodeAccelerator, message)
    IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Encode, OnEncode)
    IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Encode2, OnEncode2)
    IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer,
                        OnUseOutputBitstreamBuffer)
    IPC_MESSAGE_HANDLER(
        AcceleratedVideoEncoderMsg_RequestEncodingParametersChange,
        OnRequestEncodingParametersChange)
    IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Destroy, OnDestroy)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void GpuVideoEncodeAccelerator::RequireBitstreamBuffers(
    unsigned int input_count,
    const gfx::Size& input_coded_size,
    size_t output_buffer_size) {
  Send(new AcceleratedVideoEncoderHostMsg_RequireBitstreamBuffers(
      host_route_id_, input_count, input_coded_size, output_buffer_size));
  input_coded_size_ = input_coded_size;
  output_buffer_size_ = output_buffer_size;
}

void GpuVideoEncodeAccelerator::BitstreamBufferReady(
    int32_t bitstream_buffer_id,
    size_t payload_size,
    bool key_frame) {
  Send(new AcceleratedVideoEncoderHostMsg_BitstreamBufferReady(
      host_route_id_, bitstream_buffer_id, payload_size, key_frame));
}

void GpuVideoEncodeAccelerator::NotifyError(
    media::VideoEncodeAccelerator::Error error) {
  Send(new AcceleratedVideoEncoderHostMsg_NotifyError(host_route_id_, error));
}

void GpuVideoEncodeAccelerator::OnWillDestroyStub() {
  DCHECK(stub_);
  stub_->channel()->RemoveRoute(host_route_id_);
  stub_->RemoveDestructionObserver(this);
  encoder_.reset();
  delete this;
}

// static
gpu::VideoEncodeAcceleratorSupportedProfiles
GpuVideoEncodeAccelerator::GetSupportedProfiles(
    const gpu::GpuPreferences& gpu_preferences) {
  media::VideoEncodeAccelerator::SupportedProfiles profiles;
  std::vector<GpuVideoEncodeAccelerator::CreateVEAFp> create_vea_fps =
      CreateVEAFps(gpu_preferences);

  for (size_t i = 0; i < create_vea_fps.size(); ++i) {
    scoped_ptr<media::VideoEncodeAccelerator>
        encoder = (*create_vea_fps[i])();
    if (!encoder)
      continue;
    media::VideoEncodeAccelerator::SupportedProfiles vea_profiles =
        encoder->GetSupportedProfiles();
    GpuVideoAcceleratorUtil::InsertUniqueEncodeProfiles(
        vea_profiles, &profiles);
  }
  return GpuVideoAcceleratorUtil::ConvertMediaToGpuEncodeProfiles(profiles);
}

// static
std::vector<GpuVideoEncodeAccelerator::CreateVEAFp>
GpuVideoEncodeAccelerator::CreateVEAFps(
    const gpu::GpuPreferences& gpu_preferences) {
  std::vector<GpuVideoEncodeAccelerator::CreateVEAFp> create_vea_fps;
#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC)
  create_vea_fps.push_back(&GpuVideoEncodeAccelerator::CreateV4L2VEA);
#endif
#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
  if (!gpu_preferences.disable_vaapi_accelerated_video_encode)
    create_vea_fps.push_back(&GpuVideoEncodeAccelerator::CreateVaapiVEA);
#endif
#if defined(OS_ANDROID) && defined(ENABLE_WEBRTC)
  if (!gpu_preferences.disable_web_rtc_hw_encoding)
    create_vea_fps.push_back(&GpuVideoEncodeAccelerator::CreateAndroidVEA);
#endif
  return create_vea_fps;
}

#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC)
// static
scoped_ptr<media::VideoEncodeAccelerator>
GpuVideoEncodeAccelerator::CreateV4L2VEA() {
  scoped_ptr<media::VideoEncodeAccelerator> encoder;
  scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kEncoder);
  if (device)
    encoder.reset(new V4L2VideoEncodeAccelerator(device));
  return encoder;
}
#endif

#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
// static
scoped_ptr<media::VideoEncodeAccelerator>
GpuVideoEncodeAccelerator::CreateVaapiVEA() {
  return make_scoped_ptr<media::VideoEncodeAccelerator>(
      new VaapiVideoEncodeAccelerator());
}
#endif

#if defined(OS_ANDROID) && defined(ENABLE_WEBRTC)
// static
scoped_ptr<media::VideoEncodeAccelerator>
GpuVideoEncodeAccelerator::CreateAndroidVEA() {
  return make_scoped_ptr<media::VideoEncodeAccelerator>(
      new AndroidVideoEncodeAccelerator());
}
#endif

void GpuVideoEncodeAccelerator::OnEncode(
    const AcceleratedVideoEncoderMsg_Encode_Params& params) {
  DVLOG(3) << "GpuVideoEncodeAccelerator::OnEncode: frame_id = "
           << params.frame_id << ", buffer_size=" << params.buffer_size
           << ", force_keyframe=" << params.force_keyframe;
  DCHECK_EQ(media::PIXEL_FORMAT_I420, input_format_);

  // Wrap into a SharedMemory in the beginning, so that |params.buffer_handle|
  // is cleaned properly in case of an early return.
  scoped_ptr<base::SharedMemory> shm(
      new base::SharedMemory(params.buffer_handle, true));

  if (!encoder_)
    return;

  if (params.frame_id < 0) {
    DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnEncode(): invalid "
                   "frame_id=" << params.frame_id;
    NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
    return;
  }

  const uint32_t aligned_offset =
      params.buffer_offset % base::SysInfo::VMAllocationGranularity();
  base::CheckedNumeric<off_t> map_offset = params.buffer_offset;
  map_offset -= aligned_offset;
  base::CheckedNumeric<size_t> map_size = params.buffer_size;
  map_size += aligned_offset;

  if (!map_offset.IsValid() || !map_size.IsValid()) {
    DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnEncode():"
                << " invalid (buffer_offset,buffer_size)";
    NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
    return;
  }

  if (!shm->MapAt(map_offset.ValueOrDie(), map_size.ValueOrDie())) {
    DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnEncode(): "
                << "could not map frame_id=" << params.frame_id;
    NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
    return;
  }

  uint8_t* shm_memory =
      reinterpret_cast<uint8_t*>(shm->memory()) + aligned_offset;
  scoped_refptr<media::VideoFrame> frame =
      media::VideoFrame::WrapExternalSharedMemory(
          input_format_,
          input_coded_size_,
          gfx::Rect(input_visible_size_),
          input_visible_size_,
          shm_memory,
          params.buffer_size,
          params.buffer_handle,
          params.buffer_offset,
          params.timestamp);
  if (!frame) {
    DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnEncode(): "
                << "could not create a frame";
    NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
    return;
  }
  frame->AddDestructionObserver(
      media::BindToCurrentLoop(
          base::Bind(&GpuVideoEncodeAccelerator::EncodeFrameFinished,
                     weak_this_factory_.GetWeakPtr(),
                     params.frame_id,
                     base::Passed(&shm))));
  encoder_->Encode(frame, params.force_keyframe);
}

void GpuVideoEncodeAccelerator::OnEncode2(
    const AcceleratedVideoEncoderMsg_Encode_Params2& params) {
  DVLOG(3) << "GpuVideoEncodeAccelerator::OnEncode2: frame_id = "
           << params.frame_id << ", size=" << params.size.ToString()
           << ", force_keyframe=" << params.force_keyframe << ", handle type="
           << params.gpu_memory_buffer_handles[0].type;
  DCHECK_EQ(media::PIXEL_FORMAT_I420, input_format_);
  DCHECK_EQ(media::VideoFrame::NumPlanes(input_format_),
            params.gpu_memory_buffer_handles.size());

  bool map_result = true;
  uint8_t* data[media::VideoFrame::kMaxPlanes];
  int32_t strides[media::VideoFrame::kMaxPlanes];
  ScopedVector<gfx::GpuMemoryBuffer> buffers;
  const auto& handles = params.gpu_memory_buffer_handles;
  for (size_t i = 0; i < handles.size(); ++i) {
    const size_t width =
        media::VideoFrame::Columns(i, input_format_, params.size.width());
    const size_t height =
        media::VideoFrame::Rows(i, input_format_, params.size.height());
    scoped_ptr<gfx::GpuMemoryBuffer> buffer =
        GpuMemoryBufferImpl::CreateFromHandle(
            handles[i], gfx::Size(width, height), gfx::BufferFormat::R_8,
            gfx::BufferUsage::GPU_READ_CPU_READ_WRITE,
            media::BindToCurrentLoop(base::Bind(&DestroyGpuMemoryBuffer)));

    // TODO(emircan): Refactor such that each frame is mapped once.
    // See http://crbug/536938.
    if (!buffer.get() || !buffer->Map()) {
      map_result = false;
      continue;
    }

    data[i] = reinterpret_cast<uint8_t*>(buffer->memory(0));
    strides[i] = buffer->stride(0);
    buffers.push_back(buffer.release());
  }

  if (!map_result) {
    DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnEncode2(): "
                << "failed to map buffers";
    NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
    return;
  }

  if (!encoder_)
    return;

  if (params.frame_id < 0) {
    DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnEncode2(): invalid frame_id="
                << params.frame_id;
    NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
    return;
  }

  scoped_refptr<media::VideoFrame> frame =
      media::VideoFrame::WrapExternalYuvData(
          input_format_,
          input_coded_size_,
          gfx::Rect(input_visible_size_),
          input_visible_size_,
          strides[media::VideoFrame::kYPlane],
          strides[media::VideoFrame::kUPlane],
          strides[media::VideoFrame::kVPlane],
          data[media::VideoFrame::kYPlane],
          data[media::VideoFrame::kUPlane],
          data[media::VideoFrame::kVPlane],
          params.timestamp);
  if (!frame.get()) {
    DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnEncode2(): "
                << "could not create a frame";
    NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
    return;
  }
  frame->AddDestructionObserver(media::BindToCurrentLoop(
      base::Bind(&GpuVideoEncodeAccelerator::EncodeFrameFinished2,
                 weak_this_factory_.GetWeakPtr(), params.frame_id,
                 base::Passed(&buffers))));
  encoder_->Encode(frame, params.force_keyframe);
}

void GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer(
    int32_t buffer_id,
    base::SharedMemoryHandle buffer_handle,
    uint32_t buffer_size) {
  DVLOG(3) << "GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer(): "
              "buffer_id=" << buffer_id
           << ", buffer_size=" << buffer_size;
  if (!encoder_)
    return;
  if (buffer_id < 0) {
    DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer(): "
                   "invalid buffer_id=" << buffer_id;
    NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
    return;
  }
  if (buffer_size < output_buffer_size_) {
    DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer(): "
                   "buffer too small for buffer_id=" << buffer_id;
    NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
    return;
  }
  encoder_->UseOutputBitstreamBuffer(
      media::BitstreamBuffer(buffer_id, buffer_handle, buffer_size));
}

void GpuVideoEncodeAccelerator::OnDestroy() {
  DVLOG(2) << "GpuVideoEncodeAccelerator::OnDestroy()";
  OnWillDestroyStub();
}

void GpuVideoEncodeAccelerator::OnRequestEncodingParametersChange(
    uint32_t bitrate,
    uint32_t framerate) {
  DVLOG(2) << "GpuVideoEncodeAccelerator::OnRequestEncodingParametersChange(): "
              "bitrate=" << bitrate
           << ", framerate=" << framerate;
  if (!encoder_)
    return;
  encoder_->RequestEncodingParametersChange(bitrate, framerate);
}

void GpuVideoEncodeAccelerator::EncodeFrameFinished(
    int32_t frame_id,
    scoped_ptr<base::SharedMemory> shm) {
  Send(new AcceleratedVideoEncoderHostMsg_NotifyInputDone(host_route_id_,
                                                          frame_id));
  // Just let |shm| fall out of scope.
}

void GpuVideoEncodeAccelerator::EncodeFrameFinished2(
    int32_t frame_id,
    ScopedVector<gfx::GpuMemoryBuffer> buffers) {
  // TODO(emircan): Consider calling Unmap() in dtor.
  for (const auto& buffer : buffers)
    buffer->Unmap();
  Send(new AcceleratedVideoEncoderHostMsg_NotifyInputDone(host_route_id_,
                                                          frame_id));
  // Just let |buffers| fall out of scope.
}

void GpuVideoEncodeAccelerator::Send(IPC::Message* message) {
  stub_->channel()->Send(message);
}

}  // namespace content
