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 be55133dd6..4f389b88ae 100644 --- a/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.cc +++ b/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.cc @@ -293,8 +293,11 @@ int SimulcastEncoderAdapter::Encode( // scale it to match what the encoder expects (below). if ((dst_width == src_width && dst_height == src_height) || input_image.IsZeroSize()) { - streaminfos_[stream_idx].encoder->Encode(input_image, codec_specific_info, - &stream_frame_types); + int ret = streaminfos_[stream_idx].encoder->Encode( + input_image, codec_specific_info, &stream_frame_types); + if (ret != WEBRTC_VIDEO_CODEC_OK) { + return ret; + } } else { VideoFrame dst_frame; // Making sure that destination frame is of sufficient size. @@ -318,8 +321,11 @@ int SimulcastEncoderAdapter::Encode( libyuv::kFilterBilinear); dst_frame.set_timestamp(input_image.timestamp()); dst_frame.set_render_time_ms(input_image.render_time_ms()); - streaminfos_[stream_idx].encoder->Encode(dst_frame, codec_specific_info, - &stream_frame_types); + int ret = streaminfos_[stream_idx].encoder->Encode( + dst_frame, codec_specific_info, &stream_frame_types); + if (ret != WEBRTC_VIDEO_CODEC_OK) { + 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 aafcd797ac..89c61cec3a 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 @@ -121,7 +121,7 @@ class MockVideoEncoder : public VideoEncoder { int32_t Encode(const VideoFrame& inputImage, const CodecSpecificInfo* codecSpecificInfo, const std::vector* frame_types) /* override */ { - return 0; + return encode_return_value_; } int32_t RegisterEncodeCompleteCallback( @@ -160,10 +160,15 @@ class MockVideoEncoder : public VideoEncoder { supports_native_handle_ = enabled; } + void set_encode_return_value(int value) { + encode_return_value_ = value; + } + MOCK_CONST_METHOD0(ImplementationName, const char*()); private: bool supports_native_handle_ = false; + int encode_return_value_ = WEBRTC_VIDEO_CODEC_OK; VideoCodec codec_; EncodedImageCallback* callback_; }; @@ -171,7 +176,8 @@ class MockVideoEncoder : public VideoEncoder { class MockVideoEncoderFactory : public VideoEncoderFactory { public: VideoEncoder* Create() override { - MockVideoEncoder* encoder = new MockVideoEncoder(); + MockVideoEncoder* encoder = new + ::testing::NiceMock(); const char* encoder_name = encoder_names_.empty() ? "codec_implementation_name" : encoder_names_[encoders_.size()]; @@ -460,5 +466,33 @@ TEST_F(TestSimulcastEncoderAdapterFake, EXPECT_FALSE(adapter_->SupportsNativeHandle()); } +TEST_F(TestSimulcastEncoderAdapterFake, TestFailureReturnCodesFromEncodeCalls) { + TestVp8Simulcast::DefaultSettings( + &codec_, static_cast(kTestTemporalLayerProfile)); + codec_.numberOfSimulcastStreams = 3; + EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + adapter_->RegisterEncodeCompleteCallback(this); + ASSERT_EQ(3u, helper_->factory()->encoders().size()); + // Tell the 2nd encoder to request software fallback. + helper_->factory()->encoders()[1]->set_encode_return_value( + WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE); + + // Send a fake frame and assert the return is software fallback. + VideoFrame input_frame; + int half_width = (kDefaultWidth + 1) / 2; + input_frame.CreateEmptyFrame(kDefaultWidth, kDefaultHeight, kDefaultWidth, + half_width, half_width); + memset(input_frame.video_frame_buffer()->MutableDataY(), 0, + input_frame.allocated_size(kYPlane)); + memset(input_frame.video_frame_buffer()->MutableDataU(), 0, + input_frame.allocated_size(kUPlane)); + memset(input_frame.video_frame_buffer()->MutableDataV(), 0, + input_frame.allocated_size(kVPlane)); + + std::vector frame_types(3, kVideoFrameKey); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE, + adapter_->Encode(input_frame, nullptr, &frame_types)); +} + } // namespace testing } // namespace webrtc