From cddfc46db6c59cce72dd76aaecdacb1c1852dd5c Mon Sep 17 00:00:00 2001 From: philipel Date: Wed, 12 Feb 2020 11:24:45 +0100 Subject: [PATCH] Added java interface VideoEncoderFactory.VideoEncoderSelector and implemented VideoEncoderSelectorWrapper. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: webrtc:11341 Change-Id: Ic15658e09643aec119a97ddfaebfdb72ba3407c7 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168487 Reviewed-by: Sami Kalliomäki Commit-Queue: Philip Eliasson Cr-Commit-Position: refs/heads/master@{#30519} --- .../api/org/webrtc/VideoEncoderFactory.java | 28 ++++++++++ .../src/jni/video_encoder_factory_wrapper.cc | 55 +++++++++++++++++++ .../src/jni/video_encoder_factory_wrapper.h | 2 + 3 files changed, 85 insertions(+) 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_;