2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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.
11 #include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
13 #include <assert.h> // assert
14 #include <stdlib.h> // rand
15 #include <string.h> // memcpy
17 #include <algorithm> // min
19 #include "webrtc/common_types.h"
20 #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
21 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
22 #include "webrtc/system_wrappers/interface/logging.h"
23 #include "webrtc/system_wrappers/interface/trace_event.h"
27 using RTCPUtility::RTCPCnameInformation;
29 NACKStringBuilder::NACKStringBuilder() :
30 _stream(""), _count(0), _consecutive(false)
35 NACKStringBuilder::~NACKStringBuilder() {}
37 void NACKStringBuilder::PushNACK(uint16_t nack)
42 } else if (nack == _prevNack + 1)
49 _stream << "-" << _prevNack;
52 _stream << "," << nack;
58 std::string NACKStringBuilder::GetResult()
62 _stream << "-" << _prevNack;
68 RTCPSender::FeedbackState::FeedbackState()
69 : send_payload_type(0),
77 has_last_xr_rr(false) {}
79 RTCPSender::RTCPSender(const int32_t id,
82 ReceiveStatistics* receive_statistics) :
87 _criticalSectionTransport(CriticalSectionWrapper::CreateCriticalSection()),
90 _criticalSectionRTCPSender(CriticalSectionWrapper::CreateCriticalSection()),
98 _nextTimeToSendRTCP(0),
100 last_rtp_timestamp_(0),
101 last_frame_capture_time_ms_(-1),
105 receive_statistics_(receive_statistics),
106 internal_report_blocks_(),
107 external_report_blocks_(),
121 _sequenceNumberFIR(0),
138 xrSendReceiverReferenceTimeEnabled_(false),
139 _xrSendVoIPMetric(false),
142 memset(_CNAME, 0, sizeof(_CNAME));
143 memset(_lastSendReport, 0, sizeof(_lastSendReport));
144 memset(_lastRTCPTime, 0, sizeof(_lastRTCPTime));
147 RTCPSender::~RTCPSender() {
151 while (!internal_report_blocks_.empty()) {
152 delete internal_report_blocks_.begin()->second;
153 internal_report_blocks_.erase(internal_report_blocks_.begin());
155 while (!external_report_blocks_.empty()) {
156 std::map<uint32_t, RTCPReportBlock*>::iterator it =
157 external_report_blocks_.begin();
159 external_report_blocks_.erase(it);
161 while (!_csrcCNAMEs.empty()) {
162 std::map<uint32_t, RTCPCnameInformation*>::iterator it =
165 _csrcCNAMEs.erase(it);
167 delete _criticalSectionTransport;
168 delete _criticalSectionRTCPSender;
172 RTCPSender::RegisterSendTransport(Transport* outgoingTransport)
174 CriticalSectionScoped lock(_criticalSectionTransport);
175 _cbTransport = outgoingTransport;
180 RTCPSender::Status() const
182 CriticalSectionScoped lock(_criticalSectionRTCPSender);
187 RTCPSender::SetRTCPStatus(const RTCPMethod method)
189 CriticalSectionScoped lock(_criticalSectionRTCPSender);
190 if(method != kRtcpOff)
194 _nextTimeToSendRTCP = _clock->TimeInMilliseconds() +
195 (RTCP_INTERVAL_AUDIO_MS/2);
198 _nextTimeToSendRTCP = _clock->TimeInMilliseconds() +
199 (RTCP_INTERVAL_VIDEO_MS/2);
207 RTCPSender::Sending() const
209 CriticalSectionScoped lock(_criticalSectionRTCPSender);
214 RTCPSender::SetSendingStatus(const FeedbackState& feedback_state, bool sending)
216 bool sendRTCPBye = false;
218 CriticalSectionScoped lock(_criticalSectionRTCPSender);
220 if(_method != kRtcpOff)
222 if(sending == false && _sending == true)
232 return SendRTCP(feedback_state, kRtcpBye);
238 RTCPSender::REMB() const
240 CriticalSectionScoped lock(_criticalSectionRTCPSender);
245 RTCPSender::SetREMBStatus(const bool enable)
247 CriticalSectionScoped lock(_criticalSectionRTCPSender);
253 RTCPSender::SetREMBData(const uint32_t bitrate,
254 const uint8_t numberOfSSRC,
255 const uint32_t* SSRC)
257 CriticalSectionScoped lock(_criticalSectionRTCPSender);
258 _rembBitrate = bitrate;
260 if(_sizeRembSSRC < numberOfSSRC)
263 _rembSSRC = new uint32_t[numberOfSSRC];
264 _sizeRembSSRC = numberOfSSRC;
267 _lengthRembSSRC = numberOfSSRC;
268 for (int i = 0; i < numberOfSSRC; i++)
270 _rembSSRC[i] = SSRC[i];
273 // Send a REMB immediately if we have a new REMB. The frequency of REMBs is
274 // throttled by the caller.
275 _nextTimeToSendRTCP = _clock->TimeInMilliseconds();
280 RTCPSender::TMMBR() const
282 CriticalSectionScoped lock(_criticalSectionRTCPSender);
287 RTCPSender::SetTMMBRStatus(const bool enable)
289 CriticalSectionScoped lock(_criticalSectionRTCPSender);
295 RTCPSender::IJ() const
297 CriticalSectionScoped lock(_criticalSectionRTCPSender);
302 RTCPSender::SetIJStatus(const bool enable)
304 CriticalSectionScoped lock(_criticalSectionRTCPSender);
309 void RTCPSender::SetStartTimestamp(uint32_t start_timestamp) {
310 CriticalSectionScoped lock(_criticalSectionRTCPSender);
311 start_timestamp_ = start_timestamp;
314 void RTCPSender::SetLastRtpTime(uint32_t rtp_timestamp,
315 int64_t capture_time_ms) {
316 CriticalSectionScoped lock(_criticalSectionRTCPSender);
317 last_rtp_timestamp_ = rtp_timestamp;
318 if (capture_time_ms < 0) {
319 // We don't currently get a capture time from VoiceEngine.
320 last_frame_capture_time_ms_ = _clock->TimeInMilliseconds();
322 last_frame_capture_time_ms_ = capture_time_ms;
327 RTCPSender::SetSSRC( const uint32_t ssrc)
329 CriticalSectionScoped lock(_criticalSectionRTCPSender);
333 // not first SetSSRC, probably due to a collision
334 // schedule a new RTCP report
335 // make sure that we send a RTP packet
336 _nextTimeToSendRTCP = _clock->TimeInMilliseconds() + 100;
341 void RTCPSender::SetRemoteSSRC(uint32_t ssrc)
343 CriticalSectionScoped lock(_criticalSectionRTCPSender);
348 RTCPSender::SetCameraDelay(const int32_t delayMS)
350 CriticalSectionScoped lock(_criticalSectionRTCPSender);
351 if(delayMS > 1000 || delayMS < -1000)
353 LOG(LS_WARNING) << "Delay can't be larger than 1 second: "
357 _cameraDelayMS = delayMS;
361 int32_t RTCPSender::SetCNAME(const char cName[RTCP_CNAME_SIZE]) {
365 CriticalSectionScoped lock(_criticalSectionRTCPSender);
366 _CNAME[RTCP_CNAME_SIZE - 1] = 0;
367 strncpy(_CNAME, cName, RTCP_CNAME_SIZE - 1);
371 int32_t RTCPSender::AddMixedCNAME(const uint32_t SSRC,
372 const char cName[RTCP_CNAME_SIZE]) {
374 CriticalSectionScoped lock(_criticalSectionRTCPSender);
375 if (_csrcCNAMEs.size() >= kRtpCsrcSize) {
378 RTCPCnameInformation* ptr = new RTCPCnameInformation();
379 ptr->name[RTCP_CNAME_SIZE - 1] = 0;
380 strncpy(ptr->name, cName, RTCP_CNAME_SIZE - 1);
381 _csrcCNAMEs[SSRC] = ptr;
385 int32_t RTCPSender::RemoveMixedCNAME(const uint32_t SSRC) {
386 CriticalSectionScoped lock(_criticalSectionRTCPSender);
387 std::map<uint32_t, RTCPCnameInformation*>::iterator it =
388 _csrcCNAMEs.find(SSRC);
390 if (it == _csrcCNAMEs.end()) {
394 _csrcCNAMEs.erase(it);
399 RTCPSender::TimeToSendRTCPReport(const bool sendKeyframeBeforeRTP) const
402 For audio we use a fix 5 sec interval
404 For video we use 1 sec interval fo a BW smaller than 360 kbit/s,
405 technicaly we break the max 5% RTCP BW for video below 10 kbit/s but
406 that should be extremely rare
411 MAX RTCP BW is 5% if the session BW
412 A send report is approximately 65 bytes inc CNAME
413 A receiver report is approximately 28 bytes
415 The RECOMMENDED value for the reduced minimum in seconds is 360
416 divided by the session bandwidth in kilobits/second. This minimum
417 is smaller than 5 seconds for bandwidths greater than 72 kb/s.
419 If the participant has not yet sent an RTCP packet (the variable
420 initial is true), the constant Tmin is set to 2.5 seconds, else it
423 The interval between RTCP packets is varied randomly over the
424 range [0.5,1.5] times the calculated interval to avoid unintended
425 synchronization of all participants
428 If the participant is a sender (we_sent true), the constant C is
429 set to the average RTCP packet size (avg_rtcp_size) divided by 25%
430 of the RTCP bandwidth (rtcp_bw), and the constant n is set to the
434 If we_sent is not true, the constant C is set
435 to the average RTCP packet size divided by 75% of the RTCP
436 bandwidth. The constant n is set to the number of receivers
437 (members - senders). If the number of senders is greater than
438 25%, senders and receivers are treated together.
440 reconsideration NOT required for peer-to-peer
441 "timer reconsideration" is
442 employed. This algorithm implements a simple back-off mechanism
443 which causes users to hold back RTCP packet transmission if the
444 group sizes are increasing.
446 n = number of members
447 C = avg_size/(rtcpBW/4)
449 3. The deterministic calculated interval Td is set to max(Tmin, n*C).
451 4. The calculated interval T is set to a number uniformly distributed
452 between 0.5 and 1.5 times the deterministic calculated interval.
454 5. The resulting value of T is divided by e-3/2=1.21828 to compensate
455 for the fact that the timer reconsideration algorithm converges to
456 a value of the RTCP bandwidth below the intended average
459 int64_t now = _clock->TimeInMilliseconds();
461 CriticalSectionScoped lock(_criticalSectionRTCPSender);
463 if(_method == kRtcpOff)
468 if(!_audio && sendKeyframeBeforeRTP)
470 // for video key-frames we want to send the RTCP before the large key-frame
471 // if we have a 100 ms margin
472 now += RTCP_SEND_BEFORE_KEY_FRAME_MS;
475 if(now >= _nextTimeToSendRTCP)
479 } else if(now < 0x0000ffff && _nextTimeToSendRTCP > 0xffff0000) // 65 sec margin
488 RTCPSender::LastSendReport( uint32_t& lastRTCPTime)
490 CriticalSectionScoped lock(_criticalSectionRTCPSender);
492 lastRTCPTime = _lastRTCPTime[0];
493 return _lastSendReport[0];
497 RTCPSender::SendTimeOfSendReport(const uint32_t sendReport)
499 CriticalSectionScoped lock(_criticalSectionRTCPSender);
501 // This is only saved when we are the sender
502 if((_lastSendReport[0] == 0) || (sendReport == 0))
504 return 0; // will be ignored
507 for(int i = 0; i < RTCP_NUMBER_OF_SR; ++i)
509 if( _lastSendReport[i] == sendReport)
511 return _lastRTCPTime[i];
518 bool RTCPSender::SendTimeOfXrRrReport(uint32_t mid_ntp,
519 int64_t* time_ms) const {
520 CriticalSectionScoped lock(_criticalSectionRTCPSender);
522 if (last_xr_rr_.empty()) {
525 std::map<uint32_t, int64_t>::const_iterator it = last_xr_rr_.find(mid_ntp);
526 if (it == last_xr_rr_.end()) {
529 *time_ms = it->second;
533 void RTCPSender::GetPacketTypeCounter(
534 RtcpPacketTypeCounter* packet_counter) const {
535 CriticalSectionScoped lock(_criticalSectionRTCPSender);
536 *packet_counter = packet_type_counter_;
539 int32_t RTCPSender::AddExternalReportBlock(
541 const RTCPReportBlock* reportBlock) {
542 CriticalSectionScoped lock(_criticalSectionRTCPSender);
543 return AddReportBlock(SSRC, &external_report_blocks_, reportBlock);
546 int32_t RTCPSender::AddReportBlock(
548 std::map<uint32_t, RTCPReportBlock*>* report_blocks,
549 const RTCPReportBlock* reportBlock) {
552 if (report_blocks->size() >= RTCP_MAX_REPORT_BLOCKS) {
553 LOG(LS_WARNING) << "Too many report blocks.";
556 std::map<uint32_t, RTCPReportBlock*>::iterator it =
557 report_blocks->find(SSRC);
558 if (it != report_blocks->end()) {
560 report_blocks->erase(it);
562 RTCPReportBlock* copyReportBlock = new RTCPReportBlock();
563 memcpy(copyReportBlock, reportBlock, sizeof(RTCPReportBlock));
564 (*report_blocks)[SSRC] = copyReportBlock;
568 int32_t RTCPSender::RemoveExternalReportBlock(uint32_t SSRC) {
569 CriticalSectionScoped lock(_criticalSectionRTCPSender);
571 std::map<uint32_t, RTCPReportBlock*>::iterator it =
572 external_report_blocks_.find(SSRC);
574 if (it == external_report_blocks_.end()) {
578 external_report_blocks_.erase(it);
582 int32_t RTCPSender::BuildSR(const FeedbackState& feedback_state,
589 if(pos + 52 >= IP_PACKET_SIZE)
591 LOG(LS_WARNING) << "Failed to build Sender Report.";
596 uint32_t posNumberOfReportBlocks = pos;
597 rtcpbuffer[pos++]=(uint8_t)0x80;
600 rtcpbuffer[pos++]=(uint8_t)200;
602 for(int i = (RTCP_NUMBER_OF_SR-2); i >= 0; i--)
605 _lastSendReport[i+1] = _lastSendReport[i];
606 _lastRTCPTime[i+1] =_lastRTCPTime[i];
609 _lastRTCPTime[0] = Clock::NtpToMs(NTPsec, NTPfrac);
610 _lastSendReport[0] = (NTPsec << 16) + (NTPfrac >> 16);
612 // The timestamp of this RTCP packet should be estimated as the timestamp of
613 // the frame being captured at this moment. We are calculating that
614 // timestamp as the last frame's timestamp + the time since the last frame
616 RTPtime = start_timestamp_ + last_rtp_timestamp_ +
617 (_clock->TimeInMilliseconds() - last_frame_capture_time_ms_) *
618 (feedback_state.frequency_hz / 1000);
621 // Save for our length field
626 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
629 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, NTPsec);
631 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, NTPfrac);
633 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, RTPtime);
636 //sender's packet count
637 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos,
638 feedback_state.packets_sent);
641 //sender's octet count
642 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos,
643 feedback_state.media_bytes_sent);
646 uint8_t numberOfReportBlocks = 0;
647 int32_t retVal = WriteAllReportBlocksToBuffer(rtcpbuffer, pos,
648 numberOfReportBlocks,
656 rtcpbuffer[posNumberOfReportBlocks] += numberOfReportBlocks;
658 uint16_t len = uint16_t((pos/4) -1);
659 RtpUtility::AssignUWord16ToBuffer(rtcpbuffer + 2, len);
664 int32_t RTCPSender::BuildSDEC(uint8_t* rtcpbuffer, int& pos) {
665 size_t lengthCname = strlen(_CNAME);
666 assert(lengthCname < RTCP_CNAME_SIZE);
669 if(pos + 12 + lengthCname >= IP_PACKET_SIZE) {
670 LOG(LS_WARNING) << "Failed to build SDEC.";
673 // SDEC Source Description
675 // We always need to add SDES CNAME
676 rtcpbuffer[pos++] = static_cast<uint8_t>(0x80 + 1 + _csrcCNAMEs.size());
677 rtcpbuffer[pos++] = static_cast<uint8_t>(202);
679 // handle SDES length later on
680 uint32_t SDESLengthPos = pos;
685 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
689 rtcpbuffer[pos++] = static_cast<uint8_t>(1);
692 rtcpbuffer[pos++] = static_cast<uint8_t>(lengthCname);
694 uint16_t SDESLength = 10;
696 memcpy(&rtcpbuffer[pos], _CNAME, lengthCname);
698 SDESLength += (uint16_t)lengthCname;
700 uint16_t padding = 0;
701 // We must have a zero field even if we have an even multiple of 4 bytes
702 if ((pos % 4) == 0) {
706 while ((pos % 4) != 0) {
710 SDESLength += padding;
712 std::map<uint32_t, RTCPUtility::RTCPCnameInformation*>::iterator it =
715 for(; it != _csrcCNAMEs.end(); it++) {
716 RTCPCnameInformation* cname = it->second;
717 uint32_t SSRC = it->first;
720 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, SSRC);
724 rtcpbuffer[pos++] = static_cast<uint8_t>(1);
726 size_t length = strlen(cname->name);
727 assert(length < RTCP_CNAME_SIZE);
729 rtcpbuffer[pos++]= static_cast<uint8_t>(length);
732 memcpy(&rtcpbuffer[pos],cname->name, length);
735 SDESLength += length;
736 uint16_t padding = 0;
738 // We must have a zero field even if we have an even multiple of 4 bytes
743 while((pos % 4) != 0){
745 rtcpbuffer[pos++] = 0;
747 SDESLength += padding;
749 // in 32-bit words minus one and we don't count the header
750 uint16_t buffer_length = (SDESLength / 4) - 1;
751 RtpUtility::AssignUWord16ToBuffer(rtcpbuffer + SDESLengthPos, buffer_length);
756 RTCPSender::BuildRR(uint8_t* rtcpbuffer,
758 const uint32_t NTPsec,
759 const uint32_t NTPfrac)
762 if(pos + 32 >= IP_PACKET_SIZE)
766 uint32_t posNumberOfReportBlocks = pos;
768 rtcpbuffer[pos++]=(uint8_t)0x80;
769 rtcpbuffer[pos++]=(uint8_t)201;
771 // Save for our length field
776 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
779 uint8_t numberOfReportBlocks = 0;
780 int retVal = WriteAllReportBlocksToBuffer(rtcpbuffer, pos,
781 numberOfReportBlocks,
788 rtcpbuffer[posNumberOfReportBlocks] += numberOfReportBlocks;
790 uint16_t len = uint16_t((pos)/4 -1);
791 RtpUtility::AssignUWord16ToBuffer(rtcpbuffer + 2, len);
795 // From RFC 5450: Transmission Time Offsets in RTP Streams.
797 // 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
798 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
799 // hdr |V=2|P| RC | PT=IJ=195 | length |
800 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
801 // | inter-arrival jitter |
802 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
806 // | inter-arrival jitter |
807 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
809 // If present, this RTCP packet must be placed after a receiver report
810 // (inside a compound RTCP packet), and MUST have the same value for RC
811 // (reception report count) as the receiver report.
814 RTCPSender::BuildExtendedJitterReport(
817 const uint32_t jitterTransmissionTimeOffset)
819 if (external_report_blocks_.size() > 0)
821 // TODO(andresp): Remove external report blocks since they are not
823 LOG(LS_ERROR) << "Handling of external report blocks not implemented.";
828 if(pos + 8 >= IP_PACKET_SIZE)
832 // add picture loss indicator
834 rtcpbuffer[pos++]=(uint8_t)0x80 + RC;
835 rtcpbuffer[pos++]=(uint8_t)195;
837 // Used fixed length of 2
838 rtcpbuffer[pos++]=(uint8_t)0;
839 rtcpbuffer[pos++]=(uint8_t)(1);
841 // Add inter-arrival jitter
842 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos,
843 jitterTransmissionTimeOffset);
849 RTCPSender::BuildPLI(uint8_t* rtcpbuffer, int& pos)
852 if(pos + 12 >= IP_PACKET_SIZE)
856 // add picture loss indicator
858 rtcpbuffer[pos++]=(uint8_t)0x80 + FMT;
859 rtcpbuffer[pos++]=(uint8_t)206;
861 //Used fixed length of 2
862 rtcpbuffer[pos++]=(uint8_t)0;
863 rtcpbuffer[pos++]=(uint8_t)(2);
866 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
869 // Add the remote SSRC
870 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _remoteSSRC);
875 int32_t RTCPSender::BuildFIR(uint8_t* rtcpbuffer,
879 if(pos + 20 >= IP_PACKET_SIZE) {
883 _sequenceNumberFIR++; // do not increase if repetition
886 // add full intra request indicator
888 rtcpbuffer[pos++] = (uint8_t)0x80 + FMT;
889 rtcpbuffer[pos++] = (uint8_t)206;
892 rtcpbuffer[pos++] = (uint8_t)0;
893 rtcpbuffer[pos++] = (uint8_t)(4);
896 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
899 // RFC 5104 4.3.1.2. Semantics
900 // SSRC of media source
901 rtcpbuffer[pos++] = (uint8_t)0;
902 rtcpbuffer[pos++] = (uint8_t)0;
903 rtcpbuffer[pos++] = (uint8_t)0;
904 rtcpbuffer[pos++] = (uint8_t)0;
906 // Additional Feedback Control Information (FCI)
907 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _remoteSSRC);
910 rtcpbuffer[pos++] = (uint8_t)(_sequenceNumberFIR);
911 rtcpbuffer[pos++] = (uint8_t)0;
912 rtcpbuffer[pos++] = (uint8_t)0;
913 rtcpbuffer[pos++] = (uint8_t)0;
919 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
920 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
921 | First | Number | PictureID |
922 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
925 RTCPSender::BuildSLI(uint8_t* rtcpbuffer, int& pos, const uint8_t pictureID)
928 if(pos + 16 >= IP_PACKET_SIZE)
932 // add slice loss indicator
934 rtcpbuffer[pos++]=(uint8_t)0x80 + FMT;
935 rtcpbuffer[pos++]=(uint8_t)206;
937 //Used fixed length of 3
938 rtcpbuffer[pos++]=(uint8_t)0;
939 rtcpbuffer[pos++]=(uint8_t)(3);
942 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
945 // Add the remote SSRC
946 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _remoteSSRC);
949 // Add first, number & picture ID 6 bits
950 // first = 0, 13 - bits
951 // number = 0x1fff, 13 - bits only ones for now
952 uint32_t sliField = (0x1fff << 6)+ (0x3f & pictureID);
953 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, sliField);
960 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
961 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
962 | PB |0| Payload Type| Native RPSI bit string |
963 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
964 | defined per codec ... | Padding (0) |
965 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
968 * Note: not generic made for VP8
971 RTCPSender::BuildRPSI(uint8_t* rtcpbuffer,
973 const uint64_t pictureID,
974 const uint8_t payloadType)
977 if(pos + 24 >= IP_PACKET_SIZE)
981 // add Reference Picture Selection Indication
983 rtcpbuffer[pos++]=(uint8_t)0x80 + FMT;
984 rtcpbuffer[pos++]=(uint8_t)206;
987 uint32_t bitsRequired = 7;
988 uint8_t bytesRequired = 1;
989 while((pictureID>>bitsRequired) > 0)
996 if(bytesRequired > 6)
999 } else if(bytesRequired > 2)
1003 rtcpbuffer[pos++]=(uint8_t)0;
1004 rtcpbuffer[pos++]=size;
1007 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
1010 // Add the remote SSRC
1011 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _remoteSSRC);
1014 // calc padding length
1015 uint8_t paddingBytes = 4-((2+bytesRequired)%4);
1016 if(paddingBytes == 4)
1020 // add padding length in bits
1021 rtcpbuffer[pos] = paddingBytes*8; // padding can be 0, 8, 16 or 24
1025 rtcpbuffer[pos] = payloadType;
1029 for(int i = bytesRequired-1; i > 0; i--)
1031 rtcpbuffer[pos] = 0x80 | uint8_t(pictureID >> (i*7));
1034 // add last byte of picture ID
1035 rtcpbuffer[pos] = uint8_t(pictureID & 0x7f);
1039 for(int j = 0; j <paddingBytes; j++)
1041 rtcpbuffer[pos] = 0;
1048 RTCPSender::BuildREMB(uint8_t* rtcpbuffer, int& pos)
1051 if(pos + 20 + 4 * _lengthRembSSRC >= IP_PACKET_SIZE)
1055 // add application layer feedback
1057 rtcpbuffer[pos++]=(uint8_t)0x80 + FMT;
1058 rtcpbuffer[pos++]=(uint8_t)206;
1060 rtcpbuffer[pos++]=(uint8_t)0;
1061 rtcpbuffer[pos++]=_lengthRembSSRC + 4;
1064 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
1067 // Remote SSRC must be 0
1068 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, 0);
1071 rtcpbuffer[pos++]='R';
1072 rtcpbuffer[pos++]='E';
1073 rtcpbuffer[pos++]='M';
1074 rtcpbuffer[pos++]='B';
1076 rtcpbuffer[pos++] = _lengthRembSSRC;
1080 for(uint32_t i=0; i<64; i++)
1082 if(_rembBitrate <= ((uint32_t)262143 << i))
1088 const uint32_t brMantissa = (_rembBitrate >> brExp);
1089 rtcpbuffer[pos++]=(uint8_t)((brExp << 2) + ((brMantissa >> 16) & 0x03));
1090 rtcpbuffer[pos++]=(uint8_t)(brMantissa >> 8);
1091 rtcpbuffer[pos++]=(uint8_t)(brMantissa);
1093 for (int i = 0; i < _lengthRembSSRC; i++)
1095 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _rembSSRC[i]);
1102 RTCPSender::SetTargetBitrate(unsigned int target_bitrate)
1104 CriticalSectionScoped lock(_criticalSectionRTCPSender);
1105 _tmmbr_Send = target_bitrate / 1000;
1108 int32_t RTCPSender::BuildTMMBR(ModuleRtpRtcpImpl* rtp_rtcp_module,
1109 uint8_t* rtcpbuffer,
1111 if (rtp_rtcp_module == NULL)
1113 // Before sending the TMMBR check the received TMMBN, only an owner is allowed to raise the bitrate
1114 // If the sender is an owner of the TMMBN -> send TMMBR
1115 // If not an owner but the TMMBR would enter the TMMBN -> send TMMBR
1117 // get current bounding set from RTCP receiver
1118 bool tmmbrOwner = false;
1119 // store in candidateSet, allocates one extra slot
1120 TMMBRSet* candidateSet = _tmmbrHelp.CandidateSet();
1122 // holding _criticalSectionRTCPSender while calling RTCPreceiver which
1123 // will accuire _criticalSectionRTCPReceiver is a potental deadlock but
1124 // since RTCPreceiver is not doing the reverse we should be fine
1125 int32_t lengthOfBoundingSet =
1126 rtp_rtcp_module->BoundingSet(tmmbrOwner, candidateSet);
1128 if(lengthOfBoundingSet > 0)
1130 for (int32_t i = 0; i < lengthOfBoundingSet; i++)
1132 if( candidateSet->Tmmbr(i) == _tmmbr_Send &&
1133 candidateSet->PacketOH(i) == _packetOH_Send)
1135 // do not send the same tuple
1141 // use received bounding set as candidate set
1142 // add current tuple
1143 candidateSet->SetEntry(lengthOfBoundingSet,
1147 int numCandidates = lengthOfBoundingSet+ 1;
1149 // find bounding set
1150 TMMBRSet* boundingSet = NULL;
1151 int numBoundingSet = _tmmbrHelp.FindTMMBRBoundingSet(boundingSet);
1152 if(numBoundingSet > 0 || numBoundingSet <= numCandidates)
1154 tmmbrOwner = _tmmbrHelp.IsOwner(_SSRC, numBoundingSet);
1158 // did not enter bounding set, no meaning to send this request
1167 if(pos + 20 >= IP_PACKET_SIZE)
1171 // add TMMBR indicator
1173 rtcpbuffer[pos++]=(uint8_t)0x80 + FMT;
1174 rtcpbuffer[pos++]=(uint8_t)205;
1177 rtcpbuffer[pos++]=(uint8_t)0;
1178 rtcpbuffer[pos++]=(uint8_t)(4);
1181 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
1184 // RFC 5104 4.2.1.2. Semantics
1186 // SSRC of media source
1187 rtcpbuffer[pos++]=(uint8_t)0;
1188 rtcpbuffer[pos++]=(uint8_t)0;
1189 rtcpbuffer[pos++]=(uint8_t)0;
1190 rtcpbuffer[pos++]=(uint8_t)0;
1192 // Additional Feedback Control Information (FCI)
1193 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _remoteSSRC);
1196 uint32_t bitRate = _tmmbr_Send*1000;
1197 uint32_t mmbrExp = 0;
1198 for(uint32_t i=0;i<64;i++)
1200 if(bitRate <= ((uint32_t)131071 << i))
1206 uint32_t mmbrMantissa = (bitRate >> mmbrExp);
1208 rtcpbuffer[pos++]=(uint8_t)((mmbrExp << 2) + ((mmbrMantissa >> 15) & 0x03));
1209 rtcpbuffer[pos++]=(uint8_t)(mmbrMantissa >> 7);
1210 rtcpbuffer[pos++]=(uint8_t)((mmbrMantissa << 1) + ((_packetOH_Send >> 8)& 0x01));
1211 rtcpbuffer[pos++]=(uint8_t)(_packetOH_Send);
1217 RTCPSender::BuildTMMBN(uint8_t* rtcpbuffer, int& pos)
1219 TMMBRSet* boundingSet = _tmmbrHelp.BoundingSetToSend();
1220 if(boundingSet == NULL)
1225 if(pos + 12 + boundingSet->lengthOfSet()*8 >= IP_PACKET_SIZE)
1227 LOG(LS_WARNING) << "Failed to build TMMBN.";
1231 // add TMMBN indicator
1232 rtcpbuffer[pos++]=(uint8_t)0x80 + FMT;
1233 rtcpbuffer[pos++]=(uint8_t)205;
1236 int posLength = pos;
1241 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
1244 // RFC 5104 4.2.2.2. Semantics
1246 // SSRC of media source
1247 rtcpbuffer[pos++]=(uint8_t)0;
1248 rtcpbuffer[pos++]=(uint8_t)0;
1249 rtcpbuffer[pos++]=(uint8_t)0;
1250 rtcpbuffer[pos++]=(uint8_t)0;
1252 // Additional Feedback Control Information (FCI)
1253 int numBoundingSet = 0;
1254 for(uint32_t n=0; n< boundingSet->lengthOfSet(); n++)
1256 if (boundingSet->Tmmbr(n) > 0)
1258 uint32_t tmmbrSSRC = boundingSet->Ssrc(n);
1259 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, tmmbrSSRC);
1262 uint32_t bitRate = boundingSet->Tmmbr(n) * 1000;
1263 uint32_t mmbrExp = 0;
1264 for(int i=0; i<64; i++)
1266 if(bitRate <= ((uint32_t)131071 << i))
1272 uint32_t mmbrMantissa = (bitRate >> mmbrExp);
1273 uint32_t measuredOH = boundingSet->PacketOH(n);
1275 rtcpbuffer[pos++]=(uint8_t)((mmbrExp << 2) + ((mmbrMantissa >> 15) & 0x03));
1276 rtcpbuffer[pos++]=(uint8_t)(mmbrMantissa >> 7);
1277 rtcpbuffer[pos++]=(uint8_t)((mmbrMantissa << 1) + ((measuredOH >> 8)& 0x01));
1278 rtcpbuffer[pos++]=(uint8_t)(measuredOH);
1282 uint16_t length= (uint16_t)(2+2*numBoundingSet);
1283 rtcpbuffer[posLength++]=(uint8_t)(length>>8);
1284 rtcpbuffer[posLength]=(uint8_t)(length);
1289 RTCPSender::BuildAPP(uint8_t* rtcpbuffer, int& pos)
1292 if(_appData == NULL)
1294 LOG(LS_WARNING) << "Failed to build app specific.";
1297 if(pos + 12 + _appLength >= IP_PACKET_SIZE)
1299 LOG(LS_WARNING) << "Failed to build app specific.";
1302 rtcpbuffer[pos++]=(uint8_t)0x80 + _appSubType;
1305 rtcpbuffer[pos++]=(uint8_t)204;
1307 uint16_t length = (_appLength>>2) + 2; // include SSRC and name
1308 rtcpbuffer[pos++]=(uint8_t)(length>>8);
1309 rtcpbuffer[pos++]=(uint8_t)(length);
1312 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
1315 // Add our application name
1316 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _appName);
1320 memcpy(rtcpbuffer +pos, _appData,_appLength);
1326 RTCPSender::BuildNACK(uint8_t* rtcpbuffer,
1328 const int32_t nackSize,
1329 const uint16_t* nackList,
1330 std::string* nackString)
1333 if(pos + 16 >= IP_PACKET_SIZE)
1335 LOG(LS_WARNING) << "Failed to build NACK.";
1339 // int size, uint16_t* nackList
1342 rtcpbuffer[pos++]=(uint8_t)0x80 + FMT;
1343 rtcpbuffer[pos++]=(uint8_t)205;
1345 rtcpbuffer[pos++]=(uint8_t) 0;
1346 int nackSizePos = pos;
1347 rtcpbuffer[pos++]=(uint8_t)(3); //setting it to one kNACK signal as default
1350 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
1353 // Add the remote SSRC
1354 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _remoteSSRC);
1357 // Build NACK bitmasks and write them to the RTCP message.
1358 // The nack list should be sorted and not contain duplicates if one
1359 // wants to build the smallest rtcp nack packet.
1360 int numOfNackFields = 0;
1361 int maxNackFields = std::min<int>(kRtcpMaxNackFields,
1362 (IP_PACKET_SIZE - pos) / 4);
1364 while (i < nackSize && numOfNackFields < maxNackFields) {
1365 uint16_t nack = nackList[i++];
1366 uint16_t bitmask = 0;
1367 while (i < nackSize) {
1368 int shift = static_cast<uint16_t>(nackList[i] - nack) - 1;
1369 if (shift >= 0 && shift <= 15) {
1370 bitmask |= (1 << shift);
1376 // Write the sequence number and the bitmask to the packet.
1377 assert(pos + 4 < IP_PACKET_SIZE);
1378 RtpUtility::AssignUWord16ToBuffer(rtcpbuffer + pos, nack);
1380 RtpUtility::AssignUWord16ToBuffer(rtcpbuffer + pos, bitmask);
1384 rtcpbuffer[nackSizePos] = static_cast<uint8_t>(2 + numOfNackFields);
1386 if (i != nackSize) {
1387 LOG(LS_WARNING) << "Nack list too large for one packet.";
1391 NACKStringBuilder stringBuilder;
1392 for (int idx = 0; idx < i; ++idx) {
1393 stringBuilder.PushNACK(nackList[idx]);
1394 nack_stats_.ReportRequest(nackList[idx]);
1396 *nackString = stringBuilder.GetResult();
1397 packet_type_counter_.nack_requests = nack_stats_.requests();
1398 packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests();
1403 RTCPSender::BuildBYE(uint8_t* rtcpbuffer, int& pos)
1406 if(pos + 8 >= IP_PACKET_SIZE)
1413 rtcpbuffer[pos++]=(uint8_t)0x80 + 1 + _CSRCs; // number of SSRC+CSRCs
1414 rtcpbuffer[pos++]=(uint8_t)203;
1417 rtcpbuffer[pos++]=(uint8_t)0;
1418 rtcpbuffer[pos++]=(uint8_t)(1 + _CSRCs);
1421 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
1425 for(int i = 0; i < _CSRCs; i++)
1427 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _CSRC[i]);
1433 rtcpbuffer[pos++]=(uint8_t)0x80 + 1; // number of SSRC+CSRCs
1434 rtcpbuffer[pos++]=(uint8_t)203;
1437 rtcpbuffer[pos++]=(uint8_t)0;
1438 rtcpbuffer[pos++]=(uint8_t)1;
1441 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
1447 int32_t RTCPSender::BuildReceiverReferenceTime(uint8_t* buffer,
1450 uint32_t ntp_frac) {
1451 const int kRrTimeBlockLength = 20;
1452 if (pos + kRrTimeBlockLength >= IP_PACKET_SIZE) {
1456 if (last_xr_rr_.size() >= RTCP_NUMBER_OF_SR) {
1457 last_xr_rr_.erase(last_xr_rr_.begin());
1459 last_xr_rr_.insert(std::pair<uint32_t, int64_t>(
1460 RTCPUtility::MidNtp(ntp_sec, ntp_frac),
1461 Clock::NtpToMs(ntp_sec, ntp_frac)));
1464 buffer[pos++] = 0x80;
1465 buffer[pos++] = 207;
1466 buffer[pos++] = 0; // XR packet length.
1467 buffer[pos++] = 4; // XR packet length.
1469 // Add our own SSRC.
1470 RtpUtility::AssignUWord32ToBuffer(buffer + pos, _SSRC);
1474 // 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
1475 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1476 // | BT=4 | reserved | block length = 2 |
1477 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1478 // | NTP timestamp, most significant word |
1479 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1480 // | NTP timestamp, least significant word |
1481 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1483 // Add Receiver Reference Time Report block.
1484 buffer[pos++] = 4; // BT.
1485 buffer[pos++] = 0; // Reserved.
1486 buffer[pos++] = 0; // Block length.
1487 buffer[pos++] = 2; // Block length.
1490 RtpUtility::AssignUWord32ToBuffer(buffer + pos, ntp_sec);
1492 RtpUtility::AssignUWord32ToBuffer(buffer + pos, ntp_frac);
1498 int32_t RTCPSender::BuildDlrr(uint8_t* buffer,
1500 const RtcpReceiveTimeInfo& info) {
1501 const int kDlrrBlockLength = 24;
1502 if (pos + kDlrrBlockLength >= IP_PACKET_SIZE) {
1507 buffer[pos++] = 0x80;
1508 buffer[pos++] = 207;
1509 buffer[pos++] = 0; // XR packet length.
1510 buffer[pos++] = 5; // XR packet length.
1512 // Add our own SSRC.
1513 RtpUtility::AssignUWord32ToBuffer(buffer + pos, _SSRC);
1517 // 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
1518 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1519 // | BT=5 | reserved | block length |
1520 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
1521 // | SSRC_1 (SSRC of first receiver) | sub-
1522 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
1523 // | last RR (LRR) | 1
1524 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1525 // | delay since last RR (DLRR) |
1526 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
1527 // | SSRC_2 (SSRC of second receiver) | sub-
1528 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
1531 // Add DLRR sub block.
1532 buffer[pos++] = 5; // BT.
1533 buffer[pos++] = 0; // Reserved.
1534 buffer[pos++] = 0; // Block length.
1535 buffer[pos++] = 3; // Block length.
1538 RtpUtility::AssignUWord32ToBuffer(buffer + pos, info.sourceSSRC);
1540 RtpUtility::AssignUWord32ToBuffer(buffer + pos, info.lastRR);
1542 RtpUtility::AssignUWord32ToBuffer(buffer + pos, info.delaySinceLastRR);
1549 RTCPSender::BuildVoIPMetric(uint8_t* rtcpbuffer, int& pos)
1552 if(pos + 44 >= IP_PACKET_SIZE)
1558 rtcpbuffer[pos++]=(uint8_t)0x80;
1559 rtcpbuffer[pos++]=(uint8_t)207;
1561 uint32_t XRLengthPos = pos;
1563 // handle length later on
1568 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
1571 // Add a VoIP metrics block
1572 rtcpbuffer[pos++]=7;
1573 rtcpbuffer[pos++]=0;
1574 rtcpbuffer[pos++]=0;
1575 rtcpbuffer[pos++]=8;
1577 // Add the remote SSRC
1578 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _remoteSSRC);
1581 rtcpbuffer[pos++] = _xrVoIPMetric.lossRate;
1582 rtcpbuffer[pos++] = _xrVoIPMetric.discardRate;
1583 rtcpbuffer[pos++] = _xrVoIPMetric.burstDensity;
1584 rtcpbuffer[pos++] = _xrVoIPMetric.gapDensity;
1586 rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.burstDuration >> 8);
1587 rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.burstDuration);
1588 rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.gapDuration >> 8);
1589 rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.gapDuration);
1591 rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.roundTripDelay >> 8);
1592 rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.roundTripDelay);
1593 rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.endSystemDelay >> 8);
1594 rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.endSystemDelay);
1596 rtcpbuffer[pos++] = _xrVoIPMetric.signalLevel;
1597 rtcpbuffer[pos++] = _xrVoIPMetric.noiseLevel;
1598 rtcpbuffer[pos++] = _xrVoIPMetric.RERL;
1599 rtcpbuffer[pos++] = _xrVoIPMetric.Gmin;
1601 rtcpbuffer[pos++] = _xrVoIPMetric.Rfactor;
1602 rtcpbuffer[pos++] = _xrVoIPMetric.extRfactor;
1603 rtcpbuffer[pos++] = _xrVoIPMetric.MOSLQ;
1604 rtcpbuffer[pos++] = _xrVoIPMetric.MOSCQ;
1606 rtcpbuffer[pos++] = _xrVoIPMetric.RXconfig;
1607 rtcpbuffer[pos++] = 0; // reserved
1608 rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBnominal >> 8);
1609 rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBnominal);
1611 rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBmax >> 8);
1612 rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBmax);
1613 rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBabsMax >> 8);
1614 rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBabsMax);
1616 rtcpbuffer[XRLengthPos]=(uint8_t)(0);
1617 rtcpbuffer[XRLengthPos+1]=(uint8_t)(10);
1621 int32_t RTCPSender::SendRTCP(const FeedbackState& feedback_state,
1622 uint32_t packetTypeFlags,
1624 const uint16_t* nackList,
1626 uint64_t pictureID) {
1628 CriticalSectionScoped lock(_criticalSectionRTCPSender);
1629 if(_method == kRtcpOff)
1631 LOG(LS_WARNING) << "Can't send rtcp if it is disabled.";
1635 uint8_t rtcp_buffer[IP_PACKET_SIZE];
1636 int rtcp_length = PrepareRTCP(feedback_state,
1644 if (rtcp_length < 0) {
1647 // Sanity don't send empty packets.
1648 if (rtcp_length == 0)
1652 return SendToNetwork(rtcp_buffer, static_cast<uint16_t>(rtcp_length));
1655 int RTCPSender::PrepareRTCP(const FeedbackState& feedback_state,
1656 uint32_t packetTypeFlags,
1658 const uint16_t* nackList,
1661 uint8_t* rtcp_buffer,
1663 uint32_t rtcpPacketTypeFlags = packetTypeFlags;
1664 // Collect the received information.
1665 uint32_t NTPsec = 0;
1666 uint32_t NTPfrac = 0;
1667 uint32_t jitterTransmissionOffset = 0;
1670 CriticalSectionScoped lock(_criticalSectionRTCPSender);
1672 if(_TMMBR ) // Attach TMMBR to send and receive reports.
1674 rtcpPacketTypeFlags |= kRtcpTmmbr;
1678 rtcpPacketTypeFlags |= kRtcpApp;
1681 if(_REMB && _sendREMB)
1683 // Always attach REMB to SR if that is configured. Note that REMB is
1684 // only sent on one of the RTP modules in the REMB group.
1685 rtcpPacketTypeFlags |= kRtcpRemb;
1687 if(_xrSendVoIPMetric)
1689 rtcpPacketTypeFlags |= kRtcpXrVoipMetric;
1690 _xrSendVoIPMetric = false;
1692 if(_sendTMMBN) // Set when having received a TMMBR.
1694 rtcpPacketTypeFlags |= kRtcpTmmbn;
1697 if (rtcpPacketTypeFlags & kRtcpReport)
1699 if (xrSendReceiverReferenceTimeEnabled_ && !_sending)
1701 rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime;
1703 if (feedback_state.has_last_xr_rr)
1705 rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock;
1708 if(_method == kRtcpCompound)
1712 rtcpPacketTypeFlags |= kRtcpSr;
1715 rtcpPacketTypeFlags |= kRtcpRr;
1717 } else if(_method == kRtcpNonCompound)
1719 if(rtcpPacketTypeFlags & kRtcpReport)
1723 rtcpPacketTypeFlags |= kRtcpSr;
1726 rtcpPacketTypeFlags |= kRtcpRr;
1730 if( rtcpPacketTypeFlags & kRtcpRr ||
1731 rtcpPacketTypeFlags & kRtcpSr)
1733 // generate next time to send a RTCP report
1734 // seeded from RTP constructor
1735 int32_t random = rand() % 1000;
1736 int32_t timeToNext = RTCP_INTERVAL_AUDIO_MS;
1740 timeToNext = (RTCP_INTERVAL_AUDIO_MS/2) +
1741 (RTCP_INTERVAL_AUDIO_MS*random/1000);
1744 uint32_t minIntervalMs = RTCP_INTERVAL_AUDIO_MS;
1747 // Calculate bandwidth for video; 360 / send bandwidth in kbit/s.
1748 uint32_t send_bitrate_kbit = feedback_state.send_bitrate / 1000;
1749 if (send_bitrate_kbit != 0)
1750 minIntervalMs = 360000 / send_bitrate_kbit;
1752 if(minIntervalMs > RTCP_INTERVAL_VIDEO_MS)
1754 minIntervalMs = RTCP_INTERVAL_VIDEO_MS;
1756 timeToNext = (minIntervalMs/2) + (minIntervalMs*random/1000);
1758 _nextTimeToSendRTCP = _clock->TimeInMilliseconds() + timeToNext;
1761 // If the data does not fit in the packet we fill it as much as possible.
1762 int32_t buildVal = 0;
1764 // We need to send our NTP even if we haven't received any reports.
1765 _clock->CurrentNtp(NTPsec, NTPfrac);
1766 if (ShouldSendReportBlocks(rtcpPacketTypeFlags)) {
1767 StatisticianMap statisticians =
1768 receive_statistics_->GetActiveStatisticians();
1769 if (!statisticians.empty()) {
1770 StatisticianMap::const_iterator it;
1772 for (it = statisticians.begin(), i = 0; it != statisticians.end();
1774 RTCPReportBlock report_block;
1776 feedback_state, it->second, &report_block, &NTPsec, &NTPfrac))
1777 AddReportBlock(it->first, &internal_report_blocks_, &report_block);
1779 if (_IJ && !statisticians.empty()) {
1780 rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1785 if(rtcpPacketTypeFlags & kRtcpSr)
1787 buildVal = BuildSR(feedback_state, rtcp_buffer, position, NTPsec, NTPfrac);
1788 if (buildVal == -1) {
1790 } else if (buildVal == -2) {
1793 buildVal = BuildSDEC(rtcp_buffer, position);
1794 if (buildVal == -1) {
1796 } else if (buildVal == -2) {
1799 }else if(rtcpPacketTypeFlags & kRtcpRr)
1801 buildVal = BuildRR(rtcp_buffer, position, NTPsec, NTPfrac);
1802 if (buildVal == -1) {
1804 } else if (buildVal == -2) {
1810 buildVal = BuildSDEC(rtcp_buffer, position);
1811 if (buildVal == -1) {
1816 if(rtcpPacketTypeFlags & kRtcpTransmissionTimeOffset)
1818 // If present, this RTCP packet must be placed after a
1820 buildVal = BuildExtendedJitterReport(rtcp_buffer,
1822 jitterTransmissionOffset);
1823 if (buildVal == -1) {
1825 } else if (buildVal == -2) {
1829 if(rtcpPacketTypeFlags & kRtcpPli)
1831 buildVal = BuildPLI(rtcp_buffer, position);
1832 if (buildVal == -1) {
1834 } else if (buildVal == -2) {
1837 TRACE_EVENT_INSTANT0("webrtc_rtp", "RTCPSender::PLI");
1838 ++packet_type_counter_.pli_packets;
1839 TRACE_COUNTER_ID1("webrtc_rtp", "RTCP_PLICount", _SSRC,
1840 packet_type_counter_.pli_packets);
1842 if(rtcpPacketTypeFlags & kRtcpFir)
1844 buildVal = BuildFIR(rtcp_buffer, position, repeat);
1845 if (buildVal == -1) {
1847 } else if (buildVal == -2) {
1850 TRACE_EVENT_INSTANT0("webrtc_rtp", "RTCPSender::FIR");
1851 ++packet_type_counter_.fir_packets;
1852 TRACE_COUNTER_ID1("webrtc_rtp", "RTCP_FIRCount", _SSRC,
1853 packet_type_counter_.fir_packets);
1855 if(rtcpPacketTypeFlags & kRtcpSli)
1857 buildVal = BuildSLI(rtcp_buffer, position, (uint8_t)pictureID);
1858 if (buildVal == -1) {
1860 } else if (buildVal == -2) {
1864 if(rtcpPacketTypeFlags & kRtcpRpsi)
1866 const int8_t payloadType = feedback_state.send_payload_type;
1867 if (payloadType == -1) {
1870 buildVal = BuildRPSI(rtcp_buffer, position, pictureID,
1871 (uint8_t)payloadType);
1872 if (buildVal == -1) {
1874 } else if (buildVal == -2) {
1878 if(rtcpPacketTypeFlags & kRtcpRemb)
1880 buildVal = BuildREMB(rtcp_buffer, position);
1881 if (buildVal == -1) {
1883 } else if (buildVal == -2) {
1886 TRACE_EVENT_INSTANT0("webrtc_rtp", "RTCPSender::REMB");
1888 if(rtcpPacketTypeFlags & kRtcpBye)
1890 buildVal = BuildBYE(rtcp_buffer, position);
1891 if (buildVal == -1) {
1893 } else if (buildVal == -2) {
1897 if(rtcpPacketTypeFlags & kRtcpApp)
1899 buildVal = BuildAPP(rtcp_buffer, position);
1900 if (buildVal == -1) {
1902 } else if (buildVal == -2) {
1906 if(rtcpPacketTypeFlags & kRtcpTmmbr)
1908 buildVal = BuildTMMBR(feedback_state.module, rtcp_buffer, position);
1909 if (buildVal == -1) {
1911 } else if (buildVal == -2) {
1915 if(rtcpPacketTypeFlags & kRtcpTmmbn)
1917 buildVal = BuildTMMBN(rtcp_buffer, position);
1918 if (buildVal == -1) {
1920 } else if (buildVal == -2) {
1924 if(rtcpPacketTypeFlags & kRtcpNack)
1926 std::string nackString;
1927 buildVal = BuildNACK(rtcp_buffer, position, nackSize, nackList,
1929 if (buildVal == -1) {
1931 } else if (buildVal == -2) {
1934 TRACE_EVENT_INSTANT1("webrtc_rtp", "RTCPSender::NACK",
1935 "nacks", TRACE_STR_COPY(nackString.c_str()));
1936 ++packet_type_counter_.nack_packets;
1937 TRACE_COUNTER_ID1("webrtc_rtp", "RTCP_NACKCount", _SSRC,
1938 packet_type_counter_.nack_packets);
1940 if(rtcpPacketTypeFlags & kRtcpXrVoipMetric)
1942 buildVal = BuildVoIPMetric(rtcp_buffer, position);
1943 if (buildVal == -1) {
1945 } else if (buildVal == -2) {
1949 if (rtcpPacketTypeFlags & kRtcpXrReceiverReferenceTime)
1951 buildVal = BuildReceiverReferenceTime(rtcp_buffer,
1955 if (buildVal == -1) {
1957 } else if (buildVal == -2) {
1961 if (rtcpPacketTypeFlags & kRtcpXrDlrrReportBlock)
1963 buildVal = BuildDlrr(rtcp_buffer, position, feedback_state.last_xr_rr);
1964 if (buildVal == -1) {
1966 } else if (buildVal == -2) {
1973 bool RTCPSender::ShouldSendReportBlocks(uint32_t rtcp_packet_type) const {
1974 return Status() == kRtcpCompound ||
1975 (rtcp_packet_type & kRtcpReport) ||
1976 (rtcp_packet_type & kRtcpSr) ||
1977 (rtcp_packet_type & kRtcpRr);
1980 bool RTCPSender::PrepareReport(const FeedbackState& feedback_state,
1981 StreamStatistician* statistician,
1982 RTCPReportBlock* report_block,
1983 uint32_t* ntp_secs, uint32_t* ntp_frac) {
1984 // Do we have receive statistics to send?
1985 RtcpStatistics stats;
1986 if (!statistician->GetStatistics(&stats, true))
1988 report_block->fractionLost = stats.fraction_lost;
1989 report_block->cumulativeLost = stats.cumulative_lost;
1990 report_block->extendedHighSeqNum =
1991 stats.extended_max_sequence_number;
1992 report_block->jitter = stats.jitter;
1994 // get our NTP as late as possible to avoid a race
1995 _clock->CurrentNtp(*ntp_secs, *ntp_frac);
1997 // Delay since last received report
1998 uint32_t delaySinceLastReceivedSR = 0;
1999 if ((feedback_state.last_rr_ntp_secs != 0) ||
2000 (feedback_state.last_rr_ntp_frac != 0)) {
2001 // get the 16 lowest bits of seconds and the 16 higest bits of fractions
2002 uint32_t now=*ntp_secs&0x0000FFFF;
2004 now += (*ntp_frac&0xffff0000)>>16;
2006 uint32_t receiveTime = feedback_state.last_rr_ntp_secs&0x0000FFFF;
2008 receiveTime += (feedback_state.last_rr_ntp_frac&0xffff0000)>>16;
2010 delaySinceLastReceivedSR = now-receiveTime;
2012 report_block->delaySinceLastSR = delaySinceLastReceivedSR;
2013 report_block->lastSR = feedback_state.remote_sr;
2018 RTCPSender::SendToNetwork(const uint8_t* dataBuffer,
2019 const uint16_t length)
2021 CriticalSectionScoped lock(_criticalSectionTransport);
2024 if(_cbTransport->SendRTCPPacket(_id, dataBuffer, length) > 0)
2033 RTCPSender::SetCSRCStatus(const bool include)
2035 CriticalSectionScoped lock(_criticalSectionRTCPSender);
2036 _includeCSRCs = include;
2041 RTCPSender::SetCSRCs(const uint32_t arrOfCSRC[kRtpCsrcSize],
2042 const uint8_t arrLength)
2044 assert(arrLength <= kRtpCsrcSize);
2045 CriticalSectionScoped lock(_criticalSectionRTCPSender);
2047 for(int i = 0; i < arrLength;i++)
2049 _CSRC[i] = arrOfCSRC[i];
2056 RTCPSender::SetApplicationSpecificData(const uint8_t subType,
2057 const uint32_t name,
2058 const uint8_t* data,
2059 const uint16_t length)
2063 LOG(LS_ERROR) << "Failed to SetApplicationSpecificData.";
2066 CriticalSectionScoped lock(_criticalSectionRTCPSender);
2074 _appSubType = subType;
2076 _appData = new uint8_t[length];
2077 _appLength = length;
2078 memcpy(_appData, data, length);
2083 RTCPSender::SetRTCPVoIPMetrics(const RTCPVoIPMetric* VoIPMetric)
2085 CriticalSectionScoped lock(_criticalSectionRTCPSender);
2086 memcpy(&_xrVoIPMetric, VoIPMetric, sizeof(RTCPVoIPMetric));
2088 _xrSendVoIPMetric = true;
2092 void RTCPSender::SendRtcpXrReceiverReferenceTime(bool enable) {
2093 CriticalSectionScoped lock(_criticalSectionRTCPSender);
2094 xrSendReceiverReferenceTimeEnabled_ = enable;
2097 bool RTCPSender::RtcpXrReceiverReferenceTime() const {
2098 CriticalSectionScoped lock(_criticalSectionRTCPSender);
2099 return xrSendReceiverReferenceTimeEnabled_;
2102 // called under critsect _criticalSectionRTCPSender
2103 int32_t RTCPSender::WriteAllReportBlocksToBuffer(
2104 uint8_t* rtcpbuffer,
2106 uint8_t& numberOfReportBlocks,
2107 const uint32_t NTPsec,
2108 const uint32_t NTPfrac) {
2109 numberOfReportBlocks = external_report_blocks_.size();
2110 numberOfReportBlocks += internal_report_blocks_.size();
2111 if ((pos + numberOfReportBlocks * 24) >= IP_PACKET_SIZE) {
2112 LOG(LS_WARNING) << "Can't fit all report blocks.";
2115 pos = WriteReportBlocksToBuffer(rtcpbuffer, pos, internal_report_blocks_);
2116 while (!internal_report_blocks_.empty()) {
2117 delete internal_report_blocks_.begin()->second;
2118 internal_report_blocks_.erase(internal_report_blocks_.begin());
2120 pos = WriteReportBlocksToBuffer(rtcpbuffer, pos, external_report_blocks_);
2124 int32_t RTCPSender::WriteReportBlocksToBuffer(
2125 uint8_t* rtcpbuffer,
2127 const std::map<uint32_t, RTCPReportBlock*>& report_blocks) {
2128 std::map<uint32_t, RTCPReportBlock*>::const_iterator it =
2129 report_blocks.begin();
2130 for (; it != report_blocks.end(); it++) {
2131 uint32_t remoteSSRC = it->first;
2132 RTCPReportBlock* reportBlock = it->second;
2135 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + position, remoteSSRC);
2139 rtcpbuffer[position++] = reportBlock->fractionLost;
2142 RtpUtility::AssignUWord24ToBuffer(rtcpbuffer + position,
2143 reportBlock->cumulativeLost);
2146 // extended highest seq_no, contain the highest sequence number received
2147 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + position,
2148 reportBlock->extendedHighSeqNum);
2152 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + position,
2153 reportBlock->jitter);
2156 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + position,
2157 reportBlock->lastSR);
2160 RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + position,
2161 reportBlock->delaySinceLastSR);
2168 // no callbacks allowed inside this function
2170 RTCPSender::SetTMMBN(const TMMBRSet* boundingSet,
2171 const uint32_t maxBitrateKbit)
2173 CriticalSectionScoped lock(_criticalSectionRTCPSender);
2175 if (0 == _tmmbrHelp.SetTMMBRBoundingSetToSend(boundingSet, maxBitrateKbit))
2182 } // namespace webrtc