1 /*
2 * Copyright 2017 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "sdk/android/src/jni/encoded_image.h"
12
13 #include "api/video/encoded_image.h"
14 #include "rtc_base/time_utils.h"
15 #include "sdk/android/generated_video_jni/EncodedImage_jni.h"
16 #include "sdk/android/native_api/jni/java_types.h"
17 #include "sdk/android/src/jni/jni_helpers.h"
18 #include "sdk/android/src/jni/scoped_java_ref_counted.h"
19
20 namespace webrtc {
21 namespace jni {
22
23 namespace {
24
25 class JavaEncodedImageBuffer : public EncodedImageBufferInterface {
26 public:
JavaEncodedImageBuffer(JNIEnv * env,const JavaRef<jobject> & j_encoded_image,const uint8_t * payload,size_t size)27 JavaEncodedImageBuffer(JNIEnv* env,
28 const JavaRef<jobject>& j_encoded_image,
29 const uint8_t* payload,
30 size_t size)
31 : j_encoded_image_(ScopedJavaRefCounted::Retain(env, j_encoded_image)),
32 data_(const_cast<uint8_t*>(payload)),
33 size_(size) {}
34
data() const35 const uint8_t* data() const override { return data_; }
data()36 uint8_t* data() override { return data_; }
size() const37 size_t size() const override { return size_; }
38
39 private:
40 // The Java object owning the buffer.
41 const ScopedJavaRefCounted j_encoded_image_;
42
43 // TODO(bugs.webrtc.org/9378): Make const, and delete above const_cast.
44 uint8_t* const data_;
45 size_t const size_;
46 };
47 } // namespace
48
NativeToJavaFrameType(JNIEnv * env,VideoFrameType frame_type)49 ScopedJavaLocalRef<jobject> NativeToJavaFrameType(JNIEnv* env,
50 VideoFrameType frame_type) {
51 return Java_FrameType_fromNativeIndex(env, static_cast<int>(frame_type));
52 }
53
NativeToJavaEncodedImage(JNIEnv * jni,const EncodedImage & image)54 ScopedJavaLocalRef<jobject> NativeToJavaEncodedImage(
55 JNIEnv* jni,
56 const EncodedImage& image) {
57 ScopedJavaLocalRef<jobject> buffer = NewDirectByteBuffer(
58 jni, const_cast<uint8_t*>(image.data()), image.size());
59 ScopedJavaLocalRef<jobject> frame_type =
60 NativeToJavaFrameType(jni, image._frameType);
61 ScopedJavaLocalRef<jobject> qp;
62 if (image.qp_ != -1)
63 qp = NativeToJavaInteger(jni, image.qp_);
64 // TODO(bugs.webrtc.org/9378): Keep a reference to the C++ EncodedImage data,
65 // and use the releaseCallback to manage lifetime.
66 return Java_EncodedImage_Constructor(
67 jni, buffer,
68 /*releaseCallback=*/ScopedJavaGlobalRef<jobject>(nullptr),
69 static_cast<int>(image._encodedWidth),
70 static_cast<int>(image._encodedHeight),
71 image.capture_time_ms_ * rtc::kNumNanosecsPerMillisec, frame_type,
72 static_cast<jint>(image.rotation_), qp);
73 }
74
NativeToJavaFrameTypeArray(JNIEnv * env,const std::vector<VideoFrameType> & frame_types)75 ScopedJavaLocalRef<jobjectArray> NativeToJavaFrameTypeArray(
76 JNIEnv* env,
77 const std::vector<VideoFrameType>& frame_types) {
78 return NativeToJavaObjectArray(
79 env, frame_types, org_webrtc_EncodedImage_00024FrameType_clazz(env),
80 &NativeToJavaFrameType);
81 }
82
JavaToNativeEncodedImage(JNIEnv * env,const JavaRef<jobject> & j_encoded_image)83 EncodedImage JavaToNativeEncodedImage(JNIEnv* env,
84 const JavaRef<jobject>& j_encoded_image) {
85 const JavaRef<jobject>& j_buffer =
86 Java_EncodedImage_getBuffer(env, j_encoded_image);
87 const uint8_t* buffer =
88 static_cast<uint8_t*>(env->GetDirectBufferAddress(j_buffer.obj()));
89 const size_t buffer_size = env->GetDirectBufferCapacity(j_buffer.obj());
90
91 EncodedImage frame;
92 frame.SetEncodedData(rtc::make_ref_counted<JavaEncodedImageBuffer>(
93 env, j_encoded_image, buffer, buffer_size));
94
95 frame._encodedWidth = Java_EncodedImage_getEncodedWidth(env, j_encoded_image);
96 frame._encodedHeight =
97 Java_EncodedImage_getEncodedHeight(env, j_encoded_image);
98 frame.rotation_ =
99 (VideoRotation)Java_EncodedImage_getRotation(env, j_encoded_image);
100
101 frame.qp_ = JavaToNativeOptionalInt(
102 env, Java_EncodedImage_getQp(env, j_encoded_image))
103 .value_or(-1);
104
105 frame._frameType =
106 (VideoFrameType)Java_EncodedImage_getFrameType(env, j_encoded_image);
107 return frame;
108 }
109
GetJavaEncodedImageCaptureTimeNs(JNIEnv * env,const JavaRef<jobject> & j_encoded_image)110 int64_t GetJavaEncodedImageCaptureTimeNs(
111 JNIEnv* env,
112 const JavaRef<jobject>& j_encoded_image) {
113 return Java_EncodedImage_getCaptureTimeNs(env, j_encoded_image);
114 }
115
116 } // namespace jni
117 } // namespace webrtc
118