/*
 * libjingle
 * Copyright 2011 Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "talk/media/webrtc/webrtcvideoframe.h"

#include "libyuv/convert.h"
#include "libyuv/convert_from.h"
#include "libyuv/planar_functions.h"
#include "talk/media/base/videocapturer.h"
#include "talk/media/base/videocommon.h"
#include "talk/media/webrtc/webrtctexturevideoframe.h"
#include "webrtc/base/logging.h"
#include "webrtc/video_frame.h"

#define UNIMPLEMENTED                                                 \
  LOG(LS_ERROR) << "Call to unimplemented function " << __FUNCTION__; \
  ASSERT(false)

namespace cricket {

// Class that wraps ownerhip semantics of a buffer passed to it.
// * Buffers passed using Attach() become owned by this FrameBuffer and will be
//   destroyed on FrameBuffer destruction.
// * Buffers passed using Alias() are not owned and will not be destroyed on
//   FrameBuffer destruction,  The buffer then must outlive the FrameBuffer.
class WebRtcVideoFrame::FrameBuffer {
 public:
  FrameBuffer();
  explicit FrameBuffer(size_t length);
  ~FrameBuffer();

  void Attach(uint8* data, size_t length);
  void Alias(uint8* data, size_t length);
  uint8* data();
  size_t length() const;

  webrtc::VideoFrame* frame();
  const webrtc::VideoFrame* frame() const;

 private:
  rtc::scoped_ptr<uint8[]> owned_data_;
  webrtc::VideoFrame video_frame_;
};

WebRtcVideoFrame::FrameBuffer::FrameBuffer() {}

WebRtcVideoFrame::FrameBuffer::FrameBuffer(size_t length) {
  uint8* buffer = new uint8[length];
  Attach(buffer, length);
}

WebRtcVideoFrame::FrameBuffer::~FrameBuffer() {
  // Make sure that |video_frame_| doesn't delete the buffer, as |owned_data_|
  // will release the buffer if this FrameBuffer owns it.
  uint8_t* new_memory = NULL;
  size_t new_length = 0;
  size_t new_size = 0;
  video_frame_.Swap(new_memory, new_length, new_size);
}

void WebRtcVideoFrame::FrameBuffer::Attach(uint8* data, size_t length) {
  Alias(data, length);
  owned_data_.reset(data);
}

void WebRtcVideoFrame::FrameBuffer::Alias(uint8* data, size_t length) {
  owned_data_.reset();
  uint8_t* new_memory = reinterpret_cast<uint8_t*>(data);
  size_t new_length = length;
  size_t new_size = length;
  video_frame_.Swap(new_memory, new_length, new_size);
}

uint8* WebRtcVideoFrame::FrameBuffer::data() {
  return video_frame_.Buffer();
}

size_t WebRtcVideoFrame::FrameBuffer::length() const {
  return video_frame_.Length();
}

webrtc::VideoFrame* WebRtcVideoFrame::FrameBuffer::frame() {
  return &video_frame_;
}

const webrtc::VideoFrame* WebRtcVideoFrame::FrameBuffer::frame() const {
  return &video_frame_;
}

WebRtcVideoFrame::WebRtcVideoFrame()
    : video_buffer_(new RefCountedBuffer()) {}

WebRtcVideoFrame::~WebRtcVideoFrame() {}

bool WebRtcVideoFrame::Init(uint32 format,
                            int w,
                            int h,
                            int dw,
                            int dh,
                            uint8* sample,
                            size_t sample_size,
                            size_t pixel_width,
                            size_t pixel_height,
                            int64_t elapsed_time,
                            int64_t time_stamp,
                            webrtc::VideoRotation rotation) {
  return Reset(format, w, h, dw, dh, sample, sample_size, pixel_width,
               pixel_height, elapsed_time, time_stamp, rotation);
}

bool WebRtcVideoFrame::Init(const CapturedFrame* frame, int dw, int dh) {
  return Reset(frame->fourcc, frame->width, frame->height, dw, dh,
               static_cast<uint8*>(frame->data), frame->data_size,
               frame->pixel_width, frame->pixel_height, frame->elapsed_time,
               frame->time_stamp, frame->GetRotation());
}

bool WebRtcVideoFrame::Alias(const CapturedFrame* frame,
                             int dw,
                             int dh,
                             bool apply_rotation) {
  if (CanonicalFourCC(frame->fourcc) != FOURCC_I420 ||
      (apply_rotation &&
       frame->GetRotation() != webrtc::kVideoRotation_0) ||
      frame->width != dw || frame->height != dh) {
    // TODO(fbarchard): Enable aliasing of more formats.
    return Init(frame, dw, dh);
  } else {
    Alias(static_cast<uint8*>(frame->data), frame->data_size, frame->width,
          frame->height, frame->pixel_width, frame->pixel_height,
          frame->elapsed_time, frame->time_stamp, frame->GetRotation());
    return true;
  }
}

bool WebRtcVideoFrame::InitToBlack(int w, int h, size_t pixel_width,
                                   size_t pixel_height, int64_t elapsed_time,
                                   int64_t time_stamp) {
  InitToEmptyBuffer(w, h, pixel_width, pixel_height, elapsed_time, time_stamp);
  return SetToBlack();
}

void WebRtcVideoFrame::Alias(uint8* buffer,
                             size_t buffer_size,
                             int w,
                             int h,
                             size_t pixel_width,
                             size_t pixel_height,
                             int64_t elapsed_time,
                             int64_t time_stamp,
                             webrtc::VideoRotation rotation) {
  rtc::scoped_refptr<RefCountedBuffer> video_buffer(
      new RefCountedBuffer());
  video_buffer->Alias(buffer, buffer_size);
  Attach(video_buffer.get(), buffer_size, w, h, pixel_width, pixel_height,
         elapsed_time, time_stamp, rotation);
}

size_t WebRtcVideoFrame::GetWidth() const { return frame()->Width(); }

size_t WebRtcVideoFrame::GetHeight() const { return frame()->Height(); }

const uint8* WebRtcVideoFrame::GetYPlane() const {
  uint8_t* buffer = frame()->Buffer();
  return buffer;
}

const uint8* WebRtcVideoFrame::GetUPlane() const {
  uint8_t* buffer = frame()->Buffer();
  if (buffer) {
    buffer += (frame()->Width() * frame()->Height());
  }
  return buffer;
}

const uint8* WebRtcVideoFrame::GetVPlane() const {
  uint8_t* buffer = frame()->Buffer();
  if (buffer) {
    int uv_size = static_cast<int>(GetChromaSize());
    buffer += frame()->Width() * frame()->Height() + uv_size;
  }
  return buffer;
}

uint8* WebRtcVideoFrame::GetYPlane() {
  DCHECK(video_buffer_->HasOneRef());
  uint8_t* buffer = frame()->Buffer();
  return buffer;
}

uint8* WebRtcVideoFrame::GetUPlane() {
  DCHECK(video_buffer_->HasOneRef());
  uint8_t* buffer = frame()->Buffer();
  if (buffer) {
    buffer += (frame()->Width() * frame()->Height());
  }
  return buffer;
}

uint8* WebRtcVideoFrame::GetVPlane() {
  DCHECK(video_buffer_->HasOneRef());
  uint8_t* buffer = frame()->Buffer();
  if (buffer) {
    int uv_size = static_cast<int>(GetChromaSize());
    buffer += frame()->Width() * frame()->Height() + uv_size;
  }
  return buffer;
}

VideoFrame* WebRtcVideoFrame::Copy() const {
  uint8* old_buffer = video_buffer_->data();
  if (!old_buffer)
    return NULL;
  size_t new_buffer_size = video_buffer_->length();

  WebRtcVideoFrame* ret_val = new WebRtcVideoFrame();
  ret_val->Attach(video_buffer_.get(), new_buffer_size, frame()->Width(),
                  frame()->Height(), pixel_width_, pixel_height_, elapsed_time_,
                  time_stamp_, rotation_);
  return ret_val;
}

bool WebRtcVideoFrame::IsExclusive() const {
  return video_buffer_->HasOneRef();
}

bool WebRtcVideoFrame::MakeExclusive() {
  if (IsExclusive())
    return true;

  // Not exclusive already, need to copy.
  const size_t length = video_buffer_->length();
  RefCountedBuffer* exclusive_buffer = new RefCountedBuffer(length);
  memcpy(exclusive_buffer->data(), video_buffer_->data(), length);
  Attach(exclusive_buffer, length, frame()->Width(), frame()->Height(),
         pixel_width_, pixel_height_, elapsed_time_, time_stamp_, rotation_);
  return true;
}

size_t WebRtcVideoFrame::ConvertToRgbBuffer(uint32 to_fourcc, uint8* buffer,
                                            size_t size, int stride_rgb) const {
  if (!frame()->Buffer()) {
    return 0;
  }
  return VideoFrame::ConvertToRgbBuffer(to_fourcc, buffer, size, stride_rgb);
}

void WebRtcVideoFrame::Attach(RefCountedBuffer* video_buffer,
                              size_t buffer_size,
                              int w,
                              int h,
                              size_t pixel_width,
                              size_t pixel_height,
                              int64_t elapsed_time,
                              int64_t time_stamp,
                              webrtc::VideoRotation rotation) {
  if (video_buffer_.get() == video_buffer) {
    return;
  }
  video_buffer_ = video_buffer;
  frame()->SetWidth(w);
  frame()->SetHeight(h);
  pixel_width_ = pixel_width;
  pixel_height_ = pixel_height;
  elapsed_time_ = elapsed_time;
  time_stamp_ = time_stamp;
  rotation_ = rotation;
}

webrtc::VideoFrame* WebRtcVideoFrame::frame() {
  return video_buffer_->frame();
}

const webrtc::VideoFrame* WebRtcVideoFrame::frame() const {
  return video_buffer_->frame();
}

bool WebRtcVideoFrame::Reset(uint32 format,
                             int w,
                             int h,
                             int dw,
                             int dh,
                             uint8* sample,
                             size_t sample_size,
                             size_t pixel_width,
                             size_t pixel_height,
                             int64_t elapsed_time,
                             int64_t time_stamp,
                             webrtc::VideoRotation rotation) {
  if (!Validate(format, w, h, sample, sample_size)) {
    return false;
  }
  // Translate aliases to standard enums (e.g., IYUV -> I420).
  format = CanonicalFourCC(format);

  // Round display width and height down to multiple of 4, to avoid webrtc
  // size calculation error on odd sizes.
  // TODO(Ronghua): Remove this once the webrtc allocator is fixed.
  dw = (dw > 4) ? (dw & ~3) : dw;
  dh = (dh > 4) ? (dh & ~3) : dh;

  // Set up a new buffer.
  // TODO(fbarchard): Support lazy allocation.
  int new_width = dw;
  int new_height = dh;
  if (rotation == 90 || rotation == 270) {  // If rotated swap width, height.
    new_width = dh;
    new_height = dw;
  }

  // Release reference in |video_buffer| at the end of this scope, so that
  // |video_buffer_| becomes the sole owner.
  {
    size_t desired_size = SizeOf(new_width, new_height);
    rtc::scoped_refptr<RefCountedBuffer> video_buffer(
        new RefCountedBuffer(desired_size));
    // Since the libyuv::ConvertToI420 will handle the rotation, so the
    // new frame's rotation should always be 0.
    Attach(video_buffer.get(), desired_size, new_width, new_height, pixel_width,
           pixel_height, elapsed_time, time_stamp, webrtc::kVideoRotation_0);
  }

  int horiz_crop = ((w - dw) / 2) & ~1;
  // ARGB on Windows has negative height.
  // The sample's layout in memory is normal, so just correct crop.
  int vert_crop = ((abs(h) - dh) / 2) & ~1;
  // Conversion functions expect negative height to flip the image.
  int idh = (h < 0) ? -dh : dh;
  uint8* y = GetYPlane();
  int y_stride = GetYPitch();
  uint8* u = GetUPlane();
  int u_stride = GetUPitch();
  uint8* v = GetVPlane();
  int v_stride = GetVPitch();
  int r = libyuv::ConvertToI420(
      sample, sample_size, y, y_stride, u, u_stride, v, v_stride, horiz_crop,
      vert_crop, w, h, dw, idh, static_cast<libyuv::RotationMode>(rotation),
      format);
  if (r) {
    LOG(LS_ERROR) << "Error parsing format: " << GetFourccName(format)
                  << " return code : " << r;
    return false;
  }
  return true;
}

VideoFrame* WebRtcVideoFrame::CreateEmptyFrame(
    int w, int h, size_t pixel_width, size_t pixel_height, int64_t elapsed_time,
    int64_t time_stamp) const {
  WebRtcVideoFrame* frame = new WebRtcVideoFrame();
  frame->InitToEmptyBuffer(w, h, pixel_width, pixel_height, elapsed_time,
                           time_stamp);
  return frame;
}

void WebRtcVideoFrame::InitToEmptyBuffer(int w, int h, size_t pixel_width,
                                         size_t pixel_height,
                                         int64_t elapsed_time,
                                         int64_t time_stamp) {
  size_t buffer_size = VideoFrame::SizeOf(w, h);
  rtc::scoped_refptr<RefCountedBuffer> video_buffer(
      new RefCountedBuffer(buffer_size));
  Attach(video_buffer.get(), buffer_size, w, h, pixel_width, pixel_height,
         elapsed_time, time_stamp, webrtc::kVideoRotation_0);
}

WebRtcVideoRenderFrame::WebRtcVideoRenderFrame(
    const webrtc::I420VideoFrame* frame,
    int64_t elapsed_time_ms)
    : frame_(frame), elapsed_time_ms_(elapsed_time_ms) {
}

bool WebRtcVideoRenderFrame::InitToBlack(int w,
                                         int h,
                                         size_t pixel_width,
                                         size_t pixel_height,
                                         int64_t elapsed_time,
                                         int64_t time_stamp) {
  UNIMPLEMENTED;
  return false;
}

bool WebRtcVideoRenderFrame::Reset(uint32 fourcc,
                                   int w,
                                   int h,
                                   int dw,
                                   int dh,
                                   uint8* sample,
                                   size_t sample_size,
                                   size_t pixel_width,
                                   size_t pixel_height,
                                   int64_t elapsed_time,
                                   int64_t time_stamp,
                                   webrtc::VideoRotation rotation) {
  UNIMPLEMENTED;
  return false;
}

size_t WebRtcVideoRenderFrame::GetWidth() const {
  return static_cast<size_t>(frame_->width());
}
size_t WebRtcVideoRenderFrame::GetHeight() const {
  return static_cast<size_t>(frame_->height());
}

const uint8* WebRtcVideoRenderFrame::GetYPlane() const {
  return frame_->buffer(webrtc::kYPlane);
}
const uint8* WebRtcVideoRenderFrame::GetUPlane() const {
  return frame_->buffer(webrtc::kUPlane);
}
const uint8* WebRtcVideoRenderFrame::GetVPlane() const {
  return frame_->buffer(webrtc::kVPlane);
}

uint8* WebRtcVideoRenderFrame::GetYPlane() {
  UNIMPLEMENTED;
  return NULL;
}
uint8* WebRtcVideoRenderFrame::GetUPlane() {
  UNIMPLEMENTED;
  return NULL;
}
uint8* WebRtcVideoRenderFrame::GetVPlane() {
  UNIMPLEMENTED;
  return NULL;
}

int32 WebRtcVideoRenderFrame::GetYPitch() const {
  return frame_->stride(webrtc::kYPlane);
}
int32 WebRtcVideoRenderFrame::GetUPitch() const {
  return frame_->stride(webrtc::kUPlane);
}
int32 WebRtcVideoRenderFrame::GetVPitch() const {
  return frame_->stride(webrtc::kVPlane);
}

void* WebRtcVideoRenderFrame::GetNativeHandle() const {
  return frame_->native_handle();
}

size_t WebRtcVideoRenderFrame::GetPixelWidth() const {
  return 1;
}
size_t WebRtcVideoRenderFrame::GetPixelHeight() const {
  return 1;
}

int64_t WebRtcVideoRenderFrame::GetElapsedTime() const {
  return elapsed_time_ms_ * rtc::kNumNanosecsPerMillisec;
}
int64_t WebRtcVideoRenderFrame::GetTimeStamp() const {
  return frame_->render_time_ms() * rtc::kNumNanosecsPerMillisec;
}
void WebRtcVideoRenderFrame::SetElapsedTime(int64_t elapsed_time) {
  UNIMPLEMENTED;
}
void WebRtcVideoRenderFrame::SetTimeStamp(int64_t time_stamp) {
  UNIMPLEMENTED;
}

webrtc::VideoRotation WebRtcVideoRenderFrame::GetVideoRotation() const {
  UNIMPLEMENTED;
  return webrtc::kVideoRotation_0;
}

// TODO(magjed): Make this copy shallow instead of deep, BUG=1128. There is no
// way to guarantee that the underlying webrtc::I420VideoFrame |frame_| will
// outlive the returned object. The only safe option is to make a deep copy.
// This can be fixed by making webrtc::I420VideoFrame reference counted, or
// adding a similar shallow copy function to it.
VideoFrame* WebRtcVideoRenderFrame::Copy() const {
  if (frame_->native_handle() != NULL) {
    return new WebRtcTextureVideoFrame(
        static_cast<webrtc::NativeHandle*>(frame_->native_handle()),
        static_cast<size_t>(frame_->width()),
        static_cast<size_t>(frame_->height()), GetElapsedTime(),
        GetTimeStamp());
  }
  WebRtcVideoFrame* new_frame = new WebRtcVideoFrame();
  new_frame->InitToEmptyBuffer(frame_->width(), frame_->height(), 1, 1,
                               GetElapsedTime(), GetTimeStamp());
  CopyToPlanes(new_frame->GetYPlane(), new_frame->GetUPlane(),
               new_frame->GetVPlane(), new_frame->GetYPitch(),
               new_frame->GetUPitch(), new_frame->GetVPitch());
  return new_frame;
}

bool WebRtcVideoRenderFrame::MakeExclusive() {
  UNIMPLEMENTED;
  return false;
}

size_t WebRtcVideoRenderFrame::CopyToBuffer(uint8* buffer, size_t size) const {
  UNIMPLEMENTED;
  return 0;
}

VideoFrame* WebRtcVideoRenderFrame::CreateEmptyFrame(int w,
                                                     int h,
                                                     size_t pixel_width,
                                                     size_t pixel_height,
                                                     int64_t elapsed_time,
                                                     int64_t time_stamp) const {
  WebRtcVideoFrame* frame = new WebRtcVideoFrame();
  frame->InitToBlack(w, h, pixel_width, pixel_height, elapsed_time, time_stamp);
  return frame;
}

}  // namespace cricket
