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:
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
Reference in New Issue
Block a user