/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/video_frame.h"

#include <string.h>

#include <algorithm>  // swap

#include "webrtc/base/bind.h"
#include "webrtc/base/checks.h"

namespace webrtc {

// FFmpeg's decoder, used by H264DecoderImpl, requires up to 8 bytes padding due
// to optimized bitstream readers. See avcodec_decode_video2.
const size_t EncodedImage::kBufferPaddingBytesH264 = 8;

VideoFrame::VideoFrame()
    : video_frame_buffer_(nullptr),
      timestamp_rtp_(0),
      ntp_time_ms_(0),
      timestamp_us_(0),
      rotation_(kVideoRotation_0) {}

VideoFrame::VideoFrame(const rtc::scoped_refptr<VideoFrameBuffer>& buffer,
                       webrtc::VideoRotation rotation,
                       int64_t timestamp_us)
    : video_frame_buffer_(buffer),
      timestamp_rtp_(0),
      ntp_time_ms_(0),
      timestamp_us_(timestamp_us),
      rotation_(rotation) {}

VideoFrame::VideoFrame(const rtc::scoped_refptr<VideoFrameBuffer>& buffer,
                       uint32_t timestamp,
                       int64_t render_time_ms,
                       VideoRotation rotation)
    : video_frame_buffer_(buffer),
      timestamp_rtp_(timestamp),
      ntp_time_ms_(0),
      timestamp_us_(render_time_ms * rtc::kNumMicrosecsPerMillisec),
      rotation_(rotation) {
  RTC_DCHECK(buffer);
}

void VideoFrame::CreateEmptyFrame(int width,
                                  int height,
                                  int stride_y,
                                  int stride_u,
                                  int stride_v) {
  const int half_width = (width + 1) / 2;
  RTC_DCHECK_GT(width, 0);
  RTC_DCHECK_GT(height, 0);
  RTC_DCHECK_GE(stride_y, width);
  RTC_DCHECK_GE(stride_u, half_width);
  RTC_DCHECK_GE(stride_v, half_width);

  // Creating empty frame - reset all values.
  timestamp_rtp_ = 0;
  ntp_time_ms_ = 0;
  timestamp_us_ = 0;
  rotation_ = kVideoRotation_0;

  // Allocate a new buffer.
  video_frame_buffer_ = I420Buffer::Create(
      width, height, stride_y, stride_u, stride_v);
}

void VideoFrame::CreateFrame(const uint8_t* buffer_y,
                             const uint8_t* buffer_u,
                             const uint8_t* buffer_v,
                             int width,
                             int height,
                             int stride_y,
                             int stride_u,
                             int stride_v,
                             VideoRotation rotation) {
  const int half_height = (height + 1) / 2;
  const int expected_size_y = height * stride_y;
  const int expected_size_u = half_height * stride_u;
  const int expected_size_v = half_height * stride_v;
  CreateEmptyFrame(width, height, stride_y, stride_u, stride_v);
  memcpy(video_frame_buffer_->MutableDataY(), buffer_y, expected_size_y);
  memcpy(video_frame_buffer_->MutableDataU(), buffer_u, expected_size_u);
  memcpy(video_frame_buffer_->MutableDataV(), buffer_v, expected_size_v);
  rotation_ = rotation;
}

void VideoFrame::CreateFrame(const uint8_t* buffer,
                             int width,
                             int height,
                             VideoRotation rotation) {
  const int stride_y = width;
  const int stride_uv = (width + 1) / 2;

  const uint8_t* buffer_y = buffer;
  const uint8_t* buffer_u = buffer_y + stride_y * height;
  const uint8_t* buffer_v = buffer_u + stride_uv * ((height + 1) / 2);
  CreateFrame(buffer_y, buffer_u, buffer_v, width, height, stride_y,
              stride_uv, stride_uv, rotation);
}

void VideoFrame::CopyFrame(const VideoFrame& videoFrame) {
  ShallowCopy(videoFrame);

  // If backed by a plain memory buffer, create a new, non-shared, copy.
  if (video_frame_buffer_ && !video_frame_buffer_->native_handle()) {
    video_frame_buffer_ = I420Buffer::Copy(video_frame_buffer_);
  }
}

void VideoFrame::ShallowCopy(const VideoFrame& videoFrame) {
  video_frame_buffer_ = videoFrame.video_frame_buffer();
  timestamp_rtp_ = videoFrame.timestamp_rtp_;
  ntp_time_ms_ = videoFrame.ntp_time_ms_;
  timestamp_us_ = videoFrame.timestamp_us_;
  rotation_ = videoFrame.rotation_;
}

// TODO(nisse): Delete. Besides test code, only one use, in
// webrtcvideoengine2.cc:CreateBlackFrame.
int VideoFrame::allocated_size(PlaneType type) const {
  const int plane_height = (type == kYPlane) ? height() : (height() + 1) / 2;
  int stride;
  switch (type) {
    case kYPlane:
      stride = video_frame_buffer_->StrideY();
      break;
    case kUPlane:
      stride = video_frame_buffer_->StrideU();
      break;
    case kVPlane:
      stride = video_frame_buffer_->StrideV();
      break;
    default:
      RTC_NOTREACHED();
      return 0;
  }
  return plane_height * stride;
}

int VideoFrame::width() const {
  return video_frame_buffer_ ? video_frame_buffer_->width() : 0;
}

int VideoFrame::height() const {
  return video_frame_buffer_ ? video_frame_buffer_->height() : 0;
}

bool VideoFrame::IsZeroSize() const {
  return !video_frame_buffer_;
}

const rtc::scoped_refptr<VideoFrameBuffer>& VideoFrame::video_frame_buffer()
    const {
  return video_frame_buffer_;
}

size_t EncodedImage::GetBufferPaddingBytes(VideoCodecType codec_type) {
  switch (codec_type) {
    case kVideoCodecVP8:
    case kVideoCodecVP9:
      return 0;
    case kVideoCodecH264:
      return kBufferPaddingBytesH264;
    case kVideoCodecI420:
    case kVideoCodecRED:
    case kVideoCodecULPFEC:
    case kVideoCodecGeneric:
    case kVideoCodecUnknown:
      return 0;
  }
  RTC_NOTREACHED();
  return 0;
}

}  // namespace webrtc
