• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "webrtc/video_engine/test/libvietest/include/tb_external_transport.h"
12 
13 #include <assert.h>
14 
15 #include <math.h>
16 #include <stdio.h> // printf
17 #include <stdlib.h> // rand
18 
19 #if defined(WEBRTC_LINUX) || defined(__linux__)
20 #include <string.h>
21 #endif
22 #if defined(WEBRTC_MAC)
23 #include <string.h>
24 #endif
25 
26 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
27 #include "webrtc/system_wrappers/interface/event_wrapper.h"
28 #include "webrtc/system_wrappers/interface/thread_wrapper.h"
29 #include "webrtc/system_wrappers/interface/tick_util.h"
30 #include "webrtc/video_engine/include/vie_network.h"
31 
32 #if defined(_WIN32)
33 #pragma warning(disable: 4355) // 'this' : used in base member initializer list
34 #endif
35 
36 const uint8_t kSenderReportPayloadType = 200;
37 const uint8_t kReceiverReportPayloadType = 201;
38 
TbExternalTransport(webrtc::ViENetwork & vieNetwork,int sender_channel,TbExternalTransport::SsrcChannelMap * receive_channels)39 TbExternalTransport::TbExternalTransport(
40     webrtc::ViENetwork& vieNetwork,
41     int sender_channel,
42     TbExternalTransport::SsrcChannelMap* receive_channels)
43     :
44       sender_channel_(sender_channel),
45       receive_channels_(receive_channels),
46       _vieNetwork(vieNetwork),
47       _thread(*webrtc::ThreadWrapper::CreateThread(
48           ViEExternalTransportRun, this, webrtc::kHighPriority,
49           "AutotestTransport")),
50       _event(*webrtc::EventWrapper::Create()),
51       _crit(*webrtc::CriticalSectionWrapper::CreateCriticalSection()),
52       _statCrit(*webrtc::CriticalSectionWrapper::CreateCriticalSection()),
53       network_parameters_(),
54       _rtpCount(0),
55       _rtcpCount(0),
56       _dropCount(0),
57       packet_counters_(),
58       _rtpPackets(),
59       _rtcpPackets(),
60       _send_frame_callback(NULL),
61       _receive_frame_callback(NULL),
62       _temporalLayers(0),
63       _seqNum(0),
64       _sendPID(0),
65       _receivedPID(0),
66       _switchLayer(false),
67       _currentRelayLayer(0),
68       _lastTimeMs(webrtc::TickTime::MillisecondTimestamp()),
69       _checkSSRC(false),
70       _lastSSRC(0),
71       _filterSSRC(false),
72       _SSRC(0),
73       _checkSequenceNumber(0),
74       _firstSequenceNumber(0),
75       _firstRTPTimestamp(0),
76       _lastSendRTPTimestamp(0),
77       _lastReceiveRTPTimestamp(0),
78       last_receive_time_(-1),
79       previous_drop_(false)
80 {
81     srand((int) webrtc::TickTime::MicrosecondTimestamp());
82     unsigned int tId = 0;
83     memset(&network_parameters_, 0, sizeof(NetworkParameters));
84     _thread.Start(tId);
85 }
86 
~TbExternalTransport()87 TbExternalTransport::~TbExternalTransport()
88 {
89     _thread.SetNotAlive();
90     _event.Set();
91     if (_thread.Stop())
92     {
93         delete &_thread;
94         delete &_event;
95     }
96     for (std::list<VideoPacket*>::iterator it = _rtpPackets.begin();
97          it != _rtpPackets.end(); ++it) {
98         delete *it;
99     }
100     _rtpPackets.clear();
101     for (std::list<VideoPacket*>::iterator it = _rtcpPackets.begin();
102          it != _rtcpPackets.end(); ++it) {
103         delete *it;
104     }
105     _rtcpPackets.clear();
106     delete &_crit;
107     delete &_statCrit;
108 }
109 
SendPacket(int channel,const void * data,int len)110 int TbExternalTransport::SendPacket(int channel, const void *data, int len)
111 {
112   // Parse timestamp from RTP header according to RFC 3550, section 5.1.
113     uint8_t* ptr = (uint8_t*)data;
114     uint8_t payload_type = ptr[1] & 0x7F;
115     uint32_t rtp_timestamp = ptr[4] << 24;
116     rtp_timestamp += ptr[5] << 16;
117     rtp_timestamp += ptr[6] << 8;
118     rtp_timestamp += ptr[7];
119     _crit.Enter();
120     if (_firstRTPTimestamp == 0) {
121       _firstRTPTimestamp = rtp_timestamp;
122     }
123     _crit.Leave();
124     if (_send_frame_callback != NULL &&
125         _lastSendRTPTimestamp != rtp_timestamp) {
126       _send_frame_callback->FrameSent(rtp_timestamp);
127     }
128     ++packet_counters_[payload_type];
129     _lastSendRTPTimestamp = rtp_timestamp;
130 
131     if (_filterSSRC)
132     {
133         uint8_t* ptr = (uint8_t*)data;
134         uint32_t ssrc = ptr[8] << 24;
135         ssrc += ptr[9] << 16;
136         ssrc += ptr[10] << 8;
137         ssrc += ptr[11];
138         if (ssrc != _SSRC)
139         {
140             return len; // return len to avoid error in trace file
141         }
142     }
143     if (_temporalLayers) {
144         // parse out vp8 temporal layers
145         // 12 bytes RTP
146         uint8_t* ptr = (uint8_t*)data;
147 
148         if (ptr[12] & 0x80 &&  // X-bit
149             ptr[13] & 0x20)  // T-bit
150         {
151             int offset = 1;
152             if (ptr[13] & 0x80) // PID-bit
153             {
154                 offset++;
155                 if (ptr[14] & 0x80) // 2 byte PID
156                 {
157                     offset++;
158                 }
159             }
160             if (ptr[13] & 0x40)
161             {
162                 offset++;
163             }
164             unsigned char TID = (ptr[13 + offset] >> 5);
165             unsigned int timeMs = NowMs();
166 
167             // Every 5 second switch layer
168             if (_lastTimeMs + 5000 < timeMs)
169             {
170                 _lastTimeMs = timeMs;
171                 _switchLayer = true;
172             }
173             // Switch at the non ref frame
174             if (_switchLayer && (ptr[12] & 0x20))
175             {   // N-bit
176               _currentRelayLayer++;
177                 if (_currentRelayLayer >= _temporalLayers)
178                   _currentRelayLayer = 0;
179 
180                 _switchLayer = false;
181                 printf("\t Switching to layer:%d\n", _currentRelayLayer);
182             }
183             if (_currentRelayLayer < TID)
184             {
185                 return len; // return len to avoid error in trace file
186             }
187             if (ptr[14] & 0x80) // 2 byte PID
188             {
189                 if(_receivedPID != ptr[15])
190                 {
191                     _sendPID++;
192                     _receivedPID = ptr[15];
193                 }
194             } else
195             {
196               if(_receivedPID != ptr[14])
197               {
198                 _sendPID++;
199                 _receivedPID = ptr[14];
200               }
201             }
202         }
203     }
204     _statCrit.Enter();
205     _rtpCount++;
206     _statCrit.Leave();
207 
208     // Packet loss.
209     switch (network_parameters_.loss_model)
210     {
211         case (kNoLoss):
212             previous_drop_ = false;
213             break;
214         case (kUniformLoss):
215             previous_drop_ = UniformLoss(network_parameters_.packet_loss_rate);
216             break;
217         case (kGilbertElliotLoss):
218             previous_drop_ = GilbertElliotLoss(
219                 network_parameters_.packet_loss_rate,
220                 network_parameters_.burst_length);
221             break;
222     }
223     // Never drop packets from the first RTP timestamp (first frame)
224     // transmitted.
225     if (previous_drop_ && _firstRTPTimestamp != rtp_timestamp)
226     {
227         _statCrit.Enter();
228         _dropCount++;
229         _statCrit.Leave();
230         return len;
231     }
232 
233     VideoPacket* newPacket = new VideoPacket();
234     memcpy(newPacket->packetBuffer, data, len);
235 
236     if (_temporalLayers)
237     {
238         // rewrite seqNum
239         newPacket->packetBuffer[2] = _seqNum >> 8;
240         newPacket->packetBuffer[3] = _seqNum;
241         _seqNum++;
242 
243         // rewrite PID
244         if (newPacket->packetBuffer[14] & 0x80) // 2 byte PID
245         {
246             newPacket->packetBuffer[14] = (_sendPID >> 8) | 0x80;
247             newPacket->packetBuffer[15] = _sendPID;
248         } else
249         {
250             newPacket->packetBuffer[14] = (_sendPID & 0x7f);
251         }
252     }
253     newPacket->length = len;
254     newPacket->channel = channel;
255 
256     _crit.Enter();
257     // Add jitter and make sure receiveTime isn't lower than receive time of
258     // last frame.
259     int network_delay_ms = GaussianRandom(
260         network_parameters_.mean_one_way_delay,
261         network_parameters_.std_dev_one_way_delay);
262     newPacket->receiveTime = NowMs() + network_delay_ms;
263     if (newPacket->receiveTime < last_receive_time_) {
264       newPacket->receiveTime = last_receive_time_;
265     }
266     _rtpPackets.push_back(newPacket);
267     _event.Set();
268     _crit.Leave();
269     return len;
270 }
271 
RegisterSendFrameCallback(SendFrameCallback * callback)272 void TbExternalTransport::RegisterSendFrameCallback(
273     SendFrameCallback* callback) {
274   _send_frame_callback = callback;
275 }
276 
RegisterReceiveFrameCallback(ReceiveFrameCallback * callback)277 void TbExternalTransport::RegisterReceiveFrameCallback(
278     ReceiveFrameCallback* callback) {
279   _receive_frame_callback = callback;
280 }
281 
282 // Set to 0 to disable.
SetTemporalToggle(unsigned char layers)283 void TbExternalTransport::SetTemporalToggle(unsigned char layers)
284 {
285     _temporalLayers = layers;
286 }
287 
SendRTCPPacket(int channel,const void * data,int len)288 int TbExternalTransport::SendRTCPPacket(int channel, const void *data, int len)
289 {
290     _statCrit.Enter();
291     _rtcpCount++;
292     _statCrit.Leave();
293 
294     VideoPacket* newPacket = new VideoPacket();
295     memcpy(newPacket->packetBuffer, data, len);
296     newPacket->length = len;
297     newPacket->channel = channel;
298 
299     _crit.Enter();
300     int network_delay_ms = GaussianRandom(
301             network_parameters_.mean_one_way_delay,
302             network_parameters_.std_dev_one_way_delay);
303     newPacket->receiveTime = NowMs() + network_delay_ms;
304     _rtcpPackets.push_back(newPacket);
305     _event.Set();
306     _crit.Leave();
307     return len;
308 }
309 
SetNetworkParameters(const NetworkParameters & network_parameters)310 void TbExternalTransport::SetNetworkParameters(
311     const NetworkParameters& network_parameters)
312 {
313     webrtc::CriticalSectionScoped cs(&_crit);
314     network_parameters_ = network_parameters;
315 }
316 
SetSSRCFilter(uint32_t ssrc)317 void TbExternalTransport::SetSSRCFilter(uint32_t ssrc)
318 {
319     webrtc::CriticalSectionScoped cs(&_crit);
320     _filterSSRC = true;
321     _SSRC = ssrc;
322 }
323 
ClearStats()324 void TbExternalTransport::ClearStats()
325 {
326     webrtc::CriticalSectionScoped cs(&_statCrit);
327     _rtpCount = 0;
328     _dropCount = 0;
329     _rtcpCount = 0;
330     packet_counters_.clear();
331 }
332 
GetStats(int32_t & numRtpPackets,int32_t & numDroppedPackets,int32_t & numRtcpPackets,std::map<uint8_t,int> * packet_counters)333 void TbExternalTransport::GetStats(int32_t& numRtpPackets,
334                                    int32_t& numDroppedPackets,
335                                    int32_t& numRtcpPackets,
336                                    std::map<uint8_t, int>* packet_counters)
337 {
338     webrtc::CriticalSectionScoped cs(&_statCrit);
339     numRtpPackets = _rtpCount;
340     numDroppedPackets = _dropCount;
341     numRtcpPackets = _rtcpCount;
342     *packet_counters = packet_counters_;
343 }
344 
EnableSSRCCheck()345 void TbExternalTransport::EnableSSRCCheck()
346 {
347     webrtc::CriticalSectionScoped cs(&_statCrit);
348     _checkSSRC = true;
349 }
350 
ReceivedSSRC()351 unsigned int TbExternalTransport::ReceivedSSRC()
352 {
353     webrtc::CriticalSectionScoped cs(&_statCrit);
354     return _lastSSRC;
355 }
356 
EnableSequenceNumberCheck()357 void TbExternalTransport::EnableSequenceNumberCheck()
358 {
359     webrtc::CriticalSectionScoped cs(&_statCrit);
360     _checkSequenceNumber = true;
361 }
362 
GetFirstSequenceNumber()363 unsigned short TbExternalTransport::GetFirstSequenceNumber()
364 {
365     webrtc::CriticalSectionScoped cs(&_statCrit);
366     return _firstSequenceNumber;
367 }
368 
EmptyQueue() const369 bool TbExternalTransport::EmptyQueue() const {
370   webrtc::CriticalSectionScoped cs(&_crit);
371   return _rtpPackets.empty() && _rtcpPackets.empty();
372 }
373 
ViEExternalTransportRun(void * object)374 bool TbExternalTransport::ViEExternalTransportRun(void* object)
375 {
376     return static_cast<TbExternalTransport*>
377         (object)->ViEExternalTransportProcess();
378 }
ViEExternalTransportProcess()379 bool TbExternalTransport::ViEExternalTransportProcess()
380 {
381     unsigned int waitTime = KMaxWaitTimeMs;
382 
383     VideoPacket* packet = NULL;
384 
385     _crit.Enter();
386     while (!_rtpPackets.empty())
387     {
388         // Take first packet in queue
389         packet = _rtpPackets.front();
390         int64_t timeToReceive = 0;
391         if (packet)
392         {
393           timeToReceive = packet->receiveTime - NowMs();
394         }
395         else
396         {
397           // There should never be any empty packets in the list.
398           assert(false);
399         }
400         if (timeToReceive > 0)
401         {
402             // No packets to receive yet
403             if (timeToReceive < waitTime && timeToReceive > 0)
404             {
405                 waitTime = (unsigned int) timeToReceive;
406             }
407             break;
408         }
409         _rtpPackets.pop_front();
410         _crit.Leave();
411 
412         // Send to ViE
413         if (packet)
414         {
415             unsigned int ssrc = 0;
416             {
417                 webrtc::CriticalSectionScoped cs(&_statCrit);
418                 ssrc = ((packet->packetBuffer[8]) << 24);
419                 ssrc += (packet->packetBuffer[9] << 16);
420                 ssrc += (packet->packetBuffer[10] << 8);
421                 ssrc += packet->packetBuffer[11];
422                 if (_checkSSRC)
423                 {
424                     _lastSSRC = ((packet->packetBuffer[8]) << 24);
425                     _lastSSRC += (packet->packetBuffer[9] << 16);
426                     _lastSSRC += (packet->packetBuffer[10] << 8);
427                     _lastSSRC += packet->packetBuffer[11];
428                     _checkSSRC = false;
429                 }
430                 if (_checkSequenceNumber)
431                 {
432                     _firstSequenceNumber
433                         = (unsigned char) packet->packetBuffer[2] << 8;
434                     _firstSequenceNumber
435                         += (unsigned char) packet->packetBuffer[3];
436                     _checkSequenceNumber = false;
437                 }
438             }
439             // Signal received packet of frame
440             uint8_t* ptr = (uint8_t*)packet->packetBuffer;
441             uint32_t rtp_timestamp = ptr[4] << 24;
442             rtp_timestamp += ptr[5] << 16;
443             rtp_timestamp += ptr[6] << 8;
444             rtp_timestamp += ptr[7];
445             if (_receive_frame_callback != NULL &&
446                 _lastReceiveRTPTimestamp != rtp_timestamp) {
447               _receive_frame_callback->FrameReceived(rtp_timestamp);
448             }
449             _lastReceiveRTPTimestamp = rtp_timestamp;
450             int destination_channel = sender_channel_;
451             if (receive_channels_) {
452               SsrcChannelMap::iterator it = receive_channels_->find(ssrc);
453               if (it == receive_channels_->end()) {
454                 return false;
455               }
456               destination_channel = it->second;
457             }
458             _vieNetwork.ReceivedRTPPacket(destination_channel,
459                                           packet->packetBuffer,
460                                           packet->length,
461                                           webrtc::PacketTime());
462             delete packet;
463             packet = NULL;
464         }
465         _crit.Enter();
466     }
467     _crit.Leave();
468     _crit.Enter();
469     while (!_rtcpPackets.empty())
470     {
471         // Take first packet in queue
472         packet = _rtcpPackets.front();
473         int64_t timeToReceive = 0;
474         if (packet)
475         {
476           timeToReceive = packet->receiveTime - NowMs();
477         }
478         else
479         {
480             // There should never be any empty packets in the list.
481             assert(false);
482         }
483         if (timeToReceive > 0)
484         {
485             // No packets to receive yet
486             if (timeToReceive < waitTime && timeToReceive > 0)
487             {
488                 waitTime = (unsigned int) timeToReceive;
489             }
490             break;
491         }
492         _rtcpPackets.pop_front();
493         _crit.Leave();
494 
495         // Send to ViE
496         if (packet)
497         {
498             uint8_t pltype = static_cast<uint8_t>(packet->packetBuffer[1]);
499             if (pltype == kSenderReportPayloadType) {
500               // Sender report.
501               if (receive_channels_) {
502                 for (SsrcChannelMap::iterator it = receive_channels_->begin();
503                     it != receive_channels_->end(); ++it) {
504                   _vieNetwork.ReceivedRTCPPacket(it->second,
505                                                  packet->packetBuffer,
506                                                  packet->length);
507                 }
508               } else {
509                 _vieNetwork.ReceivedRTCPPacket(sender_channel_,
510                                                packet->packetBuffer,
511                                                packet->length);
512               }
513             } else if (pltype == kReceiverReportPayloadType) {
514               // Receiver report.
515               _vieNetwork.ReceivedRTCPPacket(sender_channel_,
516                                              packet->packetBuffer,
517                                              packet->length);
518             }
519             delete packet;
520             packet = NULL;
521         }
522         _crit.Enter();
523     }
524     _crit.Leave();
525     _event.Wait(waitTime + 1); // Add 1 ms to not call to early...
526     return true;
527 }
528 
NowMs()529 int64_t TbExternalTransport::NowMs()
530 {
531     return webrtc::TickTime::MillisecondTimestamp();
532 }
533 
UniformLoss(int loss_rate)534 bool TbExternalTransport::UniformLoss(int loss_rate) {
535   int dropThis = rand() % 100;
536   return (dropThis < loss_rate);
537 }
538 
GilbertElliotLoss(int loss_rate,int burst_length)539 bool TbExternalTransport::GilbertElliotLoss(int loss_rate, int burst_length) {
540   // Simulate bursty channel (Gilbert model)
541   // (1st order) Markov chain model with memory of the previous/last
542   // packet state (loss or received)
543 
544   // 0 = received state
545   // 1 = loss state
546 
547   // probTrans10: if previous packet is lost, prob. to -> received state
548   // probTrans11: if previous packet is lost, prob. to -> loss state
549 
550   // probTrans01: if previous packet is received, prob. to -> loss state
551   // probTrans00: if previous packet is received, prob. to -> received
552 
553   // Map the two channel parameters (average loss rate and burst length)
554   // to the transition probabilities:
555   double probTrans10 = 100 * (1.0 / burst_length);
556   double probTrans11 = (100.0 - probTrans10);
557   double probTrans01 = (probTrans10 * ( loss_rate / (100.0 - loss_rate)));
558 
559   // Note: Random loss (Bernoulli) model is a special case where:
560   // burstLength = 100.0 / (100.0 - _lossPct) (i.e., p10 + p01 = 100)
561 
562   if (previous_drop_) {
563     // Previous packet was not received.
564     return UniformLoss(probTrans11);
565   } else {
566     return UniformLoss(probTrans01);
567   }
568 }
569 
570 #define PI  3.14159265
GaussianRandom(int mean_ms,int standard_deviation_ms)571 int TbExternalTransport::GaussianRandom(int mean_ms,
572                                         int standard_deviation_ms) {
573   // Creating a Normal distribution variable from two independent uniform
574   // variables based on the Box-Muller transform.
575   double uniform1 = (rand() + 1.0) / (RAND_MAX + 1.0);
576   double uniform2 = (rand() + 1.0) / (RAND_MAX + 1.0);
577   return static_cast<int>(mean_ms + standard_deviation_ms *
578       sqrt(-2 * log(uniform1)) * cos(2 * PI * uniform2));
579 }
580