From df4883dbf02d02085af9f0f9952fe376a1bdb7d3 Mon Sep 17 00:00:00 2001 From: Magnus Jedvert Date: Fri, 17 Nov 2017 14:44:55 +0100 Subject: [PATCH] Reland "Update internal encoder factory to new interface" This is a reland of 2c8c8e26fc58a0f2789b7a5cd2646a8319c14d3e Original change's description: > Update internal encoder factory to new interface > > TBR=stefan@webrtc.org > > Bug: webrtc:7925 > Change-Id: I0bb97acdf0d58a9ce531ecdd672bb17ef96360df > Reviewed-on: https://webrtc-review.googlesource.com/21162 > Commit-Queue: Magnus Jedvert > Reviewed-by: Anders Carlsson > Reviewed-by: Rasmus Brandt > Cr-Commit-Position: refs/heads/master@{#20717} TBR=andersc@webrtc.org,brandt@webrtc.org,stefan@webrtc.org Bug: webrtc:7925 Change-Id: I0d269b3edb029e372a36c3b461a577bca2b6d0cb Reviewed-on: https://webrtc-review.googlesource.com/24000 Reviewed-by: Magnus Jedvert Commit-Queue: Magnus Jedvert Cr-Commit-Position: refs/heads/master@{#20747} --- media/engine/convert_legacy_video_factory.cc | 128 +++++++++++------- media/engine/internalencoderfactory.cc | 73 +++++----- media/engine/internalencoderfactory.h | 22 ++- media/engine/simulcast_encoder_adapter.cc | 21 ++- media/engine/simulcast_encoder_adapter.h | 6 +- .../simulcast_encoder_adapter_unittest.cc | 115 ++++++++++------ media/engine/vp8_encoder_simulcast_proxy.cc | 5 +- media/engine/vp8_encoder_simulcast_proxy.h | 7 +- .../vp8_encoder_simulcast_proxy_unittest.cc | 63 ++++----- .../test/videoprocessor_integrationtest.cc | 40 +++++- .../src/jni/androidmediaencoder_jni.cc | 14 +- video/picture_id_tests.cc | 6 +- video/video_quality_test.cc | 3 +- video/video_quality_test.h | 1 - 14 files changed, 301 insertions(+), 203 deletions(-) diff --git a/media/engine/convert_legacy_video_factory.cc b/media/engine/convert_legacy_video_factory.cc index f3638ee025..e562a020dd 100644 --- a/media/engine/convert_legacy_video_factory.cc +++ b/media/engine/convert_legacy_video_factory.cc @@ -61,32 +61,70 @@ bool IsFormatSupported( return false; } +// Converts the cricket::WebRtcVideoEncoderFactory to a +// webrtc::VideoEncoderFactory (without adding any simulcast or SW fallback). +class CricketToWebRtcEncoderFactory : public webrtc::VideoEncoderFactory { + public: + explicit CricketToWebRtcEncoderFactory( + std::unique_ptr external_encoder_factory) + : external_encoder_factory_(std::move(external_encoder_factory)) {} + + webrtc::VideoEncoderFactory::CodecInfo QueryVideoEncoder( + const webrtc::SdpVideoFormat& format) const override { + CodecInfo info; + if (!external_encoder_factory_) + return info; + + info.has_internal_source = + external_encoder_factory_->EncoderTypeHasInternalSource( + webrtc::PayloadStringToCodecType(format.name)); + info.is_hardware_accelerated = true; + return info; + } + + std::vector GetSupportedFormats() const override { + if (!external_encoder_factory_) + return std::vector(); + + std::vector formats; + for (const VideoCodec& codec : + external_encoder_factory_->supported_codecs()) { + formats.push_back(webrtc::SdpVideoFormat(codec.name, codec.params)); + } + return formats; + } + + std::unique_ptr CreateVideoEncoder( + const webrtc::SdpVideoFormat& format) override { + return CreateScopedVideoEncoder(external_encoder_factory_.get(), + VideoCodec(format)); + } + + private: + const std::unique_ptr external_encoder_factory_; +}; + +// This class combines an external factory with the internal factory and adds +// internal SW codecs, simulcast, and SW fallback wrappers. class EncoderAdapter : public webrtc::VideoEncoderFactory { public: explicit EncoderAdapter( std::unique_ptr external_encoder_factory) - : internal_encoder_factory_(new InternalEncoderFactory()), - external_encoder_factory_(std::move(external_encoder_factory)) {} + : internal_encoder_factory_(new webrtc::InternalEncoderFactory()), + external_encoder_factory_( + rtc::MakeUnique( + std::move(external_encoder_factory))) {} webrtc::VideoEncoderFactory::CodecInfo QueryVideoEncoder( - const webrtc::SdpVideoFormat& format) const { - const VideoCodec codec(format); - if (external_encoder_factory_ != nullptr && - FindMatchingCodec(external_encoder_factory_->supported_codecs(), - codec)) { - // Format is supported by the external factory. - const webrtc::VideoCodecType codec_type = - webrtc::PayloadStringToCodecType(codec.name); - webrtc::VideoEncoderFactory::CodecInfo info; - info.has_internal_source = - external_encoder_factory_->EncoderTypeHasInternalSource(codec_type); - info.is_hardware_accelerated = true; - return info; + const webrtc::SdpVideoFormat& format) const override { + if (IsFormatSupported(external_encoder_factory_->GetSupportedFormats(), + format)) { + return external_encoder_factory_->QueryVideoEncoder(format); } // Format must be one of the internal formats. - RTC_DCHECK(FindMatchingCodec(internal_encoder_factory_->supported_codecs(), - codec)); + RTC_DCHECK(IsFormatSupported( + internal_encoder_factory_->GetSupportedFormats(), format)); webrtc::VideoEncoderFactory::CodecInfo info; info.has_internal_source = false; info.is_hardware_accelerated = false; @@ -94,31 +132,27 @@ class EncoderAdapter : public webrtc::VideoEncoderFactory { } std::unique_ptr CreateVideoEncoder( - const webrtc::SdpVideoFormat& format) { - const VideoCodec codec(format); - + const webrtc::SdpVideoFormat& format) override { // Try creating internal encoder. std::unique_ptr internal_encoder; - if (FindMatchingCodec(internal_encoder_factory_->supported_codecs(), - codec)) { + if (IsFormatSupported(internal_encoder_factory_->GetSupportedFormats(), + format)) { internal_encoder = CodecNamesEq(format.name.c_str(), kVp8CodecName) ? rtc::MakeUnique( internal_encoder_factory_.get()) - : std::unique_ptr( - internal_encoder_factory_->CreateVideoEncoder(codec)); + : internal_encoder_factory_->CreateVideoEncoder(format); } // Try creating external encoder. std::unique_ptr external_encoder; - if (external_encoder_factory_ != nullptr && - FindMatchingCodec(external_encoder_factory_->supported_codecs(), - codec)) { - external_encoder = CodecNamesEq(format.name.c_str(), kVp8CodecName) - ? rtc::MakeUnique( - external_encoder_factory_.get()) - : CreateScopedVideoEncoder( - external_encoder_factory_.get(), codec); + if (IsFormatSupported(external_encoder_factory_->GetSupportedFormats(), + format)) { + external_encoder = + CodecNamesEq(format.name.c_str(), kVp8CodecName) + ? rtc::MakeUnique( + external_encoder_factory_.get()) + : external_encoder_factory_->CreateVideoEncoder(format); } if (internal_encoder && external_encoder) { @@ -131,34 +165,28 @@ class EncoderAdapter : public webrtc::VideoEncoderFactory { : std::move(internal_encoder); } - std::vector GetSupportedFormats() const { - std::vector codecs = - InternalEncoderFactory().supported_codecs(); + std::vector GetSupportedFormats() const override { + std::vector formats = + internal_encoder_factory_->GetSupportedFormats(); // Add external codecs. - if (external_encoder_factory_ != nullptr) { - const std::vector& external_codecs = - external_encoder_factory_->supported_codecs(); - for (const VideoCodec& codec : external_codecs) { - // Don't add same codec twice. - if (!FindMatchingCodec(codecs, codec)) - codecs.push_back(codec); - } - } - - std::vector formats; - for (const VideoCodec& codec : codecs) { - formats.push_back(webrtc::SdpVideoFormat(codec.name, codec.params)); + for (const webrtc::SdpVideoFormat& format : + external_encoder_factory_->GetSupportedFormats()) { + // Don't add same codec twice. + if (!IsFormatSupported(formats, format)) + formats.push_back(format); } return formats; } private: - const std::unique_ptr internal_encoder_factory_; - const std::unique_ptr external_encoder_factory_; + const std::unique_ptr internal_encoder_factory_; + const std::unique_ptr external_encoder_factory_; }; +// This class combines an external factory with the internal factory and adds +// internal SW codecs, simulcast, and SW fallback wrappers. class DecoderAdapter : public webrtc::VideoDecoderFactory { public: explicit DecoderAdapter( diff --git a/media/engine/internalencoderfactory.cc b/media/engine/internalencoderfactory.cc index fa6783f64a..c2d4d5eb04 100644 --- a/media/engine/internalencoderfactory.cc +++ b/media/engine/internalencoderfactory.cc @@ -15,9 +15,10 @@ #include "modules/video_coding/codecs/h264/include/h264.h" #include "modules/video_coding/codecs/vp8/include/vp8.h" #include "modules/video_coding/codecs/vp9/include/vp9.h" +#include "rtc_base/logging.h" #include "system_wrappers/include/field_trial.h" -namespace cricket { +namespace webrtc { namespace { @@ -33,55 +34,55 @@ bool IsFlexfecAdvertisedFieldTrialEnabled() { } // namespace -InternalEncoderFactory::InternalEncoderFactory() { - supported_codecs_.push_back(VideoCodec(kVp8CodecName)); +std::vector InternalEncoderFactory::GetSupportedFormats() + const { + std::vector supported_codecs; + supported_codecs.push_back(SdpVideoFormat(cricket::kVp8CodecName)); if (webrtc::VP9Encoder::IsSupported()) - supported_codecs_.push_back(VideoCodec(kVp9CodecName)); + supported_codecs.push_back(SdpVideoFormat(cricket::kVp9CodecName)); for (const webrtc::SdpVideoFormat& format : webrtc::SupportedH264Codecs()) - supported_codecs_.push_back(VideoCodec(format)); + supported_codecs.push_back(format); - supported_codecs_.push_back(VideoCodec(kRedCodecName)); - supported_codecs_.push_back(VideoCodec(kUlpfecCodecName)); + supported_codecs.push_back(SdpVideoFormat(cricket::kRedCodecName)); + supported_codecs.push_back(SdpVideoFormat(cricket::kUlpfecCodecName)); if (IsFlexfecAdvertisedFieldTrialEnabled()) { - VideoCodec flexfec_codec(kFlexfecCodecName); // This value is currently arbitrarily set to 10 seconds. (The unit // is microseconds.) This parameter MUST be present in the SDP, but // we never use the actual value anywhere in our code however. // TODO(brandtr): Consider honouring this value in the sender and receiver. - flexfec_codec.SetParam(kFlexfecFmtpRepairWindow, "10000000"); - supported_codecs_.push_back(flexfec_codec); + SdpVideoFormat::Parameters params = { + {cricket::kFlexfecFmtpRepairWindow, "10000000"}}; + supported_codecs.push_back( + SdpVideoFormat(cricket::kFlexfecCodecName, params)); } + + return supported_codecs; } -InternalEncoderFactory::~InternalEncoderFactory() {} - -// WebRtcVideoEncoderFactory implementation. -webrtc::VideoEncoder* InternalEncoderFactory::CreateVideoEncoder( - const VideoCodec& codec) { - const webrtc::VideoCodecType codec_type = - webrtc::PayloadStringToCodecType(codec.name); - switch (codec_type) { - case webrtc::kVideoCodecH264: - return webrtc::H264Encoder::Create(codec).release(); - case webrtc::kVideoCodecVP8: - return webrtc::VP8Encoder::Create().release(); - case webrtc::kVideoCodecVP9: - return webrtc::VP9Encoder::Create().release(); - default: - return nullptr; - } +VideoEncoderFactory::CodecInfo InternalEncoderFactory::QueryVideoEncoder( + const SdpVideoFormat& format) const { + CodecInfo info; + info.is_hardware_accelerated = false; + info.has_internal_source = false; + return info; } -const std::vector& -InternalEncoderFactory::supported_codecs() const { - return supported_codecs_; +std::unique_ptr InternalEncoderFactory::CreateVideoEncoder( + const SdpVideoFormat& format) { + if (cricket::CodecNamesEq(format.name, cricket::kVp8CodecName)) + return VP8Encoder::Create(); + + if (cricket::CodecNamesEq(format.name, cricket::kVp9CodecName)) + return VP9Encoder::Create(); + + if (cricket::CodecNamesEq(format.name, cricket::kH264CodecName)) + return H264Encoder::Create(cricket::VideoCodec(format)); + + RTC_LOG(LS_ERROR) << "Trying to created encoder of unsupported format " + << format.name; + return nullptr; } -void InternalEncoderFactory::DestroyVideoEncoder( - webrtc::VideoEncoder* encoder) { - delete encoder; -} - -} // namespace cricket +} // namespace webrtc diff --git a/media/engine/internalencoderfactory.h b/media/engine/internalencoderfactory.h index b64d90450d..28ed3fc9a5 100644 --- a/media/engine/internalencoderfactory.h +++ b/media/engine/internalencoderfactory.h @@ -11,27 +11,23 @@ #ifndef MEDIA_ENGINE_INTERNALENCODERFACTORY_H_ #define MEDIA_ENGINE_INTERNALENCODERFACTORY_H_ +#include #include -#include "media/engine/webrtcvideoencoderfactory.h" +#include "api/video_codecs/video_encoder_factory.h" -namespace cricket { +namespace webrtc { -class InternalEncoderFactory : public WebRtcVideoEncoderFactory { +class InternalEncoderFactory : public VideoEncoderFactory { public: - InternalEncoderFactory(); - virtual ~InternalEncoderFactory(); + std::vector GetSupportedFormats() const override; - // WebRtcVideoEncoderFactory implementation. - webrtc::VideoEncoder* CreateVideoEncoder( - const cricket::VideoCodec& codec) override; - const std::vector& supported_codecs() const override; - void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) override; + CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override; - private: - std::vector supported_codecs_; + std::unique_ptr CreateVideoEncoder( + const SdpVideoFormat& format) override; }; -} // namespace cricket +} // namespace webrtc #endif // MEDIA_ENGINE_INTERNALENCODERFACTORY_H_ diff --git a/media/engine/simulcast_encoder_adapter.cc b/media/engine/simulcast_encoder_adapter.cc index 808bc0fc15..3a285b8eb1 100644 --- a/media/engine/simulcast_encoder_adapter.cc +++ b/media/engine/simulcast_encoder_adapter.cc @@ -16,6 +16,7 @@ #include "libyuv/scale.h" // NOLINT #include "api/video/i420_buffer.h" +#include "api/video_codecs/video_encoder_factory.h" #include "media/engine/scopedvideoencoder.h" #include "modules/video_coding/codecs/vp8/screenshare_layers.h" #include "modules/video_coding/codecs/vp8/simulcast_rate_allocator.h" @@ -134,10 +135,24 @@ class TemporalLayersFactoryAdapter : public webrtc::TemporalLayersFactory { namespace webrtc { +SimulcastEncoderAdapter::SimulcastEncoderAdapter(VideoEncoderFactory* factory) + : inited_(0), + factory_(factory), + cricket_factory_(nullptr), + encoded_complete_callback_(nullptr), + implementation_name_("SimulcastEncoderAdapter") { + // The adapter is typically created on the worker thread, but operated on + // the encoder task queue. + encoder_queue_.Detach(); + + memset(&codec_, 0, sizeof(webrtc::VideoCodec)); +} + SimulcastEncoderAdapter::SimulcastEncoderAdapter( cricket::WebRtcVideoEncoderFactory* factory) : inited_(0), - factory_(factory), + factory_(nullptr), + cricket_factory_(factory), encoded_complete_callback_(nullptr), implementation_name_("SimulcastEncoderAdapter") { // The adapter is typically created on the worker thread, but operated on @@ -246,7 +261,9 @@ int SimulcastEncoderAdapter::InitEncode(const VideoCodec* inst, encoder = std::move(stored_encoders_.top()); stored_encoders_.pop(); } else { - encoder = CreateScopedVideoEncoder(factory_, cricket::VideoCodec("VP8")); + encoder = factory_ ? factory_->CreateVideoEncoder(SdpVideoFormat("VP8")) + : CreateScopedVideoEncoder(cricket_factory_, + cricket::VideoCodec("VP8")); } ret = encoder->InitEncode(&stream_codec, number_of_cores, max_payload_size); diff --git a/media/engine/simulcast_encoder_adapter.h b/media/engine/simulcast_encoder_adapter.h index 8833908ad2..9650cd39a8 100644 --- a/media/engine/simulcast_encoder_adapter.h +++ b/media/engine/simulcast_encoder_adapter.h @@ -26,6 +26,7 @@ namespace webrtc { class SimulcastRateAllocator; +class VideoEncoderFactory; // SimulcastEncoderAdapter implements simulcast support by creating multiple // webrtc::VideoEncoder instances with the given VideoEncoderFactory. @@ -33,6 +34,8 @@ class SimulcastRateAllocator; // interfaces should be called from the encoder task queue. class SimulcastEncoderAdapter : public VP8Encoder { public: + explicit SimulcastEncoderAdapter(VideoEncoderFactory* factory); + // Deprecated - use webrtc::VideoEncoderFactory instead. explicit SimulcastEncoderAdapter(cricket::WebRtcVideoEncoderFactory* factory); virtual ~SimulcastEncoderAdapter(); @@ -96,7 +99,8 @@ class SimulcastEncoderAdapter : public VP8Encoder { void DestroyStoredEncoders(); volatile int inited_; // Accessed atomically. - cricket::WebRtcVideoEncoderFactory* const factory_; + VideoEncoderFactory* const factory_; + cricket::WebRtcVideoEncoderFactory* const cricket_factory_; VideoCodec codec_; std::vector streaminfos_; EncodedImageCallback* encoded_complete_callback_; diff --git a/media/engine/simulcast_encoder_adapter_unittest.cc b/media/engine/simulcast_encoder_adapter_unittest.cc index a87daf574b..8087d7be0b 100644 --- a/media/engine/simulcast_encoder_adapter_unittest.cc +++ b/media/engine/simulcast_encoder_adapter_unittest.cc @@ -12,6 +12,8 @@ #include #include +#include "api/video_codecs/sdp_video_format.h" +#include "api/video_codecs/video_encoder_factory.h" #include "common_video/include/video_frame_buffer.h" #include "media/engine/internalencoderfactory.h" #include "media/engine/simulcast_encoder_adapter.h" @@ -25,8 +27,7 @@ namespace testing { class TestSimulcastEncoderAdapter : public TestVp8Simulcast { public: - TestSimulcastEncoderAdapter() - : factory_(new cricket::InternalEncoderFactory()) {} + TestSimulcastEncoderAdapter() : factory_(new InternalEncoderFactory()) {} protected: std::unique_ptr CreateEncoder() override { @@ -37,7 +38,7 @@ class TestSimulcastEncoderAdapter : public TestVp8Simulcast { } private: - std::unique_ptr factory_; + std::unique_ptr factory_; }; TEST_F(TestSimulcastEncoderAdapter, TestKeyFrameRequestsOnAllStreams) { @@ -92,8 +93,34 @@ TEST_F(TestSimulcastEncoderAdapter, TestSpatioTemporalLayers321PatternEncoder) { TestVp8Simulcast::TestSpatioTemporalLayers321PatternEncoder(); } +class MockVideoEncoder; + +class MockVideoEncoderFactory : public VideoEncoderFactory { + public: + std::vector GetSupportedFormats() const override; + + std::unique_ptr CreateVideoEncoder( + const SdpVideoFormat& format) override; + + CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override; + + const std::vector& encoders() const; + void SetEncoderNames(const std::vector& encoder_names); + void set_init_encode_return_value(int32_t value); + + void DestroyVideoEncoder(VideoEncoder* encoder); + + private: + int32_t init_encode_return_value_ = 0; + std::vector encoders_; + std::vector encoder_names_; +}; + class MockVideoEncoder : public VideoEncoder { public: + explicit MockVideoEncoder(MockVideoEncoderFactory* factory) + : factory_(factory) {} + // TODO(nisse): Valid overrides commented out, because the gmock // methods don't use any override declarations, and we want to avoid // warnings from -Winconsistent-missing-override. See @@ -131,7 +158,7 @@ class MockVideoEncoder : public VideoEncoder { return supports_native_handle_; } - virtual ~MockVideoEncoder() {} + virtual ~MockVideoEncoder() { factory_->DestroyVideoEncoder(this); } const VideoCodec& codec() const { return codec_; } @@ -158,6 +185,7 @@ class MockVideoEncoder : public VideoEncoder { MOCK_CONST_METHOD0(ImplementationName, const char*()); private: + MockVideoEncoderFactory* const factory_; bool supports_native_handle_ = false; int32_t init_encode_return_value_ = 0; BitrateAllocation last_set_bitrate_; @@ -166,53 +194,50 @@ class MockVideoEncoder : public VideoEncoder { EncodedImageCallback* callback_; }; -class MockVideoEncoderFactory : public cricket::WebRtcVideoEncoderFactory { - public: - MockVideoEncoderFactory() { - supported_codecs_.push_back(cricket::VideoCodec("VP8")); - } +std::vector MockVideoEncoderFactory::GetSupportedFormats() + const { + std::vector formats = {SdpVideoFormat("VP8")}; + return formats; +} - const std::vector& supported_codecs() const override { - return supported_codecs_; - } +std::unique_ptr MockVideoEncoderFactory::CreateVideoEncoder( + const SdpVideoFormat& format) { + std::unique_ptr encoder( + new ::testing::NiceMock(this)); + encoder->set_init_encode_return_value(init_encode_return_value_); + const char* encoder_name = encoder_names_.empty() + ? "codec_implementation_name" + : encoder_names_[encoders_.size()]; + ON_CALL(*encoder, ImplementationName()).WillByDefault(Return(encoder_name)); + encoders_.push_back(encoder.get()); + return encoder; +} - VideoEncoder* CreateVideoEncoder(const cricket::VideoCodec& codec) override { - MockVideoEncoder* encoder = new ::testing::NiceMock(); - encoder->set_init_encode_return_value(init_encode_return_value_); - const char* encoder_name = encoder_names_.empty() - ? "codec_implementation_name" - : encoder_names_[encoders_.size()]; - ON_CALL(*encoder, ImplementationName()).WillByDefault(Return(encoder_name)); - encoders_.push_back(encoder); - return encoder; - } - - void DestroyVideoEncoder(VideoEncoder* encoder) override { - for (size_t i = 0; i < encoders_.size(); ++i) { - if (encoders_[i] == encoder) { - encoders_.erase(encoders_.begin() + i); - break; - } +void MockVideoEncoderFactory::DestroyVideoEncoder(VideoEncoder* encoder) { + for (size_t i = 0; i < encoders_.size(); ++i) { + if (encoders_[i] == encoder) { + encoders_.erase(encoders_.begin() + i); + break; } - delete encoder; } +} - virtual ~MockVideoEncoderFactory() {} +VideoEncoderFactory::CodecInfo MockVideoEncoderFactory::QueryVideoEncoder( + const SdpVideoFormat& format) const { + return CodecInfo(); +} - const std::vector& encoders() const { return encoders_; } - void SetEncoderNames(const std::vector& encoder_names) { - encoder_names_ = encoder_names; - } - void set_init_encode_return_value(int32_t value) { - init_encode_return_value_ = value; - } - - private: - std::vector supported_codecs_; - int32_t init_encode_return_value_ = 0; - std::vector encoders_; - std::vector encoder_names_; -}; +const std::vector& MockVideoEncoderFactory::encoders() + const { + return encoders_; +} +void MockVideoEncoderFactory::SetEncoderNames( + const std::vector& encoder_names) { + encoder_names_ = encoder_names; +} +void MockVideoEncoderFactory::set_init_encode_return_value(int32_t value) { + init_encode_return_value_ = value; +} class TestSimulcastEncoderAdapterFakeHelper { public: diff --git a/media/engine/vp8_encoder_simulcast_proxy.cc b/media/engine/vp8_encoder_simulcast_proxy.cc index 85e37bf08c..b97e74e5ef 100644 --- a/media/engine/vp8_encoder_simulcast_proxy.cc +++ b/media/engine/vp8_encoder_simulcast_proxy.cc @@ -15,10 +15,9 @@ #include "rtc_base/checks.h" namespace webrtc { -VP8EncoderSimulcastProxy::VP8EncoderSimulcastProxy( - cricket::WebRtcVideoEncoderFactory* factory) +VP8EncoderSimulcastProxy::VP8EncoderSimulcastProxy(VideoEncoderFactory* factory) : factory_(factory), callback_(nullptr) { - encoder_ = CreateScopedVideoEncoder(factory_, cricket::VideoCodec("VP8")); + encoder_ = factory_->CreateVideoEncoder(SdpVideoFormat("VP8")); } VP8EncoderSimulcastProxy::~VP8EncoderSimulcastProxy() {} diff --git a/media/engine/vp8_encoder_simulcast_proxy.h b/media/engine/vp8_encoder_simulcast_proxy.h index 46ccae42a4..5833124c50 100644 --- a/media/engine/vp8_encoder_simulcast_proxy.h +++ b/media/engine/vp8_encoder_simulcast_proxy.h @@ -15,7 +15,7 @@ #include #include -#include "media/engine/webrtcvideoencoderfactory.h" +#include "api/video_codecs/video_encoder_factory.h" #include "modules/video_coding/codecs/vp8/include/vp8.h" namespace webrtc { @@ -24,8 +24,7 @@ namespace webrtc { // doesn't support simulcast for provided settings. class VP8EncoderSimulcastProxy : public VP8Encoder { public: - explicit VP8EncoderSimulcastProxy( - cricket::WebRtcVideoEncoderFactory* factory); + explicit VP8EncoderSimulcastProxy(VideoEncoderFactory* factory); virtual ~VP8EncoderSimulcastProxy(); // Implements VideoEncoder. @@ -48,7 +47,7 @@ class VP8EncoderSimulcastProxy : public VP8Encoder { const char* ImplementationName() const override; private: - cricket::WebRtcVideoEncoderFactory* const factory_; + VideoEncoderFactory* const factory_; std::unique_ptr encoder_; EncodedImageCallback* callback_; }; diff --git a/media/engine/vp8_encoder_simulcast_proxy_unittest.cc b/media/engine/vp8_encoder_simulcast_proxy_unittest.cc index 0b26bb8545..3e2761cfb6 100644 --- a/media/engine/vp8_encoder_simulcast_proxy_unittest.cc +++ b/media/engine/vp8_encoder_simulcast_proxy_unittest.cc @@ -13,6 +13,7 @@ #include +#include "api/test/mock_video_encoder_factory.h" #include "media/engine/webrtcvideoencoderfactory.h" #include "modules/video_coding/codecs/vp8/temporal_layers.h" #include "modules/video_coding/include/video_codec_interface.h" @@ -56,20 +57,6 @@ class MockEncoder : public VideoEncoder { MOCK_CONST_METHOD0(ImplementationName, const char*()); }; -class MockWebRtcVideoEncoderFactory - : public cricket::WebRtcVideoEncoderFactory { - public: - MockWebRtcVideoEncoderFactory() {} - virtual ~MockWebRtcVideoEncoderFactory() {} - - MOCK_METHOD1(CreateVideoEncoder, - webrtc::VideoEncoder*(const cricket::VideoCodec& codec)); - - MOCK_CONST_METHOD0(supported_codecs, std::vector&()); - - MOCK_METHOD1(DestroyVideoEncoder, void(webrtc::VideoEncoder*)); -}; - TEST(VP8EncoderSimulcastProxy, ChoosesCorrectImplementation) { const std::string kImplementationName = "Fake"; const std::string kSimulcastAdaptedImplementationName = @@ -86,56 +73,56 @@ TEST(VP8EncoderSimulcastProxy, ChoosesCorrectImplementation) { test::kTestWidth, test::kTestHeight, 2, 5000, 1000, 1000, 56}; codec_settings.numberOfSimulcastStreams = 3; - NiceMock mock_encoder; - NiceMock simulcast_factory; + NiceMock* mock_encoder = new NiceMock(); + NiceMock simulcast_factory; - EXPECT_CALL(mock_encoder, InitEncode(_, _, _)) + EXPECT_CALL(*mock_encoder, InitEncode(_, _, _)) .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK)); - EXPECT_CALL(mock_encoder, ImplementationName()) + EXPECT_CALL(*mock_encoder, ImplementationName()) .WillRepeatedly(Return(kImplementationName.c_str())); - EXPECT_CALL(simulcast_factory, CreateVideoEncoder(_)) + EXPECT_CALL(simulcast_factory, CreateVideoEncoderProxy(_)) .Times(1) - .WillOnce(Return(&mock_encoder)); + .WillOnce(Return(mock_encoder)); VP8EncoderSimulcastProxy simulcast_enabled_proxy(&simulcast_factory); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, simulcast_enabled_proxy.InitEncode(&codec_settings, 4, 1200)); EXPECT_EQ(kImplementationName, simulcast_enabled_proxy.ImplementationName()); - NiceMock mock_encoder1; - NiceMock mock_encoder2; - NiceMock mock_encoder3; - NiceMock mock_encoder4; - NiceMock nonsimulcast_factory; + NiceMock* mock_encoder1 = new NiceMock(); + NiceMock* mock_encoder2 = new NiceMock(); + NiceMock* mock_encoder3 = new NiceMock(); + NiceMock* mock_encoder4 = new NiceMock(); + NiceMock nonsimulcast_factory; - EXPECT_CALL(mock_encoder1, InitEncode(_, _, _)) + EXPECT_CALL(*mock_encoder1, InitEncode(_, _, _)) .WillOnce( Return(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED)); - EXPECT_CALL(mock_encoder1, ImplementationName()) + EXPECT_CALL(*mock_encoder1, ImplementationName()) .WillRepeatedly(Return(kImplementationName.c_str())); - EXPECT_CALL(mock_encoder2, InitEncode(_, _, _)) + EXPECT_CALL(*mock_encoder2, InitEncode(_, _, _)) .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK)); - EXPECT_CALL(mock_encoder2, ImplementationName()) + EXPECT_CALL(*mock_encoder2, ImplementationName()) .WillRepeatedly(Return(kImplementationName.c_str())); - EXPECT_CALL(mock_encoder3, InitEncode(_, _, _)) + EXPECT_CALL(*mock_encoder3, InitEncode(_, _, _)) .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK)); - EXPECT_CALL(mock_encoder3, ImplementationName()) + EXPECT_CALL(*mock_encoder3, ImplementationName()) .WillRepeatedly(Return(kImplementationName.c_str())); - EXPECT_CALL(mock_encoder4, InitEncode(_, _, _)) + EXPECT_CALL(*mock_encoder4, InitEncode(_, _, _)) .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK)); - EXPECT_CALL(mock_encoder4, ImplementationName()) + EXPECT_CALL(*mock_encoder4, ImplementationName()) .WillRepeatedly(Return(kImplementationName.c_str())); - EXPECT_CALL(nonsimulcast_factory, CreateVideoEncoder(_)) + EXPECT_CALL(nonsimulcast_factory, CreateVideoEncoderProxy(_)) .Times(4) - .WillOnce(Return(&mock_encoder1)) - .WillOnce(Return(&mock_encoder2)) - .WillOnce(Return(&mock_encoder3)) - .WillOnce(Return(&mock_encoder4)); + .WillOnce(Return(mock_encoder1)) + .WillOnce(Return(mock_encoder2)) + .WillOnce(Return(mock_encoder3)) + .WillOnce(Return(mock_encoder4)); VP8EncoderSimulcastProxy simulcast_disabled_proxy(&nonsimulcast_factory); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, diff --git a/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc b/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc index dc77605201..4694f2d8f4 100644 --- a/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc +++ b/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc @@ -80,6 +80,40 @@ bool RunEncodeInRealTime(const TestConfig& config) { #endif } +// An internal encoder factory in the old WebRtcVideoEncoderFactory format. +// TODO(magjed): Update these tests to use new webrtc::VideoEncoderFactory +// instead. +class LegacyInternalEncoderFactory : public cricket::WebRtcVideoEncoderFactory { + public: + LegacyInternalEncoderFactory() { + for (const SdpVideoFormat& format : + InternalEncoderFactory().GetSupportedFormats()) { + supported_codecs_.push_back(cricket::VideoCodec(format)); + } + } + + // WebRtcVideoEncoderFactory implementation. + VideoEncoder* CreateVideoEncoder(const cricket::VideoCodec& codec) override { + return InternalEncoderFactory() + .CreateVideoEncoder(SdpVideoFormat(codec.name, codec.params)) + .release(); + } + + const std::vector& supported_codecs() const override { + return supported_codecs_; + } + + bool EncoderTypeHasInternalSource( + webrtc::VideoCodecType type) const override { + return false; + } + + void DestroyVideoEncoder(VideoEncoder* encoder) override { delete encoder; } + + private: + std::vector supported_codecs_; +}; + // An internal decoder factory in the old WebRtcVideoDecoderFactory format. // TODO(magjed): Update these tests to use new webrtc::VideoDecoderFactory // instead. @@ -313,7 +347,7 @@ void VideoProcessorIntegrationTest::CreateEncoderAndDecoder() { RTC_NOTREACHED() << "Only support HW encoder on Android and iOS."; #endif } else { - encoder_factory.reset(new cricket::InternalEncoderFactory()); + encoder_factory.reset(new LegacyInternalEncoderFactory()); } std::unique_ptr decoder_factory; @@ -382,8 +416,8 @@ void VideoProcessorIntegrationTest::CreateEncoderAndDecoder() { if (config_.sw_fallback_encoder) { encoder_ = rtc::MakeUnique( - std::unique_ptr( - cricket::InternalEncoderFactory().CreateVideoEncoder(codec)), + InternalEncoderFactory().CreateVideoEncoder( + SdpVideoFormat(codec.name, codec.params)), std::move(encoder_)); } if (config_.sw_fallback_decoder) { diff --git a/sdk/android/src/jni/androidmediaencoder_jni.cc b/sdk/android/src/jni/androidmediaencoder_jni.cc index 1b8c4d987c..9b804c6432 100644 --- a/sdk/android/src/jni/androidmediaencoder_jni.cc +++ b/sdk/android/src/jni/androidmediaencoder_jni.cc @@ -516,11 +516,21 @@ bool MediaCodecVideoEncoder::EncodeTask::Run() { return false; } +bool IsFormatSupported( + const std::vector& supported_formats, + const std::string& name) { + for (const webrtc::SdpVideoFormat& supported_format : supported_formats) { + if (cricket::CodecNamesEq(name, supported_format.name)) + return true; + } + return false; +} + bool MediaCodecVideoEncoder::ProcessHWError( bool reset_if_fallback_unavailable) { ALOGE << "ProcessHWError"; - if (FindMatchingCodec(cricket::InternalEncoderFactory().supported_codecs(), - codec_)) { + if (IsFormatSupported(InternalEncoderFactory().GetSupportedFormats(), + codec_.name)) { ALOGE << "Fallback to SW encoder."; sw_fallback_required_ = true; return false; diff --git a/video/picture_id_tests.cc b/video/picture_id_tests.cc index cfe4332bb7..f1545d80e3 100644 --- a/video/picture_id_tests.cc +++ b/video/picture_id_tests.cc @@ -346,7 +346,7 @@ TEST_P(PictureIdTest, PictureIdIncreasingAfterStreamCountChangeVp8) { TEST_P(PictureIdTest, PictureIdContinuousAfterReconfigureSimulcastEncoderAdapter) { - cricket::InternalEncoderFactory internal_encoder_factory; + InternalEncoderFactory internal_encoder_factory; SimulcastEncoderAdapter simulcast_encoder_adapter(&internal_encoder_factory); SetupEncoder(&simulcast_encoder_adapter); TestPictureIdContinuousAfterReconfigure({1, 3, 3, 1, 1}); @@ -354,7 +354,7 @@ TEST_P(PictureIdTest, TEST_P(PictureIdTest, PictureIdIncreasingAfterRecreateStreamSimulcastEncoderAdapter) { - cricket::InternalEncoderFactory internal_encoder_factory; + InternalEncoderFactory internal_encoder_factory; SimulcastEncoderAdapter simulcast_encoder_adapter(&internal_encoder_factory); SetupEncoder(&simulcast_encoder_adapter); TestPictureIdIncreaseAfterRecreateStreams({1, 3, 3, 1, 1}); @@ -368,7 +368,7 @@ TEST_P(PictureIdTest, // If forced fallback is enabled, the picture id is set in the PayloadRouter // and the sequence should be continuous. if (GetParam() == kVp8ForcedFallbackEncoderEnabled) { - cricket::InternalEncoderFactory internal_encoder_factory; + InternalEncoderFactory internal_encoder_factory; SimulcastEncoderAdapter simulcast_encoder_adapter( &internal_encoder_factory); // Make sure that that the picture id is not reset if the stream count goes diff --git a/video/video_quality_test.cc b/video/video_quality_test.cc index 7cb7fd19c0..198b73ced7 100644 --- a/video/video_quality_test.cc +++ b/video/video_quality_test.cc @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -1393,7 +1392,7 @@ void VideoQualityTest::SetupVideo(Transport* send_transport, // encoders usually can't natively do simulcast with different frame rates // for the different layers. video_encoder_.reset( - new SimulcastEncoderAdapter(new cricket::InternalEncoderFactory())); + new SimulcastEncoderAdapter(new InternalEncoderFactory())); } else { video_encoder_ = VP8Encoder::Create(); } diff --git a/video/video_quality_test.h b/video/video_quality_test.h index ddf4ecc5a4..b7ba74dca6 100644 --- a/video/video_quality_test.h +++ b/video/video_quality_test.h @@ -145,7 +145,6 @@ class VideoQualityTest : public test::CallTest { std::vector> thumbnail_capturers_; std::unique_ptr frame_generator_; std::unique_ptr video_encoder_; - std::unique_ptr vp8_encoder_factory_; std::vector> thumbnail_encoders_; std::vector thumbnail_send_configs_;