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/video_encoder_factory_wrapper.h"
12
13 #include "api/video/render_resolution.h"
14 #include "api/video_codecs/video_encoder.h"
15 #include "rtc_base/logging.h"
16 #include "sdk/android/generated_video_jni/VideoEncoderFactory_jni.h"
17 #include "sdk/android/native_api/jni/class_loader.h"
18 #include "sdk/android/native_api/jni/java_types.h"
19 #include "sdk/android/src/jni/video_codec_info.h"
20 #include "sdk/android/src/jni/video_encoder_wrapper.h"
21
22 namespace webrtc {
23 namespace jni {
24 namespace {
25 class VideoEncoderSelectorWrapper
26 : public VideoEncoderFactory::EncoderSelectorInterface {
27 public:
VideoEncoderSelectorWrapper(JNIEnv * jni,const JavaRef<jobject> & encoder_selector)28 VideoEncoderSelectorWrapper(JNIEnv* jni,
29 const JavaRef<jobject>& encoder_selector)
30 : encoder_selector_(jni, encoder_selector) {}
31
OnCurrentEncoder(const SdpVideoFormat & format)32 void OnCurrentEncoder(const SdpVideoFormat& format) override {
33 JNIEnv* jni = AttachCurrentThreadIfNeeded();
34 ScopedJavaLocalRef<jobject> j_codec_info =
35 SdpVideoFormatToVideoCodecInfo(jni, format);
36 Java_VideoEncoderSelector_onCurrentEncoder(jni, encoder_selector_,
37 j_codec_info);
38 }
39
OnAvailableBitrate(const DataRate & rate)40 absl::optional<SdpVideoFormat> OnAvailableBitrate(
41 const DataRate& rate) override {
42 JNIEnv* jni = AttachCurrentThreadIfNeeded();
43 ScopedJavaLocalRef<jobject> codec_info =
44 Java_VideoEncoderSelector_onAvailableBitrate(jni, encoder_selector_,
45 rate.kbps<int>());
46 if (codec_info.is_null()) {
47 return absl::nullopt;
48 }
49 return VideoCodecInfoToSdpVideoFormat(jni, codec_info);
50 }
51
OnResolutionChange(const RenderResolution & resolution)52 absl::optional<SdpVideoFormat> OnResolutionChange(
53 const RenderResolution& resolution) override {
54 JNIEnv* jni = AttachCurrentThreadIfNeeded();
55 ScopedJavaLocalRef<jobject> codec_info =
56 Java_VideoEncoderSelector_onResolutionChange(
57 jni, encoder_selector_, resolution.Width(), resolution.Height());
58 if (codec_info.is_null()) {
59 return absl::nullopt;
60 }
61 return VideoCodecInfoToSdpVideoFormat(jni, codec_info);
62 }
63
OnEncoderBroken()64 absl::optional<SdpVideoFormat> OnEncoderBroken() override {
65 JNIEnv* jni = AttachCurrentThreadIfNeeded();
66 ScopedJavaLocalRef<jobject> codec_info =
67 Java_VideoEncoderSelector_onEncoderBroken(jni, encoder_selector_);
68 if (codec_info.is_null()) {
69 return absl::nullopt;
70 }
71 return VideoCodecInfoToSdpVideoFormat(jni, codec_info);
72 }
73
74 private:
75 const ScopedJavaGlobalRef<jobject> encoder_selector_;
76 };
77
78 } // namespace
79
VideoEncoderFactoryWrapper(JNIEnv * jni,const JavaRef<jobject> & encoder_factory)80 VideoEncoderFactoryWrapper::VideoEncoderFactoryWrapper(
81 JNIEnv* jni,
82 const JavaRef<jobject>& encoder_factory)
83 : encoder_factory_(jni, encoder_factory) {
84 const ScopedJavaLocalRef<jobjectArray> j_supported_codecs =
85 Java_VideoEncoderFactory_getSupportedCodecs(jni, encoder_factory);
86 supported_formats_ = JavaToNativeVector<SdpVideoFormat>(
87 jni, j_supported_codecs, &VideoCodecInfoToSdpVideoFormat);
88 const ScopedJavaLocalRef<jobjectArray> j_implementations =
89 Java_VideoEncoderFactory_getImplementations(jni, encoder_factory);
90 implementations_ = JavaToNativeVector<SdpVideoFormat>(
91 jni, j_implementations, &VideoCodecInfoToSdpVideoFormat);
92 }
93 VideoEncoderFactoryWrapper::~VideoEncoderFactoryWrapper() = default;
94
CreateVideoEncoder(const SdpVideoFormat & format)95 std::unique_ptr<VideoEncoder> VideoEncoderFactoryWrapper::CreateVideoEncoder(
96 const SdpVideoFormat& format) {
97 JNIEnv* jni = AttachCurrentThreadIfNeeded();
98 ScopedJavaLocalRef<jobject> j_codec_info =
99 SdpVideoFormatToVideoCodecInfo(jni, format);
100 ScopedJavaLocalRef<jobject> encoder = Java_VideoEncoderFactory_createEncoder(
101 jni, encoder_factory_, j_codec_info);
102 if (!encoder.obj())
103 return nullptr;
104 return JavaToNativeVideoEncoder(jni, encoder);
105 }
106
GetSupportedFormats() const107 std::vector<SdpVideoFormat> VideoEncoderFactoryWrapper::GetSupportedFormats()
108 const {
109 return supported_formats_;
110 }
111
GetImplementations() const112 std::vector<SdpVideoFormat> VideoEncoderFactoryWrapper::GetImplementations()
113 const {
114 return implementations_;
115 }
116
117 std::unique_ptr<VideoEncoderFactory::EncoderSelectorInterface>
GetEncoderSelector() const118 VideoEncoderFactoryWrapper::GetEncoderSelector() const {
119 JNIEnv* jni = AttachCurrentThreadIfNeeded();
120 ScopedJavaLocalRef<jobject> selector =
121 Java_VideoEncoderFactory_getEncoderSelector(jni, encoder_factory_);
122 if (selector.is_null()) {
123 return nullptr;
124 }
125
126 return std::make_unique<VideoEncoderSelectorWrapper>(jni, selector);
127 }
128
129 } // namespace jni
130 } // namespace webrtc
131