/*
 *  Copyright (c) 2017 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 <jni.h>

#include "api/video/video_frame.h"
#include "api/videosinkinterface.h"
#include "sdk/android/generated_video_jni/jni/VideoRenderer_jni.h"
#include "sdk/android/src/jni/jni_helpers.h"
#include "sdk/android/src/jni/videoframe.h"

namespace webrtc {
namespace jni {

// Wrapper dispatching rtc::VideoSinkInterface to a Java VideoRenderer
// instance.
class JavaVideoRendererWrapper : public rtc::VideoSinkInterface<VideoFrame> {
 public:
  JavaVideoRendererWrapper(JNIEnv* jni, const JavaRef<jobject>& j_callbacks)
      : j_callbacks_(jni, j_callbacks) {}

  ~JavaVideoRendererWrapper() override {}

  void OnFrame(const VideoFrame& video_frame) override {
    JNIEnv* env = AttachCurrentThreadIfNeeded();

    ScopedJavaLocalRef<jobject> j_frame;
    if (video_frame.video_frame_buffer()->type() ==
        VideoFrameBuffer::Type::kNative) {
      AndroidVideoFrameBuffer* android_buffer =
          static_cast<AndroidVideoFrameBuffer*>(
              video_frame.video_frame_buffer().get());
      switch (android_buffer->android_type()) {
        case AndroidVideoFrameBuffer::AndroidType::kTextureBuffer:
          j_frame = ToJavaTextureFrame(env, video_frame);
          break;
        case AndroidVideoFrameBuffer::AndroidType::kJavaBuffer:
          j_frame = FromWrappedJavaBuffer(env, video_frame);
          break;
        default:
          RTC_NOTREACHED();
      }
    } else {
      j_frame = ToJavaI420Frame(env, video_frame);
    }
    // |j_callbacks_| is responsible for releasing |j_frame| with
    // VideoRenderer.renderFrameDone().
    Java_Callbacks_renderFrame(env, j_callbacks_, j_frame);
  }

 private:
  // Make a shallow copy of |frame| to be used with Java. The callee has
  // ownership of the frame, and the frame should be released with
  // VideoRenderer.releaseNativeFrame().
  static jlong javaShallowCopy(const VideoFrame& frame) {
    return jlongFromPointer(new VideoFrame(frame));
  }

  // Return a VideoRenderer.I420Frame referring to the data in |frame|.
  ScopedJavaLocalRef<jobject> FromWrappedJavaBuffer(JNIEnv* env,
                                                    const VideoFrame& frame) {
    return Java_I420Frame_Constructor(
        env, frame.rotation(),
        static_cast<AndroidVideoBuffer*>(frame.video_frame_buffer().get())
            ->video_frame_buffer(),
        javaShallowCopy(frame));
  }

  // Return a VideoRenderer.I420Frame referring to the data in |frame|.
  ScopedJavaLocalRef<jobject> ToJavaI420Frame(JNIEnv* env,
                                              const VideoFrame& frame) {
    rtc::scoped_refptr<I420BufferInterface> i420_buffer =
        frame.video_frame_buffer()->ToI420();
    ScopedJavaLocalRef<jobject> y_buffer =
        NewDirectByteBuffer(env, const_cast<uint8_t*>(i420_buffer->DataY()),
                            i420_buffer->StrideY() * i420_buffer->height());
    size_t chroma_height = i420_buffer->ChromaHeight();
    ScopedJavaLocalRef<jobject> u_buffer =
        NewDirectByteBuffer(env, const_cast<uint8_t*>(i420_buffer->DataU()),
                            i420_buffer->StrideU() * chroma_height);
    ScopedJavaLocalRef<jobject> v_buffer =
        NewDirectByteBuffer(env, const_cast<uint8_t*>(i420_buffer->DataV()),
                            i420_buffer->StrideV() * chroma_height);
    return Java_I420Frame_createI420Frame(
        env, frame.width(), frame.height(), static_cast<int>(frame.rotation()),
        i420_buffer->StrideY(), y_buffer, i420_buffer->StrideU(), u_buffer,
        i420_buffer->StrideV(), v_buffer, javaShallowCopy(frame));
  }

  // Return a VideoRenderer.I420Frame referring texture object in |frame|.
  ScopedJavaLocalRef<jobject> ToJavaTextureFrame(JNIEnv* env,
                                                 const VideoFrame& frame) {
    NativeHandleImpl handle =
        static_cast<AndroidTextureBuffer*>(frame.video_frame_buffer().get())
            ->native_handle_impl();
    return Java_I420Frame_createTextureFrame(
        env, frame.width(), frame.height(), static_cast<int>(frame.rotation()),
        handle.oes_texture_id, handle.sampling_matrix.ToJava(env),
        javaShallowCopy(frame));
  }

  ScopedJavaGlobalRef<jobject> j_callbacks_;
};

static void JNI_VideoRenderer_FreeWrappedVideoRenderer(
    JNIEnv*,
    const JavaParamRef<jclass>&,
    jlong j_p) {
  delete reinterpret_cast<JavaVideoRendererWrapper*>(j_p);
}

static void JNI_VideoRenderer_ReleaseFrame(JNIEnv* jni,
                                           const JavaParamRef<jclass>&,
                                           jlong j_frame_ptr) {
  delete reinterpret_cast<const VideoFrame*>(j_frame_ptr);
}

static jlong JNI_VideoRenderer_CreateVideoRenderer(
    JNIEnv* jni,
    const JavaParamRef<jclass>&,
    const JavaParamRef<jobject>& j_callbacks) {
  std::unique_ptr<JavaVideoRendererWrapper> renderer(
      new JavaVideoRendererWrapper(jni, j_callbacks));
  return jlongFromPointer(renderer.release());
}

static void JNI_VideoRenderer_CopyPlane(
    JNIEnv* jni,
    const JavaParamRef<jclass>&,
    const JavaParamRef<jobject>& j_src_buffer,
    jint width,
    jint height,
    jint src_stride,
    const JavaParamRef<jobject>& j_dst_buffer,
    jint dst_stride) {
  size_t src_size = jni->GetDirectBufferCapacity(j_src_buffer.obj());
  size_t dst_size = jni->GetDirectBufferCapacity(j_dst_buffer.obj());
  RTC_CHECK(src_stride >= width) << "Wrong source stride " << src_stride;
  RTC_CHECK(dst_stride >= width) << "Wrong destination stride " << dst_stride;
  RTC_CHECK(src_size >= src_stride * height)
      << "Insufficient source buffer capacity " << src_size;
  RTC_CHECK(dst_size >= dst_stride * height)
      << "Insufficient destination buffer capacity " << dst_size;
  uint8_t* src = reinterpret_cast<uint8_t*>(
      jni->GetDirectBufferAddress(j_src_buffer.obj()));
  uint8_t* dst = reinterpret_cast<uint8_t*>(
      jni->GetDirectBufferAddress(j_dst_buffer.obj()));
  if (src_stride == dst_stride) {
    memcpy(dst, src, src_stride * height);
  } else {
    for (int i = 0; i < height; i++) {
      memcpy(dst, src, width);
      src += src_stride;
      dst += dst_stride;
    }
  }
}

}  // namespace jni
}  // namespace webrtc
