From 18314bd8d2cb27fa58e4d304bbc428e3ed1736ba Mon Sep 17 00:00:00 2001 From: Johannes Kron Date: Mon, 9 Dec 2019 11:53:08 +0100 Subject: [PATCH] Distinguish between send and receive video codecs Even though send and receive codecs are the same, they might have different support in HW. Distinguish between send and receive codecs to be able to keep track of which codecs have HW support. Bug: chromium:1029737 Change-Id: I16a80da44c5061ca42f2aabda76e6bf0b879bf7b Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/161306 Reviewed-by: Anders Carlsson Reviewed-by: Steve Anton Commit-Queue: Johannes Kron Cr-Commit-Position: refs/heads/master@{#30041} --- .../video/function_video_decoder_factory.h | 10 +- media/base/fake_media_engine.cc | 24 ++- media/base/fake_media_engine.h | 9 +- media/base/media_engine.h | 4 +- media/engine/fake_webrtc_video_engine.cc | 8 + media/engine/fake_webrtc_video_engine.h | 1 + media/engine/null_webrtc_video_engine.h | 6 +- media/engine/webrtc_video_engine.cc | 23 +-- media/engine/webrtc_video_engine.h | 3 +- media/engine/webrtc_video_engine_unittest.cc | 155 ++++++++++-------- pc/channel_manager.cc | 4 +- pc/peer_connection_media_unittest.cc | 8 +- .../RTCDefaultVideoDecoderFactory.m | 45 +++-- 13 files changed, 191 insertions(+), 109 deletions(-) diff --git a/api/test/video/function_video_decoder_factory.h b/api/test/video/function_video_decoder_factory.h index 03a4323997..23214ccf40 100644 --- a/api/test/video/function_video_decoder_factory.h +++ b/api/test/video/function_video_decoder_factory.h @@ -33,11 +33,14 @@ class FunctionVideoDecoderFactory final : public VideoDecoderFactory { std::function(const SdpVideoFormat&)> create) : create_(std::move(create)) {} + FunctionVideoDecoderFactory( + std::function()> create, + std::vector sdp_video_formats) + : create_([create](const SdpVideoFormat&) { return create(); }), + sdp_video_formats_(sdp_video_formats) {} - // Unused by tests. std::vector GetSupportedFormats() const override { - RTC_NOTREACHED(); - return {}; + return sdp_video_formats_; } std::unique_ptr CreateVideoDecoder( @@ -48,6 +51,7 @@ class FunctionVideoDecoderFactory final : public VideoDecoderFactory { private: const std::function(const SdpVideoFormat&)> create_; + const std::vector sdp_video_formats_; }; } // namespace test diff --git a/media/base/fake_media_engine.cc b/media/base/fake_media_engine.cc index c31ef97786..f194da2d85 100644 --- a/media/base/fake_media_engine.cc +++ b/media/base/fake_media_engine.cc @@ -567,7 +567,8 @@ FakeVideoEngine::FakeVideoEngine() : capture_(false), fail_create_channel_(false) { // Add a fake video codec. Note that the name must not be "" as there are // sanity checks against that. - codecs_.push_back(VideoCodec(0, "fake_video_codec")); + send_codecs_.push_back(VideoCodec(0, "fake_video_codec")); + recv_codecs_.push_back(VideoCodec(0, "fake_video_codec")); } RtpCapabilities FakeVideoEngine::GetCapabilities() const { return RtpCapabilities(); @@ -598,12 +599,22 @@ void FakeVideoEngine::UnregisterChannel(VideoMediaChannel* channel) { RTC_DCHECK(it != channels_.end()); channels_.erase(it); } -std::vector FakeVideoEngine::codecs() const { - return codecs_; +std::vector FakeVideoEngine::send_codecs() const { + return send_codecs_; } -void FakeVideoEngine::SetCodecs(const std::vector codecs) { - codecs_ = codecs; + +std::vector FakeVideoEngine::recv_codecs() const { + return recv_codecs_; } + +void FakeVideoEngine::SetSendCodecs(const std::vector codecs) { + send_codecs_ = codecs; +} + +void FakeVideoEngine::SetRecvCodecs(const std::vector codecs) { + recv_codecs_ = codecs; +} + bool FakeVideoEngine::SetCapture(bool capture) { capture_ = capture; return true; @@ -627,7 +638,8 @@ void FakeMediaEngine::SetAudioSendCodecs( voice_->SetSendCodecs(codecs); } void FakeMediaEngine::SetVideoCodecs(const std::vector& codecs) { - video_->SetCodecs(codecs); + video_->SetSendCodecs(codecs); + video_->SetRecvCodecs(codecs); } FakeVoiceMediaChannel* FakeMediaEngine::GetVoiceChannel(size_t index) { diff --git a/media/base/fake_media_engine.h b/media/base/fake_media_engine.h index 3df8f85965..7082132324 100644 --- a/media/base/fake_media_engine.h +++ b/media/base/fake_media_engine.h @@ -559,13 +559,16 @@ class FakeVideoEngine : public VideoEngineInterface { override; FakeVideoMediaChannel* GetChannel(size_t index); void UnregisterChannel(VideoMediaChannel* channel); - std::vector codecs() const override; - void SetCodecs(const std::vector codecs); + std::vector send_codecs() const override; + std::vector recv_codecs() const override; + void SetSendCodecs(const std::vector codecs); + void SetRecvCodecs(const std::vector codecs); bool SetCapture(bool capture); private: std::vector channels_; - std::vector codecs_; + std::vector send_codecs_; + std::vector recv_codecs_; bool capture_; VideoOptions options_; bool fail_create_channel_; diff --git a/media/base/media_engine.h b/media/base/media_engine.h index 173df50e34..841b2b6b0c 100644 --- a/media/base/media_engine.h +++ b/media/base/media_engine.h @@ -99,7 +99,9 @@ class VideoEngineInterface { webrtc::VideoBitrateAllocatorFactory* video_bitrate_allocator_factory) = 0; - virtual std::vector codecs() const = 0; + virtual std::vector send_codecs() const = 0; + virtual std::vector recv_codecs() const = 0; + virtual RtpCapabilities GetCapabilities() const = 0; }; diff --git a/media/engine/fake_webrtc_video_engine.cc b/media/engine/fake_webrtc_video_engine.cc index 0ee2bcc54f..ac02356156 100644 --- a/media/engine/fake_webrtc_video_engine.cc +++ b/media/engine/fake_webrtc_video_engine.cc @@ -117,6 +117,14 @@ void FakeWebRtcVideoDecoderFactory::AddSupportedVideoCodecType( supported_codec_formats_.push_back(format); } +void FakeWebRtcVideoDecoderFactory::AddSupportedVideoCodecType( + const std::string& name) { + // This is to match the default H264 params of cricket::VideoCodec. + cricket::VideoCodec video_codec(name); + supported_codec_formats_.push_back( + webrtc::SdpVideoFormat(video_codec.name, video_codec.params)); +} + int FakeWebRtcVideoDecoderFactory::GetNumCreatedDecoders() { return num_created_decoders_; } diff --git a/media/engine/fake_webrtc_video_engine.h b/media/engine/fake_webrtc_video_engine.h index 7b32ac86cf..51d7c665e4 100644 --- a/media/engine/fake_webrtc_video_engine.h +++ b/media/engine/fake_webrtc_video_engine.h @@ -68,6 +68,7 @@ class FakeWebRtcVideoDecoderFactory : public webrtc::VideoDecoderFactory { void DecoderDestroyed(FakeWebRtcVideoDecoder* decoder); void AddSupportedVideoCodecType(const webrtc::SdpVideoFormat& format); + void AddSupportedVideoCodecType(const std::string& name); int GetNumCreatedDecoders(); const std::vector& decoders(); diff --git a/media/engine/null_webrtc_video_engine.h b/media/engine/null_webrtc_video_engine.h index 590f0b0be7..5c31e21ef1 100644 --- a/media/engine/null_webrtc_video_engine.h +++ b/media/engine/null_webrtc_video_engine.h @@ -30,7 +30,11 @@ class VideoMediaChannel; // CompositeMediaEngine. class NullWebRtcVideoEngine : public VideoEngineInterface { public: - std::vector codecs() const override { + std::vector send_codecs() const override { + return std::vector(); + } + + std::vector recv_codecs() const override { return std::vector(); } diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc index e3ac88be1b..f7d942fa85 100644 --- a/media/engine/webrtc_video_engine.cc +++ b/media/engine/webrtc_video_engine.cc @@ -139,11 +139,11 @@ std::vector AssignPayloadTypesAndDefaultCodecs( return output_codecs; } -std::vector AssignPayloadTypesAndDefaultCodecs( - const webrtc::VideoEncoderFactory* encoder_factory) { - return encoder_factory ? AssignPayloadTypesAndDefaultCodecs( - encoder_factory->GetSupportedFormats()) - : std::vector(); +template +std::vector GetPayloadTypesAndDefaultCodecs(const T factory) { + return factory ? AssignPayloadTypesAndDefaultCodecs( + factory->GetSupportedFormats()) + : std::vector(); } bool IsTemporalLayersSupported(const std::string& codec_name) { @@ -476,8 +476,12 @@ VideoMediaChannel* WebRtcVideoEngine::CreateMediaChannel( encoder_factory_.get(), decoder_factory_.get(), video_bitrate_allocator_factory); } -std::vector WebRtcVideoEngine::codecs() const { - return AssignPayloadTypesAndDefaultCodecs(encoder_factory_.get()); +std::vector WebRtcVideoEngine::send_codecs() const { + return GetPayloadTypesAndDefaultCodecs(encoder_factory_.get()); +} + +std::vector WebRtcVideoEngine::recv_codecs() const { + return GetPayloadTypesAndDefaultCodecs(decoder_factory_.get()); } RtpCapabilities WebRtcVideoEngine::GetCapabilities() const { @@ -547,8 +551,7 @@ WebRtcVideoChannel::WebRtcVideoChannel( rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; sending_ = false; - recv_codecs_ = - MapCodecs(AssignPayloadTypesAndDefaultCodecs(encoder_factory_)); + recv_codecs_ = MapCodecs(GetPayloadTypesAndDefaultCodecs(decoder_factory_)); recv_flexfec_payload_type_ = recv_codecs_.front().flexfec_payload_type; } @@ -972,7 +975,7 @@ bool WebRtcVideoChannel::GetChangedRecvParameters( // Verify that every mapped codec is supported locally. const std::vector local_supported_codecs = - AssignPayloadTypesAndDefaultCodecs(encoder_factory_); + GetPayloadTypesAndDefaultCodecs(decoder_factory_); for (const VideoCodecSettings& mapped_codec : mapped_codecs) { if (!FindMatchingCodec(local_supported_codecs, mapped_codec.codec)) { RTC_LOG(LS_ERROR) diff --git a/media/engine/webrtc_video_engine.h b/media/engine/webrtc_video_engine.h index 3a0a156e2a..9b5e72db22 100644 --- a/media/engine/webrtc_video_engine.h +++ b/media/engine/webrtc_video_engine.h @@ -97,7 +97,8 @@ class WebRtcVideoEngine : public VideoEngineInterface { webrtc::VideoBitrateAllocatorFactory* video_bitrate_allocator_factory) override; - std::vector codecs() const override; + std::vector send_codecs() const override; + std::vector recv_codecs() const override; RtpCapabilities GetCapabilities() const override; private: diff --git a/media/engine/webrtc_video_engine_unittest.cc b/media/engine/webrtc_video_engine_unittest.cc index b3d36084cf..f2e61e4c7f 100644 --- a/media/engine/webrtc_video_engine_unittest.cc +++ b/media/engine/webrtc_video_engine_unittest.cc @@ -265,7 +265,7 @@ class WebRtcVideoEngineTest : public ::testing::Test { // Find the codec in the engine with the given name. The codec must be // present. cricket::VideoCodec GetEngineCodec(const std::string& name) const; - + void AddSupportedVideoCodecType(const std::string& name); VideoMediaChannel* SetSendParamsWithAllSupportedCodecs(); VideoMediaChannel* SetRecvParamsWithSupportedCodecs( @@ -296,7 +296,7 @@ TEST_F(WebRtcVideoEngineTest, DefaultRtxCodecHasAssociatedPayloadTypeSet) { encoder_factory_->AddSupportedVideoCodecType("VP8"); AssignDefaultCodec(); - std::vector engine_codecs = engine_.codecs(); + std::vector engine_codecs = engine_.send_codecs(); for (size_t i = 0; i < engine_codecs.size(); ++i) { if (engine_codecs[i].name != kRtxCodecName) continue; @@ -375,7 +375,7 @@ TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionBeforeCapturer) { // dtor is called. ::testing::NiceMock video_source; - encoder_factory_->AddSupportedVideoCodecType("VP8"); + AddSupportedVideoCodecType("VP8"); std::unique_ptr channel( SetSendParamsWithAllSupportedCodecs()); @@ -414,7 +414,7 @@ TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionBeforeAddSendStream) { // dtor is called. ::testing::NiceMock video_source; - encoder_factory_->AddSupportedVideoCodecType("VP8"); + AddSupportedVideoCodecType("VP8"); std::unique_ptr channel( SetSendParamsWithAllSupportedCodecs()); @@ -438,8 +438,8 @@ TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionBeforeAddSendStream) { TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionAfterCapturer) { ::testing::NiceMock video_source; - encoder_factory_->AddSupportedVideoCodecType("VP8"); - encoder_factory_->AddSupportedVideoCodecType("VP9"); + AddSupportedVideoCodecType("VP8"); + AddSupportedVideoCodecType("VP9"); std::unique_ptr channel( SetSendParamsWithAllSupportedCodecs()); @@ -483,7 +483,7 @@ TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionAfterCapturer) { } TEST_F(WebRtcVideoEngineTest, SetSendFailsBeforeSettingCodecs) { - encoder_factory_->AddSupportedVideoCodecType("VP8"); + AddSupportedVideoCodecType("VP8"); std::unique_ptr channel(engine_.CreateMediaChannel( call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(), @@ -498,7 +498,7 @@ TEST_F(WebRtcVideoEngineTest, SetSendFailsBeforeSettingCodecs) { } TEST_F(WebRtcVideoEngineTest, GetStatsWithoutSendCodecsSetDoesNotCrash) { - encoder_factory_->AddSupportedVideoCodecType("VP8"); + AddSupportedVideoCodecType("VP8"); std::unique_ptr channel(engine_.CreateMediaChannel( call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(), @@ -509,7 +509,7 @@ TEST_F(WebRtcVideoEngineTest, GetStatsWithoutSendCodecsSetDoesNotCrash) { } TEST_F(WebRtcVideoEngineTest, UseFactoryForVp8WhenSupported) { - encoder_factory_->AddSupportedVideoCodecType("VP8"); + AddSupportedVideoCodecType("VP8"); std::unique_ptr channel( SetSendParamsWithAllSupportedCodecs()); @@ -569,7 +569,7 @@ TEST_F(WebRtcVideoEngineTest, RtxCodecAddedForH264Codec) { encoder_factory_->AddSupportedVideoCodec(h264_high); // First figure out what payload types the test codecs got assigned. - const std::vector codecs = engine_.codecs(); + const std::vector codecs = engine_.send_codecs(); // Now search for RTX codecs for them. Expect that they all have associated // RTX codecs. EXPECT_TRUE(HasRtxCodec( @@ -586,7 +586,7 @@ TEST_F(WebRtcVideoEngineTest, RtxCodecAddedForH264Codec) { #if defined(RTC_ENABLE_VP9) TEST_F(WebRtcVideoEngineTest, CanConstructDecoderForVp9EncoderFactory) { - encoder_factory_->AddSupportedVideoCodecType("VP9"); + AddSupportedVideoCodecType("VP9"); std::unique_ptr channel( SetSendParamsWithAllSupportedCodecs()); @@ -597,7 +597,7 @@ TEST_F(WebRtcVideoEngineTest, CanConstructDecoderForVp9EncoderFactory) { #endif // defined(RTC_ENABLE_VP9) TEST_F(WebRtcVideoEngineTest, PropagatesInputFrameTimestamp) { - encoder_factory_->AddSupportedVideoCodecType("VP8"); + AddSupportedVideoCodecType("VP8"); FakeCall* fake_call = new FakeCall(); call_.reset(fake_call); std::unique_ptr channel( @@ -651,7 +651,7 @@ TEST_F(WebRtcVideoEngineTest, PropagatesInputFrameTimestamp) { } void WebRtcVideoEngineTest::AssignDefaultAptRtxTypes() { - std::vector engine_codecs = engine_.codecs(); + std::vector engine_codecs = engine_.send_codecs(); RTC_DCHECK(!engine_codecs.empty()); for (const cricket::VideoCodec& codec : engine_codecs) { if (codec.name == "rtx") { @@ -665,7 +665,7 @@ void WebRtcVideoEngineTest::AssignDefaultAptRtxTypes() { } void WebRtcVideoEngineTest::AssignDefaultCodec() { - std::vector engine_codecs = engine_.codecs(); + std::vector engine_codecs = engine_.send_codecs(); RTC_DCHECK(!engine_codecs.empty()); bool codec_set = false; for (const cricket::VideoCodec& codec : engine_codecs) { @@ -681,7 +681,7 @@ void WebRtcVideoEngineTest::AssignDefaultCodec() { size_t WebRtcVideoEngineTest::GetEngineCodecIndex( const std::string& name) const { - const std::vector codecs = engine_.codecs(); + const std::vector codecs = engine_.send_codecs(); for (size_t i = 0; i < codecs.size(); ++i) { const cricket::VideoCodec engine_codec = codecs[i]; if (!absl::EqualsIgnoreCase(name, engine_codec.name)) @@ -705,7 +705,13 @@ size_t WebRtcVideoEngineTest::GetEngineCodecIndex( cricket::VideoCodec WebRtcVideoEngineTest::GetEngineCodec( const std::string& name) const { - return engine_.codecs()[GetEngineCodecIndex(name)]; + return engine_.send_codecs()[GetEngineCodecIndex(name)]; +} + +void WebRtcVideoEngineTest::AddSupportedVideoCodecType( + const std::string& name) { + encoder_factory_->AddSupportedVideoCodecType(name); + decoder_factory_->AddSupportedVideoCodecType(name); } VideoMediaChannel* @@ -754,7 +760,7 @@ void WebRtcVideoEngineTest::ExpectRtpCapabilitySupport(const char* uri, } TEST_F(WebRtcVideoEngineTest, UsesSimulcastAdapterForVp8Factories) { - encoder_factory_->AddSupportedVideoCodecType("VP8"); + AddSupportedVideoCodecType("VP8"); std::unique_ptr channel( SetSendParamsWithAllSupportedCodecs()); @@ -791,8 +797,8 @@ TEST_F(WebRtcVideoEngineTest, UsesSimulcastAdapterForVp8Factories) { } TEST_F(WebRtcVideoEngineTest, ChannelWithH264CanChangeToVp8) { - encoder_factory_->AddSupportedVideoCodecType("VP8"); - encoder_factory_->AddSupportedVideoCodecType("H264"); + AddSupportedVideoCodecType("VP8"); + AddSupportedVideoCodecType("H264"); // Frame source. webrtc::test::FrameForwarder frame_forwarder; @@ -826,8 +832,8 @@ TEST_F(WebRtcVideoEngineTest, ChannelWithH264CanChangeToVp8) { TEST_F(WebRtcVideoEngineTest, UsesSimulcastAdapterForVp8WithCombinedVP8AndH264Factory) { - encoder_factory_->AddSupportedVideoCodecType("VP8"); - encoder_factory_->AddSupportedVideoCodecType("H264"); + AddSupportedVideoCodecType("VP8"); + AddSupportedVideoCodecType("H264"); std::unique_ptr channel(engine_.CreateMediaChannel( call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(), @@ -862,8 +868,8 @@ TEST_F(WebRtcVideoEngineTest, TEST_F(WebRtcVideoEngineTest, DestroysNonSimulcastEncoderFromCombinedVP8AndH264Factory) { - encoder_factory_->AddSupportedVideoCodecType("VP8"); - encoder_factory_->AddSupportedVideoCodecType("H264"); + AddSupportedVideoCodecType("VP8"); + AddSupportedVideoCodecType("H264"); std::unique_ptr channel(engine_.CreateMediaChannel( call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(), @@ -896,7 +902,7 @@ TEST_F(WebRtcVideoEngineTest, SimulcastEnabledForH264BehindFieldTrial) { RTC_DCHECK(!override_field_trials_); override_field_trials_ = std::make_unique( "WebRTC-H264Simulcast/Enabled/"); - encoder_factory_->AddSupportedVideoCodecType("H264"); + AddSupportedVideoCodecType("H264"); std::unique_ptr channel(engine_.CreateMediaChannel( call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(), @@ -936,13 +942,13 @@ TEST_F(WebRtcVideoEngineTest, auto flexfec = Field("name", &VideoCodec::name, "flexfec-03"); // FlexFEC is not active without field trial. - EXPECT_THAT(engine_.codecs(), Not(Contains(flexfec))); + EXPECT_THAT(engine_.send_codecs(), Not(Contains(flexfec))); // FlexFEC is active with field trial. RTC_DCHECK(!override_field_trials_); override_field_trials_ = std::make_unique( "WebRTC-FlexFEC-03-Advertised/Enabled/"); - EXPECT_THAT(engine_.codecs(), Contains(flexfec)); + EXPECT_THAT(engine_.send_codecs(), Contains(flexfec)); } // Test that codecs are added in the order they are reported from the factory. @@ -966,11 +972,11 @@ TEST_F(WebRtcVideoEngineTest, ReportSupportedAddedCodec) { // Set up external encoder factory with first codec, and initialize engine. encoder_factory_->AddSupportedVideoCodecType(kFakeExternalCodecName1); - std::vector codecs_before(engine_.codecs()); + std::vector codecs_before(engine_.send_codecs()); // Add second codec. encoder_factory_->AddSupportedVideoCodecType(kFakeExternalCodecName2); - std::vector codecs_after(engine_.codecs()); + std::vector codecs_after(engine_.send_codecs()); // The codec itself and RTX should have been added. EXPECT_EQ(codecs_before.size() + 2, codecs_after.size()); @@ -986,12 +992,11 @@ TEST_F(WebRtcVideoEngineTest, ReportRtxForExternalCodec) { encoder_factory_->AddSupportedVideoCodecType(kFakeCodecName); const size_t fake_codec_index = GetEngineCodecIndex(kFakeCodecName); - EXPECT_EQ("rtx", engine_.codecs().at(fake_codec_index + 1).name); + EXPECT_EQ("rtx", engine_.send_codecs().at(fake_codec_index + 1).name); } TEST_F(WebRtcVideoEngineTest, RegisterDecodersIfSupported) { - encoder_factory_->AddSupportedVideoCodecType("VP8"); - decoder_factory_->AddSupportedVideoCodecType(webrtc::SdpVideoFormat("VP8")); + AddSupportedVideoCodecType("VP8"); cricket::VideoRecvParameters parameters; parameters.codecs.push_back(GetEngineCodec("VP8")); @@ -1036,8 +1041,7 @@ TEST_F(WebRtcVideoEngineTest, RegisterH264DecoderIfSupported) { // empty list of RtpSource without crashing. TEST_F(WebRtcVideoEngineTest, GetSourcesWithNonExistingSsrc) { // Setup an recv stream with |kSsrc|. - encoder_factory_->AddSupportedVideoCodecType("VP8"); - decoder_factory_->AddSupportedVideoCodecType(webrtc::SdpVideoFormat("VP8")); + AddSupportedVideoCodecType("VP8"); cricket::VideoRecvParameters parameters; parameters.codecs.push_back(GetEngineCodec("VP8")); std::unique_ptr channel( @@ -1056,7 +1060,8 @@ TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, NullFactories) { std::unique_ptr decoder_factory; WebRtcVideoEngine engine(std::move(encoder_factory), std::move(decoder_factory)); - EXPECT_EQ(0u, engine.codecs().size()); + EXPECT_EQ(0u, engine.send_codecs().size()); + EXPECT_EQ(0u, engine.recv_codecs().size()); } TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, EmptyFactories) { @@ -1069,7 +1074,8 @@ TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, EmptyFactories) { (std::unique_ptr(encoder_factory)), (std::unique_ptr(decoder_factory))); EXPECT_CALL(*encoder_factory, GetSupportedFormats()); - EXPECT_EQ(0u, engine.codecs().size()); + EXPECT_EQ(0u, engine.send_codecs().size()); + EXPECT_EQ(0u, engine.recv_codecs().size()); EXPECT_CALL(*encoder_factory, Die()); EXPECT_CALL(*decoder_factory, Die()); } @@ -1098,9 +1104,11 @@ TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, Vp8) { const std::vector supported_formats = {vp8_format}; EXPECT_CALL(*encoder_factory, GetSupportedFormats()) .WillRepeatedly(::testing::Return(supported_formats)); + EXPECT_CALL(*decoder_factory, GetSupportedFormats()) + .WillRepeatedly(::testing::Return(supported_formats)); // Verify the codecs from the engine. - const std::vector engine_codecs = engine.codecs(); + const std::vector engine_codecs = engine.send_codecs(); // Verify default codecs has been added correctly. EXPECT_EQ(5u, engine_codecs.size()); EXPECT_EQ("VP8", engine_codecs.at(0).name); @@ -1233,12 +1241,14 @@ TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, NullDecoder) { const auto call = absl::WrapUnique(webrtc::Call::Create(call_config)); // Create recv channel. + EXPECT_CALL(*decoder_factory, GetSupportedFormats()) + .WillRepeatedly(::testing::Return(supported_formats)); const int recv_ssrc = 321; std::unique_ptr recv_channel(engine.CreateMediaChannel( call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(), rate_allocator_factory.get())); cricket::VideoRecvParameters recv_parameters; - recv_parameters.codecs.push_back(engine.codecs().front()); + recv_parameters.codecs.push_back(engine.recv_codecs().front()); EXPECT_TRUE(recv_channel->SetRecvParameters(recv_parameters)); EXPECT_TRUE(recv_channel->AddRecvStream( cricket::StreamParams::CreateLegacy(recv_ssrc))); @@ -1326,9 +1336,9 @@ class WebRtcVideoChannelEncodedFrameCallbackTest : public ::testing::Test { webrtc::CreateBuiltinVideoBitrateAllocatorFactory()), engine_( webrtc::CreateBuiltinVideoEncoderFactory(), - std::make_unique([]() { - return std::make_unique(); - })), + std::make_unique( + []() { return std::make_unique(); }, + kSdpVideoFormats)), channel_(absl::WrapUnique(static_cast( engine_.CreateMediaChannel( call_.get(), @@ -1339,7 +1349,7 @@ class WebRtcVideoChannelEncodedFrameCallbackTest : public ::testing::Test { network_interface_.SetDestination(channel_.get()); channel_->SetInterface(&network_interface_, webrtc::MediaTransportConfig()); cricket::VideoRecvParameters parameters; - parameters.codecs = engine_.codecs(); + parameters.codecs = engine_.recv_codecs(); channel_->SetRecvParameters(parameters); } @@ -1363,6 +1373,7 @@ class WebRtcVideoChannelEncodedFrameCallbackTest : public ::testing::Test { EXPECT_EQ(0, renderer_.errors()); } + static const std::vector kSdpVideoFormats; webrtc::FieldTrialBasedConfig field_trials_; webrtc::RtcEventLogNull event_log_; std::unique_ptr task_queue_factory_; @@ -1375,6 +1386,10 @@ class WebRtcVideoChannelEncodedFrameCallbackTest : public ::testing::Test { cricket::FakeVideoRenderer renderer_; }; +const std::vector + WebRtcVideoChannelEncodedFrameCallbackTest::kSdpVideoFormats = { + webrtc::SdpVideoFormat("VP8")}; + TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest, SetEncodedFrameBufferFunction_DefaultStream) { testing::MockFunction callback; @@ -1480,7 +1495,7 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test { network_interface_.SetDestination(channel_.get()); channel_->SetInterface(&network_interface_, webrtc::MediaTransportConfig()); cricket::VideoRecvParameters parameters; - parameters.codecs = engine_.codecs(); + parameters.codecs = engine_.send_codecs(); channel_->SetRecvParameters(parameters); EXPECT_TRUE(channel_->AddSendStream(DefaultSendStreamParams())); frame_forwarder_ = std::make_unique(); @@ -1628,7 +1643,7 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test { } cricket::VideoCodec GetEngineCodec(const std::string& name) { - for (const cricket::VideoCodec& engine_codec : engine_.codecs()) { + for (const cricket::VideoCodec& engine_codec : engine_.send_codecs()) { if (absl::EqualsIgnoreCase(name, engine_codec.name)) return engine_codec; } @@ -2370,10 +2385,10 @@ class WebRtcVideoChannelTest : public WebRtcVideoEngineTest { frame_source_(1280, 720, rtc::kNumMicrosecsPerSec / 30), last_ssrc_(0) {} void SetUp() override { - encoder_factory_->AddSupportedVideoCodecType("VP8"); - encoder_factory_->AddSupportedVideoCodecType("VP9"); + AddSupportedVideoCodecType("VP8"); + AddSupportedVideoCodecType("VP9"); #if defined(WEBRTC_USE_H264) - encoder_factory_->AddSupportedVideoCodecType("H264"); + AddSupportedVideoCodecType("H264"); #endif fake_call_.reset(new FakeCall()); @@ -2382,8 +2397,8 @@ class WebRtcVideoChannelTest : public WebRtcVideoEngineTest { webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get())); channel_->OnReadyToSend(true); last_ssrc_ = 123; - send_parameters_.codecs = engine_.codecs(); - recv_parameters_.codecs = engine_.codecs(); + send_parameters_.codecs = engine_.send_codecs(); + recv_parameters_.codecs = engine_.recv_codecs(); ASSERT_TRUE(channel_->SetSendParameters(send_parameters_)); } @@ -2555,7 +2570,7 @@ class WebRtcVideoChannelTest : public WebRtcVideoEngineTest { VerifyCodecHasDefaultFeedbackParams(default_codec_, expect_lntf_enabled); cricket::VideoSendParameters parameters; - parameters.codecs = engine_.codecs(); + parameters.codecs = engine_.send_codecs(); EXPECT_TRUE(channel_->SetSendParameters(parameters)); EXPECT_TRUE(channel_->SetSend(true)); @@ -2700,7 +2715,7 @@ TEST_F(WebRtcVideoChannelTest, SetsSyncGroupFromSyncLabel) { TEST_F(WebRtcVideoChannelTest, RecvStreamWithSimAndRtx) { cricket::VideoSendParameters parameters; - parameters.codecs = engine_.codecs(); + parameters.codecs = engine_.send_codecs(); EXPECT_TRUE(channel_->SetSendParameters(parameters)); EXPECT_TRUE(channel_->SetSend(true)); parameters.conference_mode = true; @@ -3013,7 +3028,7 @@ TEST_F(WebRtcVideoChannelTest, TransportCcCanBeEnabledAndDisabled) { // Verify that transport cc feedback is turned on when setting default codecs // since the default codecs have transport cc feedback enabled. - parameters.codecs = engine_.codecs(); + parameters.codecs = engine_.send_codecs(); EXPECT_TRUE(channel_->SetSendParameters(parameters)); stream = fake_call_->GetVideoReceiveStreams()[0]; EXPECT_TRUE(stream->GetConfig().rtp.transport_cc); @@ -3042,7 +3057,7 @@ TEST_F(WebRtcVideoChannelTest, LossNotificationCanBeEnabledAndDisabled) { { cricket::VideoSendParameters parameters; - parameters.codecs = engine_.codecs(); + parameters.codecs = engine_.send_codecs(); EXPECT_TRUE(channel_->SetSendParameters(parameters)); EXPECT_TRUE(channel_->SetSend(true)); } @@ -3066,7 +3081,7 @@ TEST_F(WebRtcVideoChannelTest, LossNotificationCanBeEnabledAndDisabled) { EXPECT_FALSE(send_stream->GetConfig().rtp.lntf.enabled); // Setting the default codecs again, including VP8, turns LNTF back on. - parameters.codecs = engine_.codecs(); + parameters.codecs = engine_.send_codecs(); EXPECT_TRUE(channel_->SetSendParameters(parameters)); recv_stream = fake_call_->GetVideoReceiveStreams()[0]; EXPECT_TRUE(recv_stream->GetConfig().rtp.lntf.enabled); @@ -3079,7 +3094,7 @@ TEST_F(WebRtcVideoChannelTest, NackIsEnabledByDefault) { VerifyCodecHasDefaultFeedbackParams(default_codec_, false); cricket::VideoSendParameters parameters; - parameters.codecs = engine_.codecs(); + parameters.codecs = engine_.send_codecs(); EXPECT_TRUE(channel_->SetSendParameters(parameters)); EXPECT_TRUE(channel_->SetSend(true)); @@ -3117,7 +3132,7 @@ TEST_F(WebRtcVideoChannelTest, NackCanBeEnabledAndDisabled) { // Verify that NACK is turned on when setting default codecs since the // default codecs have NACK enabled. - parameters.codecs = engine_.codecs(); + parameters.codecs = engine_.send_codecs(); EXPECT_TRUE(channel_->SetSendParameters(parameters)); recv_stream = fake_call_->GetVideoReceiveStreams()[0]; EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0); @@ -3855,7 +3870,7 @@ TEST_F(WebRtcVideoChannelTest, SetDefaultSendCodecs) { VideoCodec codec; EXPECT_TRUE(channel_->GetSendCodec(&codec)); - EXPECT_TRUE(codec.Matches(engine_.codecs()[0])); + EXPECT_TRUE(codec.Matches(engine_.send_codecs()[0])); // Using a RTX setup to verify that the default RTX payload type is good. const std::vector ssrcs = MAKE_VECTOR(kSsrcs1); @@ -4203,7 +4218,7 @@ TEST_F(WebRtcVideoChannelFlexfecRecvTest, TEST_F(WebRtcVideoChannelTest, SetSendCodecRejectsRtxWithoutAssociatedPayloadType) { const int kUnusedPayloadType = 127; - EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType)); + EXPECT_FALSE(FindCodecById(engine_.send_codecs(), kUnusedPayloadType)); cricket::VideoSendParameters parameters; cricket::VideoCodec rtx_codec(kUnusedPayloadType, "rtx"); @@ -4216,8 +4231,8 @@ TEST_F(WebRtcVideoChannelTest, SetSendCodecRejectsRtxWithoutMatchingVideoCodec) { const int kUnusedPayloadType1 = 126; const int kUnusedPayloadType2 = 127; - EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1)); - EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2)); + EXPECT_FALSE(FindCodecById(engine_.send_codecs(), kUnusedPayloadType1)); + EXPECT_FALSE(FindCodecById(engine_.send_codecs(), kUnusedPayloadType2)); { cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec( kUnusedPayloadType1, GetEngineCodec("VP8").id); @@ -4240,8 +4255,8 @@ TEST_F(WebRtcVideoChannelTest, TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithChangedRtxPayloadType) { const int kUnusedPayloadType1 = 126; const int kUnusedPayloadType2 = 127; - EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1)); - EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2)); + EXPECT_FALSE(FindCodecById(engine_.send_codecs(), kUnusedPayloadType1)); + EXPECT_FALSE(FindCodecById(engine_.send_codecs(), kUnusedPayloadType2)); // SSRCs for RTX. cricket::StreamParams params = @@ -4642,8 +4657,8 @@ TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithOnlyVp8) { TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithRtx) { const int kUnusedPayloadType1 = 126; const int kUnusedPayloadType2 = 127; - EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1)); - EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2)); + EXPECT_FALSE(FindCodecById(engine_.recv_codecs(), kUnusedPayloadType1)); + EXPECT_FALSE(FindCodecById(engine_.recv_codecs(), kUnusedPayloadType2)); cricket::VideoRecvParameters parameters; parameters.codecs.push_back(GetEngineCodec("VP8")); @@ -4741,8 +4756,8 @@ TEST_F(WebRtcVideoChannelTest, DuplicateRedCodecIsDropped) { TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithChangedRtxPayloadType) { const int kUnusedPayloadType1 = 126; const int kUnusedPayloadType2 = 127; - EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1)); - EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2)); + EXPECT_FALSE(FindCodecById(engine_.recv_codecs(), kUnusedPayloadType1)); + EXPECT_FALSE(FindCodecById(engine_.recv_codecs(), kUnusedPayloadType2)); // SSRCs for RTX. cricket::StreamParams params = @@ -4790,13 +4805,14 @@ TEST_F(WebRtcVideoChannelTest, SetRecvCodecsDifferentPayloadType) { TEST_F(WebRtcVideoChannelTest, SetRecvCodecsAcceptDefaultCodecs) { cricket::VideoRecvParameters parameters; - parameters.codecs = engine_.codecs(); + parameters.codecs = engine_.recv_codecs(); EXPECT_TRUE(channel_->SetRecvParameters(parameters)); FakeVideoReceiveStream* stream = AddRecvStream(); const webrtc::VideoReceiveStream::Config& config = stream->GetConfig(); - EXPECT_EQ(engine_.codecs()[0].name, config.decoders[0].video_format.name); - EXPECT_EQ(engine_.codecs()[0].id, config.decoders[0].payload_type); + EXPECT_EQ(engine_.recv_codecs()[0].name, + config.decoders[0].video_format.name); + EXPECT_EQ(engine_.recv_codecs()[0].id, config.decoders[0].payload_type); } TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectUnsupportedCodec) { @@ -5686,7 +5702,7 @@ void WebRtcVideoChannelTest::TestReceiveUnsignaledSsrcPacket( uint8_t payload_type, bool expect_created_receive_stream) { // kRedRtxPayloadType must currently be unused. - EXPECT_FALSE(FindCodecById(engine_.codecs(), kRedRtxPayloadType)); + EXPECT_FALSE(FindCodecById(engine_.recv_codecs(), kRedRtxPayloadType)); // Add a RED RTX codec. VideoCodec red_rtx_codec = @@ -7543,6 +7559,7 @@ class WebRtcVideoChannelSimulcastTest : public ::testing::Test { void SetUp() override { encoder_factory_->AddSupportedVideoCodecType("VP8"); + decoder_factory_->AddSupportedVideoCodecType("VP8"); channel_.reset(engine_.CreateMediaChannel( &fake_call_, GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(), mock_rate_allocator_factory_.get())); diff --git a/pc/channel_manager.cc b/pc/channel_manager.cc index ce8f473600..90e9752d77 100644 --- a/pc/channel_manager.cc +++ b/pc/channel_manager.cc @@ -94,7 +94,9 @@ void ChannelManager::GetSupportedVideoCodecs( } codecs->clear(); - std::vector video_codecs = media_engine_->video().codecs(); + // TODO(kron): Update code to distuiguish between send and receive codecs. Use + // send codecs for now to be consistent with old behavior. + std::vector video_codecs = media_engine_->video().send_codecs(); for (const auto& video_codec : video_codecs) { if (!enable_rtx_ && absl::EqualsIgnoreCase(kRtxCodecName, video_codec.name)) { diff --git a/pc/peer_connection_media_unittest.cc b/pc/peer_connection_media_unittest.cc index 077c4a3e43..82909303fa 100644 --- a/pc/peer_connection_media_unittest.cc +++ b/pc/peer_connection_media_unittest.cc @@ -1434,7 +1434,7 @@ TEST_F(PeerConnectionMediaTestUnifiedPlan, TEST_F(PeerConnectionMediaTestUnifiedPlan, SetCodecPreferencesVideoRejectsOnlyRtxRedFec) { auto fake_engine = std::make_unique(); - auto video_codecs = fake_engine->video().codecs(); + auto video_codecs = fake_engine->video().send_codecs(); video_codecs.push_back( cricket::VideoCodec(video_codecs.back().id + 1, cricket::kRtxCodecName)); video_codecs.push_back( @@ -1540,7 +1540,7 @@ TEST_F(PeerConnectionMediaTestUnifiedPlan, TEST_F(PeerConnectionMediaTestUnifiedPlan, SetCodecPreferencesVideoWithRtx) { auto caller_fake_engine = std::make_unique(); - auto caller_video_codecs = caller_fake_engine->video().codecs(); + auto caller_video_codecs = caller_fake_engine->video().send_codecs(); caller_video_codecs.push_back(cricket::VideoCodec( caller_video_codecs.back().id + 1, cricket::kVp8CodecName)); caller_video_codecs.push_back(cricket::VideoCodec( @@ -1592,7 +1592,7 @@ TEST_F(PeerConnectionMediaTestUnifiedPlan, SetCodecPreferencesVideoWithRtx) { TEST_F(PeerConnectionMediaTestUnifiedPlan, SetCodecPreferencesVideoCodecsNegotiation) { auto caller_fake_engine = std::make_unique(); - auto caller_video_codecs = caller_fake_engine->video().codecs(); + auto caller_video_codecs = caller_fake_engine->video().send_codecs(); caller_video_codecs.push_back(cricket::VideoCodec( caller_video_codecs.back().id + 1, cricket::kVp8CodecName)); caller_video_codecs.push_back(cricket::VideoCodec( @@ -1666,7 +1666,7 @@ TEST_F(PeerConnectionMediaTestUnifiedPlan, TEST_F(PeerConnectionMediaTestUnifiedPlan, SetCodecPreferencesVideoCodecsNegotiationReverseOrder) { auto caller_fake_engine = std::make_unique(); - auto caller_video_codecs = caller_fake_engine->video().codecs(); + auto caller_video_codecs = caller_fake_engine->video().send_codecs(); caller_video_codecs.push_back(cricket::VideoCodec( caller_video_codecs.back().id + 1, cricket::kVp8CodecName)); caller_video_codecs.push_back(cricket::VideoCodec( diff --git a/sdk/objc/components/video_codec/RTCDefaultVideoDecoderFactory.m b/sdk/objc/components/video_codec/RTCDefaultVideoDecoderFactory.m index bdb18517ca..44445f4b13 100644 --- a/sdk/objc/components/video_codec/RTCDefaultVideoDecoderFactory.m +++ b/sdk/objc/components/video_codec/RTCDefaultVideoDecoderFactory.m @@ -21,6 +21,41 @@ @implementation RTCDefaultVideoDecoderFactory +- (NSArray *)supportedCodecs { + NSDictionary *constrainedHighParams = @{ + @"profile-level-id" : kRTCMaxSupportedH264ProfileLevelConstrainedHigh, + @"level-asymmetry-allowed" : @"1", + @"packetization-mode" : @"1", + }; + RTCVideoCodecInfo *constrainedHighInfo = + [[RTCVideoCodecInfo alloc] initWithName:kRTCVideoCodecH264Name + parameters:constrainedHighParams]; + + NSDictionary *constrainedBaselineParams = @{ + @"profile-level-id" : kRTCMaxSupportedH264ProfileLevelConstrainedBaseline, + @"level-asymmetry-allowed" : @"1", + @"packetization-mode" : @"1", + }; + RTCVideoCodecInfo *constrainedBaselineInfo = + [[RTCVideoCodecInfo alloc] initWithName:kRTCVideoCodecH264Name + parameters:constrainedBaselineParams]; + + RTCVideoCodecInfo *vp8Info = [[RTCVideoCodecInfo alloc] initWithName:kRTCVideoCodecVp8Name]; + +#if defined(RTC_ENABLE_VP9) + RTCVideoCodecInfo *vp9Info = [[RTCVideoCodecInfo alloc] initWithName:kRTCVideoCodecVp9Name]; +#endif + + return @[ + constrainedHighInfo, + constrainedBaselineInfo, + vp8Info, +#if defined(RTC_ENABLE_VP9) + vp9Info, +#endif + ]; +} + - (id)createDecoder:(RTCVideoCodecInfo *)info { if ([info.name isEqualToString:kRTCVideoCodecH264Name]) { return [[RTCVideoDecoderH264 alloc] init]; @@ -35,14 +70,4 @@ return nil; } -- (NSArray *)supportedCodecs { - return @[ - [[RTCVideoCodecInfo alloc] initWithName:kRTCVideoCodecH264Name], - [[RTCVideoCodecInfo alloc] initWithName:kRTCVideoCodecVp8Name], -#if defined(RTC_ENABLE_VP9) - [[RTCVideoCodecInfo alloc] initWithName:kRTCVideoCodecVp9Name], -#endif - ]; -} - @end