Refactor FrameBuffer2 tests, without mocking the jitter estimator

Bug: webrtc:7408
Change-Id: Ibded415aefebb9b922ec88c8f5f7fb7ff23cf28d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/134467
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27805}
This commit is contained in:
Niels Möller
2019-04-29 16:12:19 +02:00
committed by Commit Bot
parent a7caaf07a1
commit 7cca042dd4

View File

@ -15,6 +15,7 @@
#include <limits> #include <limits>
#include <vector> #include <vector>
#include "absl/memory/memory.h"
#include "modules/video_coding/frame_object.h" #include "modules/video_coding/frame_object.h"
#include "modules/video_coding/jitter_estimator.h" #include "modules/video_coding/jitter_estimator.h"
#include "modules/video_coding/timing.h" #include "modules/video_coding/timing.h"
@ -22,6 +23,7 @@
#include "rtc_base/platform_thread.h" #include "rtc_base/platform_thread.h"
#include "rtc_base/random.h" #include "rtc_base/random.h"
#include "system_wrappers/include/clock.h" #include "system_wrappers/include/clock.h"
#include "test/field_trial.h"
#include "test/gmock.h" #include "test/gmock.h"
#include "test/gtest.h" #include "test/gtest.h"
@ -67,6 +69,20 @@ class VCMTimingFake : public VCMTiming {
return true; return true;
} }
int GetCurrentJitter() {
int decode_ms;
int max_decode_ms;
int current_delay_ms;
int target_delay_ms;
int jitter_buffer_ms;
int min_playout_delay_ms;
int render_delay_ms;
VCMTiming::GetTimings(&decode_ms, &max_decode_ms, &current_delay_ms,
&target_delay_ms, &jitter_buffer_ms,
&min_playout_delay_ms, &render_delay_ms);
return jitter_buffer_ms;
}
private: private:
static constexpr int kDelayMs = 50; static constexpr int kDelayMs = 50;
static constexpr int kDecodeTime = kDelayMs / 2; static constexpr int kDecodeTime = kDelayMs / 2;
@ -74,24 +90,21 @@ class VCMTimingFake : public VCMTiming {
mutable int64_t last_ms_ = -1; mutable int64_t last_ms_ = -1;
}; };
class VCMJitterEstimatorMock : public VCMJitterEstimator {
public:
explicit VCMJitterEstimatorMock(Clock* clock) : VCMJitterEstimator(clock) {}
MOCK_METHOD1(UpdateRtt, void(int64_t rttMs));
MOCK_METHOD3(UpdateEstimate,
void(int64_t frameDelayMs,
uint32_t frameSizeBytes,
bool incompleteFrame));
MOCK_METHOD2(GetJitterEstimate,
int(double rttMultiplier, double jitterEstCapMs));
};
class FrameObjectFake : public EncodedFrame { class FrameObjectFake : public EncodedFrame {
public: public:
int64_t ReceivedTime() const override { return 0; } int64_t ReceivedTime() const override { return 0; }
int64_t RenderTime() const override { return _renderTimeMs; } int64_t RenderTime() const override { return _renderTimeMs; }
bool delayed_by_retransmission() const override {
return delayed_by_retransmission_;
}
void set_delayed_by_retransmission(bool delayed) {
delayed_by_retransmission_ = delayed;
}
private:
bool delayed_by_retransmission_ = false;
}; };
class VCMReceiveStatisticsCallbackMock : public VCMReceiveStatisticsCallback { class VCMReceiveStatisticsCallbackMock : public VCMReceiveStatisticsCallback {
@ -122,7 +135,8 @@ class TestFrameBuffer2 : public ::testing::Test {
static constexpr size_t kFrameSize = 10; static constexpr size_t kFrameSize = 10;
TestFrameBuffer2() TestFrameBuffer2()
: clock_(0), : trial_("WebRTC-AddRttToPlayoutDelay/Enabled/"),
clock_(0),
timing_(&clock_), timing_(&clock_),
jitter_estimator_(&clock_), jitter_estimator_(&clock_),
buffer_(new FrameBuffer(&clock_, buffer_(new FrameBuffer(&clock_,
@ -142,7 +156,7 @@ class TestFrameBuffer2 : public ::testing::Test {
} }
template <typename... T> template <typename... T>
int InsertFrame(uint16_t picture_id, std::unique_ptr<FrameObjectFake> CreateFrame(uint16_t picture_id,
uint8_t spatial_layer, uint8_t spatial_layer,
int64_t ts_ms, int64_t ts_ms,
bool inter_layer_predicted, bool inter_layer_predicted,
@ -153,7 +167,7 @@ class TestFrameBuffer2 : public ::testing::Test {
std::array<uint16_t, sizeof...(refs)> references = { std::array<uint16_t, sizeof...(refs)> references = {
{rtc::checked_cast<uint16_t>(refs)...}}; {rtc::checked_cast<uint16_t>(refs)...}};
std::unique_ptr<FrameObjectFake> frame(new FrameObjectFake()); auto frame = absl::make_unique<FrameObjectFake>();
frame->id.picture_id = picture_id; frame->id.picture_id = picture_id;
frame->id.spatial_layer = spatial_layer; frame->id.spatial_layer = spatial_layer;
frame->SetSpatialIndex(spatial_layer); frame->SetSpatialIndex(spatial_layer);
@ -166,7 +180,25 @@ class TestFrameBuffer2 : public ::testing::Test {
frame->set_size(kFrameSize); frame->set_size(kFrameSize);
for (size_t r = 0; r < references.size(); ++r) for (size_t r = 0; r < references.size(); ++r)
frame->references[r] = references[r]; frame->references[r] = references[r];
return frame;
}
template <typename... T>
int InsertFrame(uint16_t picture_id,
uint8_t spatial_layer,
int64_t ts_ms,
bool inter_layer_predicted,
bool last_spatial_layer,
T... refs) {
return buffer_->InsertFrame(CreateFrame(picture_id, spatial_layer, ts_ms,
inter_layer_predicted,
last_spatial_layer, refs...));
}
int InsertNackedFrame(uint16_t picture_id, int64_t ts_ms) {
std::unique_ptr<FrameObjectFake> frame =
CreateFrame(picture_id, 0, ts_ms, false, true);
frame->set_delayed_by_retransmission(true);
return buffer_->InsertFrame(std::move(frame)); return buffer_->InsertFrame(std::move(frame));
} }
@ -230,9 +262,11 @@ class TestFrameBuffer2 : public ::testing::Test {
uint32_t Rand() { return rand_.Rand<uint32_t>(); } uint32_t Rand() { return rand_.Rand<uint32_t>(); }
// The ProtectionMode tests depends on rtt-multiplier experiment.
test::ScopedFieldTrials trial_;
SimulatedClock clock_; SimulatedClock clock_;
VCMTimingFake timing_; VCMTimingFake timing_;
::testing::NiceMock<VCMJitterEstimatorMock> jitter_estimator_; VCMJitterEstimator jitter_estimator_;
std::unique_ptr<FrameBuffer> buffer_; std::unique_ptr<FrameBuffer> buffer_;
std::vector<std::unique_ptr<EncodedFrame>> frames_; std::vector<std::unique_ptr<EncodedFrame>> frames_;
Random rand_; Random rand_;
@ -400,18 +434,46 @@ TEST_F(TestFrameBuffer2, InsertLateFrame) {
CheckNoFrame(2); CheckNoFrame(2);
} }
TEST_F(TestFrameBuffer2, ProtectionMode) { TEST_F(TestFrameBuffer2, ProtectionModeNackFEC) {
uint16_t pid = Rand(); uint16_t pid = Rand();
uint32_t ts = Rand(); uint32_t ts = Rand();
constexpr int64_t kRttMs = 200;
buffer_->UpdateRtt(kRttMs);
EXPECT_CALL(jitter_estimator_, GetJitterEstimate(1.0, 300.0)); // Jitter estimate unaffected by RTT in this protection mode.
InsertFrame(pid, 0, ts, false, true);
ExtractFrame();
buffer_->SetProtectionMode(kProtectionNackFEC); buffer_->SetProtectionMode(kProtectionNackFEC);
EXPECT_CALL(jitter_estimator_, GetJitterEstimate(0.0, 300.0)); InsertNackedFrame(pid, ts);
InsertFrame(pid + 1, 0, ts, false, true); InsertNackedFrame(pid + 1, ts + 100);
InsertNackedFrame(pid + 2, ts + 200);
InsertFrame(pid + 3, 0, ts + 300, false, true);
ExtractFrame(); ExtractFrame();
ExtractFrame();
ExtractFrame();
ExtractFrame();
ASSERT_EQ(4u, frames_.size());
EXPECT_LT(timing_.GetCurrentJitter(), kRttMs);
}
TEST_F(TestFrameBuffer2, ProtectionModeNack) {
uint16_t pid = Rand();
uint32_t ts = Rand();
constexpr int64_t kRttMs = 200;
buffer_->UpdateRtt(kRttMs);
// Jitter estimate includes RTT (after 3 retransmitted packets)
buffer_->SetProtectionMode(kProtectionNack);
InsertNackedFrame(pid, ts);
InsertNackedFrame(pid + 1, ts + 100);
InsertNackedFrame(pid + 2, ts + 200);
InsertFrame(pid + 3, 0, ts + 300, false, true);
ExtractFrame();
ExtractFrame();
ExtractFrame();
ExtractFrame();
ASSERT_EQ(4u, frames_.size());
EXPECT_GT(timing_.GetCurrentJitter(), kRttMs);
} }
TEST_F(TestFrameBuffer2, NoContinuousFrame) { TEST_F(TestFrameBuffer2, NoContinuousFrame) {