diff --git a/src/video_engine/test/auto_test/primitives/framedrop_primitives.cc b/src/video_engine/test/auto_test/primitives/framedrop_primitives.cc index fc7d87b107..84bf768d85 100644 --- a/src/video_engine/test/auto_test/primitives/framedrop_primitives.cc +++ b/src/video_engine/test/auto_test/primitives/framedrop_primitives.cc @@ -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); diff --git a/src/video_engine/test/auto_test/source/vie_autotest_loopback.cc b/src/video_engine/test/auto_test/source/vie_autotest_loopback.cc index d6607457a7..ee31e59375 100644 --- a/src/video_engine/test/auto_test/source/vie_autotest_loopback.cc +++ b/src/video_engine/test/auto_test/source/vie_autotest_loopback.cc @@ -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; diff --git a/src/video_engine/test/auto_test/source/vie_autotest_network.cc b/src/video_engine/test/auto_test/source/vie_autotest_network.cc index d39279fe8c..b7c95c1ead 100644 --- a/src/video_engine/test/auto_test/source/vie_autotest_network.cc +++ b/src/video_engine/test/auto_test/source/vie_autotest_network.cc @@ -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( diff --git a/src/video_engine/test/auto_test/source/vie_autotest_record.cc b/src/video_engine/test/auto_test/source/vie_autotest_record.cc index 9c423a7042..15b2a83f27 100644 --- a/src/video_engine/test/auto_test/source/vie_autotest_record.cc +++ b/src/video_engine/test/auto_test/source/vie_autotest_record.cc @@ -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"); diff --git a/src/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc b/src/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc index 573a58adcb..98e95079e4 100644 --- a/src/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc +++ b/src/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc @@ -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)); diff --git a/src/video_engine/test/auto_test/source/vie_autotest_simulcast.cc b/src/video_engine/test/auto_test/source/vie_autotest_simulcast.cc index f26340bfe7..18d28be19a 100644 --- a/src/video_engine/test/auto_test/source/vie_autotest_simulcast.cc +++ b/src/video_engine/test/auto_test/source/vie_autotest_simulcast.cc @@ -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(&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) { diff --git a/src/video_engine/test/libvietest/include/tb_external_transport.h b/src/video_engine/test/libvietest/include/tb_external_transport.h index 65788116db..b1bdc9272f 100644 --- a/src/video_engine/test/libvietest/include/tb_external_transport.h +++ b/src/video_engine/test/libvietest/include/tb_external_transport.h @@ -16,6 +16,7 @@ #define WEBRTC_VIDEO_ENGINE_TEST_AUTOTEST_INTERFACE_TB_EXTERNAL_TRANSPORT_H_ #include +#include #include "common_types.h" @@ -61,7 +62,11 @@ protected: class TbExternalTransport : public webrtc::Transport { public: - TbExternalTransport(webrtc::ViENetwork& vieNetwork); + typedef std::map 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; diff --git a/src/video_engine/test/libvietest/testbed/tb_external_transport.cc b/src/video_engine/test/libvietest/testbed/tb_external_transport.cc index e1e30be859..83de07e4fb 100644 --- a/src/video_engine/test/libvietest/testbed/tb_external_transport.cc +++ b/src/video_engine/test/libvietest/testbed/tb_external_transport.cc @@ -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(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; }