Wire up feedback to VideoSender.

BUG=
R=solenberg@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/7859004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@5474 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
stefan@webrtc.org 2014-02-03 16:33:50 +00:00
parent c9ee412070
commit 422fdbf502
4 changed files with 142 additions and 30 deletions

View File

@ -16,27 +16,38 @@ namespace webrtc {
namespace testing {
namespace bwe {
std::vector<const PacketSenderFactory*> VideoSenderFactories(uint32_t count) {
class VideoPacketSenderFactory : public PacketSenderFactory {
public:
VideoPacketSenderFactory(float fps, uint32_t kbps, uint32_t ssrc,
float frame_offset)
: fps_(fps),
kbps_(kbps),
ssrc_(ssrc),
frame_offset_(frame_offset) {
}
virtual ~VideoPacketSenderFactory() {}
virtual PacketSender* Create() const {
return new VideoSender(NULL, fps_, kbps_, ssrc_, frame_offset_);
}
private:
float fps_;
uint32_t kbps_;
uint32_t ssrc_;
float frame_offset_;
};
class VideoPacketSenderFactory : public PacketSenderFactory {
public:
VideoPacketSenderFactory(float fps, uint32_t kbps, uint32_t ssrc,
float frame_offset)
: fps_(fps),
kbps_(kbps),
ssrc_(ssrc),
frame_offset_(frame_offset) {
}
virtual ~VideoPacketSenderFactory() {}
virtual PacketSender* Create() const {
return new VideoSender(NULL, fps_, kbps_, ssrc_, frame_offset_);
}
protected:
float fps_;
uint32_t kbps_;
uint32_t ssrc_;
float frame_offset_;
bool adaptive_;
};
class AdaptiveVideoPacketSenderFactory : public VideoPacketSenderFactory {
public:
AdaptiveVideoPacketSenderFactory(float fps, uint32_t kbps, uint32_t ssrc,
float frame_offset)
: VideoPacketSenderFactory(fps, kbps, ssrc, frame_offset) {}
virtual PacketSender* Create() const {
return new AdaptiveVideoSender(NULL, fps_, kbps_, ssrc_, frame_offset_);
}
};
std::vector<const PacketSenderFactory*> VideoSenderFactories(uint32_t count) {
static const VideoPacketSenderFactory factories[] = {
VideoPacketSenderFactory(30.00f, 150, 0x1234, 0.13f),
VideoPacketSenderFactory(15.00f, 500, 0x2345, 0.16f),
@ -49,6 +60,25 @@ std::vector<const PacketSenderFactory*> VideoSenderFactories(uint32_t count) {
VideoPacketSenderFactory(30.02f, 150, 0x9012, 0.39f),
VideoPacketSenderFactory(30.03f, 150, 0x0123, 0.52f)
};
assert(count <= sizeof(factories) / sizeof(factories[0]));
std::vector<const PacketSenderFactory*> result;
for (uint32_t i = 0; i < count; ++i) {
result.push_back(&factories[i]);
}
return result;
}
std::vector<const PacketSenderFactory*> AdaptiveVideoSenderFactories(
uint32_t count) {
static const VideoPacketSenderFactory factories[] = {
AdaptiveVideoPacketSenderFactory(30.00f, 150, 0x1234, 0.13f),
AdaptiveVideoPacketSenderFactory(30.00f, 300, 0x3456, 0.26f),
AdaptiveVideoPacketSenderFactory(15.00f, 600, 0x4567, 0.39f),
};
assert(count <= sizeof(factories) / sizeof(factories[0]));
std::vector<const PacketSenderFactory*> result;
@ -77,6 +107,13 @@ BweTestConfig MakeBweTestConfig(uint32_t sender_count) {
return result;
}
BweTestConfig MakeAdaptiveBweTestConfig(uint32_t sender_count) {
BweTestConfig result = {
AdaptiveVideoSenderFactories(sender_count), EstimatorConfigs()
};
return result;
}
INSTANTIATE_TEST_CASE_P(VideoSendersTest, BweTest,
::testing::Values(MakeBweTestConfig(1),
MakeBweTestConfig(3)));
@ -229,13 +266,29 @@ TEST_P(BweTest, Multi2) {
RunFor(5 * 60 * 1000);
}
TEST_P(BweTest, SprintUplinkTest) {
// This test fixture is used to instantiate tests running with adaptive video
// senders.
class AdaptiveBweTest : public BweTest {
public:
AdaptiveBweTest() : BweTest() {}
virtual ~AdaptiveBweTest() {}
private:
DISALLOW_COPY_AND_ASSIGN(AdaptiveBweTest);
};
INSTANTIATE_TEST_CASE_P(VideoSendersTest, AdaptiveBweTest,
::testing::Values(MakeAdaptiveBweTestConfig(1),
MakeAdaptiveBweTestConfig(3)));
TEST_P(AdaptiveBweTest, SprintUplinkTest) {
TraceBasedDeliveryFilter filter(this);
ASSERT_TRUE(filter.Init(test::ResourcePath("sprint-uplink", "rx")));
RunFor(60 * 1000);
}
TEST_P(BweTest, Verizon4gDownlinkTest) {
TEST_P(AdaptiveBweTest, Verizon4gDownlinkTest) {
TraceBasedDeliveryFilter filter(this);
ASSERT_TRUE(filter.Init(test::ResourcePath("verizon4g-downlink", "rx")));
RunFor(22 * 60 * 1000);

View File

@ -353,10 +353,10 @@ VideoSender::VideoSender(PacketProcessorListener* listener, float fps,
kMaxPayloadSizeBytes(1000),
kTimestampBase(0xff80ff00ul),
frame_period_ms_(1000.0 / fps),
next_frame_ms_(frame_period_ms_ * first_frame_offset),
now_ms_(0.0),
bytes_per_second_((1000 * kbps) / 8),
frame_size_bytes_(bytes_per_second_ / fps),
next_frame_ms_(frame_period_ms_ * first_frame_offset),
now_ms_(0.0),
prototype_header_() {
assert(first_frame_offset >= 0.0f);
assert(first_frame_offset < 1.0f);
@ -398,6 +398,18 @@ void VideoSender::RunFor(int64_t time_ms, Packets* in_out) {
}
in_out->merge(newPackets);
}
AdaptiveVideoSender::AdaptiveVideoSender(PacketProcessorListener* listener,
float fps,
uint32_t kbps,
uint32_t ssrc,
float first_frame_offset)
: VideoSender(listener, fps, kbps, ssrc, first_frame_offset) {}
void AdaptiveVideoSender::GiveFeedback(const PacketSender::Feedback& feedback) {
bytes_per_second_ = feedback.estimated_bps / 8;
frame_size_bytes_ = (bytes_per_second_ * frame_period_ms_ + 500) / 1000;
}
} // namespace bwe
} // namespace testing
} // namespace webrtc

View File

@ -320,6 +320,9 @@ class PacketSender : public PacketProcessor {
// Call GiveFeedback() with the returned interval in milliseconds, provided
// there is a new estimate available.
// Note that changing the feedback interval affects the timing of when the
// output of the estimators is sampled and therefore the baseline files may
// have to be regenerated.
virtual int64_t GetFeedbackIntervalMs() const { return 1000; }
virtual void GiveFeedback(const Feedback& feedback) {}
@ -344,22 +347,35 @@ class VideoSender : public PacketSender {
virtual uint32_t GetCapacityKbps() const;
// TODO(solenberg): void SetFrameRate(float fps);
// TODO(solenberg): void SetRate(uint32_t kbps);
virtual void RunFor(int64_t time_ms, Packets* in_out);
private:
protected:
const uint32_t kMaxPayloadSizeBytes;
const uint32_t kTimestampBase;
double frame_period_ms_;
double next_frame_ms_;
double now_ms_;
const double frame_period_ms_;
uint32_t bytes_per_second_;
uint32_t frame_size_bytes_;
private:
double next_frame_ms_;
double now_ms_;
RTPHeader prototype_header_;
DISALLOW_IMPLICIT_CONSTRUCTORS(VideoSender);
};
class AdaptiveVideoSender : public VideoSender {
public:
AdaptiveVideoSender(PacketProcessorListener* listener, float fps,
uint32_t kbps, uint32_t ssrc, float first_frame_offset);
virtual ~AdaptiveVideoSender() {}
virtual int64_t GetFeedbackIntervalMs() const { return 500; }
virtual void GiveFeedback(const Feedback& feedback);
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(AdaptiveVideoSender);
};
} // namespace bwe
} // namespace testing
} // namespace webrtc

View File

@ -873,6 +873,37 @@ TEST(BweTestFramework_VideoSenderTest, TestAppendInOrder) {
ASSERT_TRUE(IsTimeSorted(packets));
EXPECT_EQ(60u, packets.size());
}
TEST(BweTestFramework_VideoSenderTest, FeedbackIneffective) {
VideoSender sender(NULL, 25.0f, 820, 0x1234, 0);
EXPECT_EQ(102500u, sender.bytes_per_second());
TestVideoSender(&sender, 9998, 1250, 100, 1025000);
// Make sure feedback has no effect on a regular video sender.
PacketSender::Feedback feedback = { 512000 };
sender.GiveFeedback(feedback);
EXPECT_EQ(102500u, sender.bytes_per_second());
TestVideoSender(&sender, 9998, 1250, 100, 1025000);
}
TEST(BweTestFramework_AdaptiveVideoSenderTest, FeedbackChangesBitrate) {
AdaptiveVideoSender sender(NULL, 25.0f, 820, 0x1234, 0);
EXPECT_EQ(102500u, sender.bytes_per_second());
TestVideoSender(&sender, 9998, 1250, 100, 1025000);
// Make sure we can reduce the bitrate.
PacketSender::Feedback feedback = { 512000 };
sender.GiveFeedback(feedback);
EXPECT_EQ(64000u, sender.bytes_per_second());
TestVideoSender(&sender, 9998, 750, 560, 640000);
// Increase the bitrate to the initial bitrate and verify that the output is
// the same.
feedback.estimated_bps = 820000;
sender.GiveFeedback(feedback);
EXPECT_EQ(102500u, sender.bytes_per_second());
TestVideoSender(&sender, 9998, 1250, 100, 1025000);
}
} // namespace bwe
} // namespace testing
} // namespace webrtc