diff --git a/sdk/android/api/org/webrtc/VideoEncoderFactory.java b/sdk/android/api/org/webrtc/VideoEncoderFactory.java index b318e8ba85..9c0f2b437c 100644 --- a/sdk/android/api/org/webrtc/VideoEncoderFactory.java +++ b/sdk/android/api/org/webrtc/VideoEncoderFactory.java @@ -14,6 +14,25 @@ import android.support.annotation.Nullable; /** Factory for creating VideoEncoders. */ public interface VideoEncoderFactory { + public interface VideoEncoderSelector { + /** Called with the VideoCodecInfo of the currently used encoder. */ + @CalledByNative("VideoEncoderSelector") void onCurrentEncoder(VideoCodecInfo info); + + /** + * Called with the current encoding bitrate. Returns null if the encoder + * selector which to keep the current encoder or a VideoCodecInfo if a + * new encoder is preferred. + */ + @Nullable @CalledByNative("VideoEncoderSelector") VideoCodecInfo onEncodingBitrate(int kbps); + + /** + * Called when the currently used encoder signal itself as broken. Returns + * null if the encoder selector which to keep the current encoder or a + * VideoCodecInfo if a new encoder is preferred. + */ + @Nullable @CalledByNative("VideoEncoderSelector") VideoCodecInfo onEncoderBroken(); + } + /** Creates an encoder for the given video codec. */ @Nullable @CalledByNative VideoEncoder createEncoder(VideoCodecInfo info); @@ -32,4 +51,13 @@ public interface VideoEncoderFactory { default VideoCodecInfo[] getImplementations() { return getSupportedCodecs(); } + + /** + * Returns a VideoEncoderSelector if implemented by the VideoEncoderFactory, + * null otherwise. + */ + @CalledByNative + default VideoEncoderSelector getEncoderSelector() { + return null; + } } diff --git a/sdk/android/src/jni/video_encoder_factory_wrapper.cc b/sdk/android/src/jni/video_encoder_factory_wrapper.cc index 538cc5bade..795f82bd8f 100644 --- a/sdk/android/src/jni/video_encoder_factory_wrapper.cc +++ b/sdk/android/src/jni/video_encoder_factory_wrapper.cc @@ -20,6 +20,49 @@ namespace webrtc { namespace jni { +namespace { +class VideoEncoderSelectorWrapper + : public VideoEncoderFactory::EncoderSelectorInterface { + public: + VideoEncoderSelectorWrapper(JNIEnv* jni, + const JavaRef& encoder_selector) + : encoder_selector_(jni, encoder_selector) {} + + void OnCurrentEncoder(const SdpVideoFormat& format) override { + JNIEnv* jni = AttachCurrentThreadIfNeeded(); + ScopedJavaLocalRef j_codec_info = + SdpVideoFormatToVideoCodecInfo(jni, format); + Java_VideoEncoderSelector_onCurrentEncoder(jni, encoder_selector_, + j_codec_info); + } + + absl::optional OnEncodingBitrate( + const DataRate& rate) override { + JNIEnv* jni = AttachCurrentThreadIfNeeded(); + ScopedJavaLocalRef codec_info = + Java_VideoEncoderSelector_onEncodingBitrate(jni, encoder_selector_, + rate.kbps()); + if (codec_info.is_null()) { + return absl::nullopt; + } + return VideoCodecInfoToSdpVideoFormat(jni, codec_info); + } + + absl::optional OnEncoderBroken() override { + JNIEnv* jni = AttachCurrentThreadIfNeeded(); + ScopedJavaLocalRef codec_info = + Java_VideoEncoderSelector_onEncoderBroken(jni, encoder_selector_); + if (codec_info.is_null()) { + return absl::nullopt; + } + return VideoCodecInfoToSdpVideoFormat(jni, codec_info); + } + + private: + const ScopedJavaGlobalRef encoder_selector_; +}; + +} // namespace VideoEncoderFactoryWrapper::VideoEncoderFactoryWrapper( JNIEnv* jni, @@ -73,5 +116,17 @@ VideoEncoderFactory::CodecInfo VideoEncoderFactoryWrapper::QueryVideoEncoder( return codec_info; } +std::unique_ptr +VideoEncoderFactoryWrapper::GetEncoderSelector() const { + JNIEnv* jni = AttachCurrentThreadIfNeeded(); + ScopedJavaLocalRef selector = + Java_VideoEncoderFactory_getEncoderSelector(jni, encoder_factory_); + if (selector.is_null()) { + return nullptr; + } + + return std::make_unique(jni, selector); +} + } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/video_encoder_factory_wrapper.h b/sdk/android/src/jni/video_encoder_factory_wrapper.h index 7f033aea80..799ae0f2bc 100644 --- a/sdk/android/src/jni/video_encoder_factory_wrapper.h +++ b/sdk/android/src/jni/video_encoder_factory_wrapper.h @@ -39,6 +39,8 @@ class VideoEncoderFactoryWrapper : public VideoEncoderFactory { CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override; + std::unique_ptr GetEncoderSelector() const override; + private: const ScopedJavaGlobalRef encoder_factory_; std::vector supported_formats_;