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