Add tests for verifying transport feedback for audio and video.

BUG=webrtc:5263
R=mflodman@webrtc.org

Review URL: https://codereview.webrtc.org/1589523002 .

Cr-Commit-Position: refs/heads/master@{#11255}
This commit is contained in:
Stefan Holmer 2016-01-14 20:34:30 +01:00
parent fcfc804e43
commit 04cb763955
2 changed files with 140 additions and 100 deletions

View File

@ -31,7 +31,7 @@ CallTest::CallTest()
audio_send_config_(nullptr), audio_send_config_(nullptr),
audio_send_stream_(nullptr), audio_send_stream_(nullptr),
fake_encoder_(clock_), fake_encoder_(clock_),
num_video_streams_(0), num_video_streams_(1),
num_audio_streams_(0), num_audio_streams_(0),
fake_send_audio_device_(nullptr), fake_send_audio_device_(nullptr),
fake_recv_audio_device_(nullptr) {} fake_recv_audio_device_(nullptr) {}
@ -60,9 +60,9 @@ void CallTest::RunBaseTest(BaseTest* test) {
} }
CreateReceiverCall(recv_config); CreateReceiverCall(recv_config);
} }
test->OnCallsCreated(sender_call_.get(), receiver_call_.get());
send_transport_.reset(test->CreateSendTransport(sender_call_.get())); send_transport_.reset(test->CreateSendTransport(sender_call_.get()));
receive_transport_.reset(test->CreateReceiveTransport()); receive_transport_.reset(test->CreateReceiveTransport());
test->OnCallsCreated(sender_call_.get(), receiver_call_.get());
if (test->ShouldCreateReceivers()) { if (test->ShouldCreateReceivers()) {
send_transport_->SetReceiver(receiver_call_->Receiver()); send_transport_->SetReceiver(receiver_call_->Receiver());
@ -97,8 +97,10 @@ void CallTest::RunBaseTest(BaseTest* test) {
test->OnAudioStreamsCreated(audio_send_stream_, audio_receive_streams_); test->OnAudioStreamsCreated(audio_send_stream_, audio_receive_streams_);
} }
if (num_video_streams_ > 0) {
CreateFrameGeneratorCapturer(); CreateFrameGeneratorCapturer();
test->OnFrameGeneratorCapturerCreated(frame_generator_capturer_.get()); test->OnFrameGeneratorCapturerCreated(frame_generator_capturer_.get());
}
Start(); Start();
test->PerformTest(); test->PerformTest();
@ -179,17 +181,20 @@ void CallTest::CreateSendConfig(size_t num_video_streams,
RTC_DCHECK(num_video_streams <= kNumSsrcs); RTC_DCHECK(num_video_streams <= kNumSsrcs);
RTC_DCHECK_LE(num_audio_streams, 1u); RTC_DCHECK_LE(num_audio_streams, 1u);
RTC_DCHECK(num_audio_streams == 0 || voe_send_.channel_id >= 0); RTC_DCHECK(num_audio_streams == 0 || voe_send_.channel_id >= 0);
if (num_video_streams > 0) {
video_send_config_ = VideoSendStream::Config(send_transport); video_send_config_ = VideoSendStream::Config(send_transport);
video_send_config_.encoder_settings.encoder = &fake_encoder_; video_send_config_.encoder_settings.encoder = &fake_encoder_;
video_send_config_.encoder_settings.payload_name = "FAKE"; video_send_config_.encoder_settings.payload_name = "FAKE";
video_send_config_.encoder_settings.payload_type = kFakeVideoSendPayloadType; video_send_config_.encoder_settings.payload_type =
kFakeVideoSendPayloadType;
video_send_config_.rtp.extensions.push_back( video_send_config_.rtp.extensions.push_back(
RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId)); RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId));
video_encoder_config_.streams = test::CreateVideoStreams(num_video_streams); video_encoder_config_.streams = test::CreateVideoStreams(num_video_streams);
for (size_t i = 0; i < num_video_streams; ++i) for (size_t i = 0; i < num_video_streams; ++i)
video_send_config_.rtp.ssrcs.push_back(kVideoSendSsrcs[i]); video_send_config_.rtp.ssrcs.push_back(kVideoSendSsrcs[i]);
video_send_config_.rtp.extensions.push_back( video_send_config_.rtp.extensions.push_back(RtpExtension(
RtpExtension(RtpExtension::kVideoRotation, kVideoRotationRtpExtensionId)); RtpExtension::kVideoRotation, kVideoRotationRtpExtensionId));
}
if (num_audio_streams > 0) { if (num_audio_streams > 0) {
audio_send_config_ = AudioSendStream::Config(send_transport); audio_send_config_ = AudioSendStream::Config(send_transport);
@ -199,10 +204,10 @@ void CallTest::CreateSendConfig(size_t num_video_streams,
} }
void CallTest::CreateMatchingReceiveConfigs(Transport* rtcp_send_transport) { void CallTest::CreateMatchingReceiveConfigs(Transport* rtcp_send_transport) {
RTC_DCHECK(!video_send_config_.rtp.ssrcs.empty());
RTC_DCHECK(video_receive_configs_.empty()); RTC_DCHECK(video_receive_configs_.empty());
RTC_DCHECK(allocated_decoders_.empty()); RTC_DCHECK(allocated_decoders_.empty());
RTC_DCHECK(num_audio_streams_ == 0 || voe_send_.channel_id >= 0); if (num_video_streams_ > 0) {
RTC_DCHECK(!video_send_config_.rtp.ssrcs.empty());
VideoReceiveStream::Config video_config(rtcp_send_transport); VideoReceiveStream::Config video_config(rtcp_send_transport);
video_config.rtp.remb = true; video_config.rtp.remb = true;
video_config.rtp.local_ssrc = kReceiverLocalVideoSsrc; video_config.rtp.local_ssrc = kReceiverLocalVideoSsrc;
@ -217,9 +222,11 @@ void CallTest::CreateMatchingReceiveConfigs(Transport* rtcp_send_transport) {
video_config.rtp.remote_ssrc = video_send_config_.rtp.ssrcs[i]; video_config.rtp.remote_ssrc = video_send_config_.rtp.ssrcs[i];
video_receive_configs_.push_back(video_config); video_receive_configs_.push_back(video_config);
} }
}
RTC_DCHECK(num_audio_streams_ <= 1); RTC_DCHECK(num_audio_streams_ <= 1);
if (num_audio_streams_ == 1) { if (num_audio_streams_ == 1) {
RTC_DCHECK(voe_send_.channel_id >= 0);
AudioReceiveStream::Config audio_config; AudioReceiveStream::Config audio_config;
audio_config.rtp.local_ssrc = kReceiverLocalAudioSsrc; audio_config.rtp.local_ssrc = kReceiverLocalAudioSsrc;
audio_config.rtcp_send_transport = rtcp_send_transport; audio_config.rtcp_send_transport = rtcp_send_transport;

View File

@ -1542,82 +1542,115 @@ TEST_F(EndToEndTest, AssignsTransportSequenceNumbers) {
tester.RunTest(); tester.RunTest();
} }
void TransportFeedbackTest(bool feedback_enabled) { class TransportFeedbackTester : public test::EndToEndTest {
static const int kExtensionId = 5;
class TransportFeedbackObserver : public test::DirectTransport {
public: public:
TransportFeedbackObserver(Call* receiver_call, rtc::Event* done_event) explicit TransportFeedbackTester(bool feedback_enabled,
: DirectTransport(receiver_call), done_(done_event) {} size_t num_video_streams,
virtual ~TransportFeedbackObserver() {} size_t num_audio_streams)
: EndToEndTest(::webrtc::EndToEndTest::kDefaultTimeoutMs),
feedback_enabled_(feedback_enabled),
num_video_streams_(num_video_streams),
num_audio_streams_(num_audio_streams) {
// Only one stream of each supported for now.
EXPECT_LE(num_video_streams, 1u);
EXPECT_LE(num_audio_streams, 1u);
}
bool SendRtcp(const uint8_t* data, size_t length) override { protected:
Action OnSendRtcp(const uint8_t* data, size_t length) override {
EXPECT_FALSE(HasTransportFeedback(data, length));
return SEND_PACKET;
}
Action OnReceiveRtcp(const uint8_t* data, size_t length) override {
if (HasTransportFeedback(data, length))
observation_complete_.Set();
return SEND_PACKET;
}
bool HasTransportFeedback(const uint8_t* data, size_t length) const {
RTCPUtility::RTCPParserV2 parser(data, length, true); RTCPUtility::RTCPParserV2 parser(data, length, true);
EXPECT_TRUE(parser.IsValid()); EXPECT_TRUE(parser.IsValid());
RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
while (packet_type != RTCPUtility::RTCPPacketTypes::kInvalid) { while (packet_type != RTCPUtility::RTCPPacketTypes::kInvalid) {
if (packet_type == RTCPUtility::RTCPPacketTypes::kTransportFeedback) { if (packet_type == RTCPUtility::RTCPPacketTypes::kTransportFeedback)
done_->Set(); return true;
break;
}
packet_type = parser.Iterate(); packet_type = parser.Iterate();
} }
return test::DirectTransport::SendRtcp(data, length); return false;
} }
rtc::Event* done_; void PerformTest() override {
};
class TransportFeedbackTester : public MultiStreamTest {
public:
explicit TransportFeedbackTester(bool feedback_enabled)
: feedback_enabled_(feedback_enabled), done_(false, false) {}
virtual ~TransportFeedbackTester() {}
protected:
void Wait() override {
const int64_t kDisabledFeedbackTimeoutMs = 5000; const int64_t kDisabledFeedbackTimeoutMs = 5000;
EXPECT_EQ(feedback_enabled_, done_.Wait(feedback_enabled_ EXPECT_EQ(feedback_enabled_,
observation_complete_.Wait(feedback_enabled_
? test::CallTest::kDefaultTimeoutMs ? test::CallTest::kDefaultTimeoutMs
: kDisabledFeedbackTimeoutMs)); : kDisabledFeedbackTimeoutMs));
} }
void UpdateSendConfig( void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
size_t stream_index, receiver_call_ = receiver_call;
}
size_t GetNumVideoStreams() const override { return num_video_streams_; }
size_t GetNumAudioStreams() const override { return num_audio_streams_; }
void ModifyVideoConfigs(
VideoSendStream::Config* send_config, VideoSendStream::Config* send_config,
VideoEncoderConfig* encoder_config, std::vector<VideoReceiveStream::Config>* receive_configs,
test::FrameGeneratorCapturer** frame_generator) override { VideoEncoderConfig* encoder_config) override {
send_config->rtp.extensions.clear();
send_config->rtp.extensions.push_back( send_config->rtp.extensions.push_back(
RtpExtension(RtpExtension::kTransportSequenceNumber, kExtensionId)); RtpExtension(RtpExtension::kTransportSequenceNumber, kExtensionId));
(*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
(*receive_configs)[0].rtp.transport_cc = feedback_enabled_;
} }
void UpdateReceiveConfig( void ModifyAudioConfigs(
size_t stream_index, AudioSendStream::Config* send_config,
VideoReceiveStream::Config* receive_config) override { std::vector<AudioReceiveStream::Config>* receive_configs) override {
receive_config->rtp.extensions.push_back( send_config->rtp.extensions.clear();
send_config->rtp.extensions.push_back(
RtpExtension(RtpExtension::kTransportSequenceNumber, kExtensionId)); RtpExtension(RtpExtension::kTransportSequenceNumber, kExtensionId));
receive_config->rtp.transport_cc = feedback_enabled_; (*receive_configs)[0].rtp.extensions.clear();
} (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
(*receive_configs)[0].rtp.transport_cc = feedback_enabled_;
test::DirectTransport* CreateReceiveTransport( (*receive_configs)[0].combined_audio_video_bwe = true;
Call* receiver_call) override {
return new TransportFeedbackObserver(receiver_call, &done_);
} }
private: private:
static const int kExtensionId = 5;
const bool feedback_enabled_; const bool feedback_enabled_;
rtc::Event done_; const size_t num_video_streams_;
} tester(feedback_enabled); const size_t num_audio_streams_;
tester.RunTest(); Call* receiver_call_;
};
TEST_F(EndToEndTest, VideoReceivesTransportFeedback) {
TransportFeedbackTester test(true, 1, 0);
RunBaseTest(&test);
} }
TEST_F(EndToEndTest, ReceivesTransportFeedback) { TEST_F(EndToEndTest, VideoTransportFeedbackNotConfigured) {
TransportFeedbackTest(true); TransportFeedbackTester test(false, 1, 0);
RunBaseTest(&test);
} }
TEST_F(EndToEndTest, TransportFeedbackNotConfigured) { TEST_F(EndToEndTest, AudioReceivesTransportFeedback) {
TransportFeedbackTest(false); TransportFeedbackTester test(true, 0, 1);
RunBaseTest(&test);
}
TEST_F(EndToEndTest, AudioTransportFeedbackNotConfigured) {
TransportFeedbackTester test(false, 0, 1);
RunBaseTest(&test);
}
TEST_F(EndToEndTest, AudioVideoReceivesTransportFeedback) {
TransportFeedbackTester test(true, 1, 1);
RunBaseTest(&test);
} }
TEST_F(EndToEndTest, ObserversEncodedFrames) { TEST_F(EndToEndTest, ObserversEncodedFrames) {