/*
 *  Copyright 2015 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 "sdk/android/src/jni/video_frame.h"

#include "api/scoped_refptr.h"
#include "common_video/include/video_frame_buffer.h"
#include "rtc_base/time_utils.h"
#include "sdk/android/generated_video_jni/VideoFrame_jni.h"
#include "sdk/android/src/jni/jni_helpers.h"
#include "sdk/android/src/jni/wrapped_native_i420_buffer.h"

namespace webrtc {
namespace jni {

namespace {

class AndroidVideoBuffer : public VideoFrameBuffer {
 public:
  // Creates a native VideoFrameBuffer from a Java VideoFrame.Buffer.
  static rtc::scoped_refptr<AndroidVideoBuffer> Create(
      JNIEnv* jni,
      const JavaRef<jobject>& j_video_frame_buffer);

  // Similar to the Create() above, but adopts and takes ownership of the Java
  // VideoFrame.Buffer. I.e. retain() will not be called, but release() will be
  // called when the returned AndroidVideoBuffer is destroyed.
  static rtc::scoped_refptr<AndroidVideoBuffer> Adopt(
      JNIEnv* jni,
      const JavaRef<jobject>& j_video_frame_buffer);

  ~AndroidVideoBuffer() override;

  const ScopedJavaGlobalRef<jobject>& video_frame_buffer() const;

  // Crops a region defined by `crop_x`, `crop_y`, `crop_width` and
  // `crop_height`. Scales it to size `scale_width` x `scale_height`.
  rtc::scoped_refptr<VideoFrameBuffer> CropAndScale(int crop_x,
                                                    int crop_y,
                                                    int crop_width,
                                                    int crop_height,
                                                    int scale_width,
                                                    int scale_height) override;

 protected:
  // Should not be called directly. Adopts the Java VideoFrame.Buffer. Use
  // Create() or Adopt() instead for clarity.
  AndroidVideoBuffer(JNIEnv* jni, const JavaRef<jobject>& j_video_frame_buffer);

 private:
  Type type() const override;
  int width() const override;
  int height() const override;

  rtc::scoped_refptr<I420BufferInterface> ToI420() override;

  const int width_;
  const int height_;
  // Holds a VideoFrame.Buffer.
  const ScopedJavaGlobalRef<jobject> j_video_frame_buffer_;
};

class AndroidVideoI420Buffer : public I420BufferInterface {
 public:
  // Creates a native VideoFrameBuffer from a Java VideoFrame.I420Buffer.
  static rtc::scoped_refptr<AndroidVideoI420Buffer> Create(
      JNIEnv* jni,
      int width,
      int height,
      const JavaRef<jobject>& j_video_frame_buffer);

  // Adopts and takes ownership of the Java VideoFrame.Buffer. I.e. retain()
  // will not be called, but release() will be called when the returned
  // AndroidVideoBuffer is destroyed.
  static rtc::scoped_refptr<AndroidVideoI420Buffer> Adopt(
      JNIEnv* jni,
      int width,
      int height,
      const JavaRef<jobject>& j_video_frame_buffer);

 protected:
  // Should not be called directly. Adopts the buffer. Use Adopt() instead for
  // clarity.
  AndroidVideoI420Buffer(JNIEnv* jni,
                         int width,
                         int height,
                         const JavaRef<jobject>& j_video_frame_buffer);
  ~AndroidVideoI420Buffer() override;

 private:
  const uint8_t* DataY() const override { return data_y_; }
  const uint8_t* DataU() const override { return data_u_; }
  const uint8_t* DataV() const override { return data_v_; }

  int StrideY() const override { return stride_y_; }
  int StrideU() const override { return stride_u_; }
  int StrideV() const override { return stride_v_; }

  int width() const override { return width_; }
  int height() const override { return height_; }

  const int width_;
  const int height_;
  // Holds a VideoFrame.I420Buffer.
  const ScopedJavaGlobalRef<jobject> j_video_frame_buffer_;

  const uint8_t* data_y_;
  const uint8_t* data_u_;
  const uint8_t* data_v_;
  int stride_y_;
  int stride_u_;
  int stride_v_;
};

rtc::scoped_refptr<AndroidVideoI420Buffer> AndroidVideoI420Buffer::Create(
    JNIEnv* jni,
    int width,
    int height,
    const JavaRef<jobject>& j_video_frame_buffer) {
  Java_Buffer_retain(jni, j_video_frame_buffer);
  return AndroidVideoI420Buffer::Adopt(jni, width, height,
                                       j_video_frame_buffer);
}

rtc::scoped_refptr<AndroidVideoI420Buffer> AndroidVideoI420Buffer::Adopt(
    JNIEnv* jni,
    int width,
    int height,
    const JavaRef<jobject>& j_video_frame_buffer) {
  RTC_DCHECK_EQ(
      static_cast<Type>(Java_Buffer_getBufferType(jni, j_video_frame_buffer)),
      Type::kI420);
  return rtc::make_ref_counted<AndroidVideoI420Buffer>(jni, width, height,
                                                       j_video_frame_buffer);
}

AndroidVideoI420Buffer::AndroidVideoI420Buffer(
    JNIEnv* jni,
    int width,
    int height,
    const JavaRef<jobject>& j_video_frame_buffer)
    : width_(width),
      height_(height),
      j_video_frame_buffer_(jni, j_video_frame_buffer) {
  ScopedJavaLocalRef<jobject> j_data_y =
      Java_I420Buffer_getDataY(jni, j_video_frame_buffer);
  ScopedJavaLocalRef<jobject> j_data_u =
      Java_I420Buffer_getDataU(jni, j_video_frame_buffer);
  ScopedJavaLocalRef<jobject> j_data_v =
      Java_I420Buffer_getDataV(jni, j_video_frame_buffer);

  data_y_ =
      static_cast<const uint8_t*>(jni->GetDirectBufferAddress(j_data_y.obj()));
  data_u_ =
      static_cast<const uint8_t*>(jni->GetDirectBufferAddress(j_data_u.obj()));
  data_v_ =
      static_cast<const uint8_t*>(jni->GetDirectBufferAddress(j_data_v.obj()));

  stride_y_ = Java_I420Buffer_getStrideY(jni, j_video_frame_buffer);
  stride_u_ = Java_I420Buffer_getStrideU(jni, j_video_frame_buffer);
  stride_v_ = Java_I420Buffer_getStrideV(jni, j_video_frame_buffer);
}

AndroidVideoI420Buffer::~AndroidVideoI420Buffer() {
  JNIEnv* jni = AttachCurrentThreadIfNeeded();
  Java_Buffer_release(jni, j_video_frame_buffer_);
}

}  // namespace

int64_t GetJavaVideoFrameTimestampNs(JNIEnv* jni,
                                     const JavaRef<jobject>& j_video_frame) {
  return Java_VideoFrame_getTimestampNs(jni, j_video_frame);
}

rtc::scoped_refptr<AndroidVideoBuffer> AndroidVideoBuffer::Adopt(
    JNIEnv* jni,
    const JavaRef<jobject>& j_video_frame_buffer) {
  RTC_DCHECK_EQ(
      static_cast<Type>(Java_Buffer_getBufferType(jni, j_video_frame_buffer)),
      Type::kNative);
  return rtc::make_ref_counted<AndroidVideoBuffer>(jni, j_video_frame_buffer);
}

rtc::scoped_refptr<AndroidVideoBuffer> AndroidVideoBuffer::Create(
    JNIEnv* jni,
    const JavaRef<jobject>& j_video_frame_buffer) {
  Java_Buffer_retain(jni, j_video_frame_buffer);
  return Adopt(jni, j_video_frame_buffer);
}

AndroidVideoBuffer::AndroidVideoBuffer(
    JNIEnv* jni,
    const JavaRef<jobject>& j_video_frame_buffer)
    : width_(Java_Buffer_getWidth(jni, j_video_frame_buffer)),
      height_(Java_Buffer_getHeight(jni, j_video_frame_buffer)),
      j_video_frame_buffer_(jni, j_video_frame_buffer) {}

AndroidVideoBuffer::~AndroidVideoBuffer() {
  JNIEnv* jni = AttachCurrentThreadIfNeeded();
  Java_Buffer_release(jni, j_video_frame_buffer_);
}

const ScopedJavaGlobalRef<jobject>& AndroidVideoBuffer::video_frame_buffer()
    const {
  return j_video_frame_buffer_;
}

rtc::scoped_refptr<VideoFrameBuffer> AndroidVideoBuffer::CropAndScale(
    int crop_x,
    int crop_y,
    int crop_width,
    int crop_height,
    int scale_width,
    int scale_height) {
  JNIEnv* jni = AttachCurrentThreadIfNeeded();
  return Adopt(jni, Java_Buffer_cropAndScale(jni, j_video_frame_buffer_, crop_x,
                                             crop_y, crop_width, crop_height,
                                             scale_width, scale_height));
}

VideoFrameBuffer::Type AndroidVideoBuffer::type() const {
  return Type::kNative;
}

int AndroidVideoBuffer::width() const {
  return width_;
}

int AndroidVideoBuffer::height() const {
  return height_;
}

rtc::scoped_refptr<I420BufferInterface> AndroidVideoBuffer::ToI420() {
  JNIEnv* jni = AttachCurrentThreadIfNeeded();
  ScopedJavaLocalRef<jobject> j_i420_buffer =
      Java_Buffer_toI420(jni, j_video_frame_buffer_);
  // In case I420 conversion fails, we propagate the nullptr.
  if (j_i420_buffer.is_null()) {
    return nullptr;
  }

  // We don't need to retain the buffer because toI420 returns a new object that
  // we are assumed to take the ownership of.
  return AndroidVideoI420Buffer::Adopt(jni, width_, height_, j_i420_buffer);
}

rtc::scoped_refptr<VideoFrameBuffer> JavaToNativeFrameBuffer(
    JNIEnv* jni,
    const JavaRef<jobject>& j_video_frame_buffer) {
  VideoFrameBuffer::Type type = static_cast<VideoFrameBuffer::Type>(
      Java_Buffer_getBufferType(jni, j_video_frame_buffer));
  switch (type) {
    case VideoFrameBuffer::Type::kI420: {
      const int width = Java_Buffer_getWidth(jni, j_video_frame_buffer);
      const int height = Java_Buffer_getHeight(jni, j_video_frame_buffer);
      return AndroidVideoI420Buffer::Create(jni, width, height,
                                            j_video_frame_buffer);
    }
    case VideoFrameBuffer::Type::kNative:
      return AndroidVideoBuffer::Create(jni, j_video_frame_buffer);
    default:
      RTC_CHECK_NOTREACHED();
  }
}

VideoFrame JavaToNativeFrame(JNIEnv* jni,
                             const JavaRef<jobject>& j_video_frame,
                             uint32_t timestamp_rtp) {
  ScopedJavaLocalRef<jobject> j_video_frame_buffer =
      Java_VideoFrame_getBuffer(jni, j_video_frame);
  int rotation = Java_VideoFrame_getRotation(jni, j_video_frame);
  int64_t timestamp_ns = Java_VideoFrame_getTimestampNs(jni, j_video_frame);
  rtc::scoped_refptr<VideoFrameBuffer> buffer =
      JavaToNativeFrameBuffer(jni, j_video_frame_buffer);
  return VideoFrame::Builder()
      .set_video_frame_buffer(buffer)
      .set_rtp_timestamp(timestamp_rtp)
      .set_timestamp_ms(timestamp_ns / rtc::kNumNanosecsPerMillisec)
      .set_rotation(static_cast<VideoRotation>(rotation))
      .build();
}

ScopedJavaLocalRef<jobject> NativeToJavaVideoFrame(JNIEnv* jni,
                                                   const VideoFrame& frame) {
  rtc::scoped_refptr<VideoFrameBuffer> buffer = frame.video_frame_buffer();

  if (buffer->type() == VideoFrameBuffer::Type::kNative) {
    AndroidVideoBuffer* android_buffer =
        static_cast<AndroidVideoBuffer*>(buffer.get());
    ScopedJavaLocalRef<jobject> j_video_frame_buffer(
        jni, android_buffer->video_frame_buffer());
    Java_Buffer_retain(jni, j_video_frame_buffer);
    return Java_VideoFrame_Constructor(
        jni, j_video_frame_buffer, static_cast<jint>(frame.rotation()),
        static_cast<jlong>(frame.timestamp_us() *
                           rtc::kNumNanosecsPerMicrosec));
  } else {
    return Java_VideoFrame_Constructor(
        jni, WrapI420Buffer(jni, buffer->ToI420()),
        static_cast<jint>(frame.rotation()),
        static_cast<jlong>(frame.timestamp_us() *
                           rtc::kNumNanosecsPerMicrosec));
  }
}

void ReleaseJavaVideoFrame(JNIEnv* jni, const JavaRef<jobject>& j_video_frame) {
  Java_VideoFrame_release(jni, j_video_frame);
}

}  // namespace jni
}  // namespace webrtc
