diff --git a/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.cc b/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.cc index 6026cb31d2..6e3ae4cb43 100644 --- a/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.cc +++ b/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.cc @@ -218,6 +218,9 @@ int SimulcastEncoderAdapter::InitEncode(const VideoCodec* inst, VideoEncoder* encoder = factory_->Create(); ret = encoder->InitEncode(&stream_codec, number_of_cores, max_payload_size); if (ret < 0) { + // Explicitly destroy the current encoder; because we haven't registered a + // StreamInfo for it yet, Release won't do anything about it. + factory_->Destroy(encoder); Release(); return ret; } diff --git a/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter_unittest.cc b/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter_unittest.cc index b3fe8e053d..e95ecf5d91 100644 --- a/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter_unittest.cc +++ b/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter_unittest.cc @@ -109,7 +109,7 @@ class MockVideoEncoder : public VideoEncoder { int32_t numberOfCores, size_t maxPayloadSize) /* override */ { codec_ = *codecSettings; - return 0; + return init_encode_return_value_; } MOCK_METHOD3( @@ -155,12 +155,18 @@ class MockVideoEncoder : public VideoEncoder { void set_supports_native_handle(bool enabled) { supports_native_handle_ = enabled; } + + void set_init_encode_return_value(int32_t value) { + init_encode_return_value_ = value; + } + BitrateAllocation last_set_bitrate() const { return last_set_bitrate_; } MOCK_CONST_METHOD0(ImplementationName, const char*()); private: bool supports_native_handle_ = false; + int32_t init_encode_return_value_ = 0; BitrateAllocation last_set_bitrate_; VideoCodec codec_; @@ -172,6 +178,7 @@ class MockVideoEncoderFactory : public VideoEncoderFactory { VideoEncoder* Create() 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()]; @@ -196,8 +203,12 @@ class MockVideoEncoderFactory : public VideoEncoderFactory { 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: + int32_t init_encode_return_value_ = 0; std::vector encoders_; std::vector encoder_names_; }; @@ -550,5 +561,17 @@ TEST_F(TestSimulcastEncoderAdapterFake, TestFailureReturnCodesFromEncodeCalls) { adapter_->Encode(input_frame, nullptr, &frame_types)); } +TEST_F(TestSimulcastEncoderAdapterFake, TestInitFailureCleansUpEncoders) { + TestVp8Simulcast::DefaultSettings( + &codec_, static_cast(kTestTemporalLayerProfile)); + codec_.VP8()->tl_factory = &tl_factory_; + codec_.numberOfSimulcastStreams = 3; + helper_->factory()->set_init_encode_return_value( + WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE, + adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_TRUE(helper_->factory()->encoders().empty()); +} + } // namespace testing } // namespace webrtc