xref: /aosp_15_r20/external/webrtc/sdk/android/src/jni/encoded_image.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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