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 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 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 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 272 void TbExternalTransport::RegisterSendFrameCallback( 273 SendFrameCallback* callback) { 274 _send_frame_callback = callback; 275 } 276 277 void TbExternalTransport::RegisterReceiveFrameCallback( 278 ReceiveFrameCallback* callback) { 279 _receive_frame_callback = callback; 280 } 281 282 // Set to 0 to disable. 283 void TbExternalTransport::SetTemporalToggle(unsigned char layers) 284 { 285 _temporalLayers = layers; 286 } 287 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 310 void TbExternalTransport::SetNetworkParameters( 311 const NetworkParameters& network_parameters) 312 { 313 webrtc::CriticalSectionScoped cs(&_crit); 314 network_parameters_ = network_parameters; 315 } 316 317 void TbExternalTransport::SetSSRCFilter(uint32_t ssrc) 318 { 319 webrtc::CriticalSectionScoped cs(&_crit); 320 _filterSSRC = true; 321 _SSRC = ssrc; 322 } 323 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 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 345 void TbExternalTransport::EnableSSRCCheck() 346 { 347 webrtc::CriticalSectionScoped cs(&_statCrit); 348 _checkSSRC = true; 349 } 350 351 unsigned int TbExternalTransport::ReceivedSSRC() 352 { 353 webrtc::CriticalSectionScoped cs(&_statCrit); 354 return _lastSSRC; 355 } 356 357 void TbExternalTransport::EnableSequenceNumberCheck() 358 { 359 webrtc::CriticalSectionScoped cs(&_statCrit); 360 _checkSequenceNumber = true; 361 } 362 363 unsigned short TbExternalTransport::GetFirstSequenceNumber() 364 { 365 webrtc::CriticalSectionScoped cs(&_statCrit); 366 return _firstSequenceNumber; 367 } 368 369 bool TbExternalTransport::EmptyQueue() const { 370 webrtc::CriticalSectionScoped cs(&_crit); 371 return _rtpPackets.empty() && _rtcpPackets.empty(); 372 } 373 374 bool TbExternalTransport::ViEExternalTransportRun(void* object) 375 { 376 return static_cast<TbExternalTransport*> 377 (object)->ViEExternalTransportProcess(); 378 } 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 529 int64_t TbExternalTransport::NowMs() 530 { 531 return webrtc::TickTime::MillisecondTimestamp(); 532 } 533 534 bool TbExternalTransport::UniformLoss(int loss_rate) { 535 int dropThis = rand() % 100; 536 return (dropThis < loss_rate); 537 } 538 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 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