rtcp_sender.cc revision 7c3523c1a4c828ecb2773c685145fcfbd7c3cead
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 "rtcp_sender.h" 12 13#include <cassert> // assert 14#include <cstdlib> // rand 15#include <string.h> // memcpy 16 17#include "common_types.h" 18#include "modules/remote_bitrate_estimator/remote_rate_control.h" 19#include "modules/rtp_rtcp/source/rtp_rtcp_impl.h" 20#include "system_wrappers/interface/critical_section_wrapper.h" 21#include "system_wrappers/interface/trace.h" 22 23namespace webrtc { 24 25using RTCPUtility::RTCPCnameInformation; 26 27RTCPSender::RTCPSender(const WebRtc_Word32 id, 28 const bool audio, 29 RtpRtcpClock* clock, 30 ModuleRtpRtcpImpl* owner) : 31 _id(id), 32 _audio(audio), 33 _clock(*clock), 34 _method(kRtcpOff), 35 _rtpRtcp(*owner), 36 _criticalSectionTransport(CriticalSectionWrapper::CreateCriticalSection()), 37 _cbTransport(NULL), 38 39 _criticalSectionRTCPSender(CriticalSectionWrapper::CreateCriticalSection()), 40 _usingNack(false), 41 _sending(false), 42 _sendTMMBN(false), 43 _REMB(false), 44 _sendREMB(false), 45 _TMMBR(false), 46 _IJ(false), 47 _nextTimeToSendRTCP(0), 48 start_timestamp_(0), 49 last_rtp_timestamp_(0), 50 last_frame_capture_time_ms_(-1), 51 _SSRC(0), 52 _remoteSSRC(0), 53 _CNAME(), 54 _reportBlocks(), 55 _csrcCNAMEs(), 56 57 _cameraDelayMS(0), 58 59 _lastSendReport(), 60 _lastRTCPTime(), 61 62 _CSRCs(0), 63 _CSRC(), 64 _includeCSRCs(true), 65 66 _sequenceNumberFIR(0), 67 68 _lengthRembSSRC(0), 69 _sizeRembSSRC(0), 70 _rembSSRC(NULL), 71 _rembBitrate(0), 72 73 _tmmbrHelp(), 74 _tmmbr_Send(0), 75 _packetOH_Send(0), 76 77 _appSend(false), 78 _appSubType(0), 79 _appName(), 80 _appData(NULL), 81 _appLength(0), 82 _xrSendVoIPMetric(false), 83 _xrVoIPMetric() 84{ 85 memset(_CNAME, 0, sizeof(_CNAME)); 86 memset(_lastSendReport, 0, sizeof(_lastSendReport)); 87 memset(_lastRTCPTime, 0, sizeof(_lastRTCPTime)); 88 89 WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__); 90} 91 92RTCPSender::~RTCPSender() { 93 delete [] _rembSSRC; 94 delete [] _appData; 95 96 while (!_reportBlocks.empty()) { 97 std::map<WebRtc_UWord32, RTCPReportBlock*>::iterator it = 98 _reportBlocks.begin(); 99 delete it->second; 100 _reportBlocks.erase(it); 101 } 102 while (!_csrcCNAMEs.empty()) { 103 std::map<WebRtc_UWord32, RTCPCnameInformation*>::iterator it = 104 _csrcCNAMEs.begin(); 105 delete it->second; 106 _csrcCNAMEs.erase(it); 107 } 108 delete _criticalSectionTransport; 109 delete _criticalSectionRTCPSender; 110 111 WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, _id, "%s deleted", __FUNCTION__); 112} 113 114WebRtc_Word32 115RTCPSender::Init() 116{ 117 CriticalSectionScoped lock(_criticalSectionRTCPSender); 118 119 _method = kRtcpOff; 120 _cbTransport = NULL; 121 _usingNack = false; 122 _sending = false; 123 _sendTMMBN = false; 124 _TMMBR = false; 125 _IJ = false; 126 _REMB = false; 127 _sendREMB = false; 128 last_rtp_timestamp_ = 0; 129 last_frame_capture_time_ms_ = -1; 130 start_timestamp_ = -1; 131 _SSRC = 0; 132 _remoteSSRC = 0; 133 _cameraDelayMS = 0; 134 _sequenceNumberFIR = 0; 135 _tmmbr_Send = 0; 136 _packetOH_Send = 0; 137 //_remoteRateControl.Reset(); 138 _nextTimeToSendRTCP = 0; 139 _CSRCs = 0; 140 _appSend = false; 141 _appSubType = 0; 142 143 if(_appData) 144 { 145 delete [] _appData; 146 _appData = NULL; 147 } 148 _appLength = 0; 149 150 _xrSendVoIPMetric = false; 151 152 memset(&_xrVoIPMetric, 0, sizeof(_xrVoIPMetric)); 153 memset(_CNAME, 0, sizeof(_CNAME)); 154 memset(_lastSendReport, 0, sizeof(_lastSendReport)); 155 memset(_lastRTCPTime, 0, sizeof(_lastRTCPTime)); 156 return 0; 157} 158 159void 160RTCPSender::ChangeUniqueId(const WebRtc_Word32 id) 161{ 162 _id = id; 163} 164 165WebRtc_Word32 166RTCPSender::RegisterSendTransport(Transport* outgoingTransport) 167{ 168 CriticalSectionScoped lock(_criticalSectionTransport); 169 _cbTransport = outgoingTransport; 170 return 0; 171} 172 173RTCPMethod 174RTCPSender::Status() const 175{ 176 CriticalSectionScoped lock(_criticalSectionRTCPSender); 177 return _method; 178} 179 180WebRtc_Word32 181RTCPSender::SetRTCPStatus(const RTCPMethod method) 182{ 183 CriticalSectionScoped lock(_criticalSectionRTCPSender); 184 if(method != kRtcpOff) 185 { 186 if(_audio) 187 { 188 _nextTimeToSendRTCP = _clock.GetTimeInMS() + (RTCP_INTERVAL_AUDIO_MS/2); 189 } else 190 { 191 _nextTimeToSendRTCP = _clock.GetTimeInMS() + (RTCP_INTERVAL_VIDEO_MS/2); 192 } 193 } 194 _method = method; 195 return 0; 196} 197 198bool 199RTCPSender::Sending() const 200{ 201 CriticalSectionScoped lock(_criticalSectionRTCPSender); 202 return _sending; 203} 204 205WebRtc_Word32 206RTCPSender::SetSendingStatus(const bool sending) 207{ 208 bool sendRTCPBye = false; 209 { 210 CriticalSectionScoped lock(_criticalSectionRTCPSender); 211 212 if(_method != kRtcpOff) 213 { 214 if(sending == false && _sending == true) 215 { 216 // Trigger RTCP bye 217 sendRTCPBye = true; 218 } 219 } 220 _sending = sending; 221 } 222 if(sendRTCPBye) 223 { 224 return SendRTCP(kRtcpBye); 225 } 226 return 0; 227} 228 229bool 230RTCPSender::REMB() const 231{ 232 CriticalSectionScoped lock(_criticalSectionRTCPSender); 233 return _REMB; 234} 235 236WebRtc_Word32 237RTCPSender::SetREMBStatus(const bool enable) 238{ 239 CriticalSectionScoped lock(_criticalSectionRTCPSender); 240 _REMB = enable; 241 return 0; 242} 243 244WebRtc_Word32 245RTCPSender::SetREMBData(const WebRtc_UWord32 bitrate, 246 const WebRtc_UWord8 numberOfSSRC, 247 const WebRtc_UWord32* SSRC) 248{ 249 CriticalSectionScoped lock(_criticalSectionRTCPSender); 250 _rembBitrate = bitrate; 251 252 if(_sizeRembSSRC < numberOfSSRC) 253 { 254 delete [] _rembSSRC; 255 _rembSSRC = new WebRtc_UWord32[numberOfSSRC]; 256 _sizeRembSSRC = numberOfSSRC; 257 } 258 259 _lengthRembSSRC = numberOfSSRC; 260 for (int i = 0; i < numberOfSSRC; i++) 261 { 262 _rembSSRC[i] = SSRC[i]; 263 } 264 _sendREMB = true; 265 return 0; 266} 267 268bool 269RTCPSender::TMMBR() const 270{ 271 CriticalSectionScoped lock(_criticalSectionRTCPSender); 272 return _TMMBR; 273} 274 275WebRtc_Word32 276RTCPSender::SetTMMBRStatus(const bool enable) 277{ 278 CriticalSectionScoped lock(_criticalSectionRTCPSender); 279 _TMMBR = enable; 280 return 0; 281} 282 283bool 284RTCPSender::IJ() const 285{ 286 CriticalSectionScoped lock(_criticalSectionRTCPSender); 287 return _IJ; 288} 289 290WebRtc_Word32 291RTCPSender::SetIJStatus(const bool enable) 292{ 293 CriticalSectionScoped lock(_criticalSectionRTCPSender); 294 _IJ = enable; 295 return 0; 296} 297 298void RTCPSender::SetStartTimestamp(uint32_t start_timestamp) { 299 start_timestamp_ = start_timestamp; 300} 301 302void RTCPSender::SetLastRtpTime(uint32_t rtp_timestamp, 303 int64_t capture_time_ms) { 304 last_rtp_timestamp_ = rtp_timestamp; 305 if (capture_time_ms < 0) { 306 // We don't currently get a capture time from VoiceEngine. 307 last_frame_capture_time_ms_ = _clock.GetTimeInMS(); 308 } else { 309 last_frame_capture_time_ms_ = capture_time_ms; 310 } 311} 312 313void 314RTCPSender::SetSSRC( const WebRtc_UWord32 ssrc) 315{ 316 CriticalSectionScoped lock(_criticalSectionRTCPSender); 317 318 if(_SSRC != 0) 319 { 320 // not first SetSSRC, probably due to a collision 321 // schedule a new RTCP report 322 // make sure that we send a RTP packet 323 _nextTimeToSendRTCP = _clock.GetTimeInMS() + 100; 324 } 325 _SSRC = ssrc; 326} 327 328WebRtc_Word32 329RTCPSender::SetRemoteSSRC( const WebRtc_UWord32 ssrc) 330{ 331 CriticalSectionScoped lock(_criticalSectionRTCPSender); 332 _remoteSSRC = ssrc; 333 //_remoteRateControl.Reset(); 334 return 0; 335} 336 337WebRtc_Word32 338RTCPSender::SetCameraDelay(const WebRtc_Word32 delayMS) 339{ 340 CriticalSectionScoped lock(_criticalSectionRTCPSender); 341 if(delayMS > 1000 || delayMS < -1000) 342 { 343 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument, delay can't be larger than 1 sec", __FUNCTION__); 344 return -1; 345 } 346 _cameraDelayMS = delayMS; 347 return 0; 348} 349 350WebRtc_Word32 RTCPSender::CNAME(char cName[RTCP_CNAME_SIZE]) { 351 assert(cName); 352 CriticalSectionScoped lock(_criticalSectionRTCPSender); 353 cName[RTCP_CNAME_SIZE - 1] = 0; 354 strncpy(cName, _CNAME, RTCP_CNAME_SIZE - 1); 355 return 0; 356} 357 358WebRtc_Word32 RTCPSender::SetCNAME(const char cName[RTCP_CNAME_SIZE]) { 359 if (!cName) 360 return -1; 361 362 CriticalSectionScoped lock(_criticalSectionRTCPSender); 363 _CNAME[RTCP_CNAME_SIZE - 1] = 0; 364 strncpy(_CNAME, cName, RTCP_CNAME_SIZE - 1); 365 return 0; 366} 367 368WebRtc_Word32 RTCPSender::AddMixedCNAME(const WebRtc_UWord32 SSRC, 369 const char cName[RTCP_CNAME_SIZE]) { 370 assert(cName); 371 CriticalSectionScoped lock(_criticalSectionRTCPSender); 372 if (_csrcCNAMEs.size() >= kRtpCsrcSize) { 373 return -1; 374 } 375 RTCPCnameInformation* ptr = new RTCPCnameInformation(); 376 ptr->name[RTCP_CNAME_SIZE - 1] = 0; 377 strncpy(ptr->name, cName, RTCP_CNAME_SIZE - 1); 378 _csrcCNAMEs[SSRC] = ptr; 379 return 0; 380} 381 382WebRtc_Word32 RTCPSender::RemoveMixedCNAME(const WebRtc_UWord32 SSRC) { 383 CriticalSectionScoped lock(_criticalSectionRTCPSender); 384 std::map<WebRtc_UWord32, RTCPCnameInformation*>::iterator it = 385 _csrcCNAMEs.find(SSRC); 386 387 if (it == _csrcCNAMEs.end()) { 388 return -1; 389 } 390 delete it->second; 391 _csrcCNAMEs.erase(it); 392 return 0; 393} 394 395bool 396RTCPSender::TimeToSendRTCPReport(const bool sendKeyframeBeforeRTP) const 397{ 398/* 399 For audio we use a fix 5 sec interval 400 401 For video we use 1 sec interval fo a BW smaller than 360 kbit/s, 402 technicaly we break the max 5% RTCP BW for video below 10 kbit/s but that should be extreamly rare 403 404 405From RFC 3550 406 407 MAX RTCP BW is 5% if the session BW 408 A send report is approximately 65 bytes inc CNAME 409 A report report is approximately 28 bytes 410 411 The RECOMMENDED value for the reduced minimum in seconds is 360 412 divided by the session bandwidth in kilobits/second. This minimum 413 is smaller than 5 seconds for bandwidths greater than 72 kb/s. 414 415 If the participant has not yet sent an RTCP packet (the variable 416 initial is true), the constant Tmin is set to 2.5 seconds, else it 417 is set to 5 seconds. 418 419 The interval between RTCP packets is varied randomly over the 420 range [0.5,1.5] times the calculated interval to avoid unintended 421 synchronization of all participants 422 423 if we send 424 If the participant is a sender (we_sent true), the constant C is 425 set to the average RTCP packet size (avg_rtcp_size) divided by 25% 426 of the RTCP bandwidth (rtcp_bw), and the constant n is set to the 427 number of senders. 428 429 if we receive only 430 If we_sent is not true, the constant C is set 431 to the average RTCP packet size divided by 75% of the RTCP 432 bandwidth. The constant n is set to the number of receivers 433 (members - senders). If the number of senders is greater than 434 25%, senders and receivers are treated together. 435 436 reconsideration NOT required for peer-to-peer 437 "timer reconsideration" is 438 employed. This algorithm implements a simple back-off mechanism 439 which causes users to hold back RTCP packet transmission if the 440 group sizes are increasing. 441 442 n = number of members 443 C = avg_size/(rtcpBW/4) 444 445 3. The deterministic calculated interval Td is set to max(Tmin, n*C). 446 447 4. The calculated interval T is set to a number uniformly distributed 448 between 0.5 and 1.5 times the deterministic calculated interval. 449 450 5. The resulting value of T is divided by e-3/2=1.21828 to compensate 451 for the fact that the timer reconsideration algorithm converges to 452 a value of the RTCP bandwidth below the intended average 453*/ 454 455 WebRtc_Word64 now = _clock.GetTimeInMS(); 456 457 CriticalSectionScoped lock(_criticalSectionRTCPSender); 458 459 if(_method == kRtcpOff) 460 { 461 return false; 462 } 463 464 if(!_audio && sendKeyframeBeforeRTP) 465 { 466 // for video key-frames we want to send the RTCP before the large key-frame 467 // if we have a 100 ms margin 468 now += RTCP_SEND_BEFORE_KEY_FRAME_MS; 469 } 470 471 if(now > _nextTimeToSendRTCP) 472 { 473 return true; 474 475 } else if(now < 0x0000ffff && _nextTimeToSendRTCP > 0xffff0000) // 65 sec margin 476 { 477 // wrap 478 return true; 479 } 480 return false; 481} 482 483WebRtc_UWord32 484RTCPSender::LastSendReport( WebRtc_UWord32& lastRTCPTime) 485{ 486 CriticalSectionScoped lock(_criticalSectionRTCPSender); 487 488 lastRTCPTime = _lastRTCPTime[0]; 489 return _lastSendReport[0]; 490} 491 492WebRtc_UWord32 493RTCPSender::SendTimeOfSendReport(const WebRtc_UWord32 sendReport) 494{ 495 CriticalSectionScoped lock(_criticalSectionRTCPSender); 496 497 // This is only saved when we are the sender 498 if((_lastSendReport[0] == 0) || (sendReport == 0)) 499 { 500 return 0; // will be ignored 501 } else 502 { 503 for(int i = 0; i < RTCP_NUMBER_OF_SR; ++i) 504 { 505 if( _lastSendReport[i] == sendReport) 506 { 507 return _lastRTCPTime[i]; 508 } 509 } 510 } 511 return 0; 512} 513 514WebRtc_Word32 RTCPSender::AddReportBlock(const WebRtc_UWord32 SSRC, 515 const RTCPReportBlock* reportBlock) { 516 if (reportBlock == NULL) { 517 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, 518 "%s invalid argument", __FUNCTION__); 519 return -1; 520 } 521 CriticalSectionScoped lock(_criticalSectionRTCPSender); 522 523 if (_reportBlocks.size() >= RTCP_MAX_REPORT_BLOCKS) { 524 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, 525 "%s invalid argument", __FUNCTION__); 526 return -1; 527 } 528 RTCPReportBlock* copyReportBlock = new RTCPReportBlock(); 529 memcpy(copyReportBlock, reportBlock, sizeof(RTCPReportBlock)); 530 _reportBlocks[SSRC] = copyReportBlock; 531 return 0; 532} 533 534WebRtc_Word32 RTCPSender::RemoveReportBlock(const WebRtc_UWord32 SSRC) { 535 CriticalSectionScoped lock(_criticalSectionRTCPSender); 536 537 std::map<WebRtc_UWord32, RTCPReportBlock*>::iterator it = 538 _reportBlocks.find(SSRC); 539 540 if (it == _reportBlocks.end()) { 541 return -1; 542 } 543 delete it->second; 544 _reportBlocks.erase(it); 545 return 0; 546} 547 548WebRtc_Word32 549RTCPSender::BuildSR(WebRtc_UWord8* rtcpbuffer, 550 WebRtc_UWord32& pos, 551 const WebRtc_UWord32 NTPsec, 552 const WebRtc_UWord32 NTPfrac, 553 const RTCPReportBlock* received) 554{ 555 // sanity 556 if(pos + 52 >= IP_PACKET_SIZE) 557 { 558 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__); 559 return -2; 560 } 561 WebRtc_UWord32 RTPtime; 562 563 WebRtc_UWord32 posNumberOfReportBlocks = pos; 564 rtcpbuffer[pos++]=(WebRtc_UWord8)0x80; 565 566 // Sender report 567 rtcpbuffer[pos++]=(WebRtc_UWord8)200; 568 569 for(int i = (RTCP_NUMBER_OF_SR-2); i >= 0; i--) 570 { 571 // shift old 572 _lastSendReport[i+1] = _lastSendReport[i]; 573 _lastRTCPTime[i+1] =_lastRTCPTime[i]; 574 } 575 576 _lastRTCPTime[0] = ModuleRTPUtility::ConvertNTPTimeToMS(NTPsec, NTPfrac); 577 _lastSendReport[0] = (NTPsec << 16) + (NTPfrac >> 16); 578 579 WebRtc_UWord32 freqHz = 90000; // For video 580 if(_audio) { 581 freqHz = _rtpRtcp.CurrentSendFrequencyHz(); 582 } 583 // The timestamp of this RTCP packet should be estimated as the timestamp of 584 // the frame being captured at this moment. We are calculating that 585 // timestamp as the last frame's timestamp + the time since the last frame 586 // was captured. 587 RTPtime = start_timestamp_ + last_rtp_timestamp_ + (_clock.GetTimeInMS() - 588 last_frame_capture_time_ms_) * (freqHz / 1000); 589 590 // Add sender data 591 // Save for our length field 592 pos++; 593 pos++; 594 595 // Add our own SSRC 596 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 597 pos += 4; 598 // NTP 599 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, NTPsec); 600 pos += 4; 601 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, NTPfrac); 602 pos += 4; 603 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, RTPtime); 604 pos += 4; 605 606 //sender's packet count 607 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _rtpRtcp.PacketCountSent()); 608 pos += 4; 609 610 //sender's octet count 611 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _rtpRtcp.ByteCountSent()); 612 pos += 4; 613 614 WebRtc_UWord8 numberOfReportBlocks = 0; 615 WebRtc_Word32 retVal = AddReportBlocks(rtcpbuffer, pos, numberOfReportBlocks, received, NTPsec, NTPfrac); 616 if(retVal < 0) 617 { 618 // 619 return retVal ; 620 } 621 rtcpbuffer[posNumberOfReportBlocks] += numberOfReportBlocks; 622 623 WebRtc_UWord16 len = WebRtc_UWord16((pos/4) -1); 624 ModuleRTPUtility::AssignUWord16ToBuffer(rtcpbuffer+2, len); 625 return 0; 626} 627 628 629WebRtc_Word32 RTCPSender::BuildSDEC(WebRtc_UWord8* rtcpbuffer, 630 WebRtc_UWord32& pos) { 631 size_t lengthCname = strlen(_CNAME); 632 assert(lengthCname < RTCP_CNAME_SIZE); 633 634 // sanity 635 if(pos + 12 + lengthCname >= IP_PACKET_SIZE) { 636 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, 637 "%s invalid argument", __FUNCTION__); 638 return -2; 639 } 640 // SDEC Source Description 641 642 // We always need to add SDES CNAME 643 rtcpbuffer[pos++] = static_cast<WebRtc_UWord8>(0x80 + 1 + _csrcCNAMEs.size()); 644 rtcpbuffer[pos++] = static_cast<WebRtc_UWord8>(202); 645 646 // handle SDES length later on 647 WebRtc_UWord32 SDESLengthPos = pos; 648 pos++; 649 pos++; 650 651 // Add our own SSRC 652 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 653 pos += 4; 654 655 // CNAME = 1 656 rtcpbuffer[pos++] = static_cast<WebRtc_UWord8>(1); 657 658 // 659 rtcpbuffer[pos++] = static_cast<WebRtc_UWord8>(lengthCname); 660 661 WebRtc_UWord16 SDESLength = 10; 662 663 memcpy(&rtcpbuffer[pos], _CNAME, lengthCname); 664 pos += lengthCname; 665 SDESLength += (WebRtc_UWord16)lengthCname; 666 667 WebRtc_UWord16 padding = 0; 668 // We must have a zero field even if we have an even multiple of 4 bytes 669 if ((pos % 4) == 0) { 670 padding++; 671 rtcpbuffer[pos++]=0; 672 } 673 while ((pos % 4) != 0) { 674 padding++; 675 rtcpbuffer[pos++]=0; 676 } 677 SDESLength += padding; 678 679 std::map<WebRtc_UWord32, RTCPUtility::RTCPCnameInformation*>::iterator it = 680 _csrcCNAMEs.begin(); 681 682 for(; it != _csrcCNAMEs.end(); it++) { 683 RTCPCnameInformation* cname = it->second; 684 WebRtc_UWord32 SSRC = it->first; 685 686 // Add SSRC 687 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, SSRC); 688 pos += 4; 689 690 // CNAME = 1 691 rtcpbuffer[pos++] = static_cast<WebRtc_UWord8>(1); 692 693 size_t length = strlen(cname->name); 694 assert(length < RTCP_CNAME_SIZE); 695 696 rtcpbuffer[pos++]= static_cast<WebRtc_UWord8>(length); 697 SDESLength += 6; 698 699 memcpy(&rtcpbuffer[pos],cname->name, length); 700 701 pos += length; 702 SDESLength += length; 703 WebRtc_UWord16 padding = 0; 704 705 // We must have a zero field even if we have an even multiple of 4 bytes 706 if((pos % 4) == 0){ 707 padding++; 708 rtcpbuffer[pos++]=0; 709 } 710 while((pos % 4) != 0){ 711 padding++; 712 rtcpbuffer[pos++] = 0; 713 } 714 SDESLength += padding; 715 } 716 // in 32-bit words minus one and we don't count the header 717 WebRtc_UWord16 buffer_length = (SDESLength / 4) - 1; 718 ModuleRTPUtility::AssignUWord16ToBuffer(rtcpbuffer + SDESLengthPos, 719 buffer_length); 720 return 0; 721} 722 723WebRtc_Word32 724RTCPSender::BuildRR(WebRtc_UWord8* rtcpbuffer, 725 WebRtc_UWord32& pos, 726 const WebRtc_UWord32 NTPsec, 727 const WebRtc_UWord32 NTPfrac, 728 const RTCPReportBlock* received) 729{ 730 // sanity one block 731 if(pos + 32 >= IP_PACKET_SIZE) 732 { 733 return -2; 734 } 735 WebRtc_UWord32 posNumberOfReportBlocks = pos; 736 737 rtcpbuffer[pos++]=(WebRtc_UWord8)0x80; 738 rtcpbuffer[pos++]=(WebRtc_UWord8)201; 739 740 // Save for our length field 741 pos++; 742 pos++; 743 744 // Add our own SSRC 745 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 746 pos += 4; 747 748 WebRtc_UWord8 numberOfReportBlocks = 0; 749 WebRtc_Word32 retVal = AddReportBlocks(rtcpbuffer, pos, numberOfReportBlocks, received, NTPsec, NTPfrac); 750 if(retVal < 0) 751 { 752 return retVal; 753 } 754 rtcpbuffer[posNumberOfReportBlocks] += numberOfReportBlocks; 755 756 WebRtc_UWord16 len = WebRtc_UWord16((pos)/4 -1); 757 ModuleRTPUtility::AssignUWord16ToBuffer(rtcpbuffer+2, len); 758 return 0; 759} 760 761// From RFC 5450: Transmission Time Offsets in RTP Streams. 762// 0 1 2 3 763// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 764// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 765// hdr |V=2|P| RC | PT=IJ=195 | length | 766// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 767// | inter-arrival jitter | 768// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 769// . . 770// . . 771// . . 772// | inter-arrival jitter | 773// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 774// 775// If present, this RTCP packet must be placed after a receiver report 776// (inside a compound RTCP packet), and MUST have the same value for RC 777// (reception report count) as the receiver report. 778 779WebRtc_Word32 780RTCPSender::BuildExtendedJitterReport( 781 WebRtc_UWord8* rtcpbuffer, 782 WebRtc_UWord32& pos, 783 const WebRtc_UWord32 jitterTransmissionTimeOffset) 784{ 785 if (_reportBlocks.size() > 0) 786 { 787 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, "Not implemented."); 788 return 0; 789 } 790 791 // sanity 792 if(pos + 8 >= IP_PACKET_SIZE) 793 { 794 return -2; 795 } 796 // add picture loss indicator 797 WebRtc_UWord8 RC = 1; 798 rtcpbuffer[pos++]=(WebRtc_UWord8)0x80 + RC; 799 rtcpbuffer[pos++]=(WebRtc_UWord8)195; 800 801 // Used fixed length of 2 802 rtcpbuffer[pos++]=(WebRtc_UWord8)0; 803 rtcpbuffer[pos++]=(WebRtc_UWord8)(1); 804 805 // Add inter-arrival jitter 806 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, 807 jitterTransmissionTimeOffset); 808 pos += 4; 809 return 0; 810} 811 812WebRtc_Word32 813RTCPSender::BuildPLI(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos) 814{ 815 // sanity 816 if(pos + 12 >= IP_PACKET_SIZE) 817 { 818 return -2; 819 } 820 // add picture loss indicator 821 WebRtc_UWord8 FMT = 1; 822 rtcpbuffer[pos++]=(WebRtc_UWord8)0x80 + FMT; 823 rtcpbuffer[pos++]=(WebRtc_UWord8)206; 824 825 //Used fixed length of 2 826 rtcpbuffer[pos++]=(WebRtc_UWord8)0; 827 rtcpbuffer[pos++]=(WebRtc_UWord8)(2); 828 829 // Add our own SSRC 830 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 831 pos += 4; 832 833 // Add the remote SSRC 834 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _remoteSSRC); 835 pos += 4; 836 return 0; 837} 838 839WebRtc_Word32 RTCPSender::BuildFIR(WebRtc_UWord8* rtcpbuffer, 840 WebRtc_UWord32& pos, 841 bool repeat) { 842 // sanity 843 if(pos + 20 >= IP_PACKET_SIZE) { 844 return -2; 845 } 846 if (!repeat) { 847 _sequenceNumberFIR++; // do not increase if repetition 848 } 849 850 // add full intra request indicator 851 WebRtc_UWord8 FMT = 4; 852 rtcpbuffer[pos++] = (WebRtc_UWord8)0x80 + FMT; 853 rtcpbuffer[pos++] = (WebRtc_UWord8)206; 854 855 //Length of 4 856 rtcpbuffer[pos++] = (WebRtc_UWord8)0; 857 rtcpbuffer[pos++] = (WebRtc_UWord8)(4); 858 859 // Add our own SSRC 860 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC); 861 pos += 4; 862 863 // RFC 5104 4.3.1.2. Semantics 864 // SSRC of media source 865 rtcpbuffer[pos++] = (WebRtc_UWord8)0; 866 rtcpbuffer[pos++] = (WebRtc_UWord8)0; 867 rtcpbuffer[pos++] = (WebRtc_UWord8)0; 868 rtcpbuffer[pos++] = (WebRtc_UWord8)0; 869 870 // Additional Feedback Control Information (FCI) 871 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _remoteSSRC); 872 pos += 4; 873 874 rtcpbuffer[pos++] = (WebRtc_UWord8)(_sequenceNumberFIR); 875 rtcpbuffer[pos++] = (WebRtc_UWord8)0; 876 rtcpbuffer[pos++] = (WebRtc_UWord8)0; 877 rtcpbuffer[pos++] = (WebRtc_UWord8)0; 878 return 0; 879} 880 881/* 882 0 1 2 3 883 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 884 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 885 | First | Number | PictureID | 886 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 887*/ 888WebRtc_Word32 889RTCPSender::BuildSLI(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos, const WebRtc_UWord8 pictureID) 890{ 891 // sanity 892 if(pos + 16 >= IP_PACKET_SIZE) 893 { 894 return -2; 895 } 896 // add slice loss indicator 897 WebRtc_UWord8 FMT = 2; 898 rtcpbuffer[pos++]=(WebRtc_UWord8)0x80 + FMT; 899 rtcpbuffer[pos++]=(WebRtc_UWord8)206; 900 901 //Used fixed length of 3 902 rtcpbuffer[pos++]=(WebRtc_UWord8)0; 903 rtcpbuffer[pos++]=(WebRtc_UWord8)(3); 904 905 // Add our own SSRC 906 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 907 pos += 4; 908 909 // Add the remote SSRC 910 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _remoteSSRC); 911 pos += 4; 912 913 // Add first, number & picture ID 6 bits 914 // first = 0, 13 - bits 915 // number = 0x1fff, 13 - bits only ones for now 916 WebRtc_UWord32 sliField = (0x1fff << 6)+ (0x3f & pictureID); 917 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, sliField); 918 pos += 4; 919 return 0; 920} 921 922/* 923 0 1 2 3 924 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 925 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 926 | PB |0| Payload Type| Native RPSI bit string | 927 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 928 | defined per codec ... | Padding (0) | 929 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 930*/ 931/* 932* Note: not generic made for VP8 933*/ 934WebRtc_Word32 935RTCPSender::BuildRPSI(WebRtc_UWord8* rtcpbuffer, 936 WebRtc_UWord32& pos, 937 const WebRtc_UWord64 pictureID, 938 const WebRtc_UWord8 payloadType) 939{ 940 // sanity 941 if(pos + 24 >= IP_PACKET_SIZE) 942 { 943 return -2; 944 } 945 // add Reference Picture Selection Indication 946 WebRtc_UWord8 FMT = 3; 947 rtcpbuffer[pos++]=(WebRtc_UWord8)0x80 + FMT; 948 rtcpbuffer[pos++]=(WebRtc_UWord8)206; 949 950 // calc length 951 WebRtc_UWord32 bitsRequired = 7; 952 WebRtc_UWord8 bytesRequired = 1; 953 while((pictureID>>bitsRequired) > 0) 954 { 955 bitsRequired += 7; 956 bytesRequired++; 957 } 958 959 WebRtc_UWord8 size = 3; 960 if(bytesRequired > 6) 961 { 962 size = 5; 963 } else if(bytesRequired > 2) 964 { 965 size = 4; 966 } 967 rtcpbuffer[pos++]=(WebRtc_UWord8)0; 968 rtcpbuffer[pos++]=size; 969 970 // Add our own SSRC 971 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 972 pos += 4; 973 974 // Add the remote SSRC 975 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _remoteSSRC); 976 pos += 4; 977 978 // calc padding length 979 WebRtc_UWord8 paddingBytes = 4-((2+bytesRequired)%4); 980 if(paddingBytes == 4) 981 { 982 paddingBytes = 0; 983 } 984 // add padding length in bits 985 rtcpbuffer[pos] = paddingBytes*8; // padding can be 0, 8, 16 or 24 986 pos++; 987 988 // add payload type 989 rtcpbuffer[pos] = payloadType; 990 pos++; 991 992 // add picture ID 993 for(int i = bytesRequired-1; i > 0; i--) 994 { 995 rtcpbuffer[pos] = 0x80 | WebRtc_UWord8(pictureID >> (i*7)); 996 pos++; 997 } 998 // add last byte of picture ID 999 rtcpbuffer[pos] = WebRtc_UWord8(pictureID & 0x7f); 1000 pos++; 1001 1002 // add padding 1003 for(int j = 0; j <paddingBytes; j++) 1004 { 1005 rtcpbuffer[pos] = 0; 1006 pos++; 1007 } 1008 return 0; 1009} 1010 1011WebRtc_Word32 1012RTCPSender::BuildREMB(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos) 1013{ 1014 // sanity 1015 if(pos + 20 + 4 * _lengthRembSSRC >= IP_PACKET_SIZE) 1016 { 1017 return -2; 1018 } 1019 // add application layer feedback 1020 WebRtc_UWord8 FMT = 15; 1021 rtcpbuffer[pos++]=(WebRtc_UWord8)0x80 + FMT; 1022 rtcpbuffer[pos++]=(WebRtc_UWord8)206; 1023 1024 rtcpbuffer[pos++]=(WebRtc_UWord8)0; 1025 rtcpbuffer[pos++]=_lengthRembSSRC + 4; 1026 1027 // Add our own SSRC 1028 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 1029 pos += 4; 1030 1031 // Remote SSRC must be 0 1032 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, 0); 1033 pos += 4; 1034 1035 rtcpbuffer[pos++]='R'; 1036 rtcpbuffer[pos++]='E'; 1037 rtcpbuffer[pos++]='M'; 1038 rtcpbuffer[pos++]='B'; 1039 1040 rtcpbuffer[pos++] = _lengthRembSSRC; 1041 // 6 bit Exp 1042 // 18 bit mantissa 1043 WebRtc_UWord8 brExp = 0; 1044 for(WebRtc_UWord32 i=0; i<64; i++) 1045 { 1046 if(_rembBitrate <= ((WebRtc_UWord32)262143 << i)) 1047 { 1048 brExp = i; 1049 break; 1050 } 1051 } 1052 const WebRtc_UWord32 brMantissa = (_rembBitrate >> brExp); 1053 rtcpbuffer[pos++]=(WebRtc_UWord8)((brExp << 2) + ((brMantissa >> 16) & 0x03)); 1054 rtcpbuffer[pos++]=(WebRtc_UWord8)(brMantissa >> 8); 1055 rtcpbuffer[pos++]=(WebRtc_UWord8)(brMantissa); 1056 1057 for (int i = 0; i < _lengthRembSSRC; i++) 1058 { 1059 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _rembSSRC[i]); 1060 pos += 4; 1061 } 1062 return 0; 1063} 1064 1065void 1066RTCPSender::SetTargetBitrate(unsigned int target_bitrate) 1067{ 1068 CriticalSectionScoped lock(_criticalSectionRTCPSender); 1069 _tmmbr_Send = target_bitrate / 1000; 1070} 1071 1072WebRtc_Word32 1073RTCPSender::BuildTMMBR(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos) 1074{ 1075 // Before sending the TMMBR check the received TMMBN, only an owner is allowed to raise the bitrate 1076 // If the sender is an owner of the TMMBN -> send TMMBR 1077 // If not an owner but the TMMBR would enter the TMMBN -> send TMMBR 1078 1079 // get current bounding set from RTCP receiver 1080 bool tmmbrOwner = false; 1081 // store in candidateSet, allocates one extra slot 1082 TMMBRSet* candidateSet = _tmmbrHelp.CandidateSet(); 1083 1084 // holding _criticalSectionRTCPSender while calling RTCPreceiver which 1085 // will accuire _criticalSectionRTCPReceiver is a potental deadlock but 1086 // since RTCPreceiver is not doing the reverse we should be fine 1087 WebRtc_Word32 lengthOfBoundingSet 1088 = _rtpRtcp.BoundingSet(tmmbrOwner, candidateSet); 1089 1090 if(lengthOfBoundingSet > 0) 1091 { 1092 for (WebRtc_Word32 i = 0; i < lengthOfBoundingSet; i++) 1093 { 1094 if( candidateSet->Tmmbr(i) == _tmmbr_Send && 1095 candidateSet->PacketOH(i) == _packetOH_Send) 1096 { 1097 // do not send the same tuple 1098 return 0; 1099 } 1100 } 1101 if(!tmmbrOwner) 1102 { 1103 // use received bounding set as candidate set 1104 // add current tuple 1105 candidateSet->SetEntry(lengthOfBoundingSet, 1106 _tmmbr_Send, 1107 _packetOH_Send, 1108 _SSRC); 1109 int numCandidates = lengthOfBoundingSet+ 1; 1110 1111 // find bounding set 1112 TMMBRSet* boundingSet = NULL; 1113 int numBoundingSet = _tmmbrHelp.FindTMMBRBoundingSet(boundingSet); 1114 if(numBoundingSet > 0 || numBoundingSet <= numCandidates) 1115 { 1116 tmmbrOwner = _tmmbrHelp.IsOwner(_SSRC, numBoundingSet); 1117 } 1118 if(!tmmbrOwner) 1119 { 1120 // did not enter bounding set, no meaning to send this request 1121 return 0; 1122 } 1123 } 1124 } 1125 1126 if(_tmmbr_Send) 1127 { 1128 // sanity 1129 if(pos + 20 >= IP_PACKET_SIZE) 1130 { 1131 return -2; 1132 } 1133 // add TMMBR indicator 1134 WebRtc_UWord8 FMT = 3; 1135 rtcpbuffer[pos++]=(WebRtc_UWord8)0x80 + FMT; 1136 rtcpbuffer[pos++]=(WebRtc_UWord8)205; 1137 1138 //Length of 4 1139 rtcpbuffer[pos++]=(WebRtc_UWord8)0; 1140 rtcpbuffer[pos++]=(WebRtc_UWord8)(4); 1141 1142 // Add our own SSRC 1143 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 1144 pos += 4; 1145 1146 // RFC 5104 4.2.1.2. Semantics 1147 1148 // SSRC of media source 1149 rtcpbuffer[pos++]=(WebRtc_UWord8)0; 1150 rtcpbuffer[pos++]=(WebRtc_UWord8)0; 1151 rtcpbuffer[pos++]=(WebRtc_UWord8)0; 1152 rtcpbuffer[pos++]=(WebRtc_UWord8)0; 1153 1154 // Additional Feedback Control Information (FCI) 1155 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _remoteSSRC); 1156 pos += 4; 1157 1158 WebRtc_UWord32 bitRate = _tmmbr_Send*1000; 1159 WebRtc_UWord32 mmbrExp = 0; 1160 for(WebRtc_UWord32 i=0;i<64;i++) 1161 { 1162 if(bitRate <= ((WebRtc_UWord32)131071 << i)) 1163 { 1164 mmbrExp = i; 1165 break; 1166 } 1167 } 1168 WebRtc_UWord32 mmbrMantissa = (bitRate >> mmbrExp); 1169 1170 rtcpbuffer[pos++]=(WebRtc_UWord8)((mmbrExp << 2) + ((mmbrMantissa >> 15) & 0x03)); 1171 rtcpbuffer[pos++]=(WebRtc_UWord8)(mmbrMantissa >> 7); 1172 rtcpbuffer[pos++]=(WebRtc_UWord8)((mmbrMantissa << 1) + ((_packetOH_Send >> 8)& 0x01)); 1173 rtcpbuffer[pos++]=(WebRtc_UWord8)(_packetOH_Send); 1174 } 1175 return 0; 1176} 1177 1178WebRtc_Word32 1179RTCPSender::BuildTMMBN(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos) 1180{ 1181 TMMBRSet* boundingSet = _tmmbrHelp.BoundingSetToSend(); 1182 if(boundingSet == NULL) 1183 { 1184 return -1; 1185 } 1186 // sanity 1187 if(pos + 12 + boundingSet->lengthOfSet()*8 >= IP_PACKET_SIZE) 1188 { 1189 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__); 1190 return -2; 1191 } 1192 WebRtc_UWord8 FMT = 4; 1193 // add TMMBN indicator 1194 rtcpbuffer[pos++]=(WebRtc_UWord8)0x80 + FMT; 1195 rtcpbuffer[pos++]=(WebRtc_UWord8)205; 1196 1197 //Add length later 1198 int posLength = pos; 1199 pos++; 1200 pos++; 1201 1202 // Add our own SSRC 1203 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 1204 pos += 4; 1205 1206 // RFC 5104 4.2.2.2. Semantics 1207 1208 // SSRC of media source 1209 rtcpbuffer[pos++]=(WebRtc_UWord8)0; 1210 rtcpbuffer[pos++]=(WebRtc_UWord8)0; 1211 rtcpbuffer[pos++]=(WebRtc_UWord8)0; 1212 rtcpbuffer[pos++]=(WebRtc_UWord8)0; 1213 1214 // Additional Feedback Control Information (FCI) 1215 int numBoundingSet = 0; 1216 for(WebRtc_UWord32 n=0; n< boundingSet->lengthOfSet(); n++) 1217 { 1218 if (boundingSet->Tmmbr(n) > 0) 1219 { 1220 WebRtc_UWord32 tmmbrSSRC = boundingSet->Ssrc(n); 1221 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, tmmbrSSRC); 1222 pos += 4; 1223 1224 WebRtc_UWord32 bitRate = boundingSet->Tmmbr(n) * 1000; 1225 WebRtc_UWord32 mmbrExp = 0; 1226 for(int i=0; i<64; i++) 1227 { 1228 if(bitRate <= ((WebRtc_UWord32)131071 << i)) 1229 { 1230 mmbrExp = i; 1231 break; 1232 } 1233 } 1234 WebRtc_UWord32 mmbrMantissa = (bitRate >> mmbrExp); 1235 WebRtc_UWord32 measuredOH = boundingSet->PacketOH(n); 1236 1237 rtcpbuffer[pos++]=(WebRtc_UWord8)((mmbrExp << 2) + ((mmbrMantissa >> 15) & 0x03)); 1238 rtcpbuffer[pos++]=(WebRtc_UWord8)(mmbrMantissa >> 7); 1239 rtcpbuffer[pos++]=(WebRtc_UWord8)((mmbrMantissa << 1) + ((measuredOH >> 8)& 0x01)); 1240 rtcpbuffer[pos++]=(WebRtc_UWord8)(measuredOH); 1241 numBoundingSet++; 1242 } 1243 } 1244 WebRtc_UWord16 length= (WebRtc_UWord16)(2+2*numBoundingSet); 1245 rtcpbuffer[posLength++]=(WebRtc_UWord8)(length>>8); 1246 rtcpbuffer[posLength]=(WebRtc_UWord8)(length); 1247 return 0; 1248} 1249 1250WebRtc_Word32 1251RTCPSender::BuildAPP(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos) 1252{ 1253 // sanity 1254 if(_appData == NULL) 1255 { 1256 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, "%s invalid state", __FUNCTION__); 1257 return -1; 1258 } 1259 if(pos + 12 + _appLength >= IP_PACKET_SIZE) 1260 { 1261 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__); 1262 return -2; 1263 } 1264 rtcpbuffer[pos++]=(WebRtc_UWord8)0x80 + _appSubType; 1265 1266 // Add APP ID 1267 rtcpbuffer[pos++]=(WebRtc_UWord8)204; 1268 1269 WebRtc_UWord16 length = (_appLength>>2) + 2; // include SSRC and name 1270 rtcpbuffer[pos++]=(WebRtc_UWord8)(length>>8); 1271 rtcpbuffer[pos++]=(WebRtc_UWord8)(length); 1272 1273 // Add our own SSRC 1274 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 1275 pos += 4; 1276 1277 // Add our application name 1278 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _appName); 1279 pos += 4; 1280 1281 // Add the data 1282 memcpy(rtcpbuffer +pos, _appData,_appLength); 1283 pos += _appLength; 1284 return 0; 1285} 1286 1287WebRtc_Word32 1288RTCPSender::BuildNACK(WebRtc_UWord8* rtcpbuffer, 1289 WebRtc_UWord32& pos, 1290 const WebRtc_Word32 nackSize, 1291 const WebRtc_UWord16* nackList) 1292{ 1293 // sanity 1294 if(pos + 16 >= IP_PACKET_SIZE) 1295 { 1296 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__); 1297 return -2; 1298 } 1299 1300 // int size, WebRtc_UWord16* nackList 1301 // add nack list 1302 WebRtc_UWord8 FMT = 1; 1303 rtcpbuffer[pos++]=(WebRtc_UWord8)0x80 + FMT; 1304 rtcpbuffer[pos++]=(WebRtc_UWord8)205; 1305 1306 rtcpbuffer[pos++]=(WebRtc_UWord8) 0; 1307 int nackSizePos = pos; 1308 rtcpbuffer[pos++]=(WebRtc_UWord8)(3); //setting it to one kNACK signal as default 1309 1310 // Add our own SSRC 1311 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 1312 pos += 4; 1313 1314 // Add the remote SSRC 1315 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _remoteSSRC); 1316 pos += 4; 1317 1318 // add the list 1319 int i = 0; 1320 int numOfNackFields = 0; 1321 while(nackSize > i && numOfNackFields < 253) 1322 { 1323 WebRtc_UWord16 nack = nackList[i]; 1324 // put dow our sequence number 1325 ModuleRTPUtility::AssignUWord16ToBuffer(rtcpbuffer+pos, nack); 1326 pos += 2; 1327 1328 i++; 1329 numOfNackFields++; 1330 if(nackSize > i) 1331 { 1332 bool moreThan16Away = (WebRtc_UWord16(nack+16) < nackList[i])?true: false; 1333 if(!moreThan16Away) 1334 { 1335 // check for a wrap 1336 if(WebRtc_UWord16(nack+16) > 0xff00 && nackList[i] < 0x0fff) 1337 { 1338 // wrap 1339 moreThan16Away = true; 1340 } 1341 } 1342 if(moreThan16Away) 1343 { 1344 // next is more than 16 away 1345 rtcpbuffer[pos++]=(WebRtc_UWord8)0; 1346 rtcpbuffer[pos++]=(WebRtc_UWord8)0; 1347 } else 1348 { 1349 // build our bitmask 1350 WebRtc_UWord16 bitmask = 0; 1351 1352 bool within16Away = (WebRtc_UWord16(nack+16) > nackList[i])?true: false; 1353 if(within16Away) 1354 { 1355 // check for a wrap 1356 if(WebRtc_UWord16(nack+16) > 0xff00 && nackList[i] < 0x0fff) 1357 { 1358 // wrap 1359 within16Away = false; 1360 } 1361 } 1362 1363 while( nackSize > i && within16Away) 1364 { 1365 WebRtc_Word16 shift = (nackList[i]-nack)-1; 1366 assert(!(shift > 15) && !(shift < 0)); 1367 1368 bitmask += (1<< shift); 1369 i++; 1370 if(nackSize > i) 1371 { 1372 within16Away = (WebRtc_UWord16(nack+16) > nackList[i])?true: false; 1373 if(within16Away) 1374 { 1375 // check for a wrap 1376 if(WebRtc_UWord16(nack+16) > 0xff00 && nackList[i] < 0x0fff) 1377 { 1378 // wrap 1379 within16Away = false; 1380 } 1381 } 1382 } 1383 } 1384 ModuleRTPUtility::AssignUWord16ToBuffer(rtcpbuffer+pos, bitmask); 1385 pos += 2; 1386 } 1387 // sanity do we have room from one more 4 byte block? 1388 if(pos + 4 >= IP_PACKET_SIZE) 1389 { 1390 return -2; 1391 } 1392 } else 1393 { 1394 // no more in the list 1395 rtcpbuffer[pos++]=(WebRtc_UWord8)0; 1396 rtcpbuffer[pos++]=(WebRtc_UWord8)0; 1397 } 1398 } 1399 rtcpbuffer[nackSizePos]=(WebRtc_UWord8)(2+numOfNackFields); 1400 return 0; 1401} 1402 1403WebRtc_Word32 1404RTCPSender::BuildBYE(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos) 1405{ 1406 // sanity 1407 if(pos + 8 >= IP_PACKET_SIZE) 1408 { 1409 return -2; 1410 } 1411 if(_includeCSRCs) 1412 { 1413 // Add a bye packet 1414 rtcpbuffer[pos++]=(WebRtc_UWord8)0x80 + 1 + _CSRCs; // number of SSRC+CSRCs 1415 rtcpbuffer[pos++]=(WebRtc_UWord8)203; 1416 1417 // length 1418 rtcpbuffer[pos++]=(WebRtc_UWord8)0; 1419 rtcpbuffer[pos++]=(WebRtc_UWord8)(1 + _CSRCs); 1420 1421 // Add our own SSRC 1422 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 1423 pos += 4; 1424 1425 // add CSRCs 1426 for(int i = 0; i < _CSRCs; i++) 1427 { 1428 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _CSRC[i]); 1429 pos += 4; 1430 } 1431 } else 1432 { 1433 // Add a bye packet 1434 rtcpbuffer[pos++]=(WebRtc_UWord8)0x80 + 1; // number of SSRC+CSRCs 1435 rtcpbuffer[pos++]=(WebRtc_UWord8)203; 1436 1437 // length 1438 rtcpbuffer[pos++]=(WebRtc_UWord8)0; 1439 rtcpbuffer[pos++]=(WebRtc_UWord8)1; 1440 1441 // Add our own SSRC 1442 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 1443 pos += 4; 1444 } 1445 return 0; 1446} 1447 1448WebRtc_Word32 1449RTCPSender::BuildVoIPMetric(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos) 1450{ 1451 // sanity 1452 if(pos + 44 >= IP_PACKET_SIZE) 1453 { 1454 return -2; 1455 } 1456 1457 // Add XR header 1458 rtcpbuffer[pos++]=(WebRtc_UWord8)0x80; 1459 rtcpbuffer[pos++]=(WebRtc_UWord8)207; 1460 1461 WebRtc_UWord32 XRLengthPos = pos; 1462 1463 // handle length later on 1464 pos++; 1465 pos++; 1466 1467 // Add our own SSRC 1468 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 1469 pos += 4; 1470 1471 // Add a VoIP metrics block 1472 rtcpbuffer[pos++]=7; 1473 rtcpbuffer[pos++]=0; 1474 rtcpbuffer[pos++]=0; 1475 rtcpbuffer[pos++]=8; 1476 1477 // Add the remote SSRC 1478 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _remoteSSRC); 1479 pos += 4; 1480 1481 rtcpbuffer[pos++] = _xrVoIPMetric.lossRate; 1482 rtcpbuffer[pos++] = _xrVoIPMetric.discardRate; 1483 rtcpbuffer[pos++] = _xrVoIPMetric.burstDensity; 1484 rtcpbuffer[pos++] = _xrVoIPMetric.gapDensity; 1485 1486 rtcpbuffer[pos++] = (WebRtc_UWord8)(_xrVoIPMetric.burstDuration >> 8); 1487 rtcpbuffer[pos++] = (WebRtc_UWord8)(_xrVoIPMetric.burstDuration); 1488 rtcpbuffer[pos++] = (WebRtc_UWord8)(_xrVoIPMetric.gapDuration >> 8); 1489 rtcpbuffer[pos++] = (WebRtc_UWord8)(_xrVoIPMetric.gapDuration); 1490 1491 rtcpbuffer[pos++] = (WebRtc_UWord8)(_xrVoIPMetric.roundTripDelay >> 8); 1492 rtcpbuffer[pos++] = (WebRtc_UWord8)(_xrVoIPMetric.roundTripDelay); 1493 rtcpbuffer[pos++] = (WebRtc_UWord8)(_xrVoIPMetric.endSystemDelay >> 8); 1494 rtcpbuffer[pos++] = (WebRtc_UWord8)(_xrVoIPMetric.endSystemDelay); 1495 1496 rtcpbuffer[pos++] = _xrVoIPMetric.signalLevel; 1497 rtcpbuffer[pos++] = _xrVoIPMetric.noiseLevel; 1498 rtcpbuffer[pos++] = _xrVoIPMetric.RERL; 1499 rtcpbuffer[pos++] = _xrVoIPMetric.Gmin; 1500 1501 rtcpbuffer[pos++] = _xrVoIPMetric.Rfactor; 1502 rtcpbuffer[pos++] = _xrVoIPMetric.extRfactor; 1503 rtcpbuffer[pos++] = _xrVoIPMetric.MOSLQ; 1504 rtcpbuffer[pos++] = _xrVoIPMetric.MOSCQ; 1505 1506 rtcpbuffer[pos++] = _xrVoIPMetric.RXconfig; 1507 rtcpbuffer[pos++] = 0; // reserved 1508 rtcpbuffer[pos++] = (WebRtc_UWord8)(_xrVoIPMetric.JBnominal >> 8); 1509 rtcpbuffer[pos++] = (WebRtc_UWord8)(_xrVoIPMetric.JBnominal); 1510 1511 rtcpbuffer[pos++] = (WebRtc_UWord8)(_xrVoIPMetric.JBmax >> 8); 1512 rtcpbuffer[pos++] = (WebRtc_UWord8)(_xrVoIPMetric.JBmax); 1513 rtcpbuffer[pos++] = (WebRtc_UWord8)(_xrVoIPMetric.JBabsMax >> 8); 1514 rtcpbuffer[pos++] = (WebRtc_UWord8)(_xrVoIPMetric.JBabsMax); 1515 1516 rtcpbuffer[XRLengthPos]=(WebRtc_UWord8)(0); 1517 rtcpbuffer[XRLengthPos+1]=(WebRtc_UWord8)(10); 1518 return 0; 1519} 1520 1521WebRtc_Word32 1522RTCPSender::SendRTCP(const WebRtc_UWord32 packetTypeFlags, 1523 const WebRtc_Word32 nackSize, // NACK 1524 const WebRtc_UWord16* nackList, // NACK 1525 const bool repeat, // FIR 1526 const WebRtc_UWord64 pictureID) // SLI & RPSI 1527{ 1528 WebRtc_UWord32 rtcpPacketTypeFlags = packetTypeFlags; 1529 WebRtc_UWord32 pos = 0; 1530 WebRtc_UWord8 rtcpbuffer[IP_PACKET_SIZE]; 1531 1532 do // only to be able to use break :) (and the critsect must be inside its own scope) 1533 { 1534 // collect the received information 1535 RTCPReportBlock received; 1536 bool hasReceived = false; 1537 WebRtc_UWord32 NTPsec = 0; 1538 WebRtc_UWord32 NTPfrac = 0; 1539 bool rtcpCompound = false; 1540 WebRtc_UWord32 jitterTransmissionOffset = 0; 1541 1542 { 1543 CriticalSectionScoped lock(_criticalSectionRTCPSender); 1544 if(_method == kRtcpOff) 1545 { 1546 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, 1547 "%s invalid state", __FUNCTION__); 1548 return -1; 1549 } 1550 rtcpCompound = (_method == kRtcpCompound) ? true : false; 1551 } 1552 1553 if (rtcpCompound || 1554 rtcpPacketTypeFlags & kRtcpReport || 1555 rtcpPacketTypeFlags & kRtcpSr || 1556 rtcpPacketTypeFlags & kRtcpRr) 1557 { 1558 // get statistics from our RTPreceiver outside critsect 1559 if(_rtpRtcp.ReportBlockStatistics(&received.fractionLost, 1560 &received.cumulativeLost, 1561 &received.extendedHighSeqNum, 1562 &received.jitter, 1563 &jitterTransmissionOffset) == 0) 1564 { 1565 hasReceived = true; 1566 1567 WebRtc_UWord32 lastReceivedRRNTPsecs = 0; 1568 WebRtc_UWord32 lastReceivedRRNTPfrac = 0; 1569 WebRtc_UWord32 remoteSR = 0; 1570 1571 // ok even if we have not received a SR, we will send 0 in that case 1572 _rtpRtcp.LastReceivedNTP(lastReceivedRRNTPsecs, 1573 lastReceivedRRNTPfrac, 1574 remoteSR); 1575 1576 // get our NTP as late as possible to avoid a race 1577 _clock.CurrentNTP(NTPsec, NTPfrac); 1578 1579 // Delay since last received report 1580 WebRtc_UWord32 delaySinceLastReceivedSR = 0; 1581 if((lastReceivedRRNTPsecs !=0) || (lastReceivedRRNTPfrac !=0)) 1582 { 1583 // get the 16 lowest bits of seconds and the 16 higest bits of fractions 1584 WebRtc_UWord32 now=NTPsec&0x0000FFFF; 1585 now <<=16; 1586 now += (NTPfrac&0xffff0000)>>16; 1587 1588 WebRtc_UWord32 receiveTime = lastReceivedRRNTPsecs&0x0000FFFF; 1589 receiveTime <<=16; 1590 receiveTime += (lastReceivedRRNTPfrac&0xffff0000)>>16; 1591 1592 delaySinceLastReceivedSR = now-receiveTime; 1593 } 1594 received.delaySinceLastSR = delaySinceLastReceivedSR; 1595 received.lastSR = remoteSR; 1596 } else 1597 { 1598 // we need to send our NTP even if we dont have received any reports 1599 _clock.CurrentNTP(NTPsec, NTPfrac); 1600 } 1601 } 1602 1603 CriticalSectionScoped lock(_criticalSectionRTCPSender); 1604 1605 if(_TMMBR ) // attach TMMBR to send and receive reports 1606 { 1607 rtcpPacketTypeFlags |= kRtcpTmmbr; 1608 } 1609 if(_appSend) 1610 { 1611 rtcpPacketTypeFlags |= kRtcpApp; 1612 _appSend = false; 1613 } 1614 if(_REMB && _sendREMB) 1615 { 1616 // Always attach REMB to SR if that is configured. Note that REMB is 1617 // only sent on one of the RTP modules in the REMB group. 1618 rtcpPacketTypeFlags |= kRtcpRemb; 1619 } 1620 if(_xrSendVoIPMetric) 1621 { 1622 rtcpPacketTypeFlags |= kRtcpXrVoipMetric; 1623 _xrSendVoIPMetric = false; 1624 } 1625 if(_sendTMMBN) // set when having received a TMMBR 1626 { 1627 rtcpPacketTypeFlags |= kRtcpTmmbn; 1628 _sendTMMBN = false; 1629 } 1630 1631 if(_method == kRtcpCompound) 1632 { 1633 if(_sending) 1634 { 1635 rtcpPacketTypeFlags |= kRtcpSr; 1636 } else 1637 { 1638 rtcpPacketTypeFlags |= kRtcpRr; 1639 } 1640 if (_IJ && hasReceived) 1641 { 1642 rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset; 1643 } 1644 } else if(_method == kRtcpNonCompound) 1645 { 1646 if(rtcpPacketTypeFlags & kRtcpReport) 1647 { 1648 if(_sending) 1649 { 1650 rtcpPacketTypeFlags |= kRtcpSr; 1651 } else 1652 { 1653 rtcpPacketTypeFlags |= kRtcpRr; 1654 } 1655 } 1656 } 1657 if( rtcpPacketTypeFlags & kRtcpRr || 1658 rtcpPacketTypeFlags & kRtcpSr) 1659 { 1660 // generate next time to send a RTCP report 1661 // seeded from RTP constructor 1662 WebRtc_Word32 random = rand() % 1000; 1663 WebRtc_Word32 timeToNext = RTCP_INTERVAL_AUDIO_MS; 1664 1665 if(_audio) 1666 { 1667 timeToNext = (RTCP_INTERVAL_AUDIO_MS/2) + (RTCP_INTERVAL_AUDIO_MS*random/1000); 1668 }else 1669 { 1670 WebRtc_UWord32 minIntervalMs = RTCP_INTERVAL_AUDIO_MS; 1671 if(_sending) 1672 { 1673 // calc bw for video 360/sendBW in kbit/s 1674 WebRtc_UWord32 sendBitrateKbit = 0; 1675 WebRtc_UWord32 videoRate = 0; 1676 WebRtc_UWord32 fecRate = 0; 1677 WebRtc_UWord32 nackRate = 0; 1678 _rtpRtcp.BitrateSent(&sendBitrateKbit, 1679 &videoRate, 1680 &fecRate, 1681 &nackRate); 1682 sendBitrateKbit /= 1000; 1683 if(sendBitrateKbit != 0) 1684 { 1685 minIntervalMs = 360000/sendBitrateKbit; 1686 } 1687 } 1688 if(minIntervalMs > RTCP_INTERVAL_VIDEO_MS) 1689 { 1690 minIntervalMs = RTCP_INTERVAL_VIDEO_MS; 1691 } 1692 timeToNext = (minIntervalMs/2) + (minIntervalMs*random/1000); 1693 } 1694 _nextTimeToSendRTCP = _clock.GetTimeInMS() + timeToNext; 1695 } 1696 1697 // if the data does not fitt in the packet we fill it as much as possible 1698 WebRtc_Word32 buildVal = 0; 1699 1700 if(rtcpPacketTypeFlags & kRtcpSr) 1701 { 1702 if(hasReceived) 1703 { 1704 buildVal = BuildSR(rtcpbuffer, pos, NTPsec, NTPfrac, &received); 1705 } else 1706 { 1707 buildVal = BuildSR(rtcpbuffer, pos, NTPsec, NTPfrac); 1708 } 1709 if(buildVal == -1) 1710 { 1711 return -1; // error 1712 1713 }else if(buildVal == -2) 1714 { 1715 break; // out of buffer 1716 } 1717 buildVal = BuildSDEC(rtcpbuffer, pos); 1718 if(buildVal == -1) 1719 { 1720 return -1; // error 1721 1722 }else if(buildVal == -2) 1723 { 1724 break; // out of buffer 1725 } 1726 1727 }else if(rtcpPacketTypeFlags & kRtcpRr) 1728 { 1729 if(hasReceived) 1730 { 1731 buildVal = BuildRR(rtcpbuffer, pos, NTPsec, NTPfrac,&received); 1732 }else 1733 { 1734 buildVal = BuildRR(rtcpbuffer, pos, NTPsec, NTPfrac); 1735 } 1736 if(buildVal == -1) 1737 { 1738 return -1; // error 1739 1740 }else if(buildVal == -2) 1741 { 1742 break; // out of buffer 1743 } 1744 // only of set 1745 if(_CNAME[0] != 0) 1746 { 1747 buildVal = BuildSDEC(rtcpbuffer, pos); 1748 if(buildVal == -1) 1749 { 1750 return -1; // error 1751 } 1752 } 1753 } 1754 if(rtcpPacketTypeFlags & kRtcpTransmissionTimeOffset) 1755 { 1756 // If present, this RTCP packet must be placed after a 1757 // receiver report. 1758 buildVal = BuildExtendedJitterReport(rtcpbuffer, 1759 pos, 1760 jitterTransmissionOffset); 1761 if(buildVal == -1) 1762 { 1763 return -1; // error 1764 } 1765 else if(buildVal == -2) 1766 { 1767 break; // out of buffer 1768 } 1769 } 1770 if(rtcpPacketTypeFlags & kRtcpPli) 1771 { 1772 buildVal = BuildPLI(rtcpbuffer, pos); 1773 if(buildVal == -1) 1774 { 1775 return -1; // error 1776 1777 }else if(buildVal == -2) 1778 { 1779 break; // out of buffer 1780 } 1781 } 1782 if(rtcpPacketTypeFlags & kRtcpFir) 1783 { 1784 buildVal = BuildFIR(rtcpbuffer, pos, repeat); 1785 if(buildVal == -1) 1786 { 1787 return -1; // error 1788 1789 }else if(buildVal == -2) 1790 { 1791 break; // out of buffer 1792 } 1793 } 1794 if(rtcpPacketTypeFlags & kRtcpSli) 1795 { 1796 buildVal = BuildSLI(rtcpbuffer, pos, (WebRtc_UWord8)pictureID); 1797 if(buildVal == -1) 1798 { 1799 return -1; // error 1800 1801 }else if(buildVal == -2) 1802 { 1803 break; // out of buffer 1804 } 1805 } 1806 if(rtcpPacketTypeFlags & kRtcpRpsi) 1807 { 1808 const WebRtc_Word8 payloadType = _rtpRtcp.SendPayloadType(); 1809 if(payloadType == -1) 1810 { 1811 return -1; 1812 } 1813 buildVal = BuildRPSI(rtcpbuffer, pos, pictureID, (WebRtc_UWord8)payloadType); 1814 if(buildVal == -1) 1815 { 1816 return -1; // error 1817 1818 }else if(buildVal == -2) 1819 { 1820 break; // out of buffer 1821 } 1822 } 1823 if(rtcpPacketTypeFlags & kRtcpRemb) 1824 { 1825 buildVal = BuildREMB(rtcpbuffer, pos); 1826 if(buildVal == -1) 1827 { 1828 return -1; // error 1829 1830 }else if(buildVal == -2) 1831 { 1832 break; // out of buffer 1833 } 1834 } 1835 if(rtcpPacketTypeFlags & kRtcpBye) 1836 { 1837 buildVal = BuildBYE(rtcpbuffer, pos); 1838 if(buildVal == -1) 1839 { 1840 return -1; // error 1841 1842 }else if(buildVal == -2) 1843 { 1844 break; // out of buffer 1845 } 1846 } 1847 if(rtcpPacketTypeFlags & kRtcpApp) 1848 { 1849 buildVal = BuildAPP(rtcpbuffer, pos); 1850 if(buildVal == -1) 1851 { 1852 return -1; // error 1853 1854 }else if(buildVal == -2) 1855 { 1856 break; // out of buffer 1857 } 1858 } 1859 if(rtcpPacketTypeFlags & kRtcpTmmbr) 1860 { 1861 buildVal = BuildTMMBR(rtcpbuffer, pos); 1862 if(buildVal == -1) 1863 { 1864 return -1; // error 1865 1866 }else if(buildVal == -2) 1867 { 1868 break; // out of buffer 1869 } 1870 } 1871 if(rtcpPacketTypeFlags & kRtcpTmmbn) 1872 { 1873 buildVal = BuildTMMBN(rtcpbuffer, pos); 1874 if(buildVal == -1) 1875 { 1876 return -1; // error 1877 1878 }else if(buildVal == -2) 1879 { 1880 break; // out of buffer 1881 } 1882 } 1883 if(rtcpPacketTypeFlags & kRtcpNack) 1884 { 1885 buildVal = BuildNACK(rtcpbuffer, pos, nackSize, nackList); 1886 if(buildVal == -1) 1887 { 1888 return -1; // error 1889 1890 }else if(buildVal == -2) 1891 { 1892 break; // out of buffer 1893 } 1894 } 1895 if(rtcpPacketTypeFlags & kRtcpXrVoipMetric) 1896 { 1897 buildVal = BuildVoIPMetric(rtcpbuffer, pos); 1898 if(buildVal == -1) 1899 { 1900 return -1; // error 1901 1902 }else if(buildVal == -2) 1903 { 1904 break; // out of buffer 1905 } 1906 } 1907 }while (false); 1908 // Sanity don't send empty packets. 1909 if (pos == 0) 1910 { 1911 return -1; 1912 } 1913 return SendToNetwork(rtcpbuffer, (WebRtc_UWord16)pos); 1914} 1915 1916WebRtc_Word32 1917RTCPSender::SendToNetwork(const WebRtc_UWord8* dataBuffer, 1918 const WebRtc_UWord16 length) 1919{ 1920 CriticalSectionScoped lock(_criticalSectionTransport); 1921 if(_cbTransport) 1922 { 1923 if(_cbTransport->SendRTCPPacket(_id, dataBuffer, length) > 0) 1924 { 1925 return 0; 1926 } 1927 } 1928 return -1; 1929} 1930 1931WebRtc_Word32 1932RTCPSender::SetCSRCStatus(const bool include) 1933{ 1934 _includeCSRCs = include; 1935 return 0; 1936} 1937 1938WebRtc_Word32 1939RTCPSender::SetCSRCs(const WebRtc_UWord32 arrOfCSRC[kRtpCsrcSize], 1940 const WebRtc_UWord8 arrLength) 1941{ 1942 if(arrLength > kRtpCsrcSize) 1943 { 1944 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__); 1945 assert(false); 1946 return -1; 1947 } 1948 1949 CriticalSectionScoped lock(_criticalSectionRTCPSender); 1950 1951 for(int i = 0; i < arrLength;i++) 1952 { 1953 _CSRC[i] = arrOfCSRC[i]; 1954 } 1955 _CSRCs = arrLength; 1956 return 0; 1957} 1958 1959WebRtc_Word32 1960RTCPSender::SetApplicationSpecificData(const WebRtc_UWord8 subType, 1961 const WebRtc_UWord32 name, 1962 const WebRtc_UWord8* data, 1963 const WebRtc_UWord16 length) 1964{ 1965 if(length %4 != 0) 1966 { 1967 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__); 1968 return -1; 1969 } 1970 CriticalSectionScoped lock(_criticalSectionRTCPSender); 1971 1972 if(_appData) 1973 { 1974 delete [] _appData; 1975 } 1976 1977 _appSend = true; 1978 _appSubType = subType; 1979 _appName = name; 1980 _appData = new WebRtc_UWord8[length]; 1981 _appLength = length; 1982 memcpy(_appData, data, length); 1983 return 0; 1984} 1985 1986WebRtc_Word32 1987RTCPSender::SetRTCPVoIPMetrics(const RTCPVoIPMetric* VoIPMetric) 1988{ 1989 CriticalSectionScoped lock(_criticalSectionRTCPSender); 1990 memcpy(&_xrVoIPMetric, VoIPMetric, sizeof(RTCPVoIPMetric)); 1991 1992 _xrSendVoIPMetric = true; 1993 return 0; 1994} 1995 1996// called under critsect _criticalSectionRTCPSender 1997WebRtc_Word32 RTCPSender::AddReportBlocks(WebRtc_UWord8* rtcpbuffer, 1998 WebRtc_UWord32& pos, 1999 WebRtc_UWord8& numberOfReportBlocks, 2000 const RTCPReportBlock* received, 2001 const WebRtc_UWord32 NTPsec, 2002 const WebRtc_UWord32 NTPfrac) { 2003 // sanity one block 2004 if(pos + 24 >= IP_PACKET_SIZE) { 2005 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, 2006 "%s invalid argument", __FUNCTION__); 2007 return -1; 2008 } 2009 numberOfReportBlocks = _reportBlocks.size(); 2010 if (received) { 2011 // add our multiple RR to numberOfReportBlocks 2012 numberOfReportBlocks++; 2013 } 2014 if (received) { 2015 // answer to the one that sends to me 2016 _lastRTCPTime[0] = ModuleRTPUtility::ConvertNTPTimeToMS(NTPsec, NTPfrac); 2017 2018 // Remote SSRC 2019 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _remoteSSRC); 2020 pos += 4; 2021 2022 // fraction lost 2023 rtcpbuffer[pos++]=received->fractionLost; 2024 2025 // cumulative loss 2026 ModuleRTPUtility::AssignUWord24ToBuffer(rtcpbuffer+pos, 2027 received->cumulativeLost); 2028 pos += 3; 2029 // extended highest seq_no, contain the highest sequence number received 2030 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, 2031 received->extendedHighSeqNum); 2032 pos += 4; 2033 2034 //Jitter 2035 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, received->jitter); 2036 pos += 4; 2037 2038 // Last SR timestamp, our NTP time when we received the last report 2039 // This is the value that we read from the send report packet not when we 2040 // received it... 2041 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, received->lastSR); 2042 pos += 4; 2043 2044 // Delay since last received report,time since we received the report 2045 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, 2046 received->delaySinceLastSR); 2047 pos += 4; 2048 } 2049 if ((pos + _reportBlocks.size() * 24) >= IP_PACKET_SIZE) { 2050 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, 2051 "%s invalid argument", __FUNCTION__); 2052 return -1; 2053 } 2054 std::map<WebRtc_UWord32, RTCPReportBlock*>::iterator it = 2055 _reportBlocks.begin(); 2056 2057 for (; it != _reportBlocks.end(); it++) { 2058 // we can have multiple report block in a conference 2059 WebRtc_UWord32 remoteSSRC = it->first; 2060 RTCPReportBlock* reportBlock = it->second; 2061 if (reportBlock) { 2062 // Remote SSRC 2063 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, remoteSSRC); 2064 pos += 4; 2065 2066 // fraction lost 2067 rtcpbuffer[pos++] = reportBlock->fractionLost; 2068 2069 // cumulative loss 2070 ModuleRTPUtility::AssignUWord24ToBuffer(rtcpbuffer+pos, 2071 reportBlock->cumulativeLost); 2072 pos += 3; 2073 2074 // extended highest seq_no, contain the highest sequence number received 2075 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, 2076 reportBlock->extendedHighSeqNum); 2077 pos += 4; 2078 2079 //Jitter 2080 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, 2081 reportBlock->jitter); 2082 pos += 4; 2083 2084 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, 2085 reportBlock->lastSR); 2086 pos += 4; 2087 2088 ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, 2089 reportBlock->delaySinceLastSR); 2090 pos += 4; 2091 } 2092 } 2093 return pos; 2094} 2095 2096// no callbacks allowed inside this function 2097WebRtc_Word32 2098RTCPSender::SetTMMBN(const TMMBRSet* boundingSet, 2099 const WebRtc_UWord32 maxBitrateKbit) 2100{ 2101 CriticalSectionScoped lock(_criticalSectionRTCPSender); 2102 2103 if (0 == _tmmbrHelp.SetTMMBRBoundingSetToSend(boundingSet, maxBitrateKbit)) 2104 { 2105 _sendTMMBN = true; 2106 return 0; 2107 } 2108 return -1; 2109} 2110} // namespace webrtc 2111