Making FakeNetworkPipe demux audio and video packets.

BUG=None

Review-Url: https://codereview.webrtc.org/2794243002
Cr-Commit-Position: refs/heads/master@{#17629}
This commit is contained in:
minyue 2017-04-10 16:57:57 -07:00 committed by Commit bot
parent d9ce76444f
commit 20c84ccd48
18 changed files with 422 additions and 305 deletions

View File

@ -20,12 +20,9 @@ namespace {
// Wait half a second between stopping sending and stopping receiving audio.
constexpr int kExtraRecordTimeMs = 500;
// Large bitrate by default.
const webrtc::CodecInst kDefaultCodec{120, "OPUS", 48000, 960, 2, 64000};
// The best that can be done with PESQ.
constexpr int kAudioFileBitRate = 16000;
}
} // namespace
namespace webrtc {
namespace test {
@ -79,20 +76,20 @@ test::PacketTransport* AudioQualityTest::CreateSendTransport(
Call* sender_call) {
return new test::PacketTransport(
sender_call, this, test::PacketTransport::kSender,
MediaType::AUDIO,
GetNetworkPipeConfig());
test::CallTest::payload_type_map_, GetNetworkPipeConfig());
}
test::PacketTransport* AudioQualityTest::CreateReceiveTransport() {
return new test::PacketTransport(nullptr, this,
test::PacketTransport::kReceiver, MediaType::AUDIO,
GetNetworkPipeConfig());
return new test::PacketTransport(
nullptr, this, test::PacketTransport::kReceiver,
test::CallTest::payload_type_map_, GetNetworkPipeConfig());
}
void AudioQualityTest::ModifyAudioConfigs(
AudioSendStream::Config* send_config,
std::vector<AudioReceiveStream::Config>* receive_configs) {
send_config->send_codec_spec.codec_inst = kDefaultCodec;
send_config->send_codec_spec.codec_inst = webrtc::CodecInst{
test::CallTest::kAudioSendPayloadType, "OPUS", 48000, 960, 2, 64000};
}
void AudioQualityTest::PerformTest() {
@ -125,12 +122,12 @@ class Mobile2GNetworkTest : public AudioQualityTest {
void ModifyAudioConfigs(AudioSendStream::Config* send_config,
std::vector<AudioReceiveStream::Config>* receive_configs) override {
send_config->send_codec_spec.codec_inst = CodecInst{
120, // pltype
"OPUS", // plname
48000, // plfreq
2880, // pacsize
1, // channels
6000 // rate bits/sec
test::CallTest::kAudioSendPayloadType, // pltype
"OPUS", // plname
48000, // plfreq
2880, // pacsize
1, // channels
6000 // rate bits/sec
};
}

View File

@ -107,10 +107,10 @@ class BitrateEstimatorTest : public test::CallTest {
sender_call_.reset(Call::Create(config));
send_transport_.reset(
new test::DirectTransport(sender_call_.get(), MediaType::VIDEO));
new test::DirectTransport(sender_call_.get(), payload_type_map_));
send_transport_->SetReceiver(receiver_call_->Receiver());
receive_transport_.reset(
new test::DirectTransport(receiver_call_.get(), MediaType::VIDEO));
new test::DirectTransport(receiver_call_.get(), payload_type_map_));
receive_transport_->SetReceiver(sender_call_->Receiver());
video_send_config_ = VideoSendStream::Config(send_transport_.get());

View File

@ -191,26 +191,37 @@ void CallPerfTest::TestAudioVideoSync(FecMode fec,
FakeNetworkPipe::Config audio_net_config;
audio_net_config.queue_delay_ms = 500;
audio_net_config.loss_percent = 5;
std::map<uint8_t, MediaType> audio_pt_map;
std::map<uint8_t, MediaType> video_pt_map;
std::copy_if(std::begin(payload_type_map_), std::end(payload_type_map_),
std::inserter(audio_pt_map, audio_pt_map.end()),
[](const std::pair<const uint8_t, MediaType>& pair) {
return pair.second == MediaType::AUDIO;
});
std::copy_if(std::begin(payload_type_map_), std::end(payload_type_map_),
std::inserter(video_pt_map, video_pt_map.end()),
[](const std::pair<const uint8_t, MediaType>& pair) {
return pair.second == MediaType::VIDEO;
});
test::PacketTransport audio_send_transport(sender_call_.get(), &observer,
test::PacketTransport::kSender,
MediaType::AUDIO,
audio_net_config);
audio_pt_map, audio_net_config);
MediaTypePacketReceiver audio_receiver(receiver_call_->Receiver(),
MediaType::AUDIO);
audio_send_transport.SetReceiver(&audio_receiver);
test::PacketTransport video_send_transport(sender_call_.get(), &observer,
test::PacketTransport::kSender,
MediaType::VIDEO,
FakeNetworkPipe::Config());
test::PacketTransport video_send_transport(
sender_call_.get(), &observer, test::PacketTransport::kSender,
video_pt_map, FakeNetworkPipe::Config());
MediaTypePacketReceiver video_receiver(receiver_call_->Receiver(),
MediaType::VIDEO);
video_send_transport.SetReceiver(&video_receiver);
test::PacketTransport receive_transport(
receiver_call_.get(), &observer, test::PacketTransport::kReceiver,
MediaType::VIDEO,
FakeNetworkPipe::Config());
payload_type_map_, FakeNetworkPipe::Config());
receive_transport.SetReceiver(sender_call_->Receiver());
test::FakeDecoder fake_decoder;
@ -222,7 +233,7 @@ void CallPerfTest::TestAudioVideoSync(FecMode fec,
audio_send_config.voe_channel_id = send_channel_id;
audio_send_config.rtp.ssrc = kAudioSendSsrc;
audio_send_config.send_codec_spec.codec_inst =
CodecInst{103, "ISAC", 16000, 480, 1, 32000};
CodecInst{kAudioSendPayloadType, "ISAC", 16000, 480, 1, 32000};
AudioSendStream* audio_send_stream =
sender_call_->CreateAudioSendStream(audio_send_config);
@ -244,7 +255,7 @@ void CallPerfTest::TestAudioVideoSync(FecMode fec,
audio_recv_config.voe_channel_id = recv_channel_id;
audio_recv_config.sync_group = kSyncGroup;
audio_recv_config.decoder_factory = decoder_factory_;
audio_recv_config.decoder_map = {{103, {"ISAC", 16000, 1}}};
audio_recv_config.decoder_map = {{kAudioSendPayloadType, {"ISAC", 16000, 1}}};
AudioReceiveStream* audio_receive_stream;
@ -345,15 +356,15 @@ void CallPerfTest::TestCaptureNtpTime(const FakeNetworkPipe::Config& net_config,
private:
test::PacketTransport* CreateSendTransport(Call* sender_call) override {
return new test::PacketTransport(
sender_call, this, test::PacketTransport::kSender, MediaType::VIDEO,
net_config_);
return new test::PacketTransport(sender_call, this,
test::PacketTransport::kSender,
payload_type_map_, net_config_);
}
test::PacketTransport* CreateReceiveTransport() override {
return new test::PacketTransport(
nullptr, this, test::PacketTransport::kReceiver, MediaType::VIDEO,
net_config_);
return new test::PacketTransport(nullptr, this,
test::PacketTransport::kReceiver,
payload_type_map_, net_config_);
}
void OnFrame(const VideoFrame& video_frame) override {

View File

@ -90,10 +90,9 @@ void RampUpTester::OnVideoStreamsCreated(
}
test::PacketTransport* RampUpTester::CreateSendTransport(Call* sender_call) {
send_transport_ = new test::PacketTransport(sender_call, this,
test::PacketTransport::kSender,
SelectMediaType(),
forward_transport_config_);
send_transport_ = new test::PacketTransport(
sender_call, this, test::PacketTransport::kSender,
test::CallTest::payload_type_map_, forward_transport_config_);
return send_transport_;
}

View File

@ -26,29 +26,6 @@ namespace {
const int kVideoRotationRtpExtensionId = 4;
}
void CallTest::PayloadDemuxer::SetReceiver(PacketReceiver* receiver) {
receiver_ = receiver;
}
PacketReceiver::DeliveryStatus CallTest::PayloadDemuxer::DeliverPacket(
MediaType media_type,
const uint8_t* packet,
size_t length,
const PacketTime& packet_time) {
if (media_type == MediaType::ANY) {
// This simplistic demux logic will not make much sense for RTCP
// packets, but it seems that doesn't matter.
RTC_CHECK_GE(length, 2);
uint8_t pt = packet[1] & 0x7f;
if (pt == kFakeVideoSendPayloadType || pt == kFlexfecPayloadType) {
media_type = MediaType::VIDEO;
} else {
media_type = MediaType::AUDIO;
}
}
return receiver_->DeliverPacket(media_type, packet, length, packet_time);
}
CallTest::CallTest()
: clock_(Clock::GetRealTimeClock()),
event_log_(RtcEventLog::CreateNull()),
@ -99,20 +76,8 @@ void CallTest::RunBaseTest(BaseTest* test) {
send_transport_.reset(test->CreateSendTransport(sender_call_.get()));
if (test->ShouldCreateReceivers()) {
// For tests using only video or only audio, we rely on each test
// configuring the underlying FakeNetworkPipe with the right media
// type. But for tests sending both video and audio over the same
// FakeNetworkPipe, we need to "demux", i.e., setting the
// MediaType based on RTP payload type.
if (num_video_streams_ > 0 && num_audio_streams_ > 0) {
receive_demuxer_.SetReceiver(receiver_call_->Receiver());
send_transport_->SetReceiver(&receive_demuxer_);
send_demuxer_.SetReceiver(sender_call_->Receiver());
receive_transport_->SetReceiver(&send_demuxer_);
} else {
send_transport_->SetReceiver(receiver_call_->Receiver());
receive_transport_->SetReceiver(sender_call_->Receiver());
}
send_transport_->SetReceiver(receiver_call_->Receiver());
receive_transport_->SetReceiver(sender_call_->Receiver());
if (num_video_streams_ > 0)
receiver_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
if (num_audio_streams_ > 0)
@ -300,7 +265,7 @@ void CallTest::CreateMatchingReceiveConfigs(Transport* rtcp_send_transport) {
audio_config.voe_channel_id = voe_recv_.channel_id;
audio_config.rtp.remote_ssrc = audio_send_config_.rtp.ssrc;
audio_config.decoder_factory = decoder_factory_;
audio_config.decoder_map = {{120, {"opus", 48000, 2}}};
audio_config.decoder_map = {{kAudioSendPayloadType, {"opus", 48000, 2}}};
audio_receive_configs_.push_back(audio_config);
}
@ -462,6 +427,16 @@ const uint32_t CallTest::kReceiverLocalVideoSsrc = 0x123456;
const uint32_t CallTest::kReceiverLocalAudioSsrc = 0x1234567;
const int CallTest::kNackRtpHistoryMs = 1000;
const std::map<uint8_t, MediaType> CallTest::payload_type_map_ = {
{CallTest::kVideoSendPayloadType, MediaType::VIDEO},
{CallTest::kFakeVideoSendPayloadType, MediaType::VIDEO},
{CallTest::kSendRtxPayloadType, MediaType::VIDEO},
{CallTest::kRedPayloadType, MediaType::VIDEO},
{CallTest::kRtxRedPayloadType, MediaType::VIDEO},
{CallTest::kUlpfecPayloadType, MediaType::VIDEO},
{CallTest::kFlexfecPayloadType, MediaType::VIDEO},
{CallTest::kAudioSendPayloadType, MediaType::AUDIO}};
BaseTest::BaseTest() : event_log_(RtcEventLog::CreateNull()) {}
BaseTest::BaseTest(unsigned int timeout_ms)
@ -493,28 +468,15 @@ Call::Config BaseTest::GetReceiverCallConfig() {
void BaseTest::OnCallsCreated(Call* sender_call, Call* receiver_call) {
}
MediaType BaseTest::SelectMediaType() {
if (GetNumVideoStreams() > 0) {
if (GetNumAudioStreams() > 0) {
// Relies on PayloadDemuxer to set media type from payload type.
return MediaType::ANY;
} else {
return MediaType::VIDEO;
}
} else {
return MediaType::AUDIO;
}
}
test::PacketTransport* BaseTest::CreateSendTransport(Call* sender_call) {
return new PacketTransport(sender_call, this, test::PacketTransport::kSender,
SelectMediaType(),
CallTest::payload_type_map_,
FakeNetworkPipe::Config());
}
test::PacketTransport* BaseTest::CreateReceiveTransport() {
return new PacketTransport(nullptr, this, test::PacketTransport::kReceiver,
SelectMediaType(),
CallTest::payload_type_map_,
FakeNetworkPipe::Config());
}

View File

@ -57,25 +57,9 @@ class CallTest : public ::testing::Test {
static const uint32_t kReceiverLocalVideoSsrc;
static const uint32_t kReceiverLocalAudioSsrc;
static const int kNackRtpHistoryMs;
static const std::map<uint8_t, MediaType> payload_type_map_;
protected:
// Needed for tests sending both audio and video on the same
// FakeNetworkPipe. We then need to set correct MediaType based on
// packet payload type, before passing the packet on to Call.
class PayloadDemuxer : public PacketReceiver {
public:
PayloadDemuxer() = default;
void SetReceiver(PacketReceiver* receiver);
DeliveryStatus DeliverPacket(MediaType media_type,
const uint8_t* packet,
size_t length,
const PacketTime& packet_time) override;
private:
PacketReceiver* receiver_ = nullptr;
};
// RunBaseTest overwrites the audio_state and the voice_engine of the send and
// receive Call configs to simplify test code and avoid having old VoiceEngine
// APIs in the tests.
@ -141,9 +125,6 @@ class CallTest : public ::testing::Test {
rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_;
test::FakeVideoRenderer fake_renderer_;
PayloadDemuxer receive_demuxer_;
PayloadDemuxer send_demuxer_;
private:
// TODO(holmer): Remove once VoiceEngine is fully refactored to the new API.
// These methods are used to set up legacy voice engines and channels which is
@ -192,10 +173,6 @@ class BaseTest : public RtpRtcpObserver {
virtual Call::Config GetReceiverCallConfig();
virtual void OnCallsCreated(Call* sender_call, Call* receiver_call);
// Returns VIDEO for video-only tests, AUDIO for audio-only tests,
// and ANY for tests sending audio and video over the same
// transport.
virtual MediaType SelectMediaType();
virtual test::PacketTransport* CreateSendTransport(Call* sender_call);
virtual test::PacketTransport* CreateReceiveTransport();

View File

@ -15,17 +15,29 @@
namespace webrtc {
namespace test {
DirectTransport::DirectTransport(Call* send_call, MediaType media_type)
: DirectTransport(FakeNetworkPipe::Config(), send_call, media_type) {}
DirectTransport::DirectTransport(
Call* send_call,
const std::map<uint8_t, MediaType>& payload_type_map)
: DirectTransport(FakeNetworkPipe::Config(), send_call, payload_type_map) {}
DirectTransport::DirectTransport(
const FakeNetworkPipe::Config& config,
Call* send_call,
const std::map<uint8_t, MediaType>& payload_type_map)
: DirectTransport(
config,
send_call,
std::unique_ptr<Demuxer>(new DemuxerImpl(payload_type_map))) {}
DirectTransport::DirectTransport(const FakeNetworkPipe::Config& config,
Call* send_call, MediaType media_type)
Call* send_call,
std::unique_ptr<Demuxer> demuxer)
: send_call_(send_call),
packet_event_(false, false),
thread_(NetworkProcess, this, "NetworkProcess"),
clock_(Clock::GetRealTimeClock()),
shutting_down_(false),
fake_network_(clock_, config, media_type) {
fake_network_(clock_, config, std::move(demuxer)) {
thread_.Start();
if (send_call_) {
send_call_->SignalChannelNetworkState(MediaType::AUDIO, kNetworkUp);
@ -76,6 +88,22 @@ int DirectTransport::GetAverageDelayMs() {
return fake_network_.AverageDelay();
}
DirectTransport::ForceDemuxer::ForceDemuxer(MediaType media_type)
: media_type_(media_type) {}
void DirectTransport::ForceDemuxer::SetReceiver(PacketReceiver* receiver) {
packet_receiver_ = receiver;
}
void DirectTransport::ForceDemuxer::DeliverPacket(
const NetworkPacket* packet,
const PacketTime& packet_time) {
if (!packet_receiver_)
return;
packet_receiver_->DeliverPacket(media_type_, packet->data(),
packet->data_length(), packet_time);
}
bool DirectTransport::NetworkProcess(void* transport) {
return static_cast<DirectTransport*>(transport)->SendPackets();
}

View File

@ -30,16 +30,42 @@ namespace test {
class DirectTransport : public Transport {
public:
DirectTransport(Call* send_call, MediaType media_type);
DirectTransport(const FakeNetworkPipe::Config& config, Call* send_call,
MediaType media_type);
DirectTransport(Call* send_call,
const std::map<uint8_t, MediaType>& payload_type_map);
DirectTransport(const FakeNetworkPipe::Config& config,
Call* send_call,
const std::map<uint8_t, MediaType>& payload_type_map);
DirectTransport(const FakeNetworkPipe::Config& config,
Call* send_call,
std::unique_ptr<Demuxer> demuxer);
// These deprecated variants always use ForceDemuxer.
RTC_DEPRECATED DirectTransport(Call* send_call, MediaType media_type)
: DirectTransport(
FakeNetworkPipe::Config(),
send_call,
std::unique_ptr<Demuxer>(new ForceDemuxer(media_type))) {}
RTC_DEPRECATED DirectTransport(const FakeNetworkPipe::Config& config,
Call* send_call,
MediaType media_type)
: DirectTransport(
config,
send_call,
std::unique_ptr<Demuxer>(new ForceDemuxer(media_type))) {}
// These deprecated variants always use MediaType::VIDEO.
RTC_DEPRECATED explicit DirectTransport(Call* send_call)
: DirectTransport(send_call, MediaType::VIDEO) {}
: DirectTransport(
FakeNetworkPipe::Config(),
send_call,
std::unique_ptr<Demuxer>(new ForceDemuxer(MediaType::VIDEO))) {}
RTC_DEPRECATED DirectTransport(const FakeNetworkPipe::Config& config,
Call* send_call)
: DirectTransport(config, send_call, MediaType::VIDEO) {}
: DirectTransport(
config,
send_call,
std::unique_ptr<Demuxer>(new ForceDemuxer(MediaType::VIDEO))) {}
~DirectTransport();
@ -57,6 +83,21 @@ class DirectTransport : public Transport {
int GetAverageDelayMs();
private:
// TODO(minyue): remove when the deprecated ctors of DirectTransport that
// create ForceDemuxer are removed.
class ForceDemuxer : public Demuxer {
public:
explicit ForceDemuxer(MediaType media_type);
void SetReceiver(PacketReceiver* receiver) override;
void DeliverPacket(const NetworkPacket* packet,
const PacketTime& packet_time) override;
private:
const MediaType media_type_;
PacketReceiver* packet_receiver_;
RTC_DISALLOW_COPY_AND_ASSIGN(ForceDemuxer);
};
static bool NetworkProcess(void* transport);
bool SendPackets();

View File

@ -19,6 +19,7 @@
#include "webrtc/base/logging.h"
#include "webrtc/call/call.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
#include "webrtc/system_wrappers/include/clock.h"
namespace webrtc {
@ -27,18 +28,46 @@ namespace {
constexpr int64_t kDefaultProcessIntervalMs = 5;
}
FakeNetworkPipe::FakeNetworkPipe(Clock* clock,
const FakeNetworkPipe::Config& config,
MediaType media_type)
: FakeNetworkPipe(clock, config, media_type, 1) {}
DemuxerImpl::DemuxerImpl(const std::map<uint8_t, MediaType>& payload_type_map)
: packet_receiver_(nullptr), payload_type_map_(payload_type_map) {}
void DemuxerImpl::SetReceiver(PacketReceiver* receiver) {
packet_receiver_ = receiver;
}
void DemuxerImpl::DeliverPacket(const NetworkPacket* packet,
const PacketTime& packet_time) {
// No packet receiver means that this demuxer will terminate the flow of
// packets.
if (!packet_receiver_)
return;
const uint8_t* const packet_data = packet->data();
const size_t packet_length = packet->data_length();
MediaType media_type = MediaType::ANY;
if (!RtpHeaderParser::IsRtcp(packet_data, packet_length)) {
RTC_CHECK_GE(packet_length, 2);
const uint8_t payload_type = packet_data[1] & 0x7f;
std::map<uint8_t, MediaType>::const_iterator it =
payload_type_map_.find(payload_type);
RTC_CHECK(it != payload_type_map_.end())
<< "payload type " << static_cast<int>(payload_type) << " unknown.";
media_type = it->second;
}
packet_receiver_->DeliverPacket(media_type, packet_data, packet_length,
packet_time);
}
FakeNetworkPipe::FakeNetworkPipe(Clock* clock,
const FakeNetworkPipe::Config& config,
MediaType media_type,
std::unique_ptr<Demuxer> demuxer)
: FakeNetworkPipe(clock, config, std::move(demuxer), 1) {}
FakeNetworkPipe::FakeNetworkPipe(Clock* clock,
const FakeNetworkPipe::Config& config,
std::unique_ptr<Demuxer> demuxer,
uint64_t seed)
: clock_(clock),
media_type_(media_type),
packet_receiver_(NULL),
demuxer_(std::move(demuxer)),
random_(seed),
config_(),
dropped_packets_(0),
@ -62,7 +91,8 @@ FakeNetworkPipe::~FakeNetworkPipe() {
}
void FakeNetworkPipe::SetReceiver(PacketReceiver* receiver) {
packet_receiver_ = receiver;
RTC_CHECK(demuxer_);
demuxer_->SetReceiver(receiver);
}
void FakeNetworkPipe::SetConfig(const FakeNetworkPipe::Config& config) {
@ -89,10 +119,7 @@ void FakeNetworkPipe::SetConfig(const FakeNetworkPipe::Config& config) {
}
void FakeNetworkPipe::SendPacket(const uint8_t* data, size_t data_length) {
// A NULL packet_receiver_ means that this pipe will terminate the flow of
// packets.
if (packet_receiver_ == NULL)
return;
RTC_CHECK(demuxer_);
rtc::CritScope crit(&lock_);
if (config_.queue_length_packets > 0 &&
capacity_link_.size() >= config_.queue_length_packets) {
@ -202,8 +229,7 @@ void FakeNetworkPipe::Process() {
while (!packets_to_deliver.empty()) {
NetworkPacket* packet = packets_to_deliver.front();
packets_to_deliver.pop();
packet_receiver_->DeliverPacket(media_type_, packet->data(),
packet->data_length(), PacketTime());
demuxer_->DeliverPacket(packet, PacketTime());
delete packet;
}

View File

@ -11,14 +11,16 @@
#ifndef WEBRTC_TEST_FAKE_NETWORK_PIPE_H_
#define WEBRTC_TEST_FAKE_NETWORK_PIPE_H_
#include <memory>
#include <set>
#include <string.h>
#include <map>
#include <memory>
#include <queue>
#include <set>
#include "webrtc/base/constructormagic.h"
#include "webrtc/base/criticalsection.h"
#include "webrtc/base/random.h"
#include "webrtc/common_types.h"
#include "webrtc/typedefs.h"
namespace webrtc {
@ -59,6 +61,28 @@ class NetworkPacket {
int64_t arrival_time_;
};
class Demuxer {
public:
virtual ~Demuxer() = default;
virtual void SetReceiver(PacketReceiver* receiver) = 0;
virtual void DeliverPacket(const NetworkPacket* packet,
const PacketTime& packet_time) = 0;
};
class DemuxerImpl final : public Demuxer {
public:
explicit DemuxerImpl(const std::map<uint8_t, MediaType>& payload_type_map);
void SetReceiver(PacketReceiver* receiver) override;
void DeliverPacket(const NetworkPacket* packet,
const PacketTime& packet_time) override;
private:
PacketReceiver* packet_receiver_;
const std::map<uint8_t, MediaType> payload_type_map_;
RTC_DISALLOW_COPY_AND_ASSIGN(DemuxerImpl);
};
// Class faking a network link. This is a simple and naive solution just faking
// capacity and adding an extra transport delay in addition to the capacity
// introduced delay.
@ -83,15 +107,15 @@ class FakeNetworkPipe {
int avg_burst_loss_length = -1;
};
FakeNetworkPipe(Clock* clock, const FakeNetworkPipe::Config& config,
MediaType media_type);
FakeNetworkPipe(Clock* clock,
const FakeNetworkPipe::Config& config, MediaType media_type,
const FakeNetworkPipe::Config& config,
std::unique_ptr<Demuxer> demuxer);
FakeNetworkPipe(Clock* clock,
const FakeNetworkPipe::Config& config,
std::unique_ptr<Demuxer> demuxer,
uint64_t seed);
~FakeNetworkPipe();
// Must not be called in parallel with SendPacket or Process.
void SetReceiver(PacketReceiver* receiver);
// Sets a new configuration. This won't affect packets already in the pipe.
void SetConfig(const FakeNetworkPipe::Config& config);
@ -99,6 +123,9 @@ class FakeNetworkPipe {
// Sends a new packet to the link.
void SendPacket(const uint8_t* packet, size_t packet_length);
// Must not be called in parallel with SendPacket or Process.
void SetReceiver(PacketReceiver* receiver);
// Processes the network queues and trigger PacketReceiver::IncomingPacket for
// packets ready to be delivered.
void Process();
@ -112,9 +139,8 @@ class FakeNetworkPipe {
private:
Clock* const clock_;
const MediaType media_type_;
rtc::CriticalSection lock_;
PacketReceiver* packet_receiver_;
const std::unique_ptr<Demuxer> demuxer_;
std::queue<NetworkPacket*> capacity_link_;
Random random_;

View File

@ -11,6 +11,7 @@
#include <memory>
#include "webrtc/call/call.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
#include "webrtc/system_wrappers/include/clock.h"
#include "webrtc/test/fake_network_pipe.h"
#include "webrtc/test/gmock.h"
@ -23,52 +24,42 @@ using ::testing::Invoke;
namespace webrtc {
class TestReceiver : public PacketReceiver {
class TestDemuxer : public Demuxer {
public:
TestReceiver() {}
virtual ~TestReceiver() {}
void IncomingPacket(const uint8_t* data, size_t length) {
DeliverPacket(MediaType::ANY, data, length, PacketTime());
delete [] data;
void IncomingPacket(NetworkPacket* packet) {
DeliverPacket(packet, PacketTime());
}
virtual MOCK_METHOD4(
DeliverPacket,
DeliveryStatus(MediaType, const uint8_t*, size_t, const PacketTime&));
MOCK_METHOD1(SetReceiver, void(PacketReceiver* receiver));
MOCK_METHOD2(DeliverPacket,
void(const NetworkPacket* packet,
const PacketTime& packet_time));
};
class ReorderTestReceiver : public TestReceiver {
class ReorderTestDemuxer : public TestDemuxer {
public:
ReorderTestReceiver() {}
virtual ~ReorderTestReceiver() {}
DeliveryStatus DeliverPacket(MediaType media_type,
const uint8_t* packet,
size_t length,
const PacketTime& packet_time) override {
void DeliverPacket(const NetworkPacket* packet,
const PacketTime& packet_time) override {
RTC_DCHECK_GE(packet->data_length(), sizeof(int));
int seq_num;
memcpy(&seq_num, packet, sizeof(int));
memcpy(&seq_num, packet->data(), sizeof(int));
delivered_sequence_numbers_.push_back(seq_num);
return PacketReceiver::DELIVERY_OK;
}
std::vector<int> delivered_sequence_numbers_;
};
class MockReceiver : public PacketReceiver {
public:
MOCK_METHOD4(
DeliverPacket,
DeliveryStatus(MediaType, const uint8_t*, size_t, const PacketTime&));
};
class FakeNetworkPipeTest : public ::testing::Test {
public:
FakeNetworkPipeTest() : fake_clock_(12345) {}
protected:
virtual void SetUp() {
receiver_.reset(new TestReceiver());
ON_CALL(*receiver_, DeliverPacket(_, _, _, _))
.WillByDefault(Return(PacketReceiver::DELIVERY_OK));
}
virtual void TearDown() {
}
void SendPackets(FakeNetworkPipe* pipe, int number_packets, int packet_size) {
RTC_DCHECK_GE(packet_size, sizeof(int));
std::unique_ptr<uint8_t[]> packet(new uint8_t[packet_size]);
@ -85,47 +76,44 @@ class FakeNetworkPipeTest : public ::testing::Test {
}
SimulatedClock fake_clock_;
std::unique_ptr<TestReceiver> receiver_;
};
void DeleteMemory(uint8_t* data, int length) { delete [] data; }
// Test the capacity link and verify we get as many packets as we expect.
TEST_F(FakeNetworkPipeTest, CapacityTest) {
FakeNetworkPipe::Config config;
config.queue_length_packets = 20;
config.link_capacity_kbps = 80;
std::unique_ptr<FakeNetworkPipe> pipe(
new FakeNetworkPipe(&fake_clock_, config, MediaType::VIDEO));
pipe->SetReceiver(receiver_.get());
TestDemuxer* demuxer = new TestDemuxer();
std::unique_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(
&fake_clock_, config, std::unique_ptr<Demuxer>(demuxer)));
// Add 10 packets of 1000 bytes, = 80 kb, and verify it takes one second to
// get through the pipe.
const int kNumPackets = 10;
const int kPacketSize = 1000;
SendPackets(pipe.get(), kNumPackets , kPacketSize);
SendPackets(pipe.get(), kNumPackets, kPacketSize);
// Time to get one packet through the link.
const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
kPacketSize);
// Time haven't increased yet, so we souldn't get any packets.
EXPECT_CALL(*receiver_, DeliverPacket(MediaType::VIDEO, _, _, _)).Times(0);
EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(0);
pipe->Process();
// Advance enough time to release one packet.
fake_clock_.AdvanceTimeMilliseconds(kPacketTimeMs);
EXPECT_CALL(*receiver_, DeliverPacket(MediaType::VIDEO, _, _, _)).Times(1);
EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(1);
pipe->Process();
// Release all but one packet
fake_clock_.AdvanceTimeMilliseconds(9 * kPacketTimeMs - 1);
EXPECT_CALL(*receiver_, DeliverPacket(MediaType::VIDEO, _, _, _)).Times(8);
EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(8);
pipe->Process();
// And the last one.
fake_clock_.AdvanceTimeMilliseconds(1);
EXPECT_CALL(*receiver_, DeliverPacket(MediaType::VIDEO, _, _, _)).Times(1);
EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(1);
pipe->Process();
}
@ -135,13 +123,13 @@ TEST_F(FakeNetworkPipeTest, ExtraDelayTest) {
config.queue_length_packets = 20;
config.queue_delay_ms = 100;
config.link_capacity_kbps = 80;
std::unique_ptr<FakeNetworkPipe> pipe(
new FakeNetworkPipe(&fake_clock_, config, MediaType::AUDIO));
pipe->SetReceiver(receiver_.get());
TestDemuxer* demuxer = new TestDemuxer();
std::unique_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(
&fake_clock_, config, std::unique_ptr<Demuxer>(demuxer)));
const int kNumPackets = 2;
const int kPacketSize = 1000;
SendPackets(pipe.get(), kNumPackets , kPacketSize);
SendPackets(pipe.get(), kNumPackets, kPacketSize);
// Time to get one packet through the link.
const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
@ -149,17 +137,17 @@ TEST_F(FakeNetworkPipeTest, ExtraDelayTest) {
// Increase more than kPacketTimeMs, but not more than the extra delay.
fake_clock_.AdvanceTimeMilliseconds(kPacketTimeMs);
EXPECT_CALL(*receiver_, DeliverPacket(MediaType::AUDIO, _, _, _)).Times(0);
EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(0);
pipe->Process();
// Advance the network delay to get the first packet.
fake_clock_.AdvanceTimeMilliseconds(config.queue_delay_ms);
EXPECT_CALL(*receiver_, DeliverPacket(MediaType::AUDIO, _, _, _)).Times(1);
EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(1);
pipe->Process();
// Advance one more kPacketTimeMs to get the last packet.
fake_clock_.AdvanceTimeMilliseconds(kPacketTimeMs);
EXPECT_CALL(*receiver_, DeliverPacket(MediaType::AUDIO, _, _, _)).Times(1);
EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(1);
pipe->Process();
}
@ -169,9 +157,9 @@ TEST_F(FakeNetworkPipeTest, QueueLengthTest) {
FakeNetworkPipe::Config config;
config.queue_length_packets = 2;
config.link_capacity_kbps = 80;
std::unique_ptr<FakeNetworkPipe> pipe(
new FakeNetworkPipe(&fake_clock_, config, MediaType::VIDEO));
pipe->SetReceiver(receiver_.get());
TestDemuxer* demuxer = new TestDemuxer();
std::unique_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(
&fake_clock_, config, std::unique_ptr<Demuxer>(demuxer)));
const int kPacketSize = 1000;
const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
@ -183,7 +171,7 @@ TEST_F(FakeNetworkPipeTest, QueueLengthTest) {
// Increase time enough to deliver all three packets, verify only two are
// delivered.
fake_clock_.AdvanceTimeMilliseconds(3 * kPacketTimeMs);
EXPECT_CALL(*receiver_, DeliverPacket(MediaType::VIDEO, _, _, _)).Times(2);
EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(2);
pipe->Process();
}
@ -193,9 +181,9 @@ TEST_F(FakeNetworkPipeTest, StatisticsTest) {
config.queue_length_packets = 2;
config.queue_delay_ms = 20;
config.link_capacity_kbps = 80;
std::unique_ptr<FakeNetworkPipe> pipe(
new FakeNetworkPipe(&fake_clock_, config, MediaType::VIDEO));
pipe->SetReceiver(receiver_.get());
TestDemuxer* demuxer = new TestDemuxer();
std::unique_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(
&fake_clock_, config, std::unique_ptr<Demuxer>(demuxer)));
const int kPacketSize = 1000;
const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
@ -206,7 +194,7 @@ TEST_F(FakeNetworkPipeTest, StatisticsTest) {
fake_clock_.AdvanceTimeMilliseconds(3 * kPacketTimeMs +
config.queue_delay_ms);
EXPECT_CALL(*receiver_, DeliverPacket(MediaType::VIDEO, _, _, _)).Times(2);
EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(2);
pipe->Process();
// Packet 1: kPacketTimeMs + config.queue_delay_ms,
@ -223,9 +211,9 @@ TEST_F(FakeNetworkPipeTest, ChangingCapacityWithEmptyPipeTest) {
FakeNetworkPipe::Config config;
config.queue_length_packets = 20;
config.link_capacity_kbps = 80;
std::unique_ptr<FakeNetworkPipe> pipe(
new FakeNetworkPipe(&fake_clock_, config, MediaType::VIDEO));
pipe->SetReceiver(receiver_.get());
TestDemuxer* demuxer = new TestDemuxer();
std::unique_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(
&fake_clock_, config, std::unique_ptr<Demuxer>(demuxer)));
// Add 10 packets of 1000 bytes, = 80 kb, and verify it takes one second to
// get through the pipe.
@ -237,13 +225,13 @@ TEST_F(FakeNetworkPipeTest, ChangingCapacityWithEmptyPipeTest) {
int packet_time_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize);
// Time hasn't increased yet, so we souldn't get any packets.
EXPECT_CALL(*receiver_, DeliverPacket(MediaType::VIDEO, _, _, _)).Times(0);
EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(0);
pipe->Process();
// Advance time in steps to release one packet at a time.
for (int i = 0; i < kNumPackets; ++i) {
fake_clock_.AdvanceTimeMilliseconds(packet_time_ms);
EXPECT_CALL(*receiver_, DeliverPacket(MediaType::VIDEO, _, _, _)).Times(1);
EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(1);
pipe->Process();
}
@ -259,20 +247,20 @@ TEST_F(FakeNetworkPipeTest, ChangingCapacityWithEmptyPipeTest) {
packet_time_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize);
// Time hasn't increased yet, so we souldn't get any packets.
EXPECT_CALL(*receiver_, DeliverPacket(MediaType::VIDEO, _, _, _)).Times(0);
EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(0);
pipe->Process();
// Advance time in steps to release one packet at a time.
for (int i = 0; i < kNumPackets; ++i) {
fake_clock_.AdvanceTimeMilliseconds(packet_time_ms);
EXPECT_CALL(*receiver_, DeliverPacket(MediaType::VIDEO, _, _, _)).Times(1);
EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(1);
pipe->Process();
}
// Check that all the packets were sent.
EXPECT_EQ(static_cast<size_t>(2 * kNumPackets), pipe->sent_packets());
fake_clock_.AdvanceTimeMilliseconds(pipe->TimeUntilNextProcess());
EXPECT_CALL(*receiver_, DeliverPacket(MediaType::VIDEO, _, _, _)).Times(0);
EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(0);
pipe->Process();
}
@ -282,9 +270,9 @@ TEST_F(FakeNetworkPipeTest, ChangingCapacityWithPacketsInPipeTest) {
FakeNetworkPipe::Config config;
config.queue_length_packets = 20;
config.link_capacity_kbps = 80;
std::unique_ptr<FakeNetworkPipe> pipe(
new FakeNetworkPipe(&fake_clock_, config, MediaType::AUDIO));
pipe->SetReceiver(receiver_.get());
TestDemuxer* demuxer = new TestDemuxer();
std::unique_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(
&fake_clock_, config, std::unique_ptr<Demuxer>(demuxer)));
// Add 10 packets of 1000 bytes, = 80 kb.
const int kNumPackets = 10;
@ -306,27 +294,27 @@ TEST_F(FakeNetworkPipeTest, ChangingCapacityWithPacketsInPipeTest) {
int packet_time_2_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize);
// Time hasn't increased yet, so we souldn't get any packets.
EXPECT_CALL(*receiver_, DeliverPacket(MediaType::AUDIO, _, _, _)).Times(0);
EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(0);
pipe->Process();
// Advance time in steps to release one packet at a time.
for (int i = 0; i < kNumPackets; ++i) {
fake_clock_.AdvanceTimeMilliseconds(packet_time_1_ms);
EXPECT_CALL(*receiver_, DeliverPacket(MediaType::AUDIO, _, _, _)).Times(1);
EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(1);
pipe->Process();
}
// Advance time in steps to release one packet at a time.
for (int i = 0; i < kNumPackets; ++i) {
fake_clock_.AdvanceTimeMilliseconds(packet_time_2_ms);
EXPECT_CALL(*receiver_, DeliverPacket(MediaType::AUDIO, _, _, _)).Times(1);
EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(1);
pipe->Process();
}
// Check that all the packets were sent.
EXPECT_EQ(static_cast<size_t>(2 * kNumPackets), pipe->sent_packets());
fake_clock_.AdvanceTimeMilliseconds(pipe->TimeUntilNextProcess());
EXPECT_CALL(*receiver_, DeliverPacket(MediaType::AUDIO, _, _, _)).Times(0);
EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(0);
pipe->Process();
}
@ -337,11 +325,9 @@ TEST_F(FakeNetworkPipeTest, DisallowReorderingThenAllowReordering) {
config.link_capacity_kbps = 800;
config.queue_delay_ms = 100;
config.delay_standard_deviation_ms = 10;
std::unique_ptr<FakeNetworkPipe> pipe(
new FakeNetworkPipe(&fake_clock_, config, MediaType::VIDEO));
ReorderTestReceiver* receiver = new ReorderTestReceiver();
receiver_.reset(receiver);
pipe->SetReceiver(receiver_.get());
ReorderTestDemuxer* demuxer = new ReorderTestDemuxer();
std::unique_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(
&fake_clock_, config, std::unique_ptr<Demuxer>(demuxer)));
const uint32_t kNumPackets = 100;
const int kPacketSize = 10;
@ -350,9 +336,9 @@ TEST_F(FakeNetworkPipeTest, DisallowReorderingThenAllowReordering) {
pipe->Process();
// Confirm that all packets have been delivered in order.
EXPECT_EQ(kNumPackets, receiver->delivered_sequence_numbers_.size());
EXPECT_EQ(kNumPackets, demuxer->delivered_sequence_numbers_.size());
int last_seq_num = -1;
for (int seq_num : receiver->delivered_sequence_numbers_) {
for (int seq_num : demuxer->delivered_sequence_numbers_) {
EXPECT_GT(seq_num, last_seq_num);
last_seq_num = seq_num;
}
@ -361,15 +347,15 @@ TEST_F(FakeNetworkPipeTest, DisallowReorderingThenAllowReordering) {
pipe->SetConfig(config);
SendPackets(pipe.get(), kNumPackets, kPacketSize);
fake_clock_.AdvanceTimeMilliseconds(1000);
receiver->delivered_sequence_numbers_.clear();
demuxer->delivered_sequence_numbers_.clear();
pipe->Process();
// Confirm that all packets have been delivered
// and that reordering has occured.
EXPECT_EQ(kNumPackets, receiver->delivered_sequence_numbers_.size());
EXPECT_EQ(kNumPackets, demuxer->delivered_sequence_numbers_.size());
bool reordering_has_occured = false;
last_seq_num = -1;
for (int seq_num : receiver->delivered_sequence_numbers_) {
for (int seq_num : demuxer->delivered_sequence_numbers_) {
if (last_seq_num > seq_num) {
reordering_has_occured = true;
break;
@ -389,28 +375,26 @@ TEST_F(FakeNetworkPipeTest, BurstLoss) {
config.queue_length_packets = kNumPackets;
config.loss_percent = kLossPercent;
config.avg_burst_loss_length = kAvgBurstLength;
std::unique_ptr<FakeNetworkPipe> pipe(
new FakeNetworkPipe(&fake_clock_, config, MediaType::VIDEO));
ReorderTestReceiver* receiver = new ReorderTestReceiver();
receiver_.reset(receiver);
pipe->SetReceiver(receiver_.get());
ReorderTestDemuxer* demuxer = new ReorderTestDemuxer();
std::unique_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(
&fake_clock_, config, std::unique_ptr<Demuxer>(demuxer)));
SendPackets(pipe.get(), kNumPackets, kPacketSize);
fake_clock_.AdvanceTimeMilliseconds(1000);
pipe->Process();
// Check that the average loss is |kLossPercent| percent.
int lost_packets = kNumPackets - receiver->delivered_sequence_numbers_.size();
int lost_packets = kNumPackets - demuxer->delivered_sequence_numbers_.size();
double loss_fraction = lost_packets / static_cast<double>(kNumPackets);
EXPECT_NEAR(kLossPercent / 100.0, loss_fraction, 0.05);
// Find the number of bursts that has occurred.
size_t received_packets = receiver->delivered_sequence_numbers_.size();
size_t received_packets = demuxer->delivered_sequence_numbers_.size();
int num_bursts = 0;
for (size_t i = 0; i < received_packets - 1; ++i) {
int diff = receiver->delivered_sequence_numbers_[i + 1] -
receiver->delivered_sequence_numbers_[i];
int diff = demuxer->delivered_sequence_numbers_[i + 1] -
demuxer->delivered_sequence_numbers_[i];
if (diff > 1)
++num_bursts;
}
@ -419,4 +403,43 @@ TEST_F(FakeNetworkPipeTest, BurstLoss) {
EXPECT_NEAR(kAvgBurstLength, average_burst_length, 0.3);
}
TEST_F(FakeNetworkPipeTest, SetReceiver) {
FakeNetworkPipe::Config config;
TestDemuxer* demuxer = new TestDemuxer();
std::unique_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(
&fake_clock_, config, std::unique_ptr<Demuxer>(demuxer)));
MockReceiver packet_receiver;
EXPECT_CALL(*demuxer, SetReceiver(&packet_receiver)).Times(1);
pipe->SetReceiver(&packet_receiver);
}
TEST(DemuxerImplTest, Demuxing) {
constexpr uint8_t kVideoPayloadType = 100;
constexpr uint8_t kAudioPayloadType = 101;
constexpr int64_t kTimeNow = 12345;
constexpr int64_t kArrivalTime = kTimeNow - 1;
constexpr size_t kPacketSize = 10;
DemuxerImpl demuxer({{kVideoPayloadType, MediaType::VIDEO},
{kAudioPayloadType, MediaType::AUDIO}});
MockReceiver mock_receiver;
demuxer.SetReceiver(&mock_receiver);
std::vector<uint8_t> data(kPacketSize);
data[1] = kVideoPayloadType;
std::unique_ptr<NetworkPacket> packet(
new NetworkPacket(&data[0], kPacketSize, kTimeNow, kArrivalTime));
EXPECT_CALL(mock_receiver, DeliverPacket(MediaType::VIDEO, _, _, _))
.WillOnce(Return(PacketReceiver::DELIVERY_OK));
demuxer.DeliverPacket(packet.get(), PacketTime());
data[1] = kAudioPayloadType;
packet.reset(
new NetworkPacket(&data[0], kPacketSize, kTimeNow, kArrivalTime));
EXPECT_CALL(mock_receiver, DeliverPacket(MediaType::AUDIO, _, _, _))
.WillOnce(Return(PacketReceiver::DELIVERY_OK));
demuxer.DeliverPacket(packet.get(), PacketTime());
}
} // namespace webrtc

View File

@ -26,8 +26,9 @@ LayerFilteringTransport::LayerFilteringTransport(
uint8_t vp8_video_payload_type,
uint8_t vp9_video_payload_type,
int selected_tl,
int selected_sl)
: test::DirectTransport(config, send_call, MediaType::VIDEO),
int selected_sl,
const std::map<uint8_t, MediaType>& payload_type_map)
: test::DirectTransport(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),

View File

@ -27,7 +27,8 @@ class LayerFilteringTransport : public test::DirectTransport {
uint8_t vp8_video_payload_type,
uint8_t vp9_video_payload_type,
int selected_tl,
int selected_sl);
int selected_sl,
const std::map<uint8_t, MediaType>& payload_type_map);
bool DiscardedLastPacket() const;
bool SendRtp(const uint8_t* data,
size_t length,

View File

@ -94,9 +94,9 @@ class PacketTransport : public test::DirectTransport {
PacketTransport(Call* send_call,
RtpRtcpObserver* observer,
TransportType transport_type,
MediaType media_type,
const std::map<uint8_t, MediaType>& payload_type_map,
const FakeNetworkPipe::Config& configuration)
: test::DirectTransport(configuration, send_call, media_type),
: test::DirectTransport(configuration, send_call, payload_type_map),
observer_(observer),
transport_type_(transport_type) {}

View File

@ -66,7 +66,9 @@
namespace webrtc {
static const int kSilenceTimeoutMs = 2000;
namespace {
constexpr int kSilenceTimeoutMs = 2000;
}
class EndToEndTest : public test::CallTest {
public:
@ -210,10 +212,9 @@ TEST_F(EndToEndTest, RendersSingleDelayedFrame) {
CreateCalls(Call::Config(event_log_.get()), Call::Config(event_log_.get()));
test::DirectTransport sender_transport(
sender_call_.get(), MediaType::VIDEO);
test::DirectTransport receiver_transport(
receiver_call_.get(), MediaType::VIDEO);
test::DirectTransport sender_transport(sender_call_.get(), payload_type_map_);
test::DirectTransport receiver_transport(receiver_call_.get(),
payload_type_map_);
sender_transport.SetReceiver(receiver_call_->Receiver());
receiver_transport.SetReceiver(sender_call_->Receiver());
@ -260,10 +261,9 @@ TEST_F(EndToEndTest, TransmitsFirstFrame) {
CreateCalls(Call::Config(event_log_.get()), Call::Config(event_log_.get()));
test::DirectTransport sender_transport(
sender_call_.get(), MediaType::VIDEO);
test::DirectTransport receiver_transport(
receiver_call_.get(), MediaType::VIDEO);
test::DirectTransport sender_transport(sender_call_.get(), payload_type_map_);
test::DirectTransport receiver_transport(receiver_call_.get(),
payload_type_map_);
sender_transport.SetReceiver(receiver_call_->Receiver());
receiver_transport.SetReceiver(sender_call_->Receiver());
@ -323,7 +323,8 @@ class CodecObserver : public test::EndToEndTest,
VideoEncoderConfig* encoder_config) override {
send_config->encoder_settings.encoder = encoder_.get();
send_config->encoder_settings.payload_name = payload_name_;
send_config->encoder_settings.payload_type = 126;
send_config->encoder_settings.payload_type =
test::CallTest::kVideoSendPayloadType;
(*receive_configs)[0].renderer = this;
(*receive_configs)[0].decoders.resize(1);
@ -534,8 +535,7 @@ TEST_F(EndToEndTest, ReceivesNackAndRetransmitsAudio) {
test::PacketTransport* CreateReceiveTransport() override {
test::PacketTransport* receive_transport = new test::PacketTransport(
nullptr, this, test::PacketTransport::kReceiver,
MediaType::AUDIO,
nullptr, this, test::PacketTransport::kReceiver, payload_type_map_,
FakeNetworkPipe::Config());
receive_transport_ = receive_transport;
return receive_transport;
@ -798,7 +798,7 @@ class FlexfecRenderObserver : public test::EndToEndTest,
config.queue_delay_ms = kNetworkDelayMs;
return new test::PacketTransport(sender_call, this,
test::PacketTransport::kSender,
MediaType::VIDEO, config);
test::CallTest::payload_type_map_, config);
}
void OnFrame(const VideoFrame& video_frame) override {
@ -978,7 +978,7 @@ TEST_F(EndToEndTest, ReceivedUlpfecPacketsNotNacked) {
config.queue_delay_ms = kNetworkDelayMs;
return new test::PacketTransport(sender_call, this,
test::PacketTransport::kSender,
MediaType::VIDEO, config);
payload_type_map_, config);
}
// TODO(holmer): Investigate why we don't send FEC packets when the bitrate
@ -1320,10 +1320,9 @@ TEST_F(EndToEndTest, UnknownRtpPacketGivesUnknownSsrcReturnCode) {
CreateCalls(Call::Config(event_log_.get()), Call::Config(event_log_.get()));
test::DirectTransport send_transport(
sender_call_.get(), MediaType::VIDEO);
test::DirectTransport receive_transport(
receiver_call_.get(), MediaType::VIDEO);
test::DirectTransport send_transport(sender_call_.get(), payload_type_map_);
test::DirectTransport receive_transport(receiver_call_.get(),
payload_type_map_);
PacketInputObserver input_observer(receiver_call_->Receiver());
send_transport.SetReceiver(&input_observer);
receive_transport.SetReceiver(sender_call_->Receiver());
@ -1443,7 +1442,11 @@ TEST_F(EndToEndTest, UsesRtcpReducedSizeMode) {
// Another is set up to receive all three of these with different renderers.
class MultiStreamTest {
public:
static const size_t kNumStreams = 3;
static constexpr size_t kNumStreams = 3;
const uint8_t kVideoPayloadType = 124;
const std::map<uint8_t, MediaType> payload_type_map_ = {
{kVideoPayloadType, MediaType::VIDEO}};
struct CodecSettings {
uint32_t ssrc;
int width;
@ -1489,7 +1492,7 @@ class MultiStreamTest {
send_config.rtp.ssrcs.push_back(ssrc);
send_config.encoder_settings.encoder = encoders[i].get();
send_config.encoder_settings.payload_name = "VP8";
send_config.encoder_settings.payload_type = 124;
send_config.encoder_settings.payload_type = kVideoPayloadType;
VideoEncoderConfig encoder_config;
test::FillEncoderConfiguration(1, &encoder_config);
encoder_config.max_bitrate_bps = 100000;
@ -1550,10 +1553,10 @@ class MultiStreamTest {
VideoReceiveStream::Config* receive_config) {
}
virtual test::DirectTransport* CreateSendTransport(Call* sender_call) {
return new test::DirectTransport(sender_call, MediaType::VIDEO);
return new test::DirectTransport(sender_call, payload_type_map_);
}
virtual test::DirectTransport* CreateReceiveTransport(Call* receiver_call) {
return new test::DirectTransport(receiver_call, MediaType::VIDEO);
return new test::DirectTransport(receiver_call, payload_type_map_);
}
};
@ -1629,10 +1632,12 @@ TEST_F(EndToEndTest, AssignsTransportSequenceNumbers) {
class RtpExtensionHeaderObserver : public test::DirectTransport {
public:
RtpExtensionHeaderObserver(Call* sender_call,
const uint32_t& first_media_ssrc,
const std::map<uint32_t, uint32_t>& ssrc_map)
: DirectTransport(sender_call, MediaType::VIDEO),
RtpExtensionHeaderObserver(
Call* sender_call,
const uint32_t& first_media_ssrc,
const std::map<uint32_t, uint32_t>& ssrc_map,
const std::map<uint8_t, MediaType>& payload_type_map)
: DirectTransport(sender_call, payload_type_map),
done_(false, false),
parser_(RtpHeaderParser::Create()),
first_media_ssrc_(first_media_ssrc),
@ -1796,8 +1801,14 @@ TEST_F(EndToEndTest, AssignsTransportSequenceNumbers) {
}
test::DirectTransport* CreateSendTransport(Call* sender_call) override {
observer_ = new RtpExtensionHeaderObserver(sender_call, first_media_ssrc_,
rtx_to_media_ssrcs_);
std::map<uint8_t, MediaType> payload_type_map =
MultiStreamTest::payload_type_map_;
RTC_DCHECK(payload_type_map.find(kSendRtxPayloadType) ==
payload_type_map.end());
payload_type_map[kSendRtxPayloadType] = MediaType::VIDEO;
observer_ =
new RtpExtensionHeaderObserver(sender_call, first_media_ssrc_,
rtx_to_media_ssrcs_, payload_type_map);
return observer_;
}
@ -1948,10 +1959,9 @@ TEST_F(EndToEndTest, ObserversEncodedFrames) {
CreateCalls(Call::Config(event_log_.get()), Call::Config(event_log_.get()));
test::DirectTransport sender_transport(
sender_call_.get(), MediaType::VIDEO);
test::DirectTransport receiver_transport(
receiver_call_.get(), MediaType::VIDEO);
test::DirectTransport sender_transport(sender_call_.get(), payload_type_map_);
test::DirectTransport receiver_transport(receiver_call_.get(),
payload_type_map_);
sender_transport.SetReceiver(receiver_call_->Receiver());
receiver_transport.SetReceiver(sender_call_->Receiver());
@ -2114,8 +2124,7 @@ TEST_F(EndToEndTest, RembWithSendSideBwe) {
test::PacketTransport* CreateReceiveTransport() override {
receive_transport_ = new test::PacketTransport(
nullptr, this, test::PacketTransport::kReceiver,
MediaType::VIDEO,
nullptr, this, test::PacketTransport::kReceiver, payload_type_map_,
FakeNetworkPipe::Config());
return receive_transport_;
}
@ -3107,9 +3116,9 @@ TEST_F(EndToEndTest, GetStats) {
test::PacketTransport* CreateSendTransport(Call* sender_call) override {
FakeNetworkPipe::Config network_config;
network_config.loss_percent = 5;
return new test::PacketTransport(
sender_call, this, test::PacketTransport::kSender, MediaType::VIDEO,
network_config);
return new test::PacketTransport(sender_call, this,
test::PacketTransport::kSender,
payload_type_map_, network_config);
}
Call::Config GetSenderCallConfig() override {
@ -3661,14 +3670,12 @@ void EndToEndTest::TestRtpStatePreservation(bool use_rtx,
Call::Config config(event_log_.get());
CreateCalls(config, config);
test::PacketTransport send_transport(sender_call_.get(), &observer,
test::PacketTransport::kSender,
MediaType::VIDEO,
FakeNetworkPipe::Config());
test::PacketTransport receive_transport(nullptr, &observer,
test::PacketTransport::kReceiver,
MediaType::VIDEO,
FakeNetworkPipe::Config());
test::PacketTransport send_transport(
sender_call_.get(), &observer, test::PacketTransport::kSender,
payload_type_map_, FakeNetworkPipe::Config());
test::PacketTransport receive_transport(
nullptr, &observer, test::PacketTransport::kReceiver, payload_type_map_,
FakeNetworkPipe::Config());
send_transport.SetReceiver(receiver_call_->Receiver());
receive_transport.SetReceiver(sender_call_->Receiver());
@ -3960,11 +3967,11 @@ TEST_F(EndToEndTest, CallReportsRttForSender) {
FakeNetworkPipe::Config config;
config.queue_delay_ms = kSendDelayMs;
test::DirectTransport sender_transport(
config, sender_call_.get(), MediaType::VIDEO);
test::DirectTransport sender_transport(config, sender_call_.get(),
payload_type_map_);
config.queue_delay_ms = kReceiveDelayMs;
test::DirectTransport receiver_transport(
config, receiver_call_.get(), MediaType::VIDEO);
test::DirectTransport receiver_transport(config, receiver_call_.get(),
payload_type_map_);
sender_transport.SetReceiver(receiver_call_->Receiver());
receiver_transport.SetReceiver(sender_call_->Receiver());
@ -4026,7 +4033,7 @@ void EndToEndTest::VerifyNewVideoReceiveStreamsRespectNetworkState(
CreateCalls(config, config);
receiver_call_->SignalChannelNetworkState(network_to_bring_up, kNetworkUp);
test::DirectTransport sender_transport(sender_call_.get(), MediaType::VIDEO);
test::DirectTransport sender_transport(sender_call_.get(), payload_type_map_);
sender_transport.SetReceiver(receiver_call_->Receiver());
CreateSendConfig(1, 0, 0, &sender_transport);
CreateMatchingReceiveConfigs(transport);

View File

@ -54,6 +54,7 @@ constexpr int kSendStatsPollingIntervalMs = 1000;
constexpr int kPayloadTypeH264 = 122;
constexpr int kPayloadTypeVP8 = 123;
constexpr int kPayloadTypeVP9 = 124;
constexpr size_t kMaxComparisons = 10;
constexpr char kSyncGroup[] = "av_sync";
constexpr int kOpusMinBitrateBps = 6000;
@ -1030,7 +1031,18 @@ class Vp8EncoderFactory : public VideoEncoderFactory {
};
VideoQualityTest::VideoQualityTest()
: clock_(Clock::GetRealTimeClock()), receive_logs_(0), send_logs_(0) {}
: clock_(Clock::GetRealTimeClock()), receive_logs_(0), send_logs_(0) {
payload_type_map_ = test::CallTest::payload_type_map_;
RTC_DCHECK(payload_type_map_.find(kPayloadTypeH264) ==
payload_type_map_.end());
RTC_DCHECK(payload_type_map_.find(kPayloadTypeVP8) ==
payload_type_map_.end());
RTC_DCHECK(payload_type_map_.find(kPayloadTypeVP9) ==
payload_type_map_.end());
payload_type_map_[kPayloadTypeH264] = webrtc::MediaType::VIDEO;
payload_type_map_[kPayloadTypeVP8] = webrtc::MediaType::VIDEO;
payload_type_map_[kPayloadTypeVP9] = webrtc::MediaType::VIDEO;
}
VideoQualityTest::Params::Params()
: call({false, Call::Config::BitrateConfig()}),
@ -1590,9 +1602,10 @@ void VideoQualityTest::RunWithAnalyzer(const Params& params) {
test::LayerFilteringTransport send_transport(
params_.pipe, sender_call_.get(), kPayloadTypeVP8, kPayloadTypeVP9,
params_.video.selected_tl, params_.ss.selected_sl);
test::DirectTransport recv_transport(
params_.pipe, receiver_call_.get(), MediaType::VIDEO);
params_.video.selected_tl, params_.ss.selected_sl, payload_type_map_);
test::DirectTransport recv_transport(params_.pipe, receiver_call_.get(),
payload_type_map_);
std::string graph_title = params_.analyzer.graph_title;
if (graph_title.empty())
@ -1711,7 +1724,7 @@ void VideoQualityTest::SetupAudio(int send_channel_id,
audio_send_config_.max_bitrate_bps = kOpusBitrateFbBps;
}
audio_send_config_.send_codec_spec.codec_inst =
CodecInst{120, "OPUS", 48000, 960, 2, 64000};
CodecInst{kAudioSendPayloadType, "OPUS", 48000, 960, 2, 64000};
audio_send_config_.send_codec_spec.enable_opus_dtx = params_.audio.dtx;
audio_send_stream_ = call->CreateAudioSendStream(audio_send_config_);
@ -1723,6 +1736,7 @@ void VideoQualityTest::SetupAudio(int send_channel_id,
audio_config.rtp.transport_cc = params_.call.send_side_bwe;
audio_config.rtp.extensions = audio_send_config_.rtp.extensions;
audio_config.decoder_factory = decoder_factory_;
audio_config.decoder_map = {{kAudioSendPayloadType, {"OPUS", 48000, 2}}};
if (params_.video.enabled && params_.audio.sync_video)
audio_config.sync_group = kSyncGroup;
@ -1753,7 +1767,8 @@ void VideoQualityTest::RunWithRenderers(const Params& params) {
// calls.
test::LayerFilteringTransport transport(
params.pipe, call.get(), kPayloadTypeVP8, kPayloadTypeVP9,
params.video.selected_tl, params_.ss.selected_sl);
params.video.selected_tl, params_.ss.selected_sl, payload_type_map_);
// TODO(ivica): Use two calls to be able to merge with RunWithAnalyzer or at
// least share as much code as possible. That way this test would also match
// the full stack tests better.

View File

@ -10,6 +10,7 @@
#ifndef WEBRTC_VIDEO_VIDEO_QUALITY_TEST_H_
#define WEBRTC_VIDEO_VIDEO_QUALITY_TEST_H_
#include <map>
#include <memory>
#include <string>
#include <vector>
@ -96,6 +97,8 @@ class VideoQualityTest : public test::CallTest {
const std::vector<std::string>& sl_descriptors);
protected:
std::map<uint8_t, webrtc::MediaType> payload_type_map_;
// No-op implementation to be able to instantiate this class from non-TEST_F
// locations.
void TestBody() override;

View File

@ -438,9 +438,9 @@ class UlpfecObserver : public test::EndToEndTest {
FakeNetworkPipe::Config config;
config.loss_percent = 5;
config.queue_delay_ms = kNetworkDelayMs;
return new test::PacketTransport(sender_call, this,
test::PacketTransport::kSender,
MediaType::VIDEO, config);
return new test::PacketTransport(
sender_call, this, test::PacketTransport::kSender,
VideoSendStreamTest::payload_type_map_, config);
}
void ModifyVideoConfigs(
@ -594,9 +594,9 @@ class FlexfecObserver : public test::EndToEndTest {
FakeNetworkPipe::Config config;
config.loss_percent = 5;
config.queue_delay_ms = kNetworkDelayMs;
return new test::PacketTransport(sender_call, this,
test::PacketTransport::kSender,
MediaType::VIDEO, config);
return new test::PacketTransport(
sender_call, this, test::PacketTransport::kSender,
VideoSendStreamTest::payload_type_map_, config);
}
void ModifyVideoConfigs(
@ -1266,7 +1266,7 @@ TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
config.queue_delay_ms = kNetworkDelayMs;
return new test::PacketTransport(sender_call, this,
test::PacketTransport::kSender,
MediaType::VIDEO, config);
payload_type_map_, config);
}
void ModifyVideoConfigs(
@ -2749,7 +2749,7 @@ class Vp9HeaderObserver : public test::SendTest {
virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
private:
const int kVp9PayloadType = 105;
const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType;
class VideoStreamFactory
: public VideoEncoderConfig::VideoStreamFactoryInterface {