Adding test for relaying all simulcast streams to different receive channels.

BUG=

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@2726 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
stefan@webrtc.org 2012-09-10 13:27:47 +00:00
parent deaf685b66
commit e37ecc6f81
8 changed files with 252 additions and 80 deletions

View File

@ -126,7 +126,8 @@ void TestFullStack(const TbInterfaces& interfaces,
}
// Configure External transport to simulate network interference:
TbExternalTransport external_transport(*interfaces.network);
TbExternalTransport external_transport(*interfaces.network, video_channel,
NULL);
external_transport.SetPacketLoss(packet_loss_percent);
external_transport.SetNetworkDelay(network_delay_ms);

View File

@ -443,7 +443,7 @@ int VideoEngineSampleCode(void* window1, void* window2)
}
// Setting External transport
TbExternalTransport extTransport(*(ptrViENetwork));
TbExternalTransport extTransport(*(ptrViENetwork), videoChannel, NULL);
int testMode = 0;
std::cout << std::endl;

View File

@ -61,7 +61,8 @@ void ViEAutoTest::ViENetworkStandardTest()
//
// Transport
//
TbExternalTransport testTransport(*ViE.network);
TbExternalTransport testTransport(*ViE.network, tbChannel.videoChannel,
NULL);
EXPECT_EQ(0, ViE.network->RegisterSendTransport(
tbChannel.videoChannel, testTransport));
EXPECT_EQ(0, ViE.base->StartReceive(tbChannel.videoChannel));
@ -225,7 +226,8 @@ void ViEAutoTest::ViENetworkAPITest()
//
// External transport
//
TbExternalTransport testTransport(*ViE.network);
TbExternalTransport testTransport(*ViE.network, tbChannel.videoChannel,
NULL);
EXPECT_EQ(0, ViE.network->RegisterSendTransport(
tbChannel.videoChannel, testTransport));
EXPECT_NE(0, ViE.network->RegisterSendTransport(

View File

@ -354,7 +354,7 @@ int VideoEngineSampleRecordCode(void* window1, void* window2) {
}
// Setting External transport
TbExternalTransport extTransport(*(ptrViENetwork));
TbExternalTransport extTransport(*(ptrViENetwork), videoChannel, NULL);
error = ptrViENetwork->SetLocalReceiver(videoChannel, rtpPort);
if (error == -1) {
printf("ERROR in ViENetwork::SetLocalReceiver\n");

View File

@ -104,7 +104,8 @@ void ViEAutoTest::ViERtpRtcpStandardTest()
tbCapture.ConnectTo(tbChannel.videoChannel);
ViETest::Log("\n");
TbExternalTransport myTransport(*(ViE.network));
TbExternalTransport myTransport(*(ViE.network), tbChannel.videoChannel,
NULL);
EXPECT_EQ(0, ViE.network->RegisterSendTransport(
tbChannel.videoChannel, myTransport));
@ -375,7 +376,8 @@ void ViEAutoTest::ViERtpRtcpExtendedTest()
//tbChannel.StartReceive(rtpPort);
//tbChannel.StartSend(rtpPort);
TbExternalTransport myTransport(*(ViE.network));
TbExternalTransport myTransport(*(ViE.network), tbChannel.videoChannel,
NULL);
EXPECT_EQ(0, ViE.network->RegisterSendTransport(
tbChannel.videoChannel, myTransport));

View File

@ -22,9 +22,16 @@
#include "vie_render.h"
#include "vie_rtp_rtcp.h"
enum RelayMode {
kRelayOneStream = 1,
kRelayAllStreams = 2
};
#define VCM_RED_PAYLOAD_TYPE 96
#define VCM_ULPFEC_PAYLOAD_TYPE 97
const int kNumStreams = 3;
void InitialSingleStreamSettings(webrtc::VideoCodec* video_codec) {
video_codec->numberOfSimulcastStreams = 0;
video_codec->width = 1200;
@ -35,7 +42,7 @@ void SetSimulcastSettings(webrtc::VideoCodec* video_codec) {
video_codec->width = 1280;
video_codec->height = 720;
// simulcast settings
video_codec->numberOfSimulcastStreams = 3;
video_codec->numberOfSimulcastStreams = kNumStreams;
video_codec->simulcastStream[0].width = 320;
video_codec->simulcastStream[0].height = 180;
video_codec->simulcastStream[0].numberOfTemporalLayers = 0;
@ -59,7 +66,7 @@ void RuntimeSingleStreamSettings(webrtc::VideoCodec* video_codec) {
SetSimulcastSettings(video_codec);
video_codec->width = 1200;
video_codec->height = 800;
video_codec->numberOfSimulcastStreams = 3;
video_codec->numberOfSimulcastStreams = kNumStreams;
video_codec->simulcastStream[0].maxBitrate = 0;
video_codec->simulcastStream[1].maxBitrate = 0;
video_codec->simulcastStream[2].maxBitrate = 0;
@ -72,6 +79,7 @@ int VideoEngineSimulcastTest(void* window1, void* window2)
//********************************************************
int error = 0;
int receive_channels[kNumStreams];
//
// Create a VideoEngine instance
@ -118,6 +126,17 @@ int VideoEngineSimulcastTest(void* window1, void* window2)
return -1;
}
RelayMode relay_mode = kRelayOneStream;
printf("Select relay mode:\n");
printf("\t1. Relay one stream\n");
printf("\t2. Relay all streams\n");
if (scanf("%d", reinterpret_cast<int*>(&relay_mode)) != 1)
{
printf("Error in scanf()\n");
return -1;
}
getchar();
int videoChannel = -1;
error = ptrViEBase->CreateChannel(videoChannel);
if (error == -1)
@ -126,6 +145,17 @@ int VideoEngineSimulcastTest(void* window1, void* window2)
return -1;
}
for (int i = 0; i < kNumStreams; ++i) {
receive_channels[i] = -1;
error = ptrViEBase->CreateReceiveChannel(receive_channels[i],
videoChannel);
if (error == -1)
{
printf("ERROR in ViEBase::CreateChannel\n");
return -1;
}
}
//
// List available capture devices, allocate and connect.
//
@ -227,6 +257,13 @@ int VideoEngineSimulcastTest(void* window1, void* window2)
return -1;
}
ptrViERtpRtcp->SetRembStatus(videoChannel, true, false);
if (error == -1)
{
printf("ERROR in ViERTP_RTCP::SetRTCPStatus\n");
return -1;
}
error = ptrViERtpRtcp->SetKeyFrameRequestMethod(
videoChannel, webrtc::kViEKeyFrameRequestPliRtcp);
if (error == -1)
@ -235,6 +272,31 @@ int VideoEngineSimulcastTest(void* window1, void* window2)
return -1;
}
for (int i = 0; i < kNumStreams; ++i) {
error = ptrViERtpRtcp->SetRTCPStatus(receive_channels[i],
webrtc::kRtcpCompound_RFC4585);
if (error == -1)
{
printf("ERROR in ViERTP_RTCP::SetRTCPStatus\n");
return -1;
}
ptrViERtpRtcp->SetRembStatus(receive_channels[i], false, true);
if (error == -1)
{
printf("ERROR in ViERTP_RTCP::SetRTCPStatus\n");
return -1;
}
error = ptrViERtpRtcp->SetKeyFrameRequestMethod(
receive_channels[i], webrtc::kViEKeyFrameRequestPliRtcp);
if (error == -1)
{
printf("ERROR in ViERTP_RTCP::SetKeyFrameRequestMethod\n");
return -1;
}
}
//
// Set up rendering
//
@ -260,15 +322,20 @@ int VideoEngineSimulcastTest(void* window1, void* window2)
return -1;
}
error = ptrViERender->AddRenderer(videoChannel, window2, 1, 0.0, 0.0, 1.0,
1.0);
// Only rendering the thumbnail.
int channel_to_render = videoChannel;
if (relay_mode == kRelayAllStreams) {
channel_to_render = receive_channels[0];
}
error = ptrViERender->AddRenderer(channel_to_render, window2, 1, 0.0,
0.0, 1.0, 1.0);
if (error == -1)
{
printf("ERROR in ViERender::AddRenderer\n");
return -1;
}
error = ptrViERender->StartRender(videoChannel);
error = ptrViERender->StartRender(channel_to_render);
if (error == -1)
{
printf("ERROR in ViERender::StartRender\n");
@ -303,11 +370,13 @@ int VideoEngineSimulcastTest(void* window1, void* window2)
{
continue;
}
error = ptrViECodec->SetReceiveCodec(videoChannel, videoCodec);
if (error == -1)
{
for (int i = 0; i < kNumStreams; ++i) {
error = ptrViECodec->SetReceiveCodec(receive_channels[i], videoCodec);
if (error == -1)
{
printf("ERROR in ViECodec::SetReceiveCodec\n");
return -1;
}
}
if (videoCodec.codecType != webrtc::kVideoCodecRED
&& videoCodec.codecType != webrtc::kVideoCodecULPFEC)
@ -362,8 +431,31 @@ int VideoEngineSimulcastTest(void* window1, void* window2)
return -1;
}
TbExternalTransport::SsrcChannelMap ssrc_channel_map;
for (int idx = 0; idx < num_streams; idx++)
{
error = ptrViERtpRtcp->SetLocalSSRC(
videoChannel,
idx+1, // SSRC
webrtc::kViEStreamTypeNormal,
idx);
ssrc_channel_map[idx + 1] = receive_channels[idx];
if (error == -1)
{
printf("ERROR in ViERTP_RTCP::SetLocalSSRC(idx:%d)\n",
idx);
return -1;
}
}
TbExternalTransport::SsrcChannelMap* channel_map_ptr = &ssrc_channel_map;
if (relay_mode == kRelayOneStream) {
channel_map_ptr = NULL;
}
// Setting External transport
TbExternalTransport extTransport(*(ptrViENetwork));
TbExternalTransport extTransport(*(ptrViENetwork), videoChannel,
channel_map_ptr);
error = ptrViENetwork->RegisterSendTransport(videoChannel,
extTransport);
@ -373,32 +465,23 @@ int VideoEngineSimulcastTest(void* window1, void* window2)
return -1;
}
for (int i = 0; i < kNumStreams; ++i) {
error = ptrViENetwork->RegisterSendTransport(receive_channels[i],
extTransport);
if (error == -1)
{
printf("ERROR in ViECodec::RegisterSendTransport \n");
return -1;
}
}
extTransport.SetPacketLoss(0);
// Set network delay value
extTransport.SetNetworkDelay(10);
for (int idx = 0; idx < num_streams; idx++)
{
error = ptrViERtpRtcp->SetLocalSSRC(
videoChannel,
idx+1, // SSRC
webrtc::kViEStreamTypeNormal,
idx);
if (error == -1)
{
printf("ERROR in ViERTP_RTCP::SetLocalSSRC(idx:%d)\n",
idx);
return -1;
}
}
extTransport.SetSSRCFilter(num_streams);
error = ptrViEBase->StartReceive(videoChannel);
if (error == -1)
{
printf("ERROR in ViENetwork::StartReceive\n");
return -1;
if (relay_mode == kRelayOneStream) {
extTransport.SetSSRCFilter(num_streams);
}
error = ptrViEBase->StartSend(videoChannel);
@ -407,6 +490,21 @@ int VideoEngineSimulcastTest(void* window1, void* window2)
printf("ERROR in ViENetwork::StartSend\n");
return -1;
}
error = ptrViEBase->StartReceive(videoChannel);
if (error == -1)
{
printf("ERROR in ViENetwork::StartReceive\n");
return -1;
}
for (int i = 0; i < kNumStreams; ++i) {
error = ptrViEBase->StartReceive(receive_channels[i]);
if (error == -1)
{
printf("ERROR in ViENetwork::StartReceive\n");
return -1;
}
}
// Create a receive channel to verify that it doesn't mess up toggling
// between single stream and simulcast.
@ -463,10 +561,14 @@ int VideoEngineSimulcastTest(void* window1, void* window2)
return -1;
}
}
extTransport.SetSSRCFilter(num_streams);
if (relay_mode == kRelayOneStream) {
extTransport.SetSSRCFilter(num_streams);
}
} else if (ssrc > 0 && ssrc < 4)
{
if (relay_mode == kRelayOneStream) {
extTransport.SetSSRCFilter(ssrc);
}
} else
{
printf("Invalid SSRC\n");
@ -488,6 +590,15 @@ int VideoEngineSimulcastTest(void* window1, void* window2)
return -1;
}
for (int i = 0; i < kNumStreams; ++i) {
error = ptrViEBase->StopReceive(receive_channels[i]);
if (error == -1)
{
printf("ERROR in ViEBase::StopReceive\n");
return -1;
}
}
error = ptrViEBase->StopReceive(videoChannel);
if (error == -1)
{
@ -516,14 +627,14 @@ int VideoEngineSimulcastTest(void* window1, void* window2)
return -1;
}
error = ptrViERender->StopRender(videoChannel);
error = ptrViERender->StopRender(channel_to_render);
if (error == -1)
{
printf("ERROR in ViERender::StopRender\n");
return -1;
}
error = ptrViERender->RemoveRenderer(videoChannel);
error = ptrViERender->RemoveRenderer(channel_to_render);
if (error == -1)
{
printf("ERROR in ViERender::RemoveRenderer\n");
@ -551,6 +662,15 @@ int VideoEngineSimulcastTest(void* window1, void* window2)
return -1;
}
for (int i = 0; i < kNumStreams; ++i) {
error = ptrViEBase->DeleteChannel(receive_channels[i]);
if (error == -1)
{
printf("ERROR in ViEBase::DeleteChannel\n");
return -1;
}
}
error = ptrViEBase->DeleteChannel(videoChannel);
if (error == -1)
{

View File

@ -16,6 +16,7 @@
#define WEBRTC_VIDEO_ENGINE_TEST_AUTOTEST_INTERFACE_TB_EXTERNAL_TRANSPORT_H_
#include <list>
#include <map>
#include "common_types.h"
@ -61,7 +62,11 @@ protected:
class TbExternalTransport : public webrtc::Transport
{
public:
TbExternalTransport(webrtc::ViENetwork& vieNetwork);
typedef std::map<unsigned int, unsigned int> SsrcChannelMap;
TbExternalTransport(webrtc::ViENetwork& vieNetwork,
int sender_channel,
TbExternalTransport::SsrcChannelMap* receive_channels);
~TbExternalTransport(void);
virtual int SendPacket(int channel, const void *data, int len);
@ -115,6 +120,8 @@ private:
WebRtc_Word64 receiveTime;
} VideoPacket;
int sender_channel_;
SsrcChannelMap* receive_channels_;
webrtc::ViENetwork& _vieNetwork;
webrtc::ThreadWrapper& _thread;
webrtc::EventWrapper& _event;

View File

@ -31,39 +31,48 @@
#pragma warning(disable: 4355) // 'this' : used in base member initializer list
#endif
TbExternalTransport::TbExternalTransport(webrtc::ViENetwork& vieNetwork) :
_vieNetwork(vieNetwork),
_thread(*webrtc::ThreadWrapper::CreateThread(
ViEExternalTransportRun, this, webrtc::kHighPriority,
"AutotestTransport")),
_event(*webrtc::EventWrapper::Create()),
_crit(*webrtc::CriticalSectionWrapper::CreateCriticalSection()),
_statCrit(*webrtc::CriticalSectionWrapper::CreateCriticalSection()),
_lossRate(0),
_networkDelayMs(0),
_rtpCount(0),
_rtcpCount(0),
_dropCount(0),
_rtpPackets(),
_rtcpPackets(),
_send_frame_callback(NULL),
_receive_frame_callback(NULL),
_temporalLayers(0),
_seqNum(0),
_sendPID(0),
_receivedPID(0),
_switchLayer(false),
_currentRelayLayer(0),
_lastTimeMs(webrtc::TickTime::MillisecondTimestamp()),
_checkSSRC(false),
_lastSSRC(0),
_filterSSRC(false),
_SSRC(0),
_checkSequenceNumber(0),
_firstSequenceNumber(0),
_firstRTPTimestamp(0),
_lastSendRTPTimestamp(0),
_lastReceiveRTPTimestamp(0)
const uint8_t kSenderReportPayloadType = 200;
const uint8_t kReceiverReportPayloadType = 201;
TbExternalTransport::TbExternalTransport(
webrtc::ViENetwork& vieNetwork,
int sender_channel,
TbExternalTransport::SsrcChannelMap* receive_channels)
:
sender_channel_(sender_channel),
receive_channels_(receive_channels),
_vieNetwork(vieNetwork),
_thread(*webrtc::ThreadWrapper::CreateThread(
ViEExternalTransportRun, this, webrtc::kHighPriority,
"AutotestTransport")),
_event(*webrtc::EventWrapper::Create()),
_crit(*webrtc::CriticalSectionWrapper::CreateCriticalSection()),
_statCrit(*webrtc::CriticalSectionWrapper::CreateCriticalSection()),
_lossRate(0),
_networkDelayMs(0),
_rtpCount(0),
_rtcpCount(0),
_dropCount(0),
_rtpPackets(),
_rtcpPackets(),
_send_frame_callback(NULL),
_receive_frame_callback(NULL),
_temporalLayers(0),
_seqNum(0),
_sendPID(0),
_receivedPID(0),
_switchLayer(false),
_currentRelayLayer(0),
_lastTimeMs(webrtc::TickTime::MillisecondTimestamp()),
_checkSSRC(false),
_lastSSRC(0),
_filterSSRC(false),
_SSRC(0),
_checkSequenceNumber(0),
_firstSequenceNumber(0),
_firstRTPTimestamp(0),
_lastSendRTPTimestamp(0),
_lastReceiveRTPTimestamp(0)
{
srand((int) webrtc::TickTime::MicrosecondTimestamp());
unsigned int tId = 0;
@ -360,8 +369,13 @@ bool TbExternalTransport::ViEExternalTransportProcess()
// Send to ViE
if (packet)
{
unsigned int ssrc = 0;
{
webrtc::CriticalSectionScoped cs(_statCrit);
ssrc = ((packet->packetBuffer[8]) << 24);
ssrc += (packet->packetBuffer[9] << 16);
ssrc += (packet->packetBuffer[10] << 8);
ssrc += packet->packetBuffer[11];
if (_checkSSRC)
{
_lastSSRC = ((packet->packetBuffer[8]) << 24);
@ -390,9 +404,17 @@ bool TbExternalTransport::ViEExternalTransportProcess()
_receive_frame_callback->FrameReceived(rtp_timestamp);
}
_lastReceiveRTPTimestamp = rtp_timestamp;
_vieNetwork.ReceivedRTPPacket(packet->channel,
packet->packetBuffer, packet->length);
int destination_channel = sender_channel_;
if (receive_channels_) {
SsrcChannelMap::iterator it = receive_channels_->find(ssrc);
if (it == receive_channels_->end()) {
return false;
}
destination_channel = it->second;
}
_vieNetwork.ReceivedRTPPacket(destination_channel,
packet->packetBuffer,
packet->length);
delete packet;
packet = NULL;
}
@ -428,9 +450,27 @@ bool TbExternalTransport::ViEExternalTransportProcess()
// Send to ViE
if (packet)
{
_vieNetwork.ReceivedRTCPPacket(
packet->channel,
packet->packetBuffer, packet->length);
uint8_t pltype = static_cast<uint8_t>(packet->packetBuffer[1]);
if (pltype == kSenderReportPayloadType) {
// Sender report.
if (receive_channels_) {
for (SsrcChannelMap::iterator it = receive_channels_->begin();
it != receive_channels_->end(); ++it) {
_vieNetwork.ReceivedRTCPPacket(it->second,
packet->packetBuffer,
packet->length);
}
} else {
_vieNetwork.ReceivedRTCPPacket(sender_channel_,
packet->packetBuffer,
packet->length);
}
} else if (pltype == kReceiverReportPayloadType) {
// Receiver report.
_vieNetwork.ReceivedRTCPPacket(sender_channel_,
packet->packetBuffer,
packet->length);
}
delete packet;
packet = NULL;
}