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/ref_counted_object.h"
15 #include "rtc_base/time_utils.h"
16 #include "sdk/android/generated_video_jni/EncodedImage_jni.h"
17 #include "sdk/android/native_api/jni/java_types.h"
18 #include "sdk/android/src/jni/jni_helpers.h"
19 #include "sdk/android/src/jni/scoped_java_ref_counted.h"
20
21 namespace webrtc {
22 namespace jni {
23
24 namespace {
25
26 class JavaEncodedImageBuffer : public EncodedImageBufferInterface {
27 public:
JavaEncodedImageBuffer(JNIEnv * env,const JavaRef<jobject> & j_encoded_image,const uint8_t * payload,size_t size)28 JavaEncodedImageBuffer(JNIEnv* env,
29 const JavaRef<jobject>& j_encoded_image,
30 const uint8_t* payload,
31 size_t size)
32 : j_encoded_image_(ScopedJavaRefCounted::Retain(env, j_encoded_image)),
33 data_(const_cast<uint8_t*>(payload)),
34 size_(size) {}
35
data() const36 const uint8_t* data() const override { return data_; }
data()37 uint8_t* data() override { return data_; }
size() const38 size_t size() const override { return size_; }
39
40 private:
41 // The Java object owning the buffer.
42 const ScopedJavaRefCounted j_encoded_image_;
43
44 // TODO(bugs.webrtc.org/9378): Make const, and delete above const_cast.
45 uint8_t* const data_;
46 size_t const size_;
47 };
48 } // namespace
49
NativeToJavaFrameType(JNIEnv * env,VideoFrameType frame_type)50 ScopedJavaLocalRef<jobject> NativeToJavaFrameType(JNIEnv* env,
51 VideoFrameType frame_type) {
52 return Java_FrameType_fromNativeIndex(env, static_cast<int>(frame_type));
53 }
54
NativeToJavaEncodedImage(JNIEnv * jni,const EncodedImage & image)55 ScopedJavaLocalRef<jobject> NativeToJavaEncodedImage(
56 JNIEnv* jni,
57 const EncodedImage& image) {
58 ScopedJavaLocalRef<jobject> buffer = NewDirectByteBuffer(
59 jni, const_cast<uint8_t*>(image.data()), image.size());
60 ScopedJavaLocalRef<jobject> frame_type =
61 NativeToJavaFrameType(jni, image._frameType);
62 ScopedJavaLocalRef<jobject> qp;
63 if (image.qp_ != -1)
64 qp = NativeToJavaInteger(jni, image.qp_);
65 // TODO(bugs.webrtc.org/9378): Keep a reference to the C++ EncodedImage data,
66 // and use the releaseCallback to manage lifetime.
67 return Java_EncodedImage_Constructor(
68 jni, buffer,
69 /*releaseCallback=*/ScopedJavaGlobalRef<jobject>(nullptr),
70 static_cast<int>(image._encodedWidth),
71 static_cast<int>(image._encodedHeight),
72 image.capture_time_ms_ * rtc::kNumNanosecsPerMillisec, frame_type,
73 static_cast<jint>(image.rotation_), image._completeFrame, qp);
74 }
75
NativeToJavaFrameTypeArray(JNIEnv * env,const std::vector<VideoFrameType> & frame_types)76 ScopedJavaLocalRef<jobjectArray> NativeToJavaFrameTypeArray(
77 JNIEnv* env,
78 const std::vector<VideoFrameType>& frame_types) {
79 return NativeToJavaObjectArray(
80 env, frame_types, org_webrtc_EncodedImage_00024FrameType_clazz(env),
81 &NativeToJavaFrameType);
82 }
83
JavaToNativeEncodedImage(JNIEnv * env,const JavaRef<jobject> & j_encoded_image)84 EncodedImage JavaToNativeEncodedImage(JNIEnv* env,
85 const JavaRef<jobject>& j_encoded_image) {
86 const JavaRef<jobject>& j_buffer =
87 Java_EncodedImage_getBuffer(env, j_encoded_image);
88 const uint8_t* buffer =
89 static_cast<uint8_t*>(env->GetDirectBufferAddress(j_buffer.obj()));
90 const size_t buffer_size = env->GetDirectBufferCapacity(j_buffer.obj());
91
92 EncodedImage frame;
93 frame.SetEncodedData(new rtc::RefCountedObject<JavaEncodedImageBuffer>(
94 env, j_encoded_image, buffer, buffer_size));
95
96 frame._encodedWidth = Java_EncodedImage_getEncodedWidth(env, j_encoded_image);
97 frame._encodedHeight =
98 Java_EncodedImage_getEncodedHeight(env, j_encoded_image);
99 frame.rotation_ =
100 (VideoRotation)Java_EncodedImage_getRotation(env, j_encoded_image);
101 frame._completeFrame =
102 Java_EncodedImage_getCompleteFrame(env, j_encoded_image);
103
104 frame.qp_ = JavaToNativeOptionalInt(
105 env, Java_EncodedImage_getQp(env, j_encoded_image))
106 .value_or(-1);
107
108 frame._frameType =
109 (VideoFrameType)Java_EncodedImage_getFrameType(env, j_encoded_image);
110 return frame;
111 }
112
GetJavaEncodedImageCaptureTimeNs(JNIEnv * env,const JavaRef<jobject> & j_encoded_image)113 int64_t GetJavaEncodedImageCaptureTimeNs(
114 JNIEnv* env,
115 const JavaRef<jobject>& j_encoded_image) {
116 return Java_EncodedImage_getCaptureTimeNs(env, j_encoded_image);
117 }
118
119 } // namespace jni
120 } // namespace webrtc
121