/* * Copyright 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 "sdk/android/src/jni/encoded_image.h" #include "api/video/encoded_image.h" #include "rtc_base/time_utils.h" #include "sdk/android/generated_video_jni/EncodedImage_jni.h" #include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/scoped_java_ref_counted.h" namespace webrtc { namespace jni { namespace { class JavaEncodedImageBuffer : public EncodedImageBufferInterface { public: JavaEncodedImageBuffer(JNIEnv* env, const JavaRef& j_encoded_image, const uint8_t* payload, size_t size) : j_encoded_image_(ScopedJavaRefCounted::Retain(env, j_encoded_image)), data_(const_cast(payload)), size_(size) {} const uint8_t* data() const override { return data_; } uint8_t* data() override { return data_; } size_t size() const override { return size_; } private: // The Java object owning the buffer. const ScopedJavaRefCounted j_encoded_image_; // TODO(bugs.webrtc.org/9378): Make const, and delete above const_cast. uint8_t* const data_; size_t const size_; }; } // namespace ScopedJavaLocalRef NativeToJavaFrameType(JNIEnv* env, VideoFrameType frame_type) { return Java_FrameType_fromNativeIndex(env, static_cast(frame_type)); } ScopedJavaLocalRef NativeToJavaEncodedImage( JNIEnv* jni, const EncodedImage& image) { ScopedJavaLocalRef buffer = NewDirectByteBuffer( jni, const_cast(image.data()), image.size()); ScopedJavaLocalRef frame_type = NativeToJavaFrameType(jni, image._frameType); ScopedJavaLocalRef qp; if (image.qp_ != -1) qp = NativeToJavaInteger(jni, image.qp_); // TODO(bugs.webrtc.org/9378): Keep a reference to the C++ EncodedImage data, // and use the releaseCallback to manage lifetime. return Java_EncodedImage_Constructor( jni, buffer, /*releaseCallback=*/ScopedJavaGlobalRef(nullptr), static_cast(image._encodedWidth), static_cast(image._encodedHeight), image.capture_time_ms_ * rtc::kNumNanosecsPerMillisec, frame_type, static_cast(image.rotation_), qp); } ScopedJavaLocalRef NativeToJavaFrameTypeArray( JNIEnv* env, const std::vector& frame_types) { return NativeToJavaObjectArray( env, frame_types, org_webrtc_EncodedImage_00024FrameType_clazz(env), &NativeToJavaFrameType); } EncodedImage JavaToNativeEncodedImage(JNIEnv* env, const JavaRef& j_encoded_image) { const JavaRef& j_buffer = Java_EncodedImage_getBuffer(env, j_encoded_image); const uint8_t* buffer = static_cast(env->GetDirectBufferAddress(j_buffer.obj())); const size_t buffer_size = env->GetDirectBufferCapacity(j_buffer.obj()); EncodedImage frame; frame.SetEncodedData(rtc::make_ref_counted( env, j_encoded_image, buffer, buffer_size)); frame._encodedWidth = Java_EncodedImage_getEncodedWidth(env, j_encoded_image); frame._encodedHeight = Java_EncodedImage_getEncodedHeight(env, j_encoded_image); frame.rotation_ = (VideoRotation)Java_EncodedImage_getRotation(env, j_encoded_image); frame.qp_ = JavaToNativeOptionalInt( env, Java_EncodedImage_getQp(env, j_encoded_image)) .value_or(-1); frame._frameType = (VideoFrameType)Java_EncodedImage_getFrameType(env, j_encoded_image); return frame; } int64_t GetJavaEncodedImageCaptureTimeNs( JNIEnv* env, const JavaRef& j_encoded_image) { return Java_EncodedImage_getCaptureTimeNs(env, j_encoded_image); } } // namespace jni } // namespace webrtc