Forward Encode failure codes from sub encoders.

Previously, failure codes were ignored, which meant simulcasted codecs
couldn't e.g. trigger software fallback. This stops the simulcasted
Encode call at the first faiulre and returns that code.

Another option is to continue sending the frame to the other encoders
but still return the first failure code. It's not clear that that is any
better than just quitting as soon as a failure happens.

BUG=

Review-Url: https://codereview.webrtc.org/2008723002
Cr-Commit-Position: refs/heads/master@{#12892}
This commit is contained in:
noahric
2016-05-25 06:48:46 -07:00
committed by Commit bot
parent e5e5292adb
commit 57779104f0
2 changed files with 46 additions and 6 deletions

View File

@ -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;
}
}
}

View File

@ -121,7 +121,7 @@ class MockVideoEncoder : public VideoEncoder {
int32_t Encode(const VideoFrame& inputImage,
const CodecSpecificInfo* codecSpecificInfo,
const std::vector<FrameType>* 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<MockVideoEncoder>();
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<const int*>(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<FrameType> frame_types(3, kVideoFrameKey);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
adapter_->Encode(input_frame, nullptr, &frame_types));
}
} // namespace testing
} // namespace webrtc