• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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