Skip to content

Commit

Permalink
Implement dual stream full stack test and loopback tool
Browse files Browse the repository at this point in the history
Bug: webrtc:8588
Change-Id: I0abec4891a723c98001f4580f0cfa57a5d6d6bdb
Reviewed-on: https://webrtc-review.googlesource.com/34441
Commit-Queue: Ilya Nikolaevskiy <[email protected]>
Reviewed-by: Stefan Holmer <[email protected]>
Reviewed-by: Erik Språng <[email protected]>
Cr-Commit-Position: refs/heads/master@{#21416}
  • Loading branch information
Ilya Nikolaevskiy authored and Commit Bot committed Dec 21, 2017
1 parent c3216e1 commit 255d1cd
Show file tree
Hide file tree
Showing 14 changed files with 1,702 additions and 721 deletions.
1 change: 1 addition & 0 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ if (!build_with_chromium) {
"system_wrappers:system_wrappers_unittests",
"test",
"video:screenshare_loopback",
"video:sv_loopback",
"video:video_loopback",
"voice_engine:voice_engine_unittests",
]
Expand Down
139 changes: 85 additions & 54 deletions test/call_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -192,33 +192,34 @@ void CallTest::DestroyCalls() {
receiver_call_.reset();
}

void CallTest::CreateSendConfig(size_t num_video_streams,
size_t num_audio_streams,
size_t num_flexfec_streams,
Transport* send_transport) {
RTC_DCHECK(num_video_streams <= kNumSsrcs);
void CallTest::CreateVideoSendConfig(VideoSendStream::Config* video_config,
size_t num_video_streams,
size_t num_used_ssrcs,
Transport* send_transport) {
RTC_DCHECK_LE(num_video_streams + num_used_ssrcs, kNumSsrcs);
*video_config = VideoSendStream::Config(send_transport);
video_config->encoder_settings.encoder = &fake_encoder_;
video_config->encoder_settings.payload_name = "FAKE";
video_config->encoder_settings.payload_type = kFakeVideoSendPayloadType;
video_config->rtp.extensions.push_back(
RtpExtension(RtpExtension::kTransportSequenceNumberUri,
kTransportSequenceNumberExtensionId));
video_config->rtp.extensions.push_back(RtpExtension(
RtpExtension::kVideoContentTypeUri, kVideoContentTypeExtensionId));
FillEncoderConfiguration(num_video_streams, &video_encoder_config_);

for (size_t i = 0; i < num_video_streams; ++i)
video_config->rtp.ssrcs.push_back(kVideoSendSsrcs[num_used_ssrcs + i]);
video_config->rtp.extensions.push_back(RtpExtension(
RtpExtension::kVideoRotationUri, kVideoRotationRtpExtensionId));
}

void CallTest::CreateAudioAndFecSendConfigs(size_t num_audio_streams,
size_t num_flexfec_streams,
Transport* send_transport) {
RTC_DCHECK_LE(num_audio_streams, 1);
RTC_DCHECK_LE(num_flexfec_streams, 1);
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_.encoder_settings.encoder = &fake_encoder_;
video_send_config_.encoder_settings.payload_name = "FAKE";
video_send_config_.encoder_settings.payload_type =
kFakeVideoSendPayloadType;
video_send_config_.rtp.extensions.push_back(
RtpExtension(RtpExtension::kTransportSequenceNumberUri,
kTransportSequenceNumberExtensionId));
video_send_config_.rtp.extensions.push_back(RtpExtension(
RtpExtension::kVideoContentTypeUri, kVideoContentTypeExtensionId));
FillEncoderConfiguration(num_video_streams, &video_encoder_config_);

for (size_t i = 0; i < num_video_streams; ++i)
video_send_config_.rtp.ssrcs.push_back(kVideoSendSsrcs[i]);
video_send_config_.rtp.extensions.push_back(RtpExtension(
RtpExtension::kVideoRotationUri, kVideoRotationRtpExtensionId));
}

if (num_audio_streams > 0) {
audio_send_config_ = AudioSendStream::Config(send_transport);
audio_send_config_.voe_channel_id = voe_send_.channel_id;
Expand All @@ -237,32 +238,47 @@ void CallTest::CreateSendConfig(size_t num_video_streams,
}
}

void CallTest::CreateMatchingReceiveConfigs(Transport* rtcp_send_transport) {
video_receive_configs_.clear();
allocated_decoders_.clear();
if (num_video_streams_ > 0) {
RTC_DCHECK(!video_send_config_.rtp.ssrcs.empty());
VideoReceiveStream::Config video_config(rtcp_send_transport);
video_config.rtp.remb = false;
video_config.rtp.transport_cc = true;
video_config.rtp.local_ssrc = kReceiverLocalVideoSsrc;
for (const RtpExtension& extension : video_send_config_.rtp.extensions)
video_config.rtp.extensions.push_back(extension);
video_config.renderer = &fake_renderer_;
for (size_t i = 0; i < video_send_config_.rtp.ssrcs.size(); ++i) {
VideoReceiveStream::Decoder decoder =
test::CreateMatchingDecoder(video_send_config_.encoder_settings);
allocated_decoders_.push_back(
std::unique_ptr<VideoDecoder>(decoder.decoder));
video_config.decoders.clear();
video_config.decoders.push_back(decoder);
video_config.rtp.remote_ssrc = video_send_config_.rtp.ssrcs[i];
video_receive_configs_.push_back(video_config.Copy());
}
video_receive_configs_[0].rtp.protected_by_flexfec =
(num_flexfec_streams_ == 1);
void CallTest::CreateSendConfig(size_t num_video_streams,
size_t num_audio_streams,
size_t num_flexfec_streams,
Transport* send_transport) {
if (num_video_streams > 0) {
CreateVideoSendConfig(&video_send_config_, num_video_streams, 0,
send_transport);
}
CreateAudioAndFecSendConfigs(num_audio_streams, num_flexfec_streams,
send_transport);
}

std::vector<VideoReceiveStream::Config>
CallTest::CreateMatchingVideoReceiveConfigs(
const VideoSendStream::Config& video_send_config,
Transport* rtcp_send_transport) {
std::vector<VideoReceiveStream::Config> result;
RTC_DCHECK(!video_send_config.rtp.ssrcs.empty());
VideoReceiveStream::Config video_config(rtcp_send_transport);
video_config.rtp.remb = false;
video_config.rtp.transport_cc = true;
video_config.rtp.local_ssrc = kReceiverLocalVideoSsrc;
for (const RtpExtension& extension : video_send_config.rtp.extensions)
video_config.rtp.extensions.push_back(extension);
video_config.renderer = &fake_renderer_;
for (size_t i = 0; i < video_send_config.rtp.ssrcs.size(); ++i) {
VideoReceiveStream::Decoder decoder =
test::CreateMatchingDecoder(video_send_config.encoder_settings);
allocated_decoders_.push_back(
std::unique_ptr<VideoDecoder>(decoder.decoder));
video_config.decoders.clear();
video_config.decoders.push_back(decoder);
video_config.rtp.remote_ssrc = video_send_config.rtp.ssrcs[i];
result.push_back(video_config.Copy());
}
result[0].rtp.protected_by_flexfec = (num_flexfec_streams_ == 1);
return result;
}

void CallTest::CreateMatchingAudioAndFecConfigs(
Transport* rtcp_send_transport) {
RTC_DCHECK_GE(1, num_audio_streams_);
if (num_audio_streams_ == 1) {
RTC_DCHECK_LE(0, voe_send_.channel_id);
Expand Down Expand Up @@ -290,6 +306,20 @@ void CallTest::CreateMatchingReceiveConfigs(Transport* rtcp_send_transport) {
}
}

void CallTest::CreateMatchingReceiveConfigs(Transport* rtcp_send_transport) {
video_receive_configs_.clear();
allocated_decoders_.clear();
if (num_video_streams_ > 0) {
std::vector<VideoReceiveStream::Config> new_configs =
CreateMatchingVideoReceiveConfigs(video_send_config_,
rtcp_send_transport);
for (VideoReceiveStream::Config& config : new_configs) {
video_receive_configs_.push_back(config.Copy());
}
}
CreateMatchingAudioAndFecConfigs(rtcp_send_transport);
}

void CallTest::CreateFrameGeneratorCapturerWithDrift(Clock* clock,
float speed,
int framerate,
Expand Down Expand Up @@ -324,8 +354,6 @@ void CallTest::CreateFakeAudioDevices(
void CallTest::CreateVideoStreams() {
RTC_DCHECK(video_send_stream_ == nullptr);
RTC_DCHECK(video_receive_streams_.empty());
RTC_DCHECK(audio_send_stream_ == nullptr);
RTC_DCHECK(audio_receive_streams_.empty());

video_send_stream_ = sender_call_->CreateVideoSendStream(
video_send_config_.Copy(), video_encoder_config_.Copy());
Expand All @@ -338,6 +366,8 @@ void CallTest::CreateVideoStreams() {
}

void CallTest::CreateAudioStreams() {
RTC_DCHECK(audio_send_stream_ == nullptr);
RTC_DCHECK(audio_receive_streams_.empty());
audio_send_stream_ = sender_call_->CreateAudioSendStream(audio_send_config_);
for (size_t i = 0; i < audio_receive_configs_.size(); ++i) {
audio_receive_streams_.push_back(
Expand Down Expand Up @@ -464,6 +494,7 @@ void CallTest::DestroyVoiceEngines() {
voe_recv_.voice_engine = nullptr;
}

constexpr size_t CallTest::kNumSsrcs;
const int CallTest::kDefaultWidth;
const int CallTest::kDefaultHeight;
const int CallTest::kDefaultFramerate;
Expand All @@ -480,10 +511,10 @@ const uint8_t CallTest::kAudioSendPayloadType = 103;
const uint8_t CallTest::kPayloadTypeH264 = 122;
const uint8_t CallTest::kPayloadTypeVP8 = 123;
const uint8_t CallTest::kPayloadTypeVP9 = 124;
const uint32_t CallTest::kSendRtxSsrcs[kNumSsrcs] = {0xBADCAFD, 0xBADCAFE,
0xBADCAFF};
const uint32_t CallTest::kVideoSendSsrcs[kNumSsrcs] = {0xC0FFED, 0xC0FFEE,
0xC0FFEF};
const uint32_t CallTest::kSendRtxSsrcs[kNumSsrcs] = {
0xBADCAFD, 0xBADCAFE, 0xBADCAFF, 0xBADCB00, 0xBADCB01, 0xBADCB02};
const uint32_t CallTest::kVideoSendSsrcs[kNumSsrcs] = {
0xC0FFED, 0xC0FFEE, 0xC0FFEF, 0xC0FFF0, 0xC0FFF1, 0xC0FFF2};
const uint32_t CallTest::kAudioSendSsrc = 0xDEADBEEF;
const uint32_t CallTest::kFlexfecSendSsrc = 0xBADBEEF;
const uint32_t CallTest::kReceiverLocalVideoSsrc = 0x123456;
Expand Down
14 changes: 13 additions & 1 deletion test/call_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ class CallTest : public ::testing::Test {
CallTest();
virtual ~CallTest();

static const size_t kNumSsrcs = 3;
static constexpr size_t kNumSsrcs = 6;
static const int kNumSimulcastStreams = 3;
static const int kDefaultWidth = 320;
static const int kDefaultHeight = 180;
static const int kDefaultFramerate = 30;
Expand Down Expand Up @@ -77,11 +78,22 @@ class CallTest : public ::testing::Test {
void CreateReceiverCall(const Call::Config& config);
void DestroyCalls();

void CreateVideoSendConfig(VideoSendStream::Config* video_config,
size_t num_video_streams,
size_t num_used_ssrcs,
Transport* send_transport);
void CreateAudioAndFecSendConfigs(size_t num_audio_streams,
size_t num_flexfec_streams,
Transport* send_transport);
void CreateSendConfig(size_t num_video_streams,
size_t num_audio_streams,
size_t num_flexfec_streams,
Transport* send_transport);

std::vector<VideoReceiveStream::Config> CreateMatchingVideoReceiveConfigs(
const VideoSendStream::Config& video_send_config,
Transport* rtcp_send_transport);
void CreateMatchingAudioAndFecConfigs(Transport* rtcp_send_transport);
void CreateMatchingReceiveConfigs(Transport* rtcp_send_transport);

void CreateFrameGeneratorCapturerWithDrift(Clock* drift_clock,
Expand Down
52 changes: 50 additions & 2 deletions test/layer_filtering_transport.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,45 @@
namespace webrtc {
namespace test {

LayerFilteringTransport::LayerFilteringTransport(
SingleThreadedTaskQueueForTesting* task_queue,
const FakeNetworkPipe::Config& config,
Call* send_call,
uint8_t vp8_video_payload_type,
uint8_t vp9_video_payload_type,
int selected_tl,
int selected_sl,
const std::map<uint8_t, MediaType>& payload_type_map,
uint32_t ssrc_to_filter_min,
uint32_t ssrc_to_filter_max)
: DirectTransport(task_queue, config, send_call, payload_type_map),
vp8_video_payload_type_(vp8_video_payload_type),
vp9_video_payload_type_(vp9_video_payload_type),
selected_tl_(selected_tl),
selected_sl_(selected_sl),
discarded_last_packet_(false),
ssrc_to_filter_min_(ssrc_to_filter_min),
ssrc_to_filter_max_(ssrc_to_filter_max) {}

LayerFilteringTransport::LayerFilteringTransport(
SingleThreadedTaskQueueForTesting* task_queue,
std::unique_ptr<FakeNetworkPipe> pipe,
Call* send_call,
uint8_t vp8_video_payload_type,
uint8_t vp9_video_payload_type,
int selected_tl,
int selected_sl,
uint32_t ssrc_to_filter_min,
uint32_t ssrc_to_filter_max)
: DirectTransport(task_queue, std::move(pipe), send_call),
vp8_video_payload_type_(vp8_video_payload_type),
vp9_video_payload_type_(vp9_video_payload_type),
selected_tl_(selected_tl),
selected_sl_(selected_sl),
discarded_last_packet_(false),
ssrc_to_filter_min_(ssrc_to_filter_min),
ssrc_to_filter_max_(ssrc_to_filter_max) {}

LayerFilteringTransport::LayerFilteringTransport(
SingleThreadedTaskQueueForTesting* task_queue,
const FakeNetworkPipe::Config& config,
Expand All @@ -34,7 +73,9 @@ LayerFilteringTransport::LayerFilteringTransport(
vp9_video_payload_type_(vp9_video_payload_type),
selected_tl_(selected_tl),
selected_sl_(selected_sl),
discarded_last_packet_(false) {}
discarded_last_packet_(false),
ssrc_to_filter_min_(0),
ssrc_to_filter_max_(0xFFFFFFFF) {}

LayerFilteringTransport::LayerFilteringTransport(
SingleThreadedTaskQueueForTesting* task_queue,
Expand All @@ -49,7 +90,9 @@ LayerFilteringTransport::LayerFilteringTransport(
vp9_video_payload_type_(vp9_video_payload_type),
selected_tl_(selected_tl),
selected_sl_(selected_sl),
discarded_last_packet_(false) {}
discarded_last_packet_(false),
ssrc_to_filter_min_(0),
ssrc_to_filter_max_(0xFFFFFFFF) {}

bool LayerFilteringTransport::DiscardedLastPacket() const {
return discarded_last_packet_;
Expand All @@ -68,6 +111,11 @@ bool LayerFilteringTransport::SendRtp(const uint8_t* packet,
RTPHeader header;
parser.Parse(&header);

if (header.ssrc < ssrc_to_filter_min_ || header.ssrc > ssrc_to_filter_max_) {
// Nothing to change, forward the packet immediately.
return test::DirectTransport::SendRtp(packet, length, options);
}

RTC_DCHECK_LE(length, IP_PACKET_SIZE);
uint8_t temp_buffer[IP_PACKET_SIZE];
memcpy(temp_buffer, packet, length);
Expand Down
21 changes: 21 additions & 0 deletions test/layer_filtering_transport.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ namespace test {

class LayerFilteringTransport : public test::DirectTransport {
public:
LayerFilteringTransport(SingleThreadedTaskQueueForTesting* task_queue,
const FakeNetworkPipe::Config& config,
Call* send_call,
uint8_t vp8_video_payload_type,
uint8_t vp9_video_payload_type,
int selected_tl,
int selected_sl,
const std::map<uint8_t, MediaType>& payload_type_map,
uint32_t ssrc_to_filter_min,
uint32_t ssrc_to_filter_max);
LayerFilteringTransport(SingleThreadedTaskQueueForTesting* task_queue,
const FakeNetworkPipe::Config& config,
Call* send_call,
Expand All @@ -31,6 +41,15 @@ class LayerFilteringTransport : public test::DirectTransport {
int selected_tl,
int selected_sl,
const std::map<uint8_t, MediaType>& payload_type_map);
LayerFilteringTransport(SingleThreadedTaskQueueForTesting* task_queue,
std::unique_ptr<FakeNetworkPipe> pipe,
Call* send_call,
uint8_t vp8_video_payload_type,
uint8_t vp9_video_payload_type,
int selected_tl,
int selected_sl,
uint32_t ssrc_to_filter_min,
uint32_t ssrc_to_filter_max);
LayerFilteringTransport(SingleThreadedTaskQueueForTesting* task_queue,
std::unique_ptr<FakeNetworkPipe> pipe,
Call* send_call,
Expand All @@ -52,6 +71,8 @@ class LayerFilteringTransport : public test::DirectTransport {
const int selected_tl_;
const int selected_sl_;
bool discarded_last_packet_;
const uint32_t ssrc_to_filter_min_;
const uint32_t ssrc_to_filter_max_;
};

} // namespace test
Expand Down
24 changes: 24 additions & 0 deletions video/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,30 @@ if (rtc_include_tests) {
}
}

rtc_executable("sv_loopback") {
testonly = true
sources = [
"sv_loopback.cc",
]
deps = [
":video_quality_test",
"../rtc_base:rtc_base_approved",
"../system_wrappers:metrics_default",
"../test:field_trial",
"../test:run_test",
"../test:run_test_interface",
"../test:test_common",
"../test:test_renderer",
"../test:test_support",
"//testing/gmock",
"//testing/gtest",
]
if (!build_with_chromium && is_clang) {
# Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
}
}

rtc_executable("video_replay") {
testonly = true
sources = [
Expand Down
Loading

0 comments on commit 255d1cd

Please sign in to comment.