Refactor VP8 encoder creation logic

Now decision between using SimulcastEncoderAdapter and using VP8 encoder
is postponed before codec is initialized for VP8 internal codecs. This is done
be new VP8EncoderProxy class. New error code for codec initialization is used
to signal that simulcast parameters are not supported.

Bug: webrtc:7925
Change-Id: I3a82c21bf5dfaaa7fa25350986830523f02c39d8
Reviewed-on: https://webrtc-review.googlesource.com/13980
Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20419}
This commit is contained in:
Ilya Nikolaevskiy
2017-10-25 10:04:54 +02:00
committed by Commit Bot
parent 7ddd46386a
commit c22a3a6a7d
9 changed files with 386 additions and 27 deletions

View File

@ -67,10 +67,6 @@ TEST_F(TestVp8Impl, TestSaptioTemporalLayers333PatternEncoder) {
TestVp8Simulcast::TestSaptioTemporalLayers333PatternEncoder();
}
TEST_F(TestVp8Impl, TestSpatioTemporalLayers321PatternEncoder) {
TestVp8Simulcast::TestSpatioTemporalLayers321PatternEncoder();
}
TEST_F(TestVp8Impl, TestStrideEncodeDecode) {
TestVp8Simulcast::TestStrideEncodeDecode();
}

View File

@ -286,6 +286,64 @@ TEST_F(TestVp8Impl, DecodedQpEqualsEncodedQp) {
EXPECT_EQ(encoded_cb_.encoded_frame_.qp_, *decoded_cb_.qp_);
}
TEST_F(TestVp8Impl, ChecksSimulcastSettings) {
codec_settings_.numberOfSimulcastStreams = 2;
// Reslutions are not scaled by 2, temporal layers do not match.
codec_settings_.simulcastStream[0] = {kWidth, kHeight, 2, 4000,
3000, 2000, 80};
codec_settings_.simulcastStream[1] = {kWidth, kHeight, 3, 4000,
3000, 2000, 80};
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED,
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
codec_settings_.numberOfSimulcastStreams = 3;
// Reslutions are not scaled by 2.
codec_settings_.simulcastStream[0] = {kWidth / 2, kHeight / 2, 1, 4000,
3000, 2000, 80};
codec_settings_.simulcastStream[1] = {kWidth / 2, kHeight / 2, 1, 4000,
3000, 2000, 80};
codec_settings_.simulcastStream[2] = {kWidth, kHeight, 1, 4000,
3000, 2000, 80};
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED,
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
// Reslutions are not scaled by 2.
codec_settings_.simulcastStream[0] = {kWidth, kHeight, 1, 4000,
3000, 2000, 80};
codec_settings_.simulcastStream[1] = {kWidth, kHeight, 1, 4000,
3000, 2000, 80};
codec_settings_.simulcastStream[2] = {kWidth, kHeight, 1, 4000,
3000, 2000, 80};
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED,
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
// Temporal layers do not match.
codec_settings_.simulcastStream[0] = {kWidth / 4, kHeight / 4, 1, 4000,
3000, 2000, 80};
codec_settings_.simulcastStream[1] = {kWidth / 2, kHeight / 2, 2, 4000,
3000, 2000, 80};
codec_settings_.simulcastStream[2] = {kWidth, kHeight, 3, 4000,
3000, 2000, 80};
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED,
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
// Resolutions do not match codec config.
codec_settings_.simulcastStream[0] = {
kWidth / 4 + 1, kHeight / 4 + 1, 1, 4000, 3000, 2000, 80};
codec_settings_.simulcastStream[1] = {
kWidth / 2 + 2, kHeight / 2 + 2, 1, 4000, 3000, 2000, 80};
codec_settings_.simulcastStream[2] = {kWidth + 4, kHeight + 4, 1, 4000,
3000, 2000, 80};
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED,
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
// Everything fine: scaling by 2, top resolution matches video, temporal
// settings are the same for all layers.
codec_settings_.simulcastStream[0] = {kWidth / 4, kHeight / 4, 1, 4000,
3000, 2000, 80};
codec_settings_.simulcastStream[1] = {kWidth / 2, kHeight / 2, 1, 4000,
3000, 2000, 80};
codec_settings_.simulcastStream[2] = {kWidth, kHeight, 1, 4000,
3000, 2000, 80};
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
}
#if defined(WEBRTC_ANDROID)
#define MAYBE_AlignedStrideEncodeDecode DISABLED_AlignedStrideEncodeDecode
#else

View File

@ -100,6 +100,21 @@ bool ValidSimulcastResolutions(const VideoCodec& codec, int num_streams) {
return false;
}
}
for (int i = 1; i < num_streams; ++i) {
if (codec.simulcastStream[i].width !=
codec.simulcastStream[i - 1].width * 2) {
return false;
}
}
return true;
}
bool ValidSimulcastTemporalLayers(const VideoCodec& codec, int num_streams) {
for (int i = 0; i < num_streams - 1; ++i) {
if (codec.simulcastStream[i].numberOfTemporalLayers !=
codec.simulcastStream[i + 1].numberOfTemporalLayers)
return false;
}
return true;
}
@ -395,8 +410,10 @@ int VP8EncoderImpl::InitEncode(const VideoCodec* inst,
int number_of_streams = NumberOfStreams(*inst);
bool doing_simulcast = (number_of_streams > 1);
if (doing_simulcast && !ValidSimulcastResolutions(*inst, number_of_streams)) {
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
if (doing_simulcast &&
(!ValidSimulcastResolutions(*inst, number_of_streams) ||
!ValidSimulcastTemporalLayers(*inst, number_of_streams))) {
return WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED;
}
int num_temporal_layers =