Improve Call tests for RTX.
Also does some refactoring to reuse RtpRtcpObserver. BUG=1811 R=mflodman@webrtc.org, pbos@webrtc.org Review URL: https://webrtc-codereview.appspot.com/3809004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@5126 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
6e95d7afab
commit
69969e2e2f
@ -31,6 +31,7 @@ namespace webrtc {
|
|||||||
|
|
||||||
static unsigned int kDefaultTimeoutMs = 30 * 1000;
|
static unsigned int kDefaultTimeoutMs = 30 * 1000;
|
||||||
static unsigned int kLongTimeoutMs = 120 * 1000;
|
static unsigned int kLongTimeoutMs = 120 * 1000;
|
||||||
|
static const uint8_t kSendPayloadType = 125;
|
||||||
|
|
||||||
class CallTest : public ::testing::Test {
|
class CallTest : public ::testing::Test {
|
||||||
public:
|
public:
|
||||||
@ -59,6 +60,7 @@ class CallTest : public ::testing::Test {
|
|||||||
send_config_.encoder = &fake_encoder_;
|
send_config_.encoder = &fake_encoder_;
|
||||||
send_config_.internal_source = false;
|
send_config_.internal_source = false;
|
||||||
test::FakeEncoder::SetCodecSettings(&send_config_.codec, 1);
|
test::FakeEncoder::SetCodecSettings(&send_config_.codec, 1);
|
||||||
|
send_config_.codec.plType = kSendPayloadType;
|
||||||
|
|
||||||
receive_config_.codecs.clear();
|
receive_config_.codecs.clear();
|
||||||
receive_config_.codecs.push_back(send_config_.codec);
|
receive_config_.codecs.push_back(send_config_.codec);
|
||||||
|
@ -62,7 +62,8 @@ DirectTransport::Packet::Packet(const uint8_t* data, size_t length)
|
|||||||
|
|
||||||
void DirectTransport::QueuePacket(const uint8_t* data, size_t length) {
|
void DirectTransport::QueuePacket(const uint8_t* data, size_t length) {
|
||||||
CriticalSectionScoped crit(lock_.get());
|
CriticalSectionScoped crit(lock_.get());
|
||||||
EXPECT_TRUE(receiver_ != NULL);
|
if (receiver_ == NULL)
|
||||||
|
return;
|
||||||
packet_queue_.push_back(Packet(data, length));
|
packet_queue_.push_back(Packet(data, length));
|
||||||
packet_event_->Set();
|
packet_event_->Set();
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,6 @@ void FakeEncoder::SetCodecSettings(VideoCodec* codec,
|
|||||||
|
|
||||||
codec->codecType = kVideoCodecGeneric;
|
codec->codecType = kVideoCodecGeneric;
|
||||||
strcpy(codec->plName, "FAKE");
|
strcpy(codec->plName, "FAKE");
|
||||||
codec->plType = 125;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t FakeEncoder::InitEncode(const VideoCodec* config,
|
int32_t FakeEncoder::InitEncode(const VideoCodec* config,
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
|
||||||
#include "webrtc/typedefs.h"
|
#include "webrtc/typedefs.h"
|
||||||
#include "webrtc/video_send_stream.h"
|
#include "webrtc/video_send_stream.h"
|
||||||
|
|
||||||
@ -40,12 +41,15 @@ class RtpRtcpObserver {
|
|||||||
receive_transport_.StopSending();
|
receive_transport_.StopSending();
|
||||||
}
|
}
|
||||||
|
|
||||||
EventTypeWrapper Wait() { return observation_complete_->Wait(timeout_ms_); }
|
virtual EventTypeWrapper Wait() {
|
||||||
|
return observation_complete_->Wait(timeout_ms_);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
RtpRtcpObserver(unsigned int event_timeout_ms)
|
RtpRtcpObserver(unsigned int event_timeout_ms)
|
||||||
: lock_(CriticalSectionWrapper::CreateCriticalSection()),
|
: lock_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||||
observation_complete_(EventWrapper::Create()),
|
observation_complete_(EventWrapper::Create()),
|
||||||
|
parser_(RtpHeaderParser::Create()),
|
||||||
send_transport_(lock_.get(),
|
send_transport_(lock_.get(),
|
||||||
this,
|
this,
|
||||||
&RtpRtcpObserver::OnSendRtp,
|
&RtpRtcpObserver::OnSendRtp,
|
||||||
@ -135,6 +139,7 @@ class RtpRtcpObserver {
|
|||||||
protected:
|
protected:
|
||||||
scoped_ptr<CriticalSectionWrapper> lock_;
|
scoped_ptr<CriticalSectionWrapper> lock_;
|
||||||
scoped_ptr<EventWrapper> observation_complete_;
|
scoped_ptr<EventWrapper> observation_complete_;
|
||||||
|
scoped_ptr<RtpHeaderParser> parser_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PacketTransport send_transport_, receive_transport_;
|
PacketTransport send_transport_, receive_transport_;
|
||||||
|
@ -152,6 +152,7 @@ TEST_P(RampUpTest, RampUpWithPadding) {
|
|||||||
send_config.encoder = &encoder;
|
send_config.encoder = &encoder;
|
||||||
send_config.internal_source = false;
|
send_config.internal_source = false;
|
||||||
test::FakeEncoder::SetCodecSettings(&send_config.codec, 3);
|
test::FakeEncoder::SetCodecSettings(&send_config.codec, 3);
|
||||||
|
send_config.codec.plType = 125;
|
||||||
send_config.pacing = GetParam();
|
send_config.pacing = GetParam();
|
||||||
send_config.rtp.extensions.push_back(
|
send_config.rtp.extensions.push_back(
|
||||||
RtpExtension("toffset", kTOffsetExtensionId));
|
RtpExtension("toffset", kTOffsetExtensionId));
|
||||||
|
@ -26,32 +26,12 @@
|
|||||||
#include "webrtc/test/fake_encoder.h"
|
#include "webrtc/test/fake_encoder.h"
|
||||||
#include "webrtc/test/frame_generator_capturer.h"
|
#include "webrtc/test/frame_generator_capturer.h"
|
||||||
#include "webrtc/test/null_transport.h"
|
#include "webrtc/test/null_transport.h"
|
||||||
|
#include "webrtc/test/rtp_rtcp_observer.h"
|
||||||
#include "webrtc/video/transport_adapter.h"
|
#include "webrtc/video/transport_adapter.h"
|
||||||
#include "webrtc/video_send_stream.h"
|
#include "webrtc/video_send_stream.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
class SendTransportObserver : public test::NullTransport {
|
|
||||||
public:
|
|
||||||
explicit SendTransportObserver(unsigned long timeout_ms)
|
|
||||||
: rtp_header_parser_(RtpHeaderParser::Create()),
|
|
||||||
send_test_complete_(EventWrapper::Create()),
|
|
||||||
timeout_ms_(timeout_ms) {}
|
|
||||||
|
|
||||||
virtual EventTypeWrapper Wait() {
|
|
||||||
return send_test_complete_->Wait(timeout_ms_);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Stop() {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
scoped_ptr<RtpHeaderParser> rtp_header_parser_;
|
|
||||||
scoped_ptr<EventWrapper> send_test_complete_;
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned long timeout_ms_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class VideoSendStreamTest : public ::testing::Test {
|
class VideoSendStreamTest : public ::testing::Test {
|
||||||
public:
|
public:
|
||||||
VideoSendStreamTest() : fake_encoder_(Clock::GetRealTimeClock()) {}
|
VideoSendStreamTest() : fake_encoder_(Clock::GetRealTimeClock()) {}
|
||||||
@ -59,7 +39,7 @@ class VideoSendStreamTest : public ::testing::Test {
|
|||||||
protected:
|
protected:
|
||||||
void RunSendTest(Call* call,
|
void RunSendTest(Call* call,
|
||||||
const VideoSendStream::Config& config,
|
const VideoSendStream::Config& config,
|
||||||
SendTransportObserver* observer) {
|
test::RtpRtcpObserver* observer) {
|
||||||
send_stream_ = call->CreateSendStream(config);
|
send_stream_ = call->CreateSendStream(config);
|
||||||
scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
|
scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
|
||||||
test::FrameGeneratorCapturer::Create(
|
test::FrameGeneratorCapturer::Create(
|
||||||
@ -69,7 +49,7 @@ class VideoSendStreamTest : public ::testing::Test {
|
|||||||
|
|
||||||
EXPECT_EQ(kEventSignaled, observer->Wait());
|
EXPECT_EQ(kEventSignaled, observer->Wait());
|
||||||
|
|
||||||
observer->Stop();
|
observer->StopSending();
|
||||||
frame_generator_capturer->Stop();
|
frame_generator_capturer->Stop();
|
||||||
send_stream_->StopSend();
|
send_stream_->StopSend();
|
||||||
call->DestroySendStream(send_stream_);
|
call->DestroySendStream(send_stream_);
|
||||||
@ -81,11 +61,17 @@ class VideoSendStreamTest : public ::testing::Test {
|
|||||||
config.internal_source = false;
|
config.internal_source = false;
|
||||||
config.rtp.ssrcs.push_back(kSendSsrc);
|
config.rtp.ssrcs.push_back(kSendSsrc);
|
||||||
test::FakeEncoder::SetCodecSettings(&config.codec, 1);
|
test::FakeEncoder::SetCodecSettings(&config.codec, 1);
|
||||||
|
config.codec.plType = kFakeSendPayloadType;
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestNackRetransmission(uint32_t retransmit_ssrc);
|
void TestNackRetransmission(uint32_t retransmit_ssrc,
|
||||||
|
uint8_t retransmit_payload_type,
|
||||||
|
bool enable_pacing);
|
||||||
|
|
||||||
|
static const uint8_t kSendPayloadType;
|
||||||
|
static const uint8_t kSendRtxPayloadType;
|
||||||
|
static const uint8_t kFakeSendPayloadType;
|
||||||
static const uint32_t kSendSsrc;
|
static const uint32_t kSendSsrc;
|
||||||
static const uint32_t kSendRtxSsrc;
|
static const uint32_t kSendRtxSsrc;
|
||||||
|
|
||||||
@ -93,27 +79,30 @@ class VideoSendStreamTest : public ::testing::Test {
|
|||||||
test::FakeEncoder fake_encoder_;
|
test::FakeEncoder fake_encoder_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const uint8_t VideoSendStreamTest::kSendPayloadType = 100;
|
||||||
|
const uint8_t VideoSendStreamTest::kFakeSendPayloadType = 125;
|
||||||
|
const uint8_t VideoSendStreamTest::kSendRtxPayloadType = 98;
|
||||||
const uint32_t VideoSendStreamTest::kSendSsrc = 0xC0FFEE;
|
const uint32_t VideoSendStreamTest::kSendSsrc = 0xC0FFEE;
|
||||||
const uint32_t VideoSendStreamTest::kSendRtxSsrc = 0xBADCAFE;
|
const uint32_t VideoSendStreamTest::kSendRtxSsrc = 0xBADCAFE;
|
||||||
|
|
||||||
TEST_F(VideoSendStreamTest, SendsSetSsrc) {
|
TEST_F(VideoSendStreamTest, SendsSetSsrc) {
|
||||||
class SendSsrcObserver : public SendTransportObserver {
|
class SendSsrcObserver : public test::RtpRtcpObserver {
|
||||||
public:
|
public:
|
||||||
SendSsrcObserver() : SendTransportObserver(30 * 1000) {}
|
SendSsrcObserver() : RtpRtcpObserver(30 * 1000) {}
|
||||||
|
|
||||||
virtual bool SendRTP(const uint8_t* packet, size_t length) OVERRIDE {
|
virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
|
||||||
RTPHeader header;
|
RTPHeader header;
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
rtp_header_parser_->Parse(packet, static_cast<int>(length), &header));
|
parser_->Parse(packet, static_cast<int>(length), &header));
|
||||||
|
|
||||||
if (header.ssrc == kSendSsrc)
|
if (header.ssrc == kSendSsrc)
|
||||||
send_test_complete_->Set();
|
observation_complete_->Set();
|
||||||
|
|
||||||
return true;
|
return SEND_PACKET;
|
||||||
}
|
}
|
||||||
} observer;
|
} observer;
|
||||||
|
|
||||||
Call::Config call_config(&observer);
|
Call::Config call_config(observer.SendTransport());
|
||||||
scoped_ptr<Call> call(Call::Create(call_config));
|
scoped_ptr<Call> call(Call::Create(call_config));
|
||||||
|
|
||||||
VideoSendStream::Config send_config = GetSendTestConfig(call.get());
|
VideoSendStream::Config send_config = GetSendTestConfig(call.get());
|
||||||
@ -124,11 +113,11 @@ TEST_F(VideoSendStreamTest, SendsSetSsrc) {
|
|||||||
|
|
||||||
TEST_F(VideoSendStreamTest, SupportsCName) {
|
TEST_F(VideoSendStreamTest, SupportsCName) {
|
||||||
static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
|
static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
|
||||||
class CNameObserver : public SendTransportObserver {
|
class CNameObserver : public test::RtpRtcpObserver {
|
||||||
public:
|
public:
|
||||||
CNameObserver() : SendTransportObserver(30 * 1000) {}
|
CNameObserver() : RtpRtcpObserver(30 * 1000) {}
|
||||||
|
|
||||||
virtual bool SendRTCP(const uint8_t* packet, size_t length) OVERRIDE {
|
virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE {
|
||||||
RTCPUtility::RTCPParserV2 parser(packet, length, true);
|
RTCPUtility::RTCPParserV2 parser(packet, length, true);
|
||||||
EXPECT_TRUE(parser.IsValid());
|
EXPECT_TRUE(parser.IsValid());
|
||||||
|
|
||||||
@ -136,17 +125,17 @@ TEST_F(VideoSendStreamTest, SupportsCName) {
|
|||||||
while (packet_type != RTCPUtility::kRtcpNotValidCode) {
|
while (packet_type != RTCPUtility::kRtcpNotValidCode) {
|
||||||
if (packet_type == RTCPUtility::kRtcpSdesChunkCode) {
|
if (packet_type == RTCPUtility::kRtcpSdesChunkCode) {
|
||||||
EXPECT_EQ(parser.Packet().CName.CName, kCName);
|
EXPECT_EQ(parser.Packet().CName.CName, kCName);
|
||||||
send_test_complete_->Set();
|
observation_complete_->Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
packet_type = parser.Iterate();
|
packet_type = parser.Iterate();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return SEND_PACKET;
|
||||||
}
|
}
|
||||||
} observer;
|
} observer;
|
||||||
|
|
||||||
Call::Config call_config(&observer);
|
Call::Config call_config(observer.SendTransport());
|
||||||
scoped_ptr<Call> call(Call::Create(call_config));
|
scoped_ptr<Call> call(Call::Create(call_config));
|
||||||
|
|
||||||
VideoSendStream::Config send_config = GetSendTestConfig(call.get());
|
VideoSendStream::Config send_config = GetSendTestConfig(call.get());
|
||||||
@ -157,26 +146,26 @@ TEST_F(VideoSendStreamTest, SupportsCName) {
|
|||||||
|
|
||||||
TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
|
TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
|
||||||
static const uint8_t kAbsSendTimeExtensionId = 13;
|
static const uint8_t kAbsSendTimeExtensionId = 13;
|
||||||
class AbsoluteSendTimeObserver : public SendTransportObserver {
|
class AbsoluteSendTimeObserver : public test::RtpRtcpObserver {
|
||||||
public:
|
public:
|
||||||
AbsoluteSendTimeObserver() : SendTransportObserver(30 * 1000) {
|
AbsoluteSendTimeObserver() : RtpRtcpObserver(30 * 1000) {
|
||||||
EXPECT_TRUE(rtp_header_parser_->RegisterRtpHeaderExtension(
|
EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
|
||||||
kRtpExtensionAbsoluteSendTime, kAbsSendTimeExtensionId));
|
kRtpExtensionAbsoluteSendTime, kAbsSendTimeExtensionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool SendRTP(const uint8_t* packet, size_t length) OVERRIDE {
|
virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
|
||||||
RTPHeader header;
|
RTPHeader header;
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
rtp_header_parser_->Parse(packet, static_cast<int>(length), &header));
|
parser_->Parse(packet, static_cast<int>(length), &header));
|
||||||
|
|
||||||
if (header.extension.absoluteSendTime > 0)
|
if (header.extension.absoluteSendTime > 0)
|
||||||
send_test_complete_->Set();
|
observation_complete_->Set();
|
||||||
|
|
||||||
return true;
|
return SEND_PACKET;
|
||||||
}
|
}
|
||||||
} observer;
|
} observer;
|
||||||
|
|
||||||
Call::Config call_config(&observer);
|
Call::Config call_config(observer.SendTransport());
|
||||||
scoped_ptr<Call> call(Call::Create(call_config));
|
scoped_ptr<Call> call(Call::Create(call_config));
|
||||||
|
|
||||||
VideoSendStream::Config send_config = GetSendTestConfig(call.get());
|
VideoSendStream::Config send_config = GetSendTestConfig(call.get());
|
||||||
@ -202,26 +191,26 @@ TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
|
|||||||
}
|
}
|
||||||
} encoder(Clock::GetRealTimeClock());
|
} encoder(Clock::GetRealTimeClock());
|
||||||
|
|
||||||
class TransmissionTimeOffsetObserver : public SendTransportObserver {
|
class TransmissionTimeOffsetObserver : public test::RtpRtcpObserver {
|
||||||
public:
|
public:
|
||||||
TransmissionTimeOffsetObserver() : SendTransportObserver(30 * 1000) {
|
TransmissionTimeOffsetObserver() : RtpRtcpObserver(30 * 1000) {
|
||||||
EXPECT_TRUE(rtp_header_parser_->RegisterRtpHeaderExtension(
|
EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
|
||||||
kRtpExtensionTransmissionTimeOffset, kTOffsetExtensionId));
|
kRtpExtensionTransmissionTimeOffset, kTOffsetExtensionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool SendRTP(const uint8_t* packet, size_t length) OVERRIDE {
|
virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
|
||||||
RTPHeader header;
|
RTPHeader header;
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
rtp_header_parser_->Parse(packet, static_cast<int>(length), &header));
|
parser_->Parse(packet, static_cast<int>(length), &header));
|
||||||
|
|
||||||
EXPECT_GT(header.extension.transmissionTimeOffset, 0);
|
EXPECT_GT(header.extension.transmissionTimeOffset, 0);
|
||||||
send_test_complete_->Set();
|
observation_complete_->Set();
|
||||||
|
|
||||||
return true;
|
return SEND_PACKET;
|
||||||
}
|
}
|
||||||
} observer;
|
} observer;
|
||||||
|
|
||||||
Call::Config call_config(&observer);
|
Call::Config call_config(observer.SendTransport());
|
||||||
scoped_ptr<Call> call(Call::Create(call_config));
|
scoped_ptr<Call> call(Call::Create(call_config));
|
||||||
|
|
||||||
VideoSendStream::Config send_config = GetSendTestConfig(call.get());
|
VideoSendStream::Config send_config = GetSendTestConfig(call.get());
|
||||||
@ -291,23 +280,19 @@ class FakeReceiveStatistics : public NullReceiveStatistics {
|
|||||||
TEST_F(VideoSendStreamTest, SupportsFec) {
|
TEST_F(VideoSendStreamTest, SupportsFec) {
|
||||||
static const int kRedPayloadType = 118;
|
static const int kRedPayloadType = 118;
|
||||||
static const int kUlpfecPayloadType = 119;
|
static const int kUlpfecPayloadType = 119;
|
||||||
class FecObserver : public SendTransportObserver {
|
class FecObserver : public test::RtpRtcpObserver {
|
||||||
public:
|
public:
|
||||||
FecObserver()
|
FecObserver()
|
||||||
: SendTransportObserver(30 * 1000),
|
: RtpRtcpObserver(30 * 1000),
|
||||||
transport_adapter_(&transport_),
|
transport_adapter_(SendTransport()),
|
||||||
send_count_(0),
|
send_count_(0),
|
||||||
received_media_(false),
|
received_media_(false),
|
||||||
received_fec_(false) {}
|
received_fec_(false) {}
|
||||||
|
|
||||||
void SetReceiver(PacketReceiver* receiver) {
|
virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
|
||||||
transport_.SetReceiver(receiver);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool SendRTP(const uint8_t* packet, size_t length) OVERRIDE {
|
|
||||||
RTPHeader header;
|
RTPHeader header;
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
rtp_header_parser_->Parse(packet, static_cast<int>(length), &header));
|
parser_->Parse(packet, static_cast<int>(length), &header));
|
||||||
|
|
||||||
// Send lossy receive reports to trigger FEC enabling.
|
// Send lossy receive reports to trigger FEC enabling.
|
||||||
if (send_count_++ % 2 != 0) {
|
if (send_count_++ % 2 != 0) {
|
||||||
@ -337,25 +322,22 @@ TEST_F(VideoSendStreamTest, SupportsFec) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (received_media_ && received_fec_)
|
if (received_media_ && received_fec_)
|
||||||
send_test_complete_->Set();
|
observation_complete_->Set();
|
||||||
|
|
||||||
return true;
|
return SEND_PACKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Stop() OVERRIDE { transport_.StopSending(); }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
internal::TransportAdapter transport_adapter_;
|
internal::TransportAdapter transport_adapter_;
|
||||||
test::DirectTransport transport_;
|
|
||||||
int send_count_;
|
int send_count_;
|
||||||
bool received_media_;
|
bool received_media_;
|
||||||
bool received_fec_;
|
bool received_fec_;
|
||||||
} observer;
|
} observer;
|
||||||
|
|
||||||
Call::Config call_config(&observer);
|
Call::Config call_config(observer.SendTransport());
|
||||||
scoped_ptr<Call> call(Call::Create(call_config));
|
scoped_ptr<Call> call(Call::Create(call_config));
|
||||||
|
|
||||||
observer.SetReceiver(call->Receiver());
|
observer.SetReceivers(call->Receiver(), NULL);
|
||||||
|
|
||||||
VideoSendStream::Config send_config = GetSendTestConfig(call.get());
|
VideoSendStream::Config send_config = GetSendTestConfig(call.get());
|
||||||
send_config.rtp.fec.red_payload_type = kRedPayloadType;
|
send_config.rtp.fec.red_payload_type = kRedPayloadType;
|
||||||
@ -364,24 +346,25 @@ TEST_F(VideoSendStreamTest, SupportsFec) {
|
|||||||
RunSendTest(call.get(), send_config, &observer);
|
RunSendTest(call.get(), send_config, &observer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoSendStreamTest::TestNackRetransmission(uint32_t retransmit_ssrc) {
|
void VideoSendStreamTest::TestNackRetransmission(
|
||||||
class NackObserver : public SendTransportObserver {
|
uint32_t retransmit_ssrc,
|
||||||
|
uint8_t retransmit_payload_type,
|
||||||
|
bool enable_pacing) {
|
||||||
|
class NackObserver : public test::RtpRtcpObserver {
|
||||||
public:
|
public:
|
||||||
explicit NackObserver(uint32_t retransmit_ssrc)
|
explicit NackObserver(uint32_t retransmit_ssrc,
|
||||||
: SendTransportObserver(30 * 1000),
|
uint8_t retransmit_payload_type)
|
||||||
transport_adapter_(&transport_),
|
: RtpRtcpObserver(30 * 1000),
|
||||||
|
transport_adapter_(SendTransport()),
|
||||||
send_count_(0),
|
send_count_(0),
|
||||||
retransmit_ssrc_(retransmit_ssrc),
|
retransmit_ssrc_(retransmit_ssrc),
|
||||||
|
retransmit_payload_type_(retransmit_payload_type),
|
||||||
nacked_sequence_number_(0) {}
|
nacked_sequence_number_(0) {}
|
||||||
|
|
||||||
void SetReceiver(PacketReceiver* receiver) {
|
virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
|
||||||
transport_.SetReceiver(receiver);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool SendRTP(const uint8_t* packet, size_t length) OVERRIDE {
|
|
||||||
RTPHeader header;
|
RTPHeader header;
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
rtp_header_parser_->Parse(packet, static_cast<int>(length), &header));
|
parser_->Parse(packet, static_cast<int>(length), &header));
|
||||||
|
|
||||||
// Nack second packet after receiving the third one.
|
// Nack second packet after receiving the third one.
|
||||||
if (++send_count_ == 3) {
|
if (++send_count_ == 3) {
|
||||||
@ -411,28 +394,29 @@ void VideoSendStreamTest::TestNackRetransmission(uint32_t retransmit_ssrc) {
|
|||||||
|
|
||||||
if (sequence_number == nacked_sequence_number_) {
|
if (sequence_number == nacked_sequence_number_) {
|
||||||
EXPECT_EQ(retransmit_ssrc_, header.ssrc);
|
EXPECT_EQ(retransmit_ssrc_, header.ssrc);
|
||||||
send_test_complete_->Set();
|
EXPECT_EQ(retransmit_payload_type_, header.payloadType);
|
||||||
|
observation_complete_->Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return SEND_PACKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Stop() OVERRIDE { transport_.StopSending(); }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
internal::TransportAdapter transport_adapter_;
|
internal::TransportAdapter transport_adapter_;
|
||||||
test::DirectTransport transport_;
|
|
||||||
int send_count_;
|
int send_count_;
|
||||||
uint32_t retransmit_ssrc_;
|
uint32_t retransmit_ssrc_;
|
||||||
|
uint8_t retransmit_payload_type_;
|
||||||
uint16_t nacked_sequence_number_;
|
uint16_t nacked_sequence_number_;
|
||||||
} observer(retransmit_ssrc);
|
} observer(retransmit_ssrc, retransmit_payload_type);
|
||||||
|
|
||||||
Call::Config call_config(&observer);
|
Call::Config call_config(observer.SendTransport());
|
||||||
scoped_ptr<Call> call(Call::Create(call_config));
|
scoped_ptr<Call> call(Call::Create(call_config));
|
||||||
observer.SetReceiver(call->Receiver());
|
observer.SetReceivers(call->Receiver(), NULL);
|
||||||
|
|
||||||
VideoSendStream::Config send_config = GetSendTestConfig(call.get());
|
VideoSendStream::Config send_config = GetSendTestConfig(call.get());
|
||||||
send_config.rtp.nack.rtp_history_ms = 1000;
|
send_config.rtp.nack.rtp_history_ms = 1000;
|
||||||
|
send_config.rtp.rtx.rtx_payload_type = retransmit_payload_type;
|
||||||
|
send_config.pacing = enable_pacing;
|
||||||
if (retransmit_ssrc != kSendSsrc)
|
if (retransmit_ssrc != kSendSsrc)
|
||||||
send_config.rtp.rtx.ssrcs.push_back(retransmit_ssrc);
|
send_config.rtp.rtx.ssrcs.push_back(retransmit_ssrc);
|
||||||
|
|
||||||
@ -441,24 +425,29 @@ void VideoSendStreamTest::TestNackRetransmission(uint32_t retransmit_ssrc) {
|
|||||||
|
|
||||||
TEST_F(VideoSendStreamTest, RetransmitsNack) {
|
TEST_F(VideoSendStreamTest, RetransmitsNack) {
|
||||||
// Normal NACKs should use the send SSRC.
|
// Normal NACKs should use the send SSRC.
|
||||||
TestNackRetransmission(kSendSsrc);
|
TestNackRetransmission(kSendSsrc, kFakeSendPayloadType, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
|
TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
|
||||||
// NACKs over RTX should use a separate SSRC.
|
// NACKs over RTX should use a separate SSRC.
|
||||||
TestNackRetransmission(kSendRtxSsrc);
|
TestNackRetransmission(kSendRtxSsrc, kSendRtxPayloadType, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(VideoSendStreamTest, RetransmitsNackOverRtxWithPacing) {
|
||||||
|
// NACKs over RTX should use a separate SSRC.
|
||||||
|
TestNackRetransmission(kSendRtxSsrc, kSendRtxPayloadType, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VideoSendStreamTest, MaxPacketSize) {
|
TEST_F(VideoSendStreamTest, MaxPacketSize) {
|
||||||
class PacketSizeObserver : public SendTransportObserver {
|
class PacketSizeObserver : public test::RtpRtcpObserver {
|
||||||
public:
|
public:
|
||||||
PacketSizeObserver(size_t max_length) : SendTransportObserver(30 * 1000),
|
PacketSizeObserver(size_t max_length) : RtpRtcpObserver(30 * 1000),
|
||||||
max_length_(max_length), accumulated_size_(0) {}
|
max_length_(max_length), accumulated_size_(0) {}
|
||||||
|
|
||||||
virtual bool SendRTP(const uint8_t* packet, size_t length) OVERRIDE {
|
virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
|
||||||
RTPHeader header;
|
RTPHeader header;
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
rtp_header_parser_->Parse(packet, static_cast<int>(length), &header));
|
parser_->Parse(packet, static_cast<int>(length), &header));
|
||||||
|
|
||||||
EXPECT_LE(length, max_length_);
|
EXPECT_LE(length, max_length_);
|
||||||
|
|
||||||
@ -469,12 +458,12 @@ TEST_F(VideoSendStreamTest, MaxPacketSize) {
|
|||||||
if (accumulated_size_ + length > max_length_) {
|
if (accumulated_size_ + length > max_length_) {
|
||||||
// The packet was fragmented, total size was larger than max size,
|
// The packet was fragmented, total size was larger than max size,
|
||||||
// but size of individual fragments were within size limit => pass!
|
// but size of individual fragments were within size limit => pass!
|
||||||
send_test_complete_->Set();
|
observation_complete_->Set();
|
||||||
}
|
}
|
||||||
accumulated_size_ = 0; // Last fragment, reset packet size
|
accumulated_size_ = 0; // Last fragment, reset packet size
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return SEND_PACKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -485,7 +474,7 @@ TEST_F(VideoSendStreamTest, MaxPacketSize) {
|
|||||||
static const uint32_t kMaxPacketSize = 128;
|
static const uint32_t kMaxPacketSize = 128;
|
||||||
|
|
||||||
PacketSizeObserver observer(kMaxPacketSize);
|
PacketSizeObserver observer(kMaxPacketSize);
|
||||||
Call::Config call_config(&observer);
|
Call::Config call_config(observer.SendTransport());
|
||||||
scoped_ptr<Call> call(Call::Create(call_config));
|
scoped_ptr<Call> call(Call::Create(call_config));
|
||||||
|
|
||||||
VideoSendStream::Config send_config = GetSendTestConfig(call.get());
|
VideoSendStream::Config send_config = GetSendTestConfig(call.get());
|
||||||
@ -498,25 +487,24 @@ TEST_F(VideoSendStreamTest, CanChangeSendCodec) {
|
|||||||
static const uint8_t kFirstPayloadType = 121;
|
static const uint8_t kFirstPayloadType = 121;
|
||||||
static const uint8_t kSecondPayloadType = 122;
|
static const uint8_t kSecondPayloadType = 122;
|
||||||
|
|
||||||
class CodecChangeObserver : public SendTransportObserver {
|
class CodecChangeObserver : public test::RtpRtcpObserver {
|
||||||
public:
|
public:
|
||||||
CodecChangeObserver(VideoSendStream** send_stream_ptr)
|
CodecChangeObserver(VideoSendStream** send_stream_ptr)
|
||||||
: SendTransportObserver(30 * 1000),
|
: RtpRtcpObserver(30 * 1000),
|
||||||
received_first_payload_(EventWrapper::Create()),
|
received_first_payload_(EventWrapper::Create()),
|
||||||
send_stream_ptr_(send_stream_ptr) {}
|
send_stream_ptr_(send_stream_ptr) {}
|
||||||
|
|
||||||
virtual bool SendRTP(const uint8_t* packet, size_t length) OVERRIDE {
|
virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
|
||||||
RTPHeader header;
|
RTPHeader header;
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(parser_->Parse(packet, static_cast<int>(length), &header));
|
||||||
rtp_header_parser_->Parse(packet, static_cast<int>(length), &header));
|
|
||||||
|
|
||||||
if (header.payloadType == kFirstPayloadType) {
|
if (header.payloadType == kFirstPayloadType) {
|
||||||
received_first_payload_->Set();
|
received_first_payload_->Set();
|
||||||
} else if (header.payloadType == kSecondPayloadType) {
|
} else if (header.payloadType == kSecondPayloadType) {
|
||||||
send_test_complete_->Set();
|
observation_complete_->Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return SEND_PACKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual EventTypeWrapper Wait() OVERRIDE {
|
virtual EventTypeWrapper Wait() OVERRIDE {
|
||||||
@ -525,7 +513,7 @@ TEST_F(VideoSendStreamTest, CanChangeSendCodec) {
|
|||||||
|
|
||||||
EXPECT_TRUE((*send_stream_ptr_)->SetCodec(second_codec_));
|
EXPECT_TRUE((*send_stream_ptr_)->SetCodec(second_codec_));
|
||||||
|
|
||||||
EXPECT_EQ(kEventSignaled, SendTransportObserver::Wait())
|
EXPECT_EQ(kEventSignaled, RtpRtcpObserver::Wait())
|
||||||
<< "Timed out while waiting for second payload type.";
|
<< "Timed out while waiting for second payload type.";
|
||||||
|
|
||||||
// Return OK regardless, prevents double error reporting.
|
// Return OK regardless, prevents double error reporting.
|
||||||
@ -542,7 +530,7 @@ TEST_F(VideoSendStreamTest, CanChangeSendCodec) {
|
|||||||
VideoCodec second_codec_;
|
VideoCodec second_codec_;
|
||||||
} observer(&send_stream_);
|
} observer(&send_stream_);
|
||||||
|
|
||||||
Call::Config call_config(&observer);
|
Call::Config call_config(observer.SendTransport());
|
||||||
scoped_ptr<Call> call(Call::Create(call_config));
|
scoped_ptr<Call> call(Call::Create(call_config));
|
||||||
|
|
||||||
std::vector<VideoCodec> codecs = call->GetVideoCodecs();
|
std::vector<VideoCodec> codecs = call->GetVideoCodecs();
|
||||||
@ -570,10 +558,10 @@ TEST_F(VideoSendStreamTest, CanChangeSendCodec) {
|
|||||||
TEST_F(VideoSendStreamTest, AutoMute) {
|
TEST_F(VideoSendStreamTest, AutoMute) {
|
||||||
static const int kMuteTimeFrames = 60; // Mute for 2 seconds @ 30 fps.
|
static const int kMuteTimeFrames = 60; // Mute for 2 seconds @ 30 fps.
|
||||||
|
|
||||||
class RembObserver : public SendTransportObserver, public I420FrameCallback {
|
class RembObserver : public test::RtpRtcpObserver, public I420FrameCallback {
|
||||||
public:
|
public:
|
||||||
RembObserver()
|
RembObserver()
|
||||||
: SendTransportObserver(30 * 1000), // Timeout after 30 seconds.
|
: RtpRtcpObserver(30 * 1000), // Timeout after 30 seconds.
|
||||||
transport_adapter_(&transport_),
|
transport_adapter_(&transport_),
|
||||||
clock_(Clock::GetRealTimeClock()),
|
clock_(Clock::GetRealTimeClock()),
|
||||||
test_state_(kBeforeMute),
|
test_state_(kBeforeMute),
|
||||||
@ -588,20 +576,19 @@ TEST_F(VideoSendStreamTest, AutoMute) {
|
|||||||
transport_.SetReceiver(receiver);
|
transport_.SetReceiver(receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool SendRTCP(const uint8_t* packet, size_t length) OVERRIDE {
|
virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE {
|
||||||
// Receive statistics reporting having lost 0% of the packets.
|
// Receive statistics reporting having lost 0% of the packets.
|
||||||
// This is needed for the send-side bitrate controller to work properly.
|
// This is needed for the send-side bitrate controller to work properly.
|
||||||
CriticalSectionScoped lock(crit_sect_.get());
|
CriticalSectionScoped lock(crit_sect_.get());
|
||||||
SendRtcpFeedback(0); // REMB is only sent if value is > 0.
|
SendRtcpFeedback(0); // REMB is only sent if value is > 0.
|
||||||
return true;
|
return SEND_PACKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool SendRTP(const uint8_t* packet, size_t length) OVERRIDE {
|
virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
|
||||||
CriticalSectionScoped lock(crit_sect_.get());
|
CriticalSectionScoped lock(crit_sect_.get());
|
||||||
++rtp_count_;
|
++rtp_count_;
|
||||||
RTPHeader header;
|
RTPHeader header;
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(parser_->Parse(packet, static_cast<int>(length), &header));
|
||||||
rtp_header_parser_->Parse(packet, static_cast<int>(length), &header));
|
|
||||||
last_sequence_number_ = header.sequenceNumber;
|
last_sequence_number_ = header.sequenceNumber;
|
||||||
|
|
||||||
if (test_state_ == kBeforeMute) {
|
if (test_state_ == kBeforeMute) {
|
||||||
@ -611,10 +598,10 @@ TEST_F(VideoSendStreamTest, AutoMute) {
|
|||||||
} else if (test_state_ == kDuringMute) {
|
} else if (test_state_ == kDuringMute) {
|
||||||
mute_frame_count_ = 0;
|
mute_frame_count_ = 0;
|
||||||
} else if (test_state_ == kWaitingForPacket) {
|
} else if (test_state_ == kWaitingForPacket) {
|
||||||
send_test_complete_->Set();
|
observation_complete_->Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return SEND_PACKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method implements the I420FrameCallback.
|
// This method implements the I420FrameCallback.
|
||||||
@ -668,7 +655,7 @@ TEST_F(VideoSendStreamTest, AutoMute) {
|
|||||||
scoped_ptr<CriticalSectionWrapper> crit_sect_;
|
scoped_ptr<CriticalSectionWrapper> crit_sect_;
|
||||||
} observer;
|
} observer;
|
||||||
|
|
||||||
Call::Config call_config(&observer);
|
Call::Config call_config(observer.SendTransport());
|
||||||
scoped_ptr<Call> call(Call::Create(call_config));
|
scoped_ptr<Call> call(Call::Create(call_config));
|
||||||
observer.SetReceiver(call->Receiver());
|
observer.SetReceiver(call->Receiver());
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user