Chromium Code Reviews| Index: webrtc/modules/video_coding/codecs/vp8/simulcast_unittest.h |
| diff --git a/webrtc/modules/video_coding/codecs/vp8/simulcast_unittest.h b/webrtc/modules/video_coding/codecs/vp8/simulcast_unittest.h |
| index 56ad3a710d29528e30ec6d65636bf2062d2c5b36..32481cb152765ae0b56850c058999c2d4197b7c6 100644 |
| --- a/webrtc/modules/video_coding/codecs/vp8/simulcast_unittest.h |
| +++ b/webrtc/modules/video_coding/codecs/vp8/simulcast_unittest.h |
| @@ -12,6 +12,7 @@ |
| #define WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_SIMULCAST_UNITTEST_H_ |
| #include <algorithm> |
| +#include <map> |
| #include <memory> |
| #include <vector> |
| @@ -20,6 +21,7 @@ |
| #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" |
| #include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h" |
| #include "webrtc/modules/video_coding/include/mock/mock_video_codec_interface.h" |
| +#include "webrtc/modules/video_coding/utility/simulcast_rate_allocator.h" |
| #include "webrtc/test/gtest.h" |
| #include "webrtc/video_frame.h" |
| @@ -147,83 +149,6 @@ class Vp8TestDecodedImageCallback : public DecodedImageCallback { |
| int decoded_frames_; |
| }; |
| -class SkipEncodingUnusedStreamsTest { |
|
stefan-webrtc
2016/11/02 10:26:35
Could you comment on why this is no longer tested?
sprang_webrtc
2016/11/02 13:28:33
The purpose of this test was to make sure the code
|
| - public: |
| - std::vector<unsigned int> RunTest(VP8Encoder* encoder, |
| - VideoCodec* settings, |
| - uint32_t target_bitrate) { |
| - SpyingTemporalLayersFactory spy_factory; |
| - settings->VP8()->tl_factory = &spy_factory; |
| - EXPECT_EQ(0, encoder->InitEncode(settings, 1, 1200)); |
| - |
| - encoder->SetRates(target_bitrate, 30); |
| - |
| - std::vector<unsigned int> configured_bitrates; |
| - for (std::vector<TemporalLayers*>::const_iterator it = |
| - spy_factory.spying_layers_.begin(); |
| - it != spy_factory.spying_layers_.end(); ++it) { |
| - configured_bitrates.push_back( |
| - static_cast<SpyingTemporalLayers*>(*it)->configured_bitrate_); |
| - } |
| - return configured_bitrates; |
| - } |
| - |
| - class SpyingTemporalLayers : public TemporalLayers { |
| - public: |
| - explicit SpyingTemporalLayers(TemporalLayers* layers) |
| - : configured_bitrate_(0), layers_(layers) {} |
| - |
| - virtual ~SpyingTemporalLayers() { delete layers_; } |
| - |
| - int EncodeFlags(uint32_t timestamp) override { |
| - return layers_->EncodeFlags(timestamp); |
| - } |
| - |
| - bool ConfigureBitrates(int bitrate_kbit, |
| - int max_bitrate_kbit, |
| - int framerate, |
| - vpx_codec_enc_cfg_t* cfg) override { |
| - configured_bitrate_ = bitrate_kbit; |
| - return layers_->ConfigureBitrates(bitrate_kbit, max_bitrate_kbit, |
| - framerate, cfg); |
| - } |
| - |
| - void PopulateCodecSpecific(bool base_layer_sync, |
| - CodecSpecificInfoVP8* vp8_info, |
| - uint32_t timestamp) override { |
| - layers_->PopulateCodecSpecific(base_layer_sync, vp8_info, timestamp); |
| - } |
| - |
| - void FrameEncoded(unsigned int size, uint32_t timestamp, int qp) override { |
| - layers_->FrameEncoded(size, timestamp, qp); |
| - } |
| - |
| - int CurrentLayerId() const override { return layers_->CurrentLayerId(); } |
| - |
| - bool UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) override { |
| - return false; |
| - } |
| - |
| - int configured_bitrate_; |
| - TemporalLayers* layers_; |
| - }; |
| - |
| - class SpyingTemporalLayersFactory : public TemporalLayersFactory { |
| - public: |
| - virtual ~SpyingTemporalLayersFactory() {} |
| - TemporalLayers* Create(int temporal_layers, |
| - uint8_t initial_tl0_pic_idx) const override { |
| - SpyingTemporalLayers* layers = |
| - new SpyingTemporalLayers(TemporalLayersFactory::Create( |
| - temporal_layers, initial_tl0_pic_idx)); |
| - spying_layers_.push_back(layers); |
| - return layers; |
| - } |
| - |
| - mutable std::vector<TemporalLayers*> spying_layers_; |
| - }; |
| -}; |
| - |
| class TestVp8Simulcast : public ::testing::Test { |
| public: |
| TestVp8Simulcast(VP8Encoder* encoder, VP8Decoder* decoder) |
| @@ -265,7 +190,7 @@ class TestVp8Simulcast : public ::testing::Test { |
| static void DefaultSettings(VideoCodec* settings, |
| const int* temporal_layer_profile) { |
| - assert(settings); |
| + RTC_CHECK(settings); |
| memset(settings, 0, sizeof(VideoCodec)); |
| strncpy(settings->plName, "VP8", 4); |
| settings->codecType = kVideoCodecVP8; |
| @@ -315,12 +240,18 @@ class TestVp8Simulcast : public ::testing::Test { |
| } |
| protected: |
| - virtual void SetUp() { SetUpCodec(kDefaultTemporalLayerProfile); } |
| + void SetUp() override { SetUpCodec(kDefaultTemporalLayerProfile); } |
| - virtual void SetUpCodec(const int* temporal_layer_profile) { |
| + void TearDown() override { |
| + encoder_->Release(); |
| + decoder_->Release(); |
| + } |
| + |
| + void SetUpCodec(const int* temporal_layer_profile) { |
| encoder_->RegisterEncodeCompleteCallback(&encoder_callback_); |
| decoder_->RegisterDecodeCompleteCallback(&decoder_callback_); |
| DefaultSettings(&settings_, temporal_layer_profile); |
| + SetUpRateAllocator(); |
| EXPECT_EQ(0, encoder_->InitEncode(&settings_, 1, 1200)); |
| EXPECT_EQ(0, decoder_->InitDecode(&settings_, 1)); |
| int half_width = (kDefaultWidth + 1) / 2; |
| @@ -331,9 +262,16 @@ class TestVp8Simulcast : public ::testing::Test { |
| new VideoFrame(input_buffer_, 0, 0, webrtc::kVideoRotation_0)); |
| } |
| - virtual void TearDown() { |
| - encoder_->Release(); |
| - decoder_->Release(); |
| + void SetUpRateAllocator() { |
| + TemporalLayersFactory* tl_factory = new TemporalLayersFactory(); |
| + rate_allocator_.reset(new SimulcastRateAllocator( |
| + settings_, std::unique_ptr<TemporalLayersFactory>(tl_factory))); |
| + settings_.codecSpecific.VP8.tl_factory = tl_factory; |
| + } |
| + |
| + void SetRates(uint32_t bitrate_kbps, uint32_t fps) { |
| + encoder_->SetRateAllocation( |
| + rate_allocator_->GetAllocation(bitrate_kbps * 1000, fps), fps); |
| } |
| void ExpectStreams(FrameType frame_type, int expected_video_streams) { |
| @@ -396,7 +334,7 @@ class TestVp8Simulcast : public ::testing::Test { |
| // We currently expect all active streams to generate a key frame even though |
| // a key frame was only requested for some of them. |
| void TestKeyFrameRequestsOnAllStreams() { |
| - encoder_->SetRates(kMaxBitrates[2], 30); // To get all three streams. |
| + SetRates(kMaxBitrates[2], 30); // To get all three streams. |
| std::vector<FrameType> frame_types(kNumberOfSimulcastStreams, |
| kVideoFrameDelta); |
| ExpectStreams(kVideoFrameKey, kNumberOfSimulcastStreams); |
| @@ -431,7 +369,7 @@ class TestVp8Simulcast : public ::testing::Test { |
| void TestPaddingAllStreams() { |
| // We should always encode the base layer. |
| - encoder_->SetRates(kMinBitrates[0] - 1, 30); |
| + SetRates(kMinBitrates[0] - 1, 30); |
| std::vector<FrameType> frame_types(kNumberOfSimulcastStreams, |
| kVideoFrameDelta); |
| ExpectStreams(kVideoFrameKey, 1); |
| @@ -444,7 +382,7 @@ class TestVp8Simulcast : public ::testing::Test { |
| void TestPaddingTwoStreams() { |
| // We have just enough to get only the first stream and padding for two. |
| - encoder_->SetRates(kMinBitrates[0], 30); |
| + SetRates(kMinBitrates[0], 30); |
| std::vector<FrameType> frame_types(kNumberOfSimulcastStreams, |
| kVideoFrameDelta); |
| ExpectStreams(kVideoFrameKey, 1); |
| @@ -458,7 +396,7 @@ class TestVp8Simulcast : public ::testing::Test { |
| void TestPaddingTwoStreamsOneMaxedOut() { |
| // We are just below limit of sending second stream, so we should get |
| // the first stream maxed out (at |maxBitrate|), and padding for two. |
| - encoder_->SetRates(kTargetBitrates[0] + kMinBitrates[1] - 1, 30); |
| + SetRates(kTargetBitrates[0] + kMinBitrates[1] - 1, 30); |
| std::vector<FrameType> frame_types(kNumberOfSimulcastStreams, |
| kVideoFrameDelta); |
| ExpectStreams(kVideoFrameKey, 1); |
| @@ -471,7 +409,7 @@ class TestVp8Simulcast : public ::testing::Test { |
| void TestPaddingOneStream() { |
| // We have just enough to send two streams, so padding for one stream. |
| - encoder_->SetRates(kTargetBitrates[0] + kMinBitrates[1], 30); |
| + SetRates(kTargetBitrates[0] + kMinBitrates[1], 30); |
| std::vector<FrameType> frame_types(kNumberOfSimulcastStreams, |
| kVideoFrameDelta); |
| ExpectStreams(kVideoFrameKey, 2); |
| @@ -485,8 +423,7 @@ class TestVp8Simulcast : public ::testing::Test { |
| void TestPaddingOneStreamTwoMaxedOut() { |
| // We are just below limit of sending third stream, so we should get |
| // first stream's rate maxed out at |targetBitrate|, second at |maxBitrate|. |
| - encoder_->SetRates( |
| - kTargetBitrates[0] + kTargetBitrates[1] + kMinBitrates[2] - 1, 30); |
| + SetRates(kTargetBitrates[0] + kTargetBitrates[1] + kMinBitrates[2] - 1, 30); |
| std::vector<FrameType> frame_types(kNumberOfSimulcastStreams, |
| kVideoFrameDelta); |
| ExpectStreams(kVideoFrameKey, 2); |
| @@ -499,8 +436,7 @@ class TestVp8Simulcast : public ::testing::Test { |
| void TestSendAllStreams() { |
| // We have just enough to send all streams. |
| - encoder_->SetRates( |
| - kTargetBitrates[0] + kTargetBitrates[1] + kMinBitrates[2], 30); |
| + SetRates(kTargetBitrates[0] + kTargetBitrates[1] + kMinBitrates[2], 30); |
| std::vector<FrameType> frame_types(kNumberOfSimulcastStreams, |
| kVideoFrameDelta); |
| ExpectStreams(kVideoFrameKey, 3); |
| @@ -513,7 +449,7 @@ class TestVp8Simulcast : public ::testing::Test { |
| void TestDisablingStreams() { |
| // We should get three media streams. |
| - encoder_->SetRates(kMaxBitrates[0] + kMaxBitrates[1] + kMaxBitrates[2], 30); |
| + SetRates(kMaxBitrates[0] + kMaxBitrates[1] + kMaxBitrates[2], 30); |
| std::vector<FrameType> frame_types(kNumberOfSimulcastStreams, |
| kVideoFrameDelta); |
| ExpectStreams(kVideoFrameKey, 3); |
| @@ -524,36 +460,33 @@ class TestVp8Simulcast : public ::testing::Test { |
| EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL, &frame_types)); |
| // We should only get two streams and padding for one. |
| - encoder_->SetRates( |
| - kTargetBitrates[0] + kTargetBitrates[1] + kMinBitrates[2] / 2, 30); |
| + SetRates(kTargetBitrates[0] + kTargetBitrates[1] + kMinBitrates[2] / 2, 30); |
| ExpectStreams(kVideoFrameDelta, 2); |
| input_frame_->set_timestamp(input_frame_->timestamp() + 3000); |
| EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL, &frame_types)); |
| // We should only get the first stream and padding for two. |
| - encoder_->SetRates(kTargetBitrates[0] + kMinBitrates[1] / 2, 30); |
| + SetRates(kTargetBitrates[0] + kMinBitrates[1] / 2, 30); |
| ExpectStreams(kVideoFrameDelta, 1); |
| input_frame_->set_timestamp(input_frame_->timestamp() + 3000); |
| EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL, &frame_types)); |
| // We don't have enough bitrate for the thumbnail stream, but we should get |
| // it anyway with current configuration. |
| - encoder_->SetRates(kTargetBitrates[0] - 1, 30); |
| + SetRates(kTargetBitrates[0] - 1, 30); |
| ExpectStreams(kVideoFrameDelta, 1); |
| input_frame_->set_timestamp(input_frame_->timestamp() + 3000); |
| EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL, &frame_types)); |
| // We should only get two streams and padding for one. |
| - encoder_->SetRates( |
| - kTargetBitrates[0] + kTargetBitrates[1] + kMinBitrates[2] / 2, 30); |
| + SetRates(kTargetBitrates[0] + kTargetBitrates[1] + kMinBitrates[2] / 2, 30); |
| // We get a key frame because a new stream is being enabled. |
| ExpectStreams(kVideoFrameKey, 2); |
| input_frame_->set_timestamp(input_frame_->timestamp() + 3000); |
| EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL, &frame_types)); |
| // We should get all three streams. |
| - encoder_->SetRates( |
| - kTargetBitrates[0] + kTargetBitrates[1] + kTargetBitrates[2], 30); |
| + SetRates(kTargetBitrates[0] + kTargetBitrates[1] + kTargetBitrates[2], 30); |
| // We get a key frame because a new stream is being enabled. |
| ExpectStreams(kVideoFrameKey, 3); |
| input_frame_->set_timestamp(input_frame_->timestamp() + 3000); |
| @@ -590,10 +523,11 @@ class TestVp8Simulcast : public ::testing::Test { |
| settings_.width; |
| settings_.simulcastStream[settings_.numberOfSimulcastStreams - 1].height = |
| settings_.height; |
| + SetUpRateAllocator(); |
| EXPECT_EQ(0, encoder_->InitEncode(&settings_, 1, 1200)); |
| // Encode one frame and verify. |
| - encoder_->SetRates(kMaxBitrates[0] + kMaxBitrates[1], 30); |
| + SetRates(kMaxBitrates[0] + kMaxBitrates[1], 30); |
| std::vector<FrameType> frame_types(kNumberOfSimulcastStreams, |
| kVideoFrameDelta); |
| EXPECT_CALL( |
| @@ -611,8 +545,9 @@ class TestVp8Simulcast : public ::testing::Test { |
| DefaultSettings(&settings_, kDefaultTemporalLayerProfile); |
| // Start at the lowest bitrate for enabling base stream. |
| settings_.startBitrate = kMinBitrates[0]; |
| + SetUpRateAllocator(); |
| EXPECT_EQ(0, encoder_->InitEncode(&settings_, 1, 1200)); |
| - encoder_->SetRates(settings_.startBitrate, 30); |
| + SetRates(settings_.startBitrate, 30); |
| ExpectStreams(kVideoFrameKey, 1); |
| // Resize |input_frame_| to the new resolution. |
| half_width = (settings_.width + 1) / 2; |
| @@ -634,7 +569,7 @@ class TestVp8Simulcast : public ::testing::Test { |
| Vp8TestEncodedImageCallback encoder_callback; |
| encoder_->RegisterEncodeCompleteCallback(&encoder_callback); |
| - encoder_->SetRates(kMaxBitrates[2], 30); // To get all three streams. |
| + SetRates(kMaxBitrates[2], 30); // To get all three streams. |
| EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL, NULL)); |
| int picture_id = -1; |
| @@ -703,7 +638,7 @@ class TestVp8Simulcast : public ::testing::Test { |
| encoder_->RegisterEncodeCompleteCallback(&encoder_callback); |
| decoder_->RegisterDecodeCompleteCallback(&decoder_callback); |
| - encoder_->SetRates(kMaxBitrates[2], 30); // To get all three streams. |
| + SetRates(kMaxBitrates[2], 30); // To get all three streams. |
| // Set color. |
| int plane_offset[kNumOfPlanes]; |
| @@ -777,7 +712,7 @@ class TestVp8Simulcast : public ::testing::Test { |
| void TestSaptioTemporalLayers333PatternEncoder() { |
| Vp8TestEncodedImageCallback encoder_callback; |
| encoder_->RegisterEncodeCompleteCallback(&encoder_callback); |
| - encoder_->SetRates(kMaxBitrates[2], 30); // To get all three streams. |
| + SetRates(kMaxBitrates[2], 30); // To get all three streams. |
| int expected_temporal_idx[3] = {-1, -1, -1}; |
| bool expected_layer_sync[3] = {false, false, false}; |
| @@ -846,7 +781,7 @@ class TestVp8Simulcast : public ::testing::Test { |
| SetUpCodec(temporal_layer_profile); |
| Vp8TestEncodedImageCallback encoder_callback; |
| encoder_->RegisterEncodeCompleteCallback(&encoder_callback); |
| - encoder_->SetRates(kMaxBitrates[2], 30); // To get all three streams. |
| + SetRates(kMaxBitrates[2], 30); // To get all three streams. |
| int expected_temporal_idx[3] = {-1, -1, -1}; |
| bool expected_layer_sync[3] = {false, false, false}; |
| @@ -905,7 +840,7 @@ class TestVp8Simulcast : public ::testing::Test { |
| encoder_->RegisterEncodeCompleteCallback(&encoder_callback); |
| decoder_->RegisterDecodeCompleteCallback(&decoder_callback); |
| - encoder_->SetRates(kMaxBitrates[2], 30); // To get all three streams. |
| + SetRates(kMaxBitrates[2], 30); // To get all three streams. |
| // Setting two (possibly) problematic use cases for stride: |
| // 1. stride > width 2. stride_y != stride_uv/2 |
| int stride_y = kDefaultWidth + 20; |
| @@ -941,30 +876,6 @@ class TestVp8Simulcast : public ::testing::Test { |
| EXPECT_EQ(2, decoder_callback.DecodedFrames()); |
| } |
| - void TestSkipEncodingUnusedStreams() { |
| - SkipEncodingUnusedStreamsTest test; |
| - std::vector<unsigned int> configured_bitrate = |
| - test.RunTest(encoder_.get(), &settings_, |
| - 1); // Target bit rate 1, to force all streams but the |
| - // base one to be exceeding bandwidth constraints. |
| - EXPECT_EQ(static_cast<size_t>(kNumberOfSimulcastStreams), |
| - configured_bitrate.size()); |
| - |
| - unsigned int min_bitrate = |
| - std::max(settings_.simulcastStream[0].minBitrate, settings_.minBitrate); |
| - int stream = 0; |
| - for (std::vector<unsigned int>::const_iterator it = |
| - configured_bitrate.begin(); |
| - it != configured_bitrate.end(); ++it) { |
| - if (stream == 0) { |
| - EXPECT_EQ(min_bitrate, *it); |
| - } else { |
| - EXPECT_EQ(0u, *it); |
| - } |
| - ++stream; |
| - } |
| - } |
| - |
| std::unique_ptr<VP8Encoder> encoder_; |
| MockEncodedImageCallback encoder_callback_; |
| std::unique_ptr<VP8Decoder> decoder_; |
| @@ -972,6 +883,7 @@ class TestVp8Simulcast : public ::testing::Test { |
| VideoCodec settings_; |
| rtc::scoped_refptr<I420Buffer> input_buffer_; |
| std::unique_ptr<VideoFrame> input_frame_; |
| + std::unique_ptr<SimulcastRateAllocator> rate_allocator_; |
| }; |
| } // namespace testing |