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