From 61be2a401635eed1d13c169dc104b9ff4a2f477b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Spr=C3=A5ng?= Date: Mon, 27 Apr 2015 13:32:52 +0200 Subject: [PATCH] Clean up RTCPSender. Reformat to current code style, remove non-const references, use scoped_ptr, remove empty comments and dead code, etc.. BUG= R=stefan@webrtc.org Review URL: https://webrtc-codereview.appspot.com/49019004 Cr-Commit-Position: refs/heads/master@{#9086} --- webrtc/modules/rtp_rtcp/source/rtcp_sender.cc | 2119 ++++++++--------- webrtc/modules/rtp_rtcp/source/rtcp_sender.h | 392 ++- .../modules/rtp_rtcp/source/rtp_rtcp_impl.cc | 6 - .../modules/rtp_rtcp/source/rtp_rtcp_impl.h | 3 - 4 files changed, 1175 insertions(+), 1345 deletions(-) diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc index 82b12035ba..b8cdbe801e 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc @@ -15,7 +15,9 @@ #include // memcpy #include // min +#include // max +#include "webrtc/base/checks.h" #include "webrtc/common_types.h" #include "webrtc/modules/rtp_rtcp/source/byte_io.h" #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h" @@ -27,43 +29,35 @@ namespace webrtc { using RTCPUtility::RTCPCnameInformation; -NACKStringBuilder::NACKStringBuilder() : - _stream(""), _count(0), _consecutive(false) -{ - // Empty. +NACKStringBuilder::NACKStringBuilder() + : _stream(""), _count(0), _prevNack(0), _consecutive(false) { } NACKStringBuilder::~NACKStringBuilder() {} void NACKStringBuilder::PushNACK(uint16_t nack) { - if (_count == 0) - { - _stream << nack; - } else if (nack == _prevNack + 1) - { - _consecutive = true; - } else - { - if (_consecutive) - { - _stream << "-" << _prevNack; - _consecutive = false; - } - _stream << "," << nack; + if (_count == 0) { + _stream << nack; + } else if (nack == _prevNack + 1) { + _consecutive = true; + } else { + if (_consecutive) { + _stream << "-" << _prevNack; + _consecutive = false; } - _count++; - _prevNack = nack; + _stream << "," << nack; + } + _count++; + _prevNack = nack; } -std::string NACKStringBuilder::GetResult() -{ - if (_consecutive) - { - _stream << "-" << _prevNack; - _consecutive = false; - } - return _stream.str(); +std::string NACKStringBuilder::GetResult() { + if (_consecutive) { + _stream << "-" << _prevNack; + _consecutive = false; + } + return _stream.str(); } RTCPSender::FeedbackState::FeedbackState() @@ -75,7 +69,9 @@ RTCPSender::FeedbackState::FeedbackState() last_rr_ntp_secs(0), last_rr_ntp_frac(0), remote_sr(0), - has_last_xr_rr(false) {} + has_last_xr_rr(false), + module(nullptr) { +} RTCPSender::RTCPSender( int32_t id, @@ -127,58 +123,42 @@ RTCPSender::RTCPSender( _appSend(false), _appSubType(0), _appName(), - _appData(NULL), + _appData(nullptr), _appLength(0), xrSendReceiverReferenceTimeEnabled_(false), _xrSendVoIPMetric(false), _xrVoIPMetric(), packet_type_counter_observer_(packet_type_counter_observer) { - memset(_CNAME, 0, sizeof(_CNAME)); - memset(_lastSendReport, 0, sizeof(_lastSendReport)); - memset(_lastRTCPTime, 0, sizeof(_lastRTCPTime)); + memset(_CNAME, 0, sizeof(_CNAME)); + memset(_lastSendReport, 0, sizeof(_lastSendReport)); + memset(_lastRTCPTime, 0, sizeof(_lastRTCPTime)); } RTCPSender::~RTCPSender() { - delete [] _appData; + for (auto it : internal_report_blocks_) + delete it.second; - while (!internal_report_blocks_.empty()) { - delete internal_report_blocks_.begin()->second; - internal_report_blocks_.erase(internal_report_blocks_.begin()); - } - while (!external_report_blocks_.empty()) { - std::map::iterator it = - external_report_blocks_.begin(); - delete it->second; - external_report_blocks_.erase(it); - } - while (!_csrcCNAMEs.empty()) { - std::map::iterator it = - _csrcCNAMEs.begin(); - delete it->second; - _csrcCNAMEs.erase(it); - } - delete _criticalSectionTransport; - delete _criticalSectionRTCPSender; + for (auto it : external_report_blocks_) + delete it.second; + + for (auto it : _csrcCNAMEs) + delete it.second; } -int32_t -RTCPSender::RegisterSendTransport(Transport* outgoingTransport) -{ - CriticalSectionScoped lock(_criticalSectionTransport); - _cbTransport = outgoingTransport; - return 0; +int32_t RTCPSender::RegisterSendTransport(Transport* outgoingTransport) { + CriticalSectionScoped lock(_criticalSectionTransport.get()); + _cbTransport = outgoingTransport; + return 0; } -RTCPMethod -RTCPSender::Status() const -{ - CriticalSectionScoped lock(_criticalSectionRTCPSender); - return _method; +RTCPMethod RTCPSender::Status() const { + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); + return _method; } void RTCPSender::SetRTCPStatus(RTCPMethod method) { - CriticalSectionScoped lock(_criticalSectionRTCPSender); + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); _method = method; if (method == kRtcpOff) @@ -188,52 +168,43 @@ void RTCPSender::SetRTCPStatus(RTCPMethod method) { (_audio ? RTCP_INTERVAL_AUDIO_MS / 2 : RTCP_INTERVAL_VIDEO_MS / 2); } -bool -RTCPSender::Sending() const -{ - CriticalSectionScoped lock(_criticalSectionRTCPSender); - return _sending; +bool RTCPSender::Sending() const { + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); + return _sending; } -int32_t -RTCPSender::SetSendingStatus(const FeedbackState& feedback_state, bool sending) -{ - bool sendRTCPBye = false; - { - CriticalSectionScoped lock(_criticalSectionRTCPSender); +int32_t RTCPSender::SetSendingStatus(const FeedbackState& feedback_state, + bool sending) { + bool sendRTCPBye = false; + { + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - if(_method != kRtcpOff) - { - if(sending == false && _sending == true) - { - // Trigger RTCP bye - sendRTCPBye = true; - } - } - _sending = sending; + if (_method != kRtcpOff) { + if (sending == false && _sending == true) { + // Trigger RTCP bye + sendRTCPBye = true; + } } - if(sendRTCPBye) - { - return SendRTCP(feedback_state, kRtcpBye); - } - return 0; + _sending = sending; + } + if (sendRTCPBye) + return SendRTCP(feedback_state, kRtcpBye); + return 0; } -bool -RTCPSender::REMB() const -{ - CriticalSectionScoped lock(_criticalSectionRTCPSender); - return _REMB; +bool RTCPSender::REMB() const { + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); + return _REMB; } void RTCPSender::SetREMBStatus(bool enable) { - CriticalSectionScoped lock(_criticalSectionRTCPSender); + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); _REMB = enable; } void RTCPSender::SetREMBData(uint32_t bitrate, const std::vector& ssrcs) { - CriticalSectionScoped lock(_criticalSectionRTCPSender); + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); _rembBitrate = bitrate; remb_ssrcs_ = ssrcs; @@ -243,38 +214,34 @@ void RTCPSender::SetREMBData(uint32_t bitrate, _nextTimeToSendRTCP = _clock->TimeInMilliseconds(); } -bool -RTCPSender::TMMBR() const -{ - CriticalSectionScoped lock(_criticalSectionRTCPSender); - return _TMMBR; +bool RTCPSender::TMMBR() const { + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); + return _TMMBR; } void RTCPSender::SetTMMBRStatus(bool enable) { - CriticalSectionScoped lock(_criticalSectionRTCPSender); + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); _TMMBR = enable; } -bool -RTCPSender::IJ() const -{ - CriticalSectionScoped lock(_criticalSectionRTCPSender); - return _IJ; +bool RTCPSender::IJ() const { + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); + return _IJ; } void RTCPSender::SetIJStatus(bool enable) { - CriticalSectionScoped lock(_criticalSectionRTCPSender); + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); _IJ = enable; } void RTCPSender::SetStartTimestamp(uint32_t start_timestamp) { - CriticalSectionScoped lock(_criticalSectionRTCPSender); + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); start_timestamp_ = start_timestamp; } void RTCPSender::SetLastRtpTime(uint32_t rtp_timestamp, int64_t capture_time_ms) { - CriticalSectionScoped lock(_criticalSectionRTCPSender); + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); last_rtp_timestamp_ = rtp_timestamp; if (capture_time_ms < 0) { // We don't currently get a capture time from VoiceEngine. @@ -285,29 +252,27 @@ void RTCPSender::SetLastRtpTime(uint32_t rtp_timestamp, } void RTCPSender::SetSSRC(uint32_t ssrc) { - CriticalSectionScoped lock(_criticalSectionRTCPSender); + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - if(_SSRC != 0) - { - // not first SetSSRC, probably due to a collision - // schedule a new RTCP report - // make sure that we send a RTP packet - _nextTimeToSendRTCP = _clock->TimeInMilliseconds() + 100; - } - _SSRC = ssrc; + if (_SSRC != 0) { + // not first SetSSRC, probably due to a collision + // schedule a new RTCP report + // make sure that we send a RTP packet + _nextTimeToSendRTCP = _clock->TimeInMilliseconds() + 100; + } + _SSRC = ssrc; } -void RTCPSender::SetRemoteSSRC(uint32_t ssrc) -{ - CriticalSectionScoped lock(_criticalSectionRTCPSender); - _remoteSSRC = ssrc; +void RTCPSender::SetRemoteSSRC(uint32_t ssrc) { + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); + _remoteSSRC = ssrc; } int32_t RTCPSender::SetCNAME(const char cName[RTCP_CNAME_SIZE]) { if (!cName) return -1; - CriticalSectionScoped lock(_criticalSectionRTCPSender); + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); _CNAME[RTCP_CNAME_SIZE - 1] = 0; strncpy(_CNAME, cName, RTCP_CNAME_SIZE - 1); return 0; @@ -316,7 +281,7 @@ int32_t RTCPSender::SetCNAME(const char cName[RTCP_CNAME_SIZE]) { int32_t RTCPSender::AddMixedCNAME(uint32_t SSRC, const char cName[RTCP_CNAME_SIZE]) { assert(cName); - CriticalSectionScoped lock(_criticalSectionRTCPSender); + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); if (_csrcCNAMEs.size() >= kRtpCsrcSize) { return -1; } @@ -328,13 +293,13 @@ int32_t RTCPSender::AddMixedCNAME(uint32_t SSRC, } int32_t RTCPSender::RemoveMixedCNAME(uint32_t SSRC) { - CriticalSectionScoped lock(_criticalSectionRTCPSender); + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); std::map::iterator it = _csrcCNAMEs.find(SSRC); - if (it == _csrcCNAMEs.end()) { + if (it == _csrcCNAMEs.end()) return -1; - } + delete it->second; _csrcCNAMEs.erase(it); return 0; @@ -399,65 +364,47 @@ From RFC 3550 a value of the RTCP bandwidth below the intended average */ - int64_t now = _clock->TimeInMilliseconds(); + int64_t now = _clock->TimeInMilliseconds(); - CriticalSectionScoped lock(_criticalSectionRTCPSender); + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - if(_method == kRtcpOff) - { - return false; - } - - if(!_audio && sendKeyframeBeforeRTP) - { - // for video key-frames we want to send the RTCP before the large key-frame - // if we have a 100 ms margin - now += RTCP_SEND_BEFORE_KEY_FRAME_MS; - } - - if(now >= _nextTimeToSendRTCP) - { - return true; - - } else if(now < 0x0000ffff && _nextTimeToSendRTCP > 0xffff0000) // 65 sec margin - { - // wrap - return true; - } + if (_method == kRtcpOff) return false; -} -uint32_t RTCPSender::LastSendReport(int64_t& lastRTCPTime) -{ - CriticalSectionScoped lock(_criticalSectionRTCPSender); + if (!_audio && sendKeyframeBeforeRTP) { + // for video key-frames we want to send the RTCP before the large key-frame + // if we have a 100 ms margin + now += RTCP_SEND_BEFORE_KEY_FRAME_MS; + } - lastRTCPTime = _lastRTCPTime[0]; - return _lastSendReport[0]; + if (now >= _nextTimeToSendRTCP) { + return true; + } else if (now < 0x0000ffff && + _nextTimeToSendRTCP > 0xffff0000) { // 65 sec margin + // wrap + return true; + } + return false; } int64_t RTCPSender::SendTimeOfSendReport(uint32_t sendReport) { - CriticalSectionScoped lock(_criticalSectionRTCPSender); + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - // This is only saved when we are the sender - if((_lastSendReport[0] == 0) || (sendReport == 0)) - { - return 0; // will be ignored - } else - { - for(int i = 0; i < RTCP_NUMBER_OF_SR; ++i) - { - if( _lastSendReport[i] == sendReport) - { - return _lastRTCPTime[i]; - } - } + // This is only saved when we are the sender + if ((_lastSendReport[0] == 0) || (sendReport == 0)) { + return 0; // will be ignored + } else { + for (int i = 0; i < RTCP_NUMBER_OF_SR; ++i) { + if (_lastSendReport[i] == sendReport) + return _lastRTCPTime[i]; } - return 0; + } + return 0; } bool RTCPSender::SendTimeOfXrRrReport(uint32_t mid_ntp, int64_t* time_ms) const { - CriticalSectionScoped lock(_criticalSectionRTCPSender); + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); if (last_xr_rr_.empty()) { return false; @@ -473,7 +420,7 @@ bool RTCPSender::SendTimeOfXrRrReport(uint32_t mid_ntp, int32_t RTCPSender::AddExternalReportBlock( uint32_t SSRC, const RTCPReportBlock* reportBlock) { - CriticalSectionScoped lock(_criticalSectionRTCPSender); + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); return AddReportBlock(SSRC, &external_report_blocks_, reportBlock); } @@ -500,7 +447,7 @@ int32_t RTCPSender::AddReportBlock( } int32_t RTCPSender::RemoveExternalReportBlock(uint32_t SSRC) { - CriticalSectionScoped lock(_criticalSectionRTCPSender); + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); std::map::iterator it = external_report_blocks_.find(SSRC); @@ -515,87 +462,80 @@ int32_t RTCPSender::RemoveExternalReportBlock(uint32_t SSRC) { int32_t RTCPSender::BuildSR(const FeedbackState& feedback_state, uint8_t* rtcpbuffer, - int& pos, + int32_t pos, uint32_t NTPsec, - uint32_t NTPfrac) -{ - // sanity - if(pos + 52 >= IP_PACKET_SIZE) - { - LOG(LS_WARNING) << "Failed to build Sender Report."; - return -2; - } - uint32_t RTPtime; + uint32_t NTPfrac) { + // sanity + if (pos + 52 >= IP_PACKET_SIZE) { + LOG(LS_WARNING) << "Failed to build Sender Report."; + return -2; + } + uint32_t RTPtime; - uint32_t posNumberOfReportBlocks = pos; - rtcpbuffer[pos++]=(uint8_t)0x80; + uint32_t posNumberOfReportBlocks = pos; + rtcpbuffer[pos++] = 0x80; - // Sender report - rtcpbuffer[pos++]=(uint8_t)200; + // Sender report + rtcpbuffer[pos++] = 200; - for(int i = (RTCP_NUMBER_OF_SR-2); i >= 0; i--) - { - // shift old - _lastSendReport[i+1] = _lastSendReport[i]; - _lastRTCPTime[i+1] =_lastRTCPTime[i]; - } + for (int i = (RTCP_NUMBER_OF_SR - 2); i >= 0; i--) { + // shift old + _lastSendReport[i + 1] = _lastSendReport[i]; + _lastRTCPTime[i + 1] = _lastRTCPTime[i]; + } - _lastRTCPTime[0] = Clock::NtpToMs(NTPsec, NTPfrac); - _lastSendReport[0] = (NTPsec << 16) + (NTPfrac >> 16); + _lastRTCPTime[0] = Clock::NtpToMs(NTPsec, NTPfrac); + _lastSendReport[0] = (NTPsec << 16) + (NTPfrac >> 16); - // The timestamp of this RTCP packet should be estimated as the timestamp of - // the frame being captured at this moment. We are calculating that - // timestamp as the last frame's timestamp + the time since the last frame - // was captured. - RTPtime = start_timestamp_ + last_rtp_timestamp_ + - (_clock->TimeInMilliseconds() - last_frame_capture_time_ms_) * - (feedback_state.frequency_hz / 1000); + // The timestamp of this RTCP packet should be estimated as the timestamp of + // the frame being captured at this moment. We are calculating that + // timestamp as the last frame's timestamp + the time since the last frame + // was captured. + RTPtime = start_timestamp_ + last_rtp_timestamp_ + + (_clock->TimeInMilliseconds() - last_frame_capture_time_ms_) * + (feedback_state.frequency_hz / 1000); - // Add sender data - // Save for our length field - pos++; - pos++; + // Add sender data + // Save for our length field + pos++; + pos++; - // Add our own SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); - pos += 4; - // NTP - ByteWriter::WriteBigEndian(rtcpbuffer + pos, NTPsec); - pos += 4; - ByteWriter::WriteBigEndian(rtcpbuffer + pos, NTPfrac); - pos += 4; - ByteWriter::WriteBigEndian(rtcpbuffer + pos, RTPtime); - pos += 4; + // Add our own SSRC + ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); + pos += 4; + // NTP + ByteWriter::WriteBigEndian(rtcpbuffer + pos, NTPsec); + pos += 4; + ByteWriter::WriteBigEndian(rtcpbuffer + pos, NTPfrac); + pos += 4; + ByteWriter::WriteBigEndian(rtcpbuffer + pos, RTPtime); + pos += 4; - //sender's packet count - ByteWriter::WriteBigEndian(rtcpbuffer + pos, - feedback_state.packets_sent); - pos += 4; + // sender's packet count + ByteWriter::WriteBigEndian(rtcpbuffer + pos, + feedback_state.packets_sent); + pos += 4; - //sender's octet count - ByteWriter::WriteBigEndian(rtcpbuffer + pos, - feedback_state.media_bytes_sent); - pos += 4; + // sender's octet count + ByteWriter::WriteBigEndian(rtcpbuffer + pos, + feedback_state.media_bytes_sent); + pos += 4; - uint8_t numberOfReportBlocks = 0; - int32_t retVal = WriteAllReportBlocksToBuffer(rtcpbuffer, pos, - numberOfReportBlocks, - NTPsec, NTPfrac); - if(retVal < 0) - { - // - return retVal ; - } - pos = retVal; - rtcpbuffer[posNumberOfReportBlocks] += numberOfReportBlocks; + uint8_t numberOfReportBlocks = 0; + int32_t retVal = WriteAllReportBlocksToBuffer( + rtcpbuffer, pos, &numberOfReportBlocks, NTPsec, NTPfrac); + if (retVal < 0) + return retVal; - uint16_t len = uint16_t((pos/4) -1); - ByteWriter::WriteBigEndian(rtcpbuffer + 2, len); - return 0; + pos = retVal; + rtcpbuffer[posNumberOfReportBlocks] += numberOfReportBlocks; + + uint16_t len = static_cast((pos / 4) - 1); + ByteWriter::WriteBigEndian(rtcpbuffer + 2, len); + return pos; } - -int32_t RTCPSender::BuildSDEC(uint8_t* rtcpbuffer, int& pos) { +int32_t RTCPSender::BuildSDEC(uint8_t* rtcpbuffer, int32_t pos) { size_t lengthCname = strlen(_CNAME); assert(lengthCname < RTCP_CNAME_SIZE); @@ -607,8 +547,10 @@ int32_t RTCPSender::BuildSDEC(uint8_t* rtcpbuffer, int& pos) { // SDEC Source Description // We always need to add SDES CNAME - rtcpbuffer[pos++] = static_cast(0x80 + 1 + _csrcCNAMEs.size()); - rtcpbuffer[pos++] = static_cast(202); + size_t size = 0x80 + 1 + _csrcCNAMEs.size(); + DCHECK_LE(size, std::numeric_limits::max()); + rtcpbuffer[pos++] = static_cast(size); + rtcpbuffer[pos++] = 202; // handle SDES length later on uint32_t SDESLengthPos = pos; @@ -620,33 +562,29 @@ int32_t RTCPSender::BuildSDEC(uint8_t* rtcpbuffer, int& pos) { pos += 4; // CNAME = 1 - rtcpbuffer[pos++] = static_cast(1); - - // + rtcpbuffer[pos++] = 1; + DCHECK_LE(lengthCname, std::numeric_limits::max()); rtcpbuffer[pos++] = static_cast(lengthCname); uint16_t SDESLength = 10; memcpy(&rtcpbuffer[pos], _CNAME, lengthCname); pos += lengthCname; - SDESLength += (uint16_t)lengthCname; + SDESLength += static_cast(lengthCname); uint16_t padding = 0; // We must have a zero field even if we have an even multiple of 4 bytes if ((pos % 4) == 0) { padding++; - rtcpbuffer[pos++]=0; + rtcpbuffer[pos++] = 0; } while ((pos % 4) != 0) { padding++; - rtcpbuffer[pos++]=0; + rtcpbuffer[pos++] = 0; } SDESLength += padding; - std::map::iterator it = - _csrcCNAMEs.begin(); - - for(; it != _csrcCNAMEs.end(); it++) { + for (auto it = _csrcCNAMEs.begin(); it != _csrcCNAMEs.end(); ++it) { RTCPCnameInformation* cname = it->second; uint32_t SSRC = it->first; @@ -655,7 +593,7 @@ int32_t RTCPSender::BuildSDEC(uint8_t* rtcpbuffer, int& pos) { pos += 4; // CNAME = 1 - rtcpbuffer[pos++] = static_cast(1); + rtcpbuffer[pos++] = 1; size_t length = strlen(cname->name); assert(length < RTCP_CNAME_SIZE); @@ -684,45 +622,41 @@ int32_t RTCPSender::BuildSDEC(uint8_t* rtcpbuffer, int& pos) { uint16_t buffer_length = (SDESLength / 4) - 1; ByteWriter::WriteBigEndian(rtcpbuffer + SDESLengthPos, buffer_length); - return 0; + return pos; } int32_t RTCPSender::BuildRR(uint8_t* rtcpbuffer, - int& pos, + int32_t pos, uint32_t NTPsec, uint32_t NTPfrac) { - // sanity one block - if(pos + 32 >= IP_PACKET_SIZE) - { - return -2; - } - uint32_t posNumberOfReportBlocks = pos; + // sanity one block + if (pos + 32 >= IP_PACKET_SIZE) + return -2; - rtcpbuffer[pos++]=(uint8_t)0x80; - rtcpbuffer[pos++]=(uint8_t)201; + uint32_t posNumberOfReportBlocks = pos; - // Save for our length field - pos++; - pos++; + rtcpbuffer[pos++] = 0x80; + rtcpbuffer[pos++] = 201; - // Add our own SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); - pos += 4; + // Save for our length field + pos += 2; - uint8_t numberOfReportBlocks = 0; - int retVal = WriteAllReportBlocksToBuffer(rtcpbuffer, pos, - numberOfReportBlocks, - NTPsec, NTPfrac); - if(retVal < 0) - { - return pos; - } - pos = retVal; - rtcpbuffer[posNumberOfReportBlocks] += numberOfReportBlocks; + // Add our own SSRC + ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); + pos += 4; - uint16_t len = uint16_t((pos)/4 -1); - ByteWriter::WriteBigEndian(rtcpbuffer + 2, len); - return 0; + uint8_t numberOfReportBlocks = 0; + int retVal = WriteAllReportBlocksToBuffer( + rtcpbuffer, pos, &numberOfReportBlocks, NTPsec, NTPfrac); + if (retVal < 0) + return pos; + + pos = retVal; + rtcpbuffer[posNumberOfReportBlocks] += numberOfReportBlocks; + + uint16_t len = uint16_t((pos) / 4 - 1); + ByteWriter::WriteBigEndian(rtcpbuffer + 2, len); + return pos; } // From RFC 5450: Transmission Time Offsets in RTP Streams. @@ -743,87 +677,77 @@ int32_t RTCPSender::BuildRR(uint8_t* rtcpbuffer, // (inside a compound RTCP packet), and MUST have the same value for RC // (reception report count) as the receiver report. -int32_t -RTCPSender::BuildExtendedJitterReport( +int32_t RTCPSender::BuildExtendedJitterReport( uint8_t* rtcpbuffer, - int& pos, - const uint32_t jitterTransmissionTimeOffset) -{ - if (external_report_blocks_.size() > 0) - { - // TODO(andresp): Remove external report blocks since they are not - // supported. - LOG(LS_ERROR) << "Handling of external report blocks not implemented."; - return 0; - } - - // sanity - if(pos + 8 >= IP_PACKET_SIZE) - { - return -2; - } - // add picture loss indicator - uint8_t RC = 1; - rtcpbuffer[pos++]=(uint8_t)0x80 + RC; - rtcpbuffer[pos++]=(uint8_t)195; - - // Used fixed length of 2 - rtcpbuffer[pos++]=(uint8_t)0; - rtcpbuffer[pos++]=(uint8_t)(1); - - // Add inter-arrival jitter - ByteWriter::WriteBigEndian(rtcpbuffer + pos, - jitterTransmissionTimeOffset); - pos += 4; + int32_t pos, + const uint32_t jitterTransmissionTimeOffset) { + if (external_report_blocks_.size() > 0) { + // TODO(andresp): Remove external report blocks since they are not + // supported. + LOG(LS_ERROR) << "Handling of external report blocks not implemented."; return 0; -} + } -int32_t -RTCPSender::BuildPLI(uint8_t* rtcpbuffer, int& pos) -{ - // sanity - if(pos + 12 >= IP_PACKET_SIZE) - { - return -2; - } - // add picture loss indicator - uint8_t FMT = 1; - rtcpbuffer[pos++]=(uint8_t)0x80 + FMT; - rtcpbuffer[pos++]=(uint8_t)206; - - //Used fixed length of 2 - rtcpbuffer[pos++]=(uint8_t)0; - rtcpbuffer[pos++]=(uint8_t)(2); - - // Add our own SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); - pos += 4; - - // Add the remote SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _remoteSSRC); - pos += 4; - return 0; -} - -int32_t RTCPSender::BuildFIR(uint8_t* rtcpbuffer, - int& pos, - bool repeat) { // sanity - if(pos + 20 >= IP_PACKET_SIZE) { + if (pos + 8 >= IP_PACKET_SIZE) return -2; - } - if (!repeat) { + + // add picture loss indicator + uint8_t RC = 1; + rtcpbuffer[pos++] = 0x80 + RC; + rtcpbuffer[pos++] = 195; + + // Used fixed length of 2 + rtcpbuffer[pos++] = 0; + rtcpbuffer[pos++] = 1; + + // Add inter-arrival jitter + ByteWriter::WriteBigEndian(rtcpbuffer + pos, + jitterTransmissionTimeOffset); + pos += 4; + return pos; +} + +int32_t RTCPSender::BuildPLI(uint8_t* rtcpbuffer, int32_t pos) { + // sanity + if (pos + 12 >= IP_PACKET_SIZE) + return -2; + + // add picture loss indicator + uint8_t FMT = 1; + rtcpbuffer[pos++] = 0x80 + FMT; + rtcpbuffer[pos++] = 206; + + // Used fixed length of 2 + rtcpbuffer[pos++] = 0; + rtcpbuffer[pos++] = 2; + + // Add our own SSRC + ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); + pos += 4; + + // Add the remote SSRC + ByteWriter::WriteBigEndian(rtcpbuffer + pos, _remoteSSRC); + pos += 4; + return pos; +} + +int32_t RTCPSender::BuildFIR(uint8_t* rtcpbuffer, int32_t pos, bool repeat) { + // sanity + if (pos + 20 >= IP_PACKET_SIZE) + return -2; + + if (!repeat) _sequenceNumberFIR++; // do not increase if repetition - } // add full intra request indicator uint8_t FMT = 4; - rtcpbuffer[pos++] = (uint8_t)0x80 + FMT; - rtcpbuffer[pos++] = (uint8_t)206; + rtcpbuffer[pos++] = 0x80 + FMT; + rtcpbuffer[pos++] = 206; //Length of 4 - rtcpbuffer[pos++] = (uint8_t)0; - rtcpbuffer[pos++] = (uint8_t)(4); + rtcpbuffer[pos++] = 0; + rtcpbuffer[pos++] = 4; // Add our own SSRC ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); @@ -831,20 +755,18 @@ int32_t RTCPSender::BuildFIR(uint8_t* rtcpbuffer, // RFC 5104 4.3.1.2. Semantics // SSRC of media source - rtcpbuffer[pos++] = (uint8_t)0; - rtcpbuffer[pos++] = (uint8_t)0; - rtcpbuffer[pos++] = (uint8_t)0; - rtcpbuffer[pos++] = (uint8_t)0; + ByteWriter::WriteBigEndian(&rtcpbuffer[pos], 0); + pos += 4; // Additional Feedback Control Information (FCI) ByteWriter::WriteBigEndian(rtcpbuffer + pos, _remoteSSRC); pos += 4; - rtcpbuffer[pos++] = (uint8_t)(_sequenceNumberFIR); - rtcpbuffer[pos++] = (uint8_t)0; - rtcpbuffer[pos++] = (uint8_t)0; - rtcpbuffer[pos++] = (uint8_t)0; - return 0; + rtcpbuffer[pos++] = _sequenceNumberFIR; + rtcpbuffer[pos++] = 0; + rtcpbuffer[pos++] = 0; + rtcpbuffer[pos++] = 0; + return pos; } /* @@ -854,36 +776,37 @@ int32_t RTCPSender::BuildFIR(uint8_t* rtcpbuffer, | First | Number | PictureID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -int32_t RTCPSender::BuildSLI(uint8_t* rtcpbuffer, int& pos, uint8_t pictureID) { - // sanity - if(pos + 16 >= IP_PACKET_SIZE) - { - return -2; - } - // add slice loss indicator - uint8_t FMT = 2; - rtcpbuffer[pos++]=(uint8_t)0x80 + FMT; - rtcpbuffer[pos++]=(uint8_t)206; +int32_t RTCPSender::BuildSLI(uint8_t* rtcpbuffer, + int32_t pos, + uint8_t pictureID) { + // sanity + if (pos + 16 >= IP_PACKET_SIZE) + return -2; - //Used fixed length of 3 - rtcpbuffer[pos++]=(uint8_t)0; - rtcpbuffer[pos++]=(uint8_t)(3); + // add slice loss indicator + uint8_t FMT = 2; + rtcpbuffer[pos++] = 0x80 + FMT; + rtcpbuffer[pos++] = 206; - // Add our own SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); - pos += 4; + // Used fixed length of 3 + rtcpbuffer[pos++] = 0; + rtcpbuffer[pos++] = 3; - // Add the remote SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _remoteSSRC); - pos += 4; + // Add our own SSRC + ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); + pos += 4; - // Add first, number & picture ID 6 bits - // first = 0, 13 - bits - // number = 0x1fff, 13 - bits only ones for now - uint32_t sliField = (0x1fff << 6)+ (0x3f & pictureID); - ByteWriter::WriteBigEndian(rtcpbuffer + pos, sliField); - pos += 4; - return 0; + // Add the remote SSRC + ByteWriter::WriteBigEndian(rtcpbuffer + pos, _remoteSSRC); + pos += 4; + + // Add first, number & picture ID 6 bits + // first = 0, 13 - bits + // number = 0x1fff, 13 - bits only ones for now + uint32_t sliField = (0x1fff << 6) + (0x3f & pictureID); + ByteWriter::WriteBigEndian(rtcpbuffer + pos, sliField); + pos += 4; + return pos; } /* @@ -899,434 +822,393 @@ int32_t RTCPSender::BuildSLI(uint8_t* rtcpbuffer, int& pos, uint8_t pictureID) { * Note: not generic made for VP8 */ int32_t RTCPSender::BuildRPSI(uint8_t* rtcpbuffer, - int& pos, + int32_t pos, uint64_t pictureID, uint8_t payloadType) { - // sanity - if(pos + 24 >= IP_PACKET_SIZE) - { - return -2; - } - // add Reference Picture Selection Indication - uint8_t FMT = 3; - rtcpbuffer[pos++]=(uint8_t)0x80 + FMT; - rtcpbuffer[pos++]=(uint8_t)206; + // sanity + if (pos + 24 >= IP_PACKET_SIZE) + return -2; - // calc length - uint32_t bitsRequired = 7; - uint8_t bytesRequired = 1; - while((pictureID>>bitsRequired) > 0) - { - bitsRequired += 7; - bytesRequired++; - } + // add Reference Picture Selection Indication + uint8_t FMT = 3; + rtcpbuffer[pos++] = 0x80 + FMT; + rtcpbuffer[pos++] = 206; - uint8_t size = 3; - if(bytesRequired > 6) - { - size = 5; - } else if(bytesRequired > 2) - { - size = 4; - } - rtcpbuffer[pos++]=(uint8_t)0; - rtcpbuffer[pos++]=size; + // calc length + uint32_t bitsRequired = 7; + uint8_t bytesRequired = 1; + while ((pictureID >> bitsRequired) > 0) { + bitsRequired += 7; + bytesRequired++; + } - // Add our own SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); - pos += 4; + uint8_t size = 3; + if (bytesRequired > 6) { + size = 5; + } else if (bytesRequired > 2) { + size = 4; + } + rtcpbuffer[pos++] = 0; + rtcpbuffer[pos++] = size; - // Add the remote SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _remoteSSRC); - pos += 4; + // Add our own SSRC + ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); + pos += 4; - // calc padding length - uint8_t paddingBytes = 4-((2+bytesRequired)%4); - if(paddingBytes == 4) - { - paddingBytes = 0; - } - // add padding length in bits - rtcpbuffer[pos] = paddingBytes*8; // padding can be 0, 8, 16 or 24 + // Add the remote SSRC + ByteWriter::WriteBigEndian(rtcpbuffer + pos, _remoteSSRC); + pos += 4; + + // calc padding length + uint8_t paddingBytes = 4 - ((2 + bytesRequired) % 4); + if (paddingBytes == 4) + paddingBytes = 0; + // add padding length in bits + rtcpbuffer[pos] = paddingBytes * 8; // padding can be 0, 8, 16 or 24 + pos++; + + // add payload type + rtcpbuffer[pos] = payloadType; + pos++; + + // add picture ID + for (int i = bytesRequired - 1; i > 0; --i) { + rtcpbuffer[pos] = 0x80 | static_cast(pictureID >> (i * 7)); pos++; + } + // add last byte of picture ID + rtcpbuffer[pos] = static_cast(pictureID & 0x7f); + pos++; - // add payload type - rtcpbuffer[pos] = payloadType; + // add padding + for (int j = 0; j < paddingBytes; j++) { + rtcpbuffer[pos] = 0; pos++; - - // add picture ID - for(int i = bytesRequired-1; i > 0; i--) - { - rtcpbuffer[pos] = 0x80 | uint8_t(pictureID >> (i*7)); - pos++; - } - // add last byte of picture ID - rtcpbuffer[pos] = uint8_t(pictureID & 0x7f); - pos++; - - // add padding - for(int j = 0; j = IP_PACKET_SIZE) - { - return -2; +int32_t RTCPSender::BuildREMB(uint8_t* rtcpbuffer, int32_t pos) { + // sanity + if (pos + 20 + 4 * remb_ssrcs_.size() >= IP_PACKET_SIZE) + return -2; + + // add application layer feedback + uint8_t FMT = 15; + rtcpbuffer[pos++] = 0x80 + FMT; + rtcpbuffer[pos++] = 206; + + rtcpbuffer[pos++] = 0; + rtcpbuffer[pos++] = static_cast(remb_ssrcs_.size() + 4); + + // Add our own SSRC + ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); + pos += 4; + + // Remote SSRC must be 0 + ByteWriter::WriteBigEndian(rtcpbuffer + pos, 0); + pos += 4; + + rtcpbuffer[pos++] = 'R'; + rtcpbuffer[pos++] = 'E'; + rtcpbuffer[pos++] = 'M'; + rtcpbuffer[pos++] = 'B'; + + rtcpbuffer[pos++] = remb_ssrcs_.size(); + // 6 bit Exp + // 18 bit mantissa + uint8_t brExp = 0; + for (uint32_t i = 0; i < 64; i++) { + if (_rembBitrate <= (262143u << i)) { + brExp = i; + break; } - // add application layer feedback - uint8_t FMT = 15; - rtcpbuffer[pos++]=(uint8_t)0x80 + FMT; - rtcpbuffer[pos++]=(uint8_t)206; + } + const uint32_t brMantissa = (_rembBitrate >> brExp); + rtcpbuffer[pos++] = (uint8_t)((brExp << 2) + ((brMantissa >> 16) & 0x03)); + rtcpbuffer[pos++] = (uint8_t)(brMantissa >> 8); + rtcpbuffer[pos++] = (uint8_t)(brMantissa); - rtcpbuffer[pos++]=(uint8_t)0; - rtcpbuffer[pos++]=remb_ssrcs_.size() + 4; - - // Add our own SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); + for (size_t i = 0; i < remb_ssrcs_.size(); i++) { + ByteWriter::WriteBigEndian(rtcpbuffer + pos, remb_ssrcs_[i]); pos += 4; - - // Remote SSRC must be 0 - ByteWriter::WriteBigEndian(rtcpbuffer + pos, 0); - pos += 4; - - rtcpbuffer[pos++]='R'; - rtcpbuffer[pos++]='E'; - rtcpbuffer[pos++]='M'; - rtcpbuffer[pos++]='B'; - - rtcpbuffer[pos++] = remb_ssrcs_.size(); - // 6 bit Exp - // 18 bit mantissa - uint8_t brExp = 0; - for(uint32_t i=0; i<64; i++) - { - if(_rembBitrate <= ((uint32_t)262143 << i)) - { - brExp = i; - break; - } - } - const uint32_t brMantissa = (_rembBitrate >> brExp); - rtcpbuffer[pos++]=(uint8_t)((brExp << 2) + ((brMantissa >> 16) & 0x03)); - rtcpbuffer[pos++]=(uint8_t)(brMantissa >> 8); - rtcpbuffer[pos++]=(uint8_t)(brMantissa); - - for (size_t i = 0; i < remb_ssrcs_.size(); i++) - { - ByteWriter::WriteBigEndian(rtcpbuffer + pos, remb_ssrcs_[i]); - pos += 4; - } - return 0; + } + return pos; } -void -RTCPSender::SetTargetBitrate(unsigned int target_bitrate) -{ - CriticalSectionScoped lock(_criticalSectionRTCPSender); +void RTCPSender::SetTargetBitrate(unsigned int target_bitrate) { + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); _tmmbr_Send = target_bitrate / 1000; } int32_t RTCPSender::BuildTMMBR(ModuleRtpRtcpImpl* rtp_rtcp_module, uint8_t* rtcpbuffer, - int& pos) { - if (rtp_rtcp_module == NULL) - return -1; - // Before sending the TMMBR check the received TMMBN, only an owner is allowed to raise the bitrate - // If the sender is an owner of the TMMBN -> send TMMBR - // If not an owner but the TMMBR would enter the TMMBN -> send TMMBR + int32_t pos) { + if (rtp_rtcp_module == NULL) + return -1; + // Before sending the TMMBR check the received TMMBN, only an owner is + // allowed to raise the bitrate: + // * If the sender is an owner of the TMMBN -> send TMMBR + // * If not an owner but the TMMBR would enter the TMMBN -> send TMMBR - // get current bounding set from RTCP receiver - bool tmmbrOwner = false; - // store in candidateSet, allocates one extra slot - TMMBRSet* candidateSet = _tmmbrHelp.CandidateSet(); + // get current bounding set from RTCP receiver + bool tmmbrOwner = false; + // store in candidateSet, allocates one extra slot + TMMBRSet* candidateSet = _tmmbrHelp.CandidateSet(); - // holding _criticalSectionRTCPSender while calling RTCPreceiver which - // will accuire _criticalSectionRTCPReceiver is a potental deadlock but - // since RTCPreceiver is not doing the reverse we should be fine - int32_t lengthOfBoundingSet = - rtp_rtcp_module->BoundingSet(tmmbrOwner, candidateSet); + // holding _criticalSectionRTCPSender while calling RTCPreceiver which + // will accuire _criticalSectionRTCPReceiver is a potental deadlock but + // since RTCPreceiver is not doing the reverse we should be fine + int32_t lengthOfBoundingSet = + rtp_rtcp_module->BoundingSet(tmmbrOwner, candidateSet); - if(lengthOfBoundingSet > 0) - { - for (int32_t i = 0; i < lengthOfBoundingSet; i++) - { - if( candidateSet->Tmmbr(i) == _tmmbr_Send && - candidateSet->PacketOH(i) == _packetOH_Send) - { - // do not send the same tuple - return 0; - } - } - if(!tmmbrOwner) - { - // use received bounding set as candidate set - // add current tuple - candidateSet->SetEntry(lengthOfBoundingSet, - _tmmbr_Send, - _packetOH_Send, - _SSRC); - int numCandidates = lengthOfBoundingSet+ 1; - - // find bounding set - TMMBRSet* boundingSet = NULL; - int numBoundingSet = _tmmbrHelp.FindTMMBRBoundingSet(boundingSet); - if(numBoundingSet > 0 || numBoundingSet <= numCandidates) - { - tmmbrOwner = _tmmbrHelp.IsOwner(_SSRC, numBoundingSet); - } - if(!tmmbrOwner) - { - // did not enter bounding set, no meaning to send this request - return 0; - } - } + if (lengthOfBoundingSet > 0) { + for (int32_t i = 0; i < lengthOfBoundingSet; i++) { + if (candidateSet->Tmmbr(i) == _tmmbr_Send && + candidateSet->PacketOH(i) == _packetOH_Send) { + // do not send the same tuple + return 0; + } } + if (!tmmbrOwner) { + // use received bounding set as candidate set + // add current tuple + candidateSet->SetEntry(lengthOfBoundingSet, _tmmbr_Send, _packetOH_Send, + _SSRC); + int numCandidates = lengthOfBoundingSet + 1; - if(_tmmbr_Send) - { - // sanity - if(pos + 20 >= IP_PACKET_SIZE) - { - return -2; - } - // add TMMBR indicator - uint8_t FMT = 3; - rtcpbuffer[pos++]=(uint8_t)0x80 + FMT; - rtcpbuffer[pos++]=(uint8_t)205; - - //Length of 4 - rtcpbuffer[pos++]=(uint8_t)0; - rtcpbuffer[pos++]=(uint8_t)(4); - - // Add our own SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); - pos += 4; - - // RFC 5104 4.2.1.2. Semantics - - // SSRC of media source - rtcpbuffer[pos++]=(uint8_t)0; - rtcpbuffer[pos++]=(uint8_t)0; - rtcpbuffer[pos++]=(uint8_t)0; - rtcpbuffer[pos++]=(uint8_t)0; - - // Additional Feedback Control Information (FCI) - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _remoteSSRC); - pos += 4; - - uint32_t bitRate = _tmmbr_Send*1000; - uint32_t mmbrExp = 0; - for(uint32_t i=0;i<64;i++) - { - if(bitRate <= ((uint32_t)131071 << i)) - { - mmbrExp = i; - break; - } - } - uint32_t mmbrMantissa = (bitRate >> mmbrExp); - - rtcpbuffer[pos++]=(uint8_t)((mmbrExp << 2) + ((mmbrMantissa >> 15) & 0x03)); - rtcpbuffer[pos++]=(uint8_t)(mmbrMantissa >> 7); - rtcpbuffer[pos++]=(uint8_t)((mmbrMantissa << 1) + ((_packetOH_Send >> 8)& 0x01)); - rtcpbuffer[pos++]=(uint8_t)(_packetOH_Send); + // find bounding set + TMMBRSet* boundingSet = NULL; + int numBoundingSet = _tmmbrHelp.FindTMMBRBoundingSet(boundingSet); + if (numBoundingSet > 0 || numBoundingSet <= numCandidates) + tmmbrOwner = _tmmbrHelp.IsOwner(_SSRC, numBoundingSet); + if (!tmmbrOwner) { + // did not enter bounding set, no meaning to send this request + return 0; + } } - return 0; -} + } -int32_t -RTCPSender::BuildTMMBN(uint8_t* rtcpbuffer, int& pos) -{ - TMMBRSet* boundingSet = _tmmbrHelp.BoundingSetToSend(); - if(boundingSet == NULL) - { - return -1; - } + if (_tmmbr_Send) { // sanity - if(pos + 12 + boundingSet->lengthOfSet()*8 >= IP_PACKET_SIZE) - { - LOG(LS_WARNING) << "Failed to build TMMBN."; + if (pos + 20 >= IP_PACKET_SIZE) return -2; - } - uint8_t FMT = 4; - // add TMMBN indicator - rtcpbuffer[pos++]=(uint8_t)0x80 + FMT; - rtcpbuffer[pos++]=(uint8_t)205; - //Add length later - int posLength = pos; - pos++; - pos++; + // add TMMBR indicator + uint8_t FMT = 3; + rtcpbuffer[pos++] = 0x80 + FMT; + rtcpbuffer[pos++] = 205; + + // Length of 4 + rtcpbuffer[pos++] = 0; + rtcpbuffer[pos++] = 4; // Add our own SSRC ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); pos += 4; - // RFC 5104 4.2.2.2. Semantics + // RFC 5104 4.2.1.2. Semantics // SSRC of media source - rtcpbuffer[pos++]=(uint8_t)0; - rtcpbuffer[pos++]=(uint8_t)0; - rtcpbuffer[pos++]=(uint8_t)0; - rtcpbuffer[pos++]=(uint8_t)0; + ByteWriter::WriteBigEndian(&rtcpbuffer[pos], 0); + pos += 4; // Additional Feedback Control Information (FCI) - int numBoundingSet = 0; - for(uint32_t n=0; n< boundingSet->lengthOfSet(); n++) - { - if (boundingSet->Tmmbr(n) > 0) - { - uint32_t tmmbrSSRC = boundingSet->Ssrc(n); - ByteWriter::WriteBigEndian(rtcpbuffer + pos, tmmbrSSRC); - pos += 4; - - uint32_t bitRate = boundingSet->Tmmbr(n) * 1000; - uint32_t mmbrExp = 0; - for(int i=0; i<64; i++) - { - if(bitRate <= ((uint32_t)131071 << i)) - { - mmbrExp = i; - break; - } - } - uint32_t mmbrMantissa = (bitRate >> mmbrExp); - uint32_t measuredOH = boundingSet->PacketOH(n); - - rtcpbuffer[pos++]=(uint8_t)((mmbrExp << 2) + ((mmbrMantissa >> 15) & 0x03)); - rtcpbuffer[pos++]=(uint8_t)(mmbrMantissa >> 7); - rtcpbuffer[pos++]=(uint8_t)((mmbrMantissa << 1) + ((measuredOH >> 8)& 0x01)); - rtcpbuffer[pos++]=(uint8_t)(measuredOH); - numBoundingSet++; - } - } - uint16_t length= (uint16_t)(2+2*numBoundingSet); - rtcpbuffer[posLength++]=(uint8_t)(length>>8); - rtcpbuffer[posLength]=(uint8_t)(length); - return 0; -} - -int32_t -RTCPSender::BuildAPP(uint8_t* rtcpbuffer, int& pos) -{ - // sanity - if(_appData == NULL) - { - LOG(LS_WARNING) << "Failed to build app specific."; - return -1; - } - if(pos + 12 + _appLength >= IP_PACKET_SIZE) - { - LOG(LS_WARNING) << "Failed to build app specific."; - return -2; - } - rtcpbuffer[pos++]=(uint8_t)0x80 + _appSubType; - - // Add APP ID - rtcpbuffer[pos++]=(uint8_t)204; - - uint16_t length = (_appLength>>2) + 2; // include SSRC and name - rtcpbuffer[pos++]=(uint8_t)(length>>8); - rtcpbuffer[pos++]=(uint8_t)(length); - - // Add our own SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); - pos += 4; - - // Add our application name - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _appName); - pos += 4; - - // Add the data - memcpy(rtcpbuffer +pos, _appData,_appLength); - pos += _appLength; - return 0; -} - -int32_t RTCPSender::BuildNACK(uint8_t* rtcpbuffer, - int& pos, - int32_t nackSize, - const uint16_t* nackList, - std::string* nackString) { - // sanity - if(pos + 16 >= IP_PACKET_SIZE) - { - LOG(LS_WARNING) << "Failed to build NACK."; - return -2; - } - - // int size, uint16_t* nackList - // add nack list - uint8_t FMT = 1; - rtcpbuffer[pos++]=(uint8_t)0x80 + FMT; - rtcpbuffer[pos++]=(uint8_t)205; - - rtcpbuffer[pos++]=(uint8_t) 0; - int nackSizePos = pos; - rtcpbuffer[pos++]=(uint8_t)(3); //setting it to one kNACK signal as default - - // Add our own SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); - pos += 4; - - // Add the remote SSRC ByteWriter::WriteBigEndian(rtcpbuffer + pos, _remoteSSRC); pos += 4; - // Build NACK bitmasks and write them to the RTCP message. - // The nack list should be sorted and not contain duplicates if one - // wants to build the smallest rtcp nack packet. - int numOfNackFields = 0; - int maxNackFields = std::min(kRtcpMaxNackFields, - (IP_PACKET_SIZE - pos) / 4); - int i = 0; - while (i < nackSize && numOfNackFields < maxNackFields) { - uint16_t nack = nackList[i++]; - uint16_t bitmask = 0; - while (i < nackSize) { - int shift = static_cast(nackList[i] - nack) - 1; - if (shift >= 0 && shift <= 15) { - bitmask |= (1 << shift); - ++i; - } else { + uint32_t bitRate = _tmmbr_Send * 1000; + uint32_t mmbrExp = 0; + for (uint32_t i = 0; i < 64; i++) { + if (bitRate <= (0x1FFFFu << i)) { + mmbrExp = i; + break; + } + } + uint32_t mmbrMantissa = (bitRate >> mmbrExp); + + rtcpbuffer[pos++] = + static_cast((mmbrExp << 2) + ((mmbrMantissa >> 15) & 0x03)); + rtcpbuffer[pos++] = (uint8_t)(mmbrMantissa >> 7); + rtcpbuffer[pos++] = static_cast((mmbrMantissa << 1) + + ((_packetOH_Send >> 8) & 0x01)); + rtcpbuffer[pos++] = static_cast(_packetOH_Send); + } + return pos; +} + +int32_t RTCPSender::BuildTMMBN(uint8_t* rtcpbuffer, int32_t pos) { + TMMBRSet* boundingSet = _tmmbrHelp.BoundingSetToSend(); + if (boundingSet == NULL) + return -1; + + // sanity + if (pos + 12 + boundingSet->lengthOfSet() * 8 >= IP_PACKET_SIZE) { + LOG(LS_WARNING) << "Failed to build TMMBN."; + return -2; + } + + uint8_t FMT = 4; + // add TMMBN indicator + rtcpbuffer[pos++] = 0x80 + FMT; + rtcpbuffer[pos++] = 205; + + // Add length later + int posLength = pos; + pos++; + pos++; + + // Add our own SSRC + ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); + pos += 4; + + // RFC 5104 4.2.2.2. Semantics + + // SSRC of media source + ByteWriter::WriteBigEndian(&rtcpbuffer[pos], 0); + pos += 4; + + // Additional Feedback Control Information (FCI) + int numBoundingSet = 0; + for (uint32_t n = 0; n < boundingSet->lengthOfSet(); n++) { + if (boundingSet->Tmmbr(n) > 0) { + uint32_t tmmbrSSRC = boundingSet->Ssrc(n); + ByteWriter::WriteBigEndian(rtcpbuffer + pos, tmmbrSSRC); + pos += 4; + + uint32_t bitRate = boundingSet->Tmmbr(n) * 1000; + uint32_t mmbrExp = 0; + for (int i = 0; i < 64; i++) { + if (bitRate <= (0x1FFFFu << i)) { + mmbrExp = i; break; } } - // Write the sequence number and the bitmask to the packet. - assert(pos + 4 < IP_PACKET_SIZE); - ByteWriter::WriteBigEndian(rtcpbuffer + pos, nack); - pos += 2; - ByteWriter::WriteBigEndian(rtcpbuffer + pos, bitmask); - pos += 2; - numOfNackFields++; - } - rtcpbuffer[nackSizePos] = static_cast(2 + numOfNackFields); + uint32_t mmbrMantissa = (bitRate >> mmbrExp); + uint32_t measuredOH = boundingSet->PacketOH(n); - if (i != nackSize) { - LOG(LS_WARNING) << "Nack list too large for one packet."; + rtcpbuffer[pos++] = + static_cast((mmbrExp << 2) + ((mmbrMantissa >> 15) & 0x03)); + rtcpbuffer[pos++] = (uint8_t)(mmbrMantissa >> 7); + rtcpbuffer[pos++] = static_cast((mmbrMantissa << 1) + + ((measuredOH >> 8) & 0x01)); + rtcpbuffer[pos++] = static_cast(measuredOH); + numBoundingSet++; } - - // Report stats. - NACKStringBuilder stringBuilder; - for (int idx = 0; idx < i; ++idx) { - stringBuilder.PushNACK(nackList[idx]); - nack_stats_.ReportRequest(nackList[idx]); - } - *nackString = stringBuilder.GetResult(); - packet_type_counter_.nack_requests = nack_stats_.requests(); - packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests(); - return 0; + } + uint16_t length = static_cast(2 + 2 * numBoundingSet); + rtcpbuffer[posLength++] = static_cast(length >> 8); + rtcpbuffer[posLength] = static_cast(length); + return pos; } -int32_t RTCPSender::BuildBYE(uint8_t* rtcpbuffer, int& pos) { +int32_t RTCPSender::BuildAPP(uint8_t* rtcpbuffer, int32_t pos) { + // sanity + if (_appData == NULL) { + LOG(LS_WARNING) << "Failed to build app specific."; + return -1; + } + if (pos + 12 + _appLength >= IP_PACKET_SIZE) { + LOG(LS_WARNING) << "Failed to build app specific."; + return -2; + } + rtcpbuffer[pos++] = 0x80 + _appSubType; + + // Add APP ID + rtcpbuffer[pos++] = 204; + + uint16_t length = (_appLength >> 2) + 2; // include SSRC and name + rtcpbuffer[pos++] = static_cast(length >> 8); + rtcpbuffer[pos++] = static_cast(length); + + // Add our own SSRC + ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); + pos += 4; + + // Add our application name + ByteWriter::WriteBigEndian(rtcpbuffer + pos, _appName); + pos += 4; + + // Add the data + memcpy(rtcpbuffer + pos, _appData.get(), _appLength); + pos += _appLength; + return pos; +} + +int32_t RTCPSender::BuildNACK(uint8_t* rtcpbuffer, + int32_t pos, + int32_t nackSize, + const uint16_t* nackList, + std::string* nackString) { + // sanity + if (pos + 16 >= IP_PACKET_SIZE) { + LOG(LS_WARNING) << "Failed to build NACK."; + return -2; + } + + // int size, uint16_t* nackList + // add nack list + uint8_t FMT = 1; + rtcpbuffer[pos++] = 0x80 + FMT; + rtcpbuffer[pos++] = 205; + + rtcpbuffer[pos++] = 0; + int nackSizePos = pos; + rtcpbuffer[pos++] = 3; // setting it to one kNACK signal as default + + // Add our own SSRC + ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); + pos += 4; + + // Add the remote SSRC + ByteWriter::WriteBigEndian(rtcpbuffer + pos, _remoteSSRC); + pos += 4; + + // Build NACK bitmasks and write them to the RTCP message. + // The nack list should be sorted and not contain duplicates if one + // wants to build the smallest rtcp nack packet. + int numOfNackFields = 0; + int maxNackFields = + std::min(kRtcpMaxNackFields, (IP_PACKET_SIZE - pos) / 4); + int i = 0; + while (i < nackSize && numOfNackFields < maxNackFields) { + uint16_t nack = nackList[i++]; + uint16_t bitmask = 0; + while (i < nackSize) { + int shift = static_cast(nackList[i] - nack) - 1; + if (shift >= 0 && shift <= 15) { + bitmask |= (1 << shift); + ++i; + } else { + break; + } + } + // Write the sequence number and the bitmask to the packet. + assert(pos + 4 < IP_PACKET_SIZE); + ByteWriter::WriteBigEndian(rtcpbuffer + pos, nack); + pos += 2; + ByteWriter::WriteBigEndian(rtcpbuffer + pos, bitmask); + pos += 2; + numOfNackFields++; + } + rtcpbuffer[nackSizePos] = static_cast(2 + numOfNackFields); + + if (i != nackSize) + LOG(LS_WARNING) << "Nack list too large for one packet."; + + // Report stats. + NACKStringBuilder stringBuilder; + for (int idx = 0; idx < i; ++idx) { + stringBuilder.PushNACK(nackList[idx]); + nack_stats_.ReportRequest(nackList[idx]); + } + *nackString = stringBuilder.GetResult(); + packet_type_counter_.nack_requests = nack_stats_.requests(); + packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests(); + return pos; +} + +int32_t RTCPSender::BuildBYE(uint8_t* rtcpbuffer, int32_t pos) { // sanity if (pos + 8 >= IP_PACKET_SIZE) { return -2; @@ -1334,12 +1216,12 @@ int32_t RTCPSender::BuildBYE(uint8_t* rtcpbuffer, int& pos) { // Add a bye packet // Number of SSRC + CSRCs. - rtcpbuffer[pos++] = (uint8_t)0x80 + 1 + csrcs_.size(); - rtcpbuffer[pos++] = (uint8_t)203; + rtcpbuffer[pos++] = static_cast(0x80 + 1 + csrcs_.size()); + rtcpbuffer[pos++] = 203; // length - rtcpbuffer[pos++] = (uint8_t)0; - rtcpbuffer[pos++] = (uint8_t)(1 + csrcs_.size()); + rtcpbuffer[pos++] = 0; + rtcpbuffer[pos++] = static_cast(1 + csrcs_.size()); // Add our own SSRC ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); @@ -1351,21 +1233,19 @@ int32_t RTCPSender::BuildBYE(uint8_t* rtcpbuffer, int& pos) { pos += 4; } - return 0; + return pos; } int32_t RTCPSender::BuildReceiverReferenceTime(uint8_t* buffer, - int& pos, + int32_t pos, uint32_t ntp_sec, uint32_t ntp_frac) { const int kRrTimeBlockLength = 20; - if (pos + kRrTimeBlockLength >= IP_PACKET_SIZE) { + if (pos + kRrTimeBlockLength >= IP_PACKET_SIZE) return -2; - } - if (last_xr_rr_.size() >= RTCP_NUMBER_OF_SR) { + if (last_xr_rr_.size() >= RTCP_NUMBER_OF_SR) last_xr_rr_.erase(last_xr_rr_.begin()); - } last_xr_rr_.insert(std::pair( RTCPUtility::MidNtp(ntp_sec, ntp_frac), Clock::NtpToMs(ntp_sec, ntp_frac))); @@ -1402,16 +1282,15 @@ int32_t RTCPSender::BuildReceiverReferenceTime(uint8_t* buffer, ByteWriter::WriteBigEndian(buffer + pos, ntp_frac); pos += 4; - return 0; + return pos; } int32_t RTCPSender::BuildDlrr(uint8_t* buffer, - int& pos, + int32_t pos, const RtcpReceiveTimeInfo& info) { const int kDlrrBlockLength = 24; - if (pos + kDlrrBlockLength >= IP_PACKET_SIZE) { + if (pos + kDlrrBlockLength >= IP_PACKET_SIZE) return -2; - } // Add XR header. buffer[pos++] = 0x80; @@ -1452,80 +1331,76 @@ int32_t RTCPSender::BuildDlrr(uint8_t* buffer, ByteWriter::WriteBigEndian(buffer + pos, info.delaySinceLastRR); pos += 4; - return 0; + return pos; } -int32_t -RTCPSender::BuildVoIPMetric(uint8_t* rtcpbuffer, int& pos) -{ - // sanity - if(pos + 44 >= IP_PACKET_SIZE) - { - return -2; - } +int32_t RTCPSender::BuildVoIPMetric(uint8_t* rtcpbuffer, int32_t pos) { + // sanity + if (pos + 44 >= IP_PACKET_SIZE) + return -2; - // Add XR header - rtcpbuffer[pos++]=(uint8_t)0x80; - rtcpbuffer[pos++]=(uint8_t)207; + // Add XR header + rtcpbuffer[pos++] = 0x80; + rtcpbuffer[pos++] = 207; - uint32_t XRLengthPos = pos; + uint32_t XRLengthPos = pos; - // handle length later on - pos++; - pos++; + // handle length later on + pos++; + pos++; - // Add our own SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); - pos += 4; + // Add our own SSRC + ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); + pos += 4; - // Add a VoIP metrics block - rtcpbuffer[pos++]=7; - rtcpbuffer[pos++]=0; - rtcpbuffer[pos++]=0; - rtcpbuffer[pos++]=8; + // Add a VoIP metrics block + rtcpbuffer[pos++] = 7; + rtcpbuffer[pos++] = 0; + rtcpbuffer[pos++] = 0; + rtcpbuffer[pos++] = 8; - // Add the remote SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _remoteSSRC); - pos += 4; + // Add the remote SSRC + ByteWriter::WriteBigEndian(rtcpbuffer + pos, _remoteSSRC); + pos += 4; - rtcpbuffer[pos++] = _xrVoIPMetric.lossRate; - rtcpbuffer[pos++] = _xrVoIPMetric.discardRate; - rtcpbuffer[pos++] = _xrVoIPMetric.burstDensity; - rtcpbuffer[pos++] = _xrVoIPMetric.gapDensity; + rtcpbuffer[pos++] = _xrVoIPMetric.lossRate; + rtcpbuffer[pos++] = _xrVoIPMetric.discardRate; + rtcpbuffer[pos++] = _xrVoIPMetric.burstDensity; + rtcpbuffer[pos++] = _xrVoIPMetric.gapDensity; - rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.burstDuration >> 8); - rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.burstDuration); - rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.gapDuration >> 8); - rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.gapDuration); + rtcpbuffer[pos++] = static_cast(_xrVoIPMetric.burstDuration >> 8); + rtcpbuffer[pos++] = static_cast(_xrVoIPMetric.burstDuration); + rtcpbuffer[pos++] = static_cast(_xrVoIPMetric.gapDuration >> 8); + rtcpbuffer[pos++] = static_cast(_xrVoIPMetric.gapDuration); - rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.roundTripDelay >> 8); - rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.roundTripDelay); - rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.endSystemDelay >> 8); - rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.endSystemDelay); + rtcpbuffer[pos++] = static_cast(_xrVoIPMetric.roundTripDelay >> 8); + rtcpbuffer[pos++] = static_cast(_xrVoIPMetric.roundTripDelay); + rtcpbuffer[pos++] = static_cast(_xrVoIPMetric.endSystemDelay >> 8); + rtcpbuffer[pos++] = static_cast(_xrVoIPMetric.endSystemDelay); - rtcpbuffer[pos++] = _xrVoIPMetric.signalLevel; - rtcpbuffer[pos++] = _xrVoIPMetric.noiseLevel; - rtcpbuffer[pos++] = _xrVoIPMetric.RERL; - rtcpbuffer[pos++] = _xrVoIPMetric.Gmin; + rtcpbuffer[pos++] = _xrVoIPMetric.signalLevel; + rtcpbuffer[pos++] = _xrVoIPMetric.noiseLevel; + rtcpbuffer[pos++] = _xrVoIPMetric.RERL; + rtcpbuffer[pos++] = _xrVoIPMetric.Gmin; - rtcpbuffer[pos++] = _xrVoIPMetric.Rfactor; - rtcpbuffer[pos++] = _xrVoIPMetric.extRfactor; - rtcpbuffer[pos++] = _xrVoIPMetric.MOSLQ; - rtcpbuffer[pos++] = _xrVoIPMetric.MOSCQ; + rtcpbuffer[pos++] = _xrVoIPMetric.Rfactor; + rtcpbuffer[pos++] = _xrVoIPMetric.extRfactor; + rtcpbuffer[pos++] = _xrVoIPMetric.MOSLQ; + rtcpbuffer[pos++] = _xrVoIPMetric.MOSCQ; - rtcpbuffer[pos++] = _xrVoIPMetric.RXconfig; - rtcpbuffer[pos++] = 0; // reserved - rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBnominal >> 8); - rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBnominal); + rtcpbuffer[pos++] = _xrVoIPMetric.RXconfig; + rtcpbuffer[pos++] = 0; // reserved + rtcpbuffer[pos++] = static_cast(_xrVoIPMetric.JBnominal >> 8); + rtcpbuffer[pos++] = static_cast(_xrVoIPMetric.JBnominal); - rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBmax >> 8); - rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBmax); - rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBabsMax >> 8); - rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBabsMax); + rtcpbuffer[pos++] = static_cast(_xrVoIPMetric.JBmax >> 8); + rtcpbuffer[pos++] = static_cast(_xrVoIPMetric.JBmax); + rtcpbuffer[pos++] = static_cast(_xrVoIPMetric.JBabsMax >> 8); + rtcpbuffer[pos++] = static_cast(_xrVoIPMetric.JBabsMax); - rtcpbuffer[XRLengthPos]=(uint8_t)(0); - rtcpbuffer[XRLengthPos+1]=(uint8_t)(10); - return 0; + rtcpbuffer[XRLengthPos] = 0; + rtcpbuffer[XRLengthPos + 1] = 10; + return pos; } int32_t RTCPSender::SendRTCP(const FeedbackState& feedback_state, @@ -1535,11 +1410,10 @@ int32_t RTCPSender::SendRTCP(const FeedbackState& feedback_state, bool repeat, uint64_t pictureID) { { - CriticalSectionScoped lock(_criticalSectionRTCPSender); - if(_method == kRtcpOff) - { - LOG(LS_WARNING) << "Can't send rtcp if it is disabled."; - return -1; + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); + if (_method == kRtcpOff) { + LOG(LS_WARNING) << "Can't send rtcp if it is disabled."; + return -1; } } uint8_t rtcp_buffer[IP_PACKET_SIZE]; @@ -1551,14 +1425,13 @@ int32_t RTCPSender::SendRTCP(const FeedbackState& feedback_state, pictureID, rtcp_buffer, IP_PACKET_SIZE); - if (rtcp_length < 0) { + if (rtcp_length < 0) return -1; - } + // Sanity don't send empty packets. if (rtcp_length == 0) - { return -1; - } + return SendToNetwork(rtcp_buffer, static_cast(rtcp_length)); } @@ -1577,99 +1450,76 @@ int RTCPSender::PrepareRTCP(const FeedbackState& feedback_state, uint32_t jitterTransmissionOffset = 0; int position = 0; - CriticalSectionScoped lock(_criticalSectionRTCPSender); + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - if (packet_type_counter_.first_packet_time_ms == -1) { + if (packet_type_counter_.first_packet_time_ms == -1) packet_type_counter_.first_packet_time_ms = _clock->TimeInMilliseconds(); + + // Attach TMMBR to send and receive reports. + if (_TMMBR) + rtcpPacketTypeFlags |= kRtcpTmmbr; + if (_appSend) { + rtcpPacketTypeFlags |= kRtcpApp; + _appSend = false; } - if(_TMMBR ) // Attach TMMBR to send and receive reports. - { - rtcpPacketTypeFlags |= kRtcpTmmbr; + if (_REMB && _sendREMB) { + // Always attach REMB to SR if that is configured. Note that REMB is + // only sent on one of the RTP modules in the REMB group. + rtcpPacketTypeFlags |= kRtcpRemb; } - if(_appSend) - { - rtcpPacketTypeFlags |= kRtcpApp; - _appSend = false; - } - if(_REMB && _sendREMB) - { - // Always attach REMB to SR if that is configured. Note that REMB is - // only sent on one of the RTP modules in the REMB group. - rtcpPacketTypeFlags |= kRtcpRemb; - } - if(_xrSendVoIPMetric) - { + if (_xrSendVoIPMetric) { rtcpPacketTypeFlags |= kRtcpXrVoipMetric; _xrSendVoIPMetric = false; } - if(_sendTMMBN) // Set when having received a TMMBR. - { - rtcpPacketTypeFlags |= kRtcpTmmbn; - _sendTMMBN = false; + // Set when having received a TMMBR. + if (_sendTMMBN) { + rtcpPacketTypeFlags |= kRtcpTmmbn; + _sendTMMBN = false; } - if (rtcpPacketTypeFlags & kRtcpReport) - { - if (xrSendReceiverReferenceTimeEnabled_ && !_sending) - { - rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime; - } - if (feedback_state.has_last_xr_rr) - { - rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock; - } + if (rtcpPacketTypeFlags & kRtcpReport) { + if (xrSendReceiverReferenceTimeEnabled_ && !_sending) + rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime; + if (feedback_state.has_last_xr_rr) + rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock; } - if(_method == kRtcpCompound) - { - if(_sending) - { - rtcpPacketTypeFlags |= kRtcpSr; - } else - { - rtcpPacketTypeFlags |= kRtcpRr; - } - } else if(_method == kRtcpNonCompound) - { - if(rtcpPacketTypeFlags & kRtcpReport) - { - if(_sending) - { - rtcpPacketTypeFlags |= kRtcpSr; - } else - { - rtcpPacketTypeFlags |= kRtcpRr; - } + if (_method == kRtcpCompound) { + if (_sending) { + rtcpPacketTypeFlags |= kRtcpSr; + } else { + rtcpPacketTypeFlags |= kRtcpRr; + } + } else if (_method == kRtcpNonCompound) { + if (rtcpPacketTypeFlags & kRtcpReport) { + if (_sending) { + rtcpPacketTypeFlags |= kRtcpSr; + } else { + rtcpPacketTypeFlags |= kRtcpRr; } + } } - if( rtcpPacketTypeFlags & kRtcpRr || - rtcpPacketTypeFlags & kRtcpSr) - { - // generate next time to send a RTCP report - // seeded from RTP constructor - int32_t random = rand() % 1000; - int32_t timeToNext = RTCP_INTERVAL_AUDIO_MS; + if ((rtcpPacketTypeFlags & kRtcpRr) || (rtcpPacketTypeFlags & kRtcpSr)) { + // generate next time to send a RTCP report + // seeded from RTP constructor + int32_t random = rand() % 1000; + int32_t timeToNext = RTCP_INTERVAL_AUDIO_MS; - if(_audio) - { - timeToNext = (RTCP_INTERVAL_AUDIO_MS/2) + - (RTCP_INTERVAL_AUDIO_MS*random/1000); - }else - { - uint32_t minIntervalMs = RTCP_INTERVAL_AUDIO_MS; - if(_sending) - { - // Calculate bandwidth for video; 360 / send bandwidth in kbit/s. - uint32_t send_bitrate_kbit = feedback_state.send_bitrate / 1000; - if (send_bitrate_kbit != 0) - minIntervalMs = 360000 / send_bitrate_kbit; - } - if(minIntervalMs > RTCP_INTERVAL_VIDEO_MS) - { - minIntervalMs = RTCP_INTERVAL_VIDEO_MS; - } - timeToNext = (minIntervalMs/2) + (minIntervalMs*random/1000); + if (_audio) { + timeToNext = (RTCP_INTERVAL_AUDIO_MS / 2) + + (RTCP_INTERVAL_AUDIO_MS * random / 1000); + } else { + uint32_t minIntervalMs = RTCP_INTERVAL_AUDIO_MS; + if (_sending) { + // Calculate bandwidth for video; 360 / send bandwidth in kbit/s. + uint32_t send_bitrate_kbit = feedback_state.send_bitrate / 1000; + if (send_bitrate_kbit != 0) + minIntervalMs = 360000 / send_bitrate_kbit; } - _nextTimeToSendRTCP = _clock->TimeInMilliseconds() + timeToNext; + if (minIntervalMs > RTCP_INTERVAL_VIDEO_MS) + minIntervalMs = RTCP_INTERVAL_VIDEO_MS; + timeToNext = (minIntervalMs / 2) + (minIntervalMs * random / 1000); + } + _nextTimeToSendRTCP = _clock->TimeInMilliseconds() + timeToNext; } // If the data does not fit in the packet we fill it as much as possible. @@ -1681,212 +1531,232 @@ int RTCPSender::PrepareRTCP(const FeedbackState& feedback_state, StatisticianMap statisticians = receive_statistics_->GetActiveStatisticians(); if (!statisticians.empty()) { - StatisticianMap::const_iterator it; - int i; - for (it = statisticians.begin(), i = 0; it != statisticians.end(); - ++it, ++i) { + for (auto it = statisticians.begin(); it != statisticians.end(); ++it) { RTCPReportBlock report_block; - if (PrepareReport( - feedback_state, it->second, &report_block, &NTPsec, &NTPfrac)) + if (PrepareReport(feedback_state, it->second, &report_block, &NTPsec, + &NTPfrac)) { AddReportBlock(it->first, &internal_report_blocks_, &report_block); + } } - if (_IJ && !statisticians.empty()) { + if (_IJ && !statisticians.empty()) rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset; - } } } - if(rtcpPacketTypeFlags & kRtcpSr) - { + if (rtcpPacketTypeFlags & kRtcpSr) { buildVal = BuildSR(feedback_state, rtcp_buffer, position, NTPsec, NTPfrac); - if (buildVal == -1) { + switch (buildVal) { + case -1: return -1; - } else if (buildVal == -2) { + case -2: return position; - } - buildVal = BuildSDEC(rtcp_buffer, position); - if (buildVal == -1) { + default: + position = buildVal; + } + buildVal = BuildSDEC(rtcp_buffer, position); + switch (buildVal) { + case -1: return -1; - } else if (buildVal == -2) { + case -2: return position; - } - }else if(rtcpPacketTypeFlags & kRtcpRr) - { - buildVal = BuildRR(rtcp_buffer, position, NTPsec, NTPfrac); - if (buildVal == -1) { + default: + position = buildVal; + } + } else if (rtcpPacketTypeFlags & kRtcpRr) { + buildVal = BuildRR(rtcp_buffer, position, NTPsec, NTPfrac); + switch (buildVal) { + case -1: return -1; - } else if (buildVal == -2) { + case -2: return position; - } - // only of set - if(_CNAME[0] != 0) - { - buildVal = BuildSDEC(rtcp_buffer, position); - if (buildVal == -1) { - return -1; - } - } + default: + position = buildVal; + } + // only of set + if (_CNAME[0] != 0) { + if (BuildSDEC(rtcp_buffer, position) == -1) + return -1; + } } - if(rtcpPacketTypeFlags & kRtcpTransmissionTimeOffset) - { - // If present, this RTCP packet must be placed after a - // receiver report. - buildVal = BuildExtendedJitterReport(rtcp_buffer, - position, - jitterTransmissionOffset); - if (buildVal == -1) { + if (rtcpPacketTypeFlags & kRtcpTransmissionTimeOffset) { + // If present, this RTCP packet must be placed after a + // receiver report. + buildVal = BuildExtendedJitterReport(rtcp_buffer, position, + jitterTransmissionOffset); + switch (buildVal) { + case -1: return -1; - } else if (buildVal == -2) { + case -2: return position; - } + default: + position = buildVal; + } } - if(rtcpPacketTypeFlags & kRtcpPli) - { - buildVal = BuildPLI(rtcp_buffer, position); - if (buildVal == -1) { + if (rtcpPacketTypeFlags & kRtcpPli) { + buildVal = BuildPLI(rtcp_buffer, position); + switch (buildVal) { + case -1: return -1; - } else if (buildVal == -2) { + case -2: return position; - } - TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), - "RTCPSender::PLI"); - ++packet_type_counter_.pli_packets; - TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), - "RTCP_PLICount", _SSRC, - packet_type_counter_.pli_packets); + default: + position = buildVal; + } + TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), + "RTCPSender::PLI"); + ++packet_type_counter_.pli_packets; + TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_PLICount", + _SSRC, packet_type_counter_.pli_packets); } - if(rtcpPacketTypeFlags & kRtcpFir) - { - buildVal = BuildFIR(rtcp_buffer, position, repeat); - if (buildVal == -1) { + if (rtcpPacketTypeFlags & kRtcpFir) { + buildVal = BuildFIR(rtcp_buffer, position, repeat); + switch (buildVal) { + case -1: return -1; - } else if (buildVal == -2) { + case -2: return position; - } - TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), - "RTCPSender::FIR"); - ++packet_type_counter_.fir_packets; - TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), - "RTCP_FIRCount", _SSRC, - packet_type_counter_.fir_packets); + default: + position = buildVal; + } + TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), + "RTCPSender::FIR"); + ++packet_type_counter_.fir_packets; + TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_FIRCount", + _SSRC, packet_type_counter_.fir_packets); } - if(rtcpPacketTypeFlags & kRtcpSli) - { - buildVal = BuildSLI(rtcp_buffer, position, (uint8_t)pictureID); - if (buildVal == -1) { + if (rtcpPacketTypeFlags & kRtcpSli) { + buildVal = BuildSLI(rtcp_buffer, position, pictureID); + switch (buildVal) { + case -1: return -1; - } else if (buildVal == -2) { + case -2: return position; - } + default: + position = buildVal; + } } - if(rtcpPacketTypeFlags & kRtcpRpsi) - { - const int8_t payloadType = feedback_state.send_payload_type; - if (payloadType == -1) { + if (rtcpPacketTypeFlags & kRtcpRpsi) { + const int8_t payloadType = feedback_state.send_payload_type; + if (payloadType == -1) + return -1; + buildVal = BuildRPSI(rtcp_buffer, position, pictureID, payloadType); + switch (buildVal) { + case -1: return -1; - } - buildVal = BuildRPSI(rtcp_buffer, position, pictureID, - (uint8_t)payloadType); - if (buildVal == -1) { - return -1; - } else if (buildVal == -2) { + case -2: return position; - } + default: + position = buildVal; + } } - if(rtcpPacketTypeFlags & kRtcpRemb) - { - buildVal = BuildREMB(rtcp_buffer, position); - if (buildVal == -1) { + if (rtcpPacketTypeFlags & kRtcpRemb) { + buildVal = BuildREMB(rtcp_buffer, position); + switch (buildVal) { + case -1: return -1; - } else if (buildVal == -2) { + case -2: return position; - } - TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), - "RTCPSender::REMB"); + default: + position = buildVal; + } + TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), + "RTCPSender::REMB"); } - if(rtcpPacketTypeFlags & kRtcpBye) - { - buildVal = BuildBYE(rtcp_buffer, position); - if (buildVal == -1) { + if (rtcpPacketTypeFlags & kRtcpBye) { + buildVal = BuildBYE(rtcp_buffer, position); + switch (buildVal) { + case -1: return -1; - } else if (buildVal == -2) { + case -2: return position; - } + default: + position = buildVal; + } } - if(rtcpPacketTypeFlags & kRtcpApp) - { - buildVal = BuildAPP(rtcp_buffer, position); - if (buildVal == -1) { + if (rtcpPacketTypeFlags & kRtcpApp) { + buildVal = BuildAPP(rtcp_buffer, position); + switch (buildVal) { + case -1: return -1; - } else if (buildVal == -2) { + case -2: return position; - } + default: + position = buildVal; + } } - if(rtcpPacketTypeFlags & kRtcpTmmbr) - { - buildVal = BuildTMMBR(feedback_state.module, rtcp_buffer, position); - if (buildVal == -1) { + if (rtcpPacketTypeFlags & kRtcpTmmbr) { + switch (buildVal = + BuildTMMBR(feedback_state.module, rtcp_buffer, position)) { + case -1: return -1; - } else if (buildVal == -2) { + case -2: return position; - } + default: + position = buildVal; + } } - if(rtcpPacketTypeFlags & kRtcpTmmbn) - { - buildVal = BuildTMMBN(rtcp_buffer, position); - if (buildVal == -1) { + if (rtcpPacketTypeFlags & kRtcpTmmbn) { + buildVal = BuildTMMBN(rtcp_buffer, position); + switch (buildVal) { + case -1: return -1; - } else if (buildVal == -2) { + case -2: return position; - } + default: + position = buildVal; + } } - if(rtcpPacketTypeFlags & kRtcpNack) - { - std::string nackString; - buildVal = BuildNACK(rtcp_buffer, position, nackSize, nackList, - &nackString); - if (buildVal == -1) { + if (rtcpPacketTypeFlags & kRtcpNack) { + std::string nackString; + switch (buildVal = BuildNACK(rtcp_buffer, position, nackSize, nackList, + &nackString)) { + case -1: return -1; - } else if (buildVal == -2) { + case -2: return position; - } - TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), - "RTCPSender::NACK", "nacks", - TRACE_STR_COPY(nackString.c_str())); - ++packet_type_counter_.nack_packets; - TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), - "RTCP_NACKCount", _SSRC, - packet_type_counter_.nack_packets); + default: + position = buildVal; + } + TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), + "RTCPSender::NACK", "nacks", + TRACE_STR_COPY(nackString.c_str())); + ++packet_type_counter_.nack_packets; + TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_NACKCount", + _SSRC, packet_type_counter_.nack_packets); } - if(rtcpPacketTypeFlags & kRtcpXrVoipMetric) - { - buildVal = BuildVoIPMetric(rtcp_buffer, position); - if (buildVal == -1) { + if (rtcpPacketTypeFlags & kRtcpXrVoipMetric) { + buildVal = BuildVoIPMetric(rtcp_buffer, position); + switch (buildVal) { + case -1: return -1; - } else if (buildVal == -2) { + case -2: return position; - } + default: + position = buildVal; + } } - if (rtcpPacketTypeFlags & kRtcpXrReceiverReferenceTime) - { - buildVal = BuildReceiverReferenceTime(rtcp_buffer, - position, - NTPsec, - NTPfrac); - if (buildVal == -1) { + if (rtcpPacketTypeFlags & kRtcpXrReceiverReferenceTime) { + buildVal = + BuildReceiverReferenceTime(rtcp_buffer, position, NTPsec, NTPfrac); + switch (buildVal) { + case -1: return -1; - } else if (buildVal == -2) { + case -2: return position; - } + default: + position = buildVal; + } } - if (rtcpPacketTypeFlags & kRtcpXrDlrrReportBlock) - { - buildVal = BuildDlrr(rtcp_buffer, position, feedback_state.last_xr_rr); - if (buildVal == -1) { + if (rtcpPacketTypeFlags & kRtcpXrDlrrReportBlock) { + switch (buildVal = + BuildDlrr(rtcp_buffer, position, feedback_state.last_xr_rr)) { + case -1: return -1; - } else if (buildVal == -2) { + case -2: return position; - } + default: + position = buildVal; + } } if (packet_type_counter_observer_ != NULL) { @@ -1926,13 +1796,13 @@ bool RTCPSender::PrepareReport(const FeedbackState& feedback_state, if ((feedback_state.last_rr_ntp_secs != 0) || (feedback_state.last_rr_ntp_frac != 0)) { // get the 16 lowest bits of seconds and the 16 higest bits of fractions - uint32_t now=*ntp_secs&0x0000FFFF; - now <<=16; - now += (*ntp_frac&0xffff0000)>>16; + uint32_t now = *ntp_secs & 0x0000FFFF; + now <<= 16; + now += (*ntp_frac & 0xffff0000) >> 16; - uint32_t receiveTime = feedback_state.last_rr_ntp_secs&0x0000FFFF; - receiveTime <<=16; - receiveTime += (feedback_state.last_rr_ntp_frac&0xffff0000)>>16; + uint32_t receiveTime = feedback_state.last_rr_ntp_secs & 0x0000FFFF; + receiveTime <<= 16; + receiveTime += (feedback_state.last_rr_ntp_frac & 0xffff0000) >> 16; delaySinceLastReceivedSR = now-receiveTime; } @@ -1942,20 +1812,17 @@ bool RTCPSender::PrepareReport(const FeedbackState& feedback_state, } int32_t RTCPSender::SendToNetwork(const uint8_t* dataBuffer, size_t length) { - CriticalSectionScoped lock(_criticalSectionTransport); - if(_cbTransport) - { - if(_cbTransport->SendRTCPPacket(_id, dataBuffer, length) > 0) - { - return 0; - } - } - return -1; + CriticalSectionScoped lock(_criticalSectionTransport.get()); + if (_cbTransport) { + if (_cbTransport->SendRTCPPacket(_id, dataBuffer, length) > 0) + return 0; + } + return -1; } void RTCPSender::SetCsrcs(const std::vector& csrcs) { assert(csrcs.size() <= kRtpCsrcSize); - CriticalSectionScoped lock(_criticalSectionRTCPSender); + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); csrcs_ = csrcs; } @@ -1963,56 +1830,48 @@ int32_t RTCPSender::SetApplicationSpecificData(uint8_t subType, uint32_t name, const uint8_t* data, uint16_t length) { - if(length %4 != 0) - { - LOG(LS_ERROR) << "Failed to SetApplicationSpecificData."; - return -1; - } - CriticalSectionScoped lock(_criticalSectionRTCPSender); + if (length % 4 != 0) { + LOG(LS_ERROR) << "Failed to SetApplicationSpecificData."; + return -1; + } + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - if(_appData) - { - delete [] _appData; - } - - _appSend = true; - _appSubType = subType; - _appName = name; - _appData = new uint8_t[length]; - _appLength = length; - memcpy(_appData, data, length); - return 0; + _appSend = true; + _appSubType = subType; + _appName = name; + _appData.reset(new uint8_t[length]); + _appLength = length; + memcpy(_appData.get(), data, length); + return 0; } -int32_t -RTCPSender::SetRTCPVoIPMetrics(const RTCPVoIPMetric* VoIPMetric) -{ - CriticalSectionScoped lock(_criticalSectionRTCPSender); - memcpy(&_xrVoIPMetric, VoIPMetric, sizeof(RTCPVoIPMetric)); +int32_t RTCPSender::SetRTCPVoIPMetrics(const RTCPVoIPMetric* VoIPMetric) { + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); + memcpy(&_xrVoIPMetric, VoIPMetric, sizeof(RTCPVoIPMetric)); - _xrSendVoIPMetric = true; - return 0; + _xrSendVoIPMetric = true; + return 0; } void RTCPSender::SendRtcpXrReceiverReferenceTime(bool enable) { - CriticalSectionScoped lock(_criticalSectionRTCPSender); + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); xrSendReceiverReferenceTimeEnabled_ = enable; } bool RTCPSender::RtcpXrReceiverReferenceTime() const { - CriticalSectionScoped lock(_criticalSectionRTCPSender); + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); return xrSendReceiverReferenceTimeEnabled_; } // called under critsect _criticalSectionRTCPSender int32_t RTCPSender::WriteAllReportBlocksToBuffer(uint8_t* rtcpbuffer, int pos, - uint8_t& numberOfReportBlocks, + uint8_t* numberOfReportBlocks, uint32_t NTPsec, uint32_t NTPfrac) { - numberOfReportBlocks = external_report_blocks_.size(); - numberOfReportBlocks += internal_report_blocks_.size(); - if ((pos + numberOfReportBlocks * 24) >= IP_PACKET_SIZE) { + *numberOfReportBlocks = external_report_blocks_.size(); + *numberOfReportBlocks += internal_report_blocks_.size(); + if ((pos + *numberOfReportBlocks * 24) >= IP_PACKET_SIZE) { LOG(LS_WARNING) << "Can't fit all report blocks."; return -1; } @@ -2072,13 +1931,13 @@ int32_t RTCPSender::WriteReportBlocksToBuffer( // no callbacks allowed inside this function int32_t RTCPSender::SetTMMBN(const TMMBRSet* boundingSet, uint32_t maxBitrateKbit) { - CriticalSectionScoped lock(_criticalSectionRTCPSender); + CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - if (0 == _tmmbrHelp.SetTMMBRBoundingSetToSend(boundingSet, maxBitrateKbit)) - { - _sendTMMBN = true; - return 0; - } - return -1; + if (0 == _tmmbrHelp.SetTMMBRBoundingSetToSend(boundingSet, maxBitrateKbit)) { + _sendTMMBN = true; + return 0; + } + return -1; } + } // namespace webrtc diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender.h b/webrtc/modules/rtp_rtcp/source/rtcp_sender.h index 6722ea2b00..dbdee0c126 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.h +++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.h @@ -67,284 +67,264 @@ public: // Used when generating TMMBR. ModuleRtpRtcpImpl* module; }; + RTCPSender(int32_t id, bool audio, Clock* clock, ReceiveStatistics* receive_statistics, RtcpPacketTypeCounterObserver* packet_type_counter_observer); - virtual ~RTCPSender(); + virtual ~RTCPSender(); - int32_t RegisterSendTransport(Transport* outgoingTransport); + int32_t RegisterSendTransport(Transport* outgoingTransport); - RTCPMethod Status() const; - void SetRTCPStatus(RTCPMethod method); + RTCPMethod Status() const; + void SetRTCPStatus(RTCPMethod method); - bool Sending() const; - int32_t SetSendingStatus(const FeedbackState& feedback_state, - bool enabled); // combine the functions + bool Sending() const; + int32_t SetSendingStatus(const FeedbackState& feedback_state, + bool enabled); // combine the functions - int32_t SetNackStatus(bool enable); + int32_t SetNackStatus(bool enable); - void SetStartTimestamp(uint32_t start_timestamp); + void SetStartTimestamp(uint32_t start_timestamp); - void SetLastRtpTime(uint32_t rtp_timestamp, - int64_t capture_time_ms); + void SetLastRtpTime(uint32_t rtp_timestamp, int64_t capture_time_ms); - void SetSSRC(uint32_t ssrc); + void SetSSRC(uint32_t ssrc); - void SetRemoteSSRC(uint32_t ssrc); + void SetRemoteSSRC(uint32_t ssrc); - int32_t SetCNAME(const char cName[RTCP_CNAME_SIZE]); + int32_t SetCNAME(const char cName[RTCP_CNAME_SIZE]); - int32_t AddMixedCNAME(uint32_t SSRC, const char cName[RTCP_CNAME_SIZE]); + int32_t AddMixedCNAME(uint32_t SSRC, const char cName[RTCP_CNAME_SIZE]); - int32_t RemoveMixedCNAME(uint32_t SSRC); + int32_t RemoveMixedCNAME(uint32_t SSRC); - int64_t SendTimeOfSendReport(uint32_t sendReport); + int64_t SendTimeOfSendReport(uint32_t sendReport); - bool SendTimeOfXrRrReport(uint32_t mid_ntp, int64_t* time_ms) const; + bool SendTimeOfXrRrReport(uint32_t mid_ntp, int64_t* time_ms) const; - bool TimeToSendRTCPReport(bool sendKeyframeBeforeRTP = false) const; + bool TimeToSendRTCPReport(bool sendKeyframeBeforeRTP = false) const; - uint32_t LastSendReport(int64_t& lastRTCPTime); + int32_t SendRTCP(const FeedbackState& feedback_state, + uint32_t rtcpPacketTypeFlags, + int32_t nackSize = 0, + const uint16_t* nackList = 0, + bool repeat = false, + uint64_t pictureID = 0); - int32_t SendRTCP( - const FeedbackState& feedback_state, - uint32_t rtcpPacketTypeFlags, - int32_t nackSize = 0, - const uint16_t* nackList = 0, - bool repeat = false, - uint64_t pictureID = 0); + int32_t AddExternalReportBlock(uint32_t SSRC, + const RTCPReportBlock* receiveBlock); - int32_t AddExternalReportBlock( - uint32_t SSRC, - const RTCPReportBlock* receiveBlock); + int32_t RemoveExternalReportBlock(uint32_t SSRC); - int32_t RemoveExternalReportBlock(uint32_t SSRC); + bool REMB() const; - /* - * REMB - */ - bool REMB() const; + void SetREMBStatus(bool enable); - void SetREMBStatus(bool enable); + void SetREMBData(uint32_t bitrate, const std::vector& ssrcs); - void SetREMBData(uint32_t bitrate, const std::vector& ssrcs); + bool TMMBR() const; - /* - * TMMBR - */ - bool TMMBR() const; + void SetTMMBRStatus(bool enable); - void SetTMMBRStatus(bool enable); + int32_t SetTMMBN(const TMMBRSet* boundingSet, uint32_t maxBitrateKbit); - int32_t SetTMMBN(const TMMBRSet* boundingSet, uint32_t maxBitrateKbit); + // Extended jitter report + bool IJ() const; - /* - * Extended jitter report - */ - bool IJ() const; + void SetIJStatus(bool enable); - void SetIJStatus(bool enable); + int32_t SetApplicationSpecificData(uint8_t subType, + uint32_t name, + const uint8_t* data, + uint16_t length); + int32_t SetRTCPVoIPMetrics(const RTCPVoIPMetric* VoIPMetric); - /* - * - */ + void SendRtcpXrReceiverReferenceTime(bool enable); - int32_t SetApplicationSpecificData(uint8_t subType, - uint32_t name, - const uint8_t* data, - uint16_t length); + bool RtcpXrReceiverReferenceTime() const; - int32_t SetRTCPVoIPMetrics(const RTCPVoIPMetric* VoIPMetric); + void SetCsrcs(const std::vector& csrcs); - void SendRtcpXrReceiverReferenceTime(bool enable); - - bool RtcpXrReceiverReferenceTime() const; - - void SetCsrcs(const std::vector& csrcs); - - void SetTargetBitrate(unsigned int target_bitrate); + void SetTargetBitrate(unsigned int target_bitrate); private: int32_t SendToNetwork(const uint8_t* dataBuffer, size_t length); int32_t WriteAllReportBlocksToBuffer(uint8_t* rtcpbuffer, int pos, - uint8_t& numberOfReportBlocks, + uint8_t* numberOfReportBlocks, uint32_t NTPsec, uint32_t NTPfrac) EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); - int32_t WriteReportBlocksToBuffer( - uint8_t* rtcpbuffer, - int32_t position, - const std::map& report_blocks); + int32_t WriteReportBlocksToBuffer( + uint8_t* rtcpbuffer, + int32_t position, + const std::map& report_blocks); - int32_t AddReportBlock( - uint32_t SSRC, - std::map* report_blocks, - const RTCPReportBlock* receiveBlock); + int32_t AddReportBlock(uint32_t SSRC, + std::map* report_blocks, + const RTCPReportBlock* receiveBlock); - bool PrepareReport(const FeedbackState& feedback_state, - StreamStatistician* statistician, - RTCPReportBlock* report_block, - uint32_t* ntp_secs, uint32_t* ntp_frac); + bool PrepareReport(const FeedbackState& feedback_state, + StreamStatistician* statistician, + RTCPReportBlock* report_block, + uint32_t* ntp_secs, + uint32_t* ntp_frac); - int32_t BuildSR(const FeedbackState& feedback_state, - uint8_t* rtcpbuffer, - int& pos, - uint32_t NTPsec, - uint32_t NTPfrac) - EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildSR(const FeedbackState& feedback_state, + uint8_t* rtcpbuffer, + int32_t pos, + uint32_t NTPsec, + uint32_t NTPfrac) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); - int32_t BuildRR(uint8_t* rtcpbuffer, - int& pos, - uint32_t NTPsec, - uint32_t NTPfrac) - EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildRR(uint8_t* rtcpbuffer, + int32_t pos, + uint32_t NTPsec, + uint32_t NTPfrac) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); - int PrepareRTCP( - const FeedbackState& feedback_state, - uint32_t packetTypeFlags, - int32_t nackSize, - const uint16_t* nackList, - bool repeat, - uint64_t pictureID, - uint8_t* rtcp_buffer, - int buffer_size); + int PrepareRTCP(const FeedbackState& feedback_state, + uint32_t packetTypeFlags, + int32_t nackSize, + const uint16_t* nackList, + bool repeat, + uint64_t pictureID, + uint8_t* rtcp_buffer, + int buffer_size); - bool ShouldSendReportBlocks(uint32_t rtcp_packet_type) const; + bool ShouldSendReportBlocks(uint32_t rtcp_packet_type) const; - int32_t BuildExtendedJitterReport(uint8_t* rtcpbuffer, - int& pos, - uint32_t jitterTransmissionTimeOffset) - EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildExtendedJitterReport(uint8_t* rtcpbuffer, + int32_t pos, + uint32_t jitterTransmissionTimeOffset) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); - int32_t BuildSDEC(uint8_t* rtcpbuffer, int& pos) - EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); - int32_t BuildPLI(uint8_t* rtcpbuffer, int& pos) - EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); - int32_t BuildREMB(uint8_t* rtcpbuffer, int& pos) - EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); - int32_t BuildTMMBR(ModuleRtpRtcpImpl* module, uint8_t* rtcpbuffer, int& pos) - EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); - int32_t BuildTMMBN(uint8_t* rtcpbuffer, int& pos) - EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); - int32_t BuildAPP(uint8_t* rtcpbuffer, int& pos) - EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); - int32_t BuildVoIPMetric(uint8_t* rtcpbuffer, int& pos) - EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); - int32_t BuildBYE(uint8_t* rtcpbuffer, int& pos) - EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); - int32_t BuildFIR(uint8_t* rtcpbuffer, int& pos, bool repeat) - EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); - int32_t BuildSLI(uint8_t* rtcpbuffer, int& pos, uint8_t pictureID) - EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); - int32_t BuildRPSI(uint8_t* rtcpbuffer, - int& pos, - uint64_t pictureID, - uint8_t payloadType) - EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildSDEC(uint8_t* rtcpbuffer, int32_t pos) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildPLI(uint8_t* rtcpbuffer, int32_t pos) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildREMB(uint8_t* rtcpbuffer, int32_t pos) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildTMMBR(ModuleRtpRtcpImpl* module, uint8_t* rtcpbuffer, int32_t pos) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildTMMBN(uint8_t* rtcpbuffer, int32_t pos) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildAPP(uint8_t* rtcpbuffer, int32_t pos) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildVoIPMetric(uint8_t* rtcpbuffer, int32_t pos) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildBYE(uint8_t* rtcpbuffer, int32_t pos) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildFIR(uint8_t* rtcpbuffer, int32_t pos, bool repeat) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildSLI(uint8_t* rtcpbuffer, int32_t pos, uint8_t pictureID) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildRPSI(uint8_t* rtcpbuffer, + int32_t pos, + uint64_t pictureID, + uint8_t payloadType) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); - int32_t BuildNACK(uint8_t* rtcpbuffer, - int& pos, - int32_t nackSize, - const uint16_t* nackList, - std::string* nackString) - EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); - int32_t BuildReceiverReferenceTime(uint8_t* buffer, - int& pos, - uint32_t ntp_sec, - uint32_t ntp_frac) - EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); - int32_t BuildDlrr(uint8_t* buffer, - int& pos, - const RtcpReceiveTimeInfo& info) - EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildNACK(uint8_t* rtcpbuffer, + int32_t pos, + int32_t nackSize, + const uint16_t* nackList, + std::string* nackString) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildReceiverReferenceTime(uint8_t* buffer, + int32_t pos, + uint32_t ntp_sec, + uint32_t ntp_frac) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildDlrr(uint8_t* buffer, + int32_t pos, + const RtcpReceiveTimeInfo& info) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); private: - const int32_t _id; - const bool _audio; - Clock* const _clock; - RTCPMethod _method GUARDED_BY(_criticalSectionRTCPSender); + const int32_t _id; + const bool _audio; + Clock* const _clock; + RTCPMethod _method GUARDED_BY(_criticalSectionRTCPSender); - CriticalSectionWrapper* _criticalSectionTransport; - Transport* _cbTransport GUARDED_BY(_criticalSectionTransport); + rtc::scoped_ptr _criticalSectionTransport; + Transport* _cbTransport GUARDED_BY(_criticalSectionTransport); - CriticalSectionWrapper* _criticalSectionRTCPSender; - bool _usingNack GUARDED_BY(_criticalSectionRTCPSender); - bool _sending GUARDED_BY(_criticalSectionRTCPSender); - bool _sendTMMBN GUARDED_BY(_criticalSectionRTCPSender); - bool _REMB GUARDED_BY(_criticalSectionRTCPSender); - bool _sendREMB GUARDED_BY(_criticalSectionRTCPSender); - bool _TMMBR GUARDED_BY(_criticalSectionRTCPSender); - bool _IJ GUARDED_BY(_criticalSectionRTCPSender); + rtc::scoped_ptr _criticalSectionRTCPSender; + bool _usingNack GUARDED_BY(_criticalSectionRTCPSender); + bool _sending GUARDED_BY(_criticalSectionRTCPSender); + bool _sendTMMBN GUARDED_BY(_criticalSectionRTCPSender); + bool _REMB GUARDED_BY(_criticalSectionRTCPSender); + bool _sendREMB GUARDED_BY(_criticalSectionRTCPSender); + bool _TMMBR GUARDED_BY(_criticalSectionRTCPSender); + bool _IJ GUARDED_BY(_criticalSectionRTCPSender); - int64_t _nextTimeToSendRTCP GUARDED_BY(_criticalSectionRTCPSender); + int64_t _nextTimeToSendRTCP GUARDED_BY(_criticalSectionRTCPSender); - uint32_t start_timestamp_ GUARDED_BY(_criticalSectionRTCPSender); - uint32_t last_rtp_timestamp_ GUARDED_BY(_criticalSectionRTCPSender); - int64_t last_frame_capture_time_ms_ GUARDED_BY(_criticalSectionRTCPSender); - uint32_t _SSRC GUARDED_BY(_criticalSectionRTCPSender); - // SSRC that we receive on our RTP channel - uint32_t _remoteSSRC GUARDED_BY(_criticalSectionRTCPSender); - char _CNAME[RTCP_CNAME_SIZE] GUARDED_BY(_criticalSectionRTCPSender); + uint32_t start_timestamp_ GUARDED_BY(_criticalSectionRTCPSender); + uint32_t last_rtp_timestamp_ GUARDED_BY(_criticalSectionRTCPSender); + int64_t last_frame_capture_time_ms_ GUARDED_BY(_criticalSectionRTCPSender); + uint32_t _SSRC GUARDED_BY(_criticalSectionRTCPSender); + // SSRC that we receive on our RTP channel + uint32_t _remoteSSRC GUARDED_BY(_criticalSectionRTCPSender); + char _CNAME[RTCP_CNAME_SIZE] GUARDED_BY(_criticalSectionRTCPSender); - ReceiveStatistics* receive_statistics_ - GUARDED_BY(_criticalSectionRTCPSender); - std::map internal_report_blocks_ - GUARDED_BY(_criticalSectionRTCPSender); - std::map external_report_blocks_ - GUARDED_BY(_criticalSectionRTCPSender); - std::map _csrcCNAMEs - GUARDED_BY(_criticalSectionRTCPSender); + ReceiveStatistics* receive_statistics_ GUARDED_BY(_criticalSectionRTCPSender); + std::map internal_report_blocks_ + GUARDED_BY(_criticalSectionRTCPSender); + std::map external_report_blocks_ + GUARDED_BY(_criticalSectionRTCPSender); + std::map _csrcCNAMEs + GUARDED_BY(_criticalSectionRTCPSender); - // Sent - uint32_t _lastSendReport[RTCP_NUMBER_OF_SR] GUARDED_BY( - _criticalSectionRTCPSender); // allow packet loss and RTT above 1 sec - int64_t _lastRTCPTime[RTCP_NUMBER_OF_SR] GUARDED_BY( - _criticalSectionRTCPSender); + // Sent + uint32_t _lastSendReport[RTCP_NUMBER_OF_SR] GUARDED_BY( + _criticalSectionRTCPSender); // allow packet loss and RTT above 1 sec + int64_t _lastRTCPTime[RTCP_NUMBER_OF_SR] GUARDED_BY( + _criticalSectionRTCPSender); - // Sent XR receiver reference time report. - // . - std::map last_xr_rr_ - GUARDED_BY(_criticalSectionRTCPSender); + // Sent XR receiver reference time report. + // . + std::map last_xr_rr_ GUARDED_BY(_criticalSectionRTCPSender); - // send CSRCs - std::vector csrcs_ GUARDED_BY(_criticalSectionRTCPSender); + // send CSRCs + std::vector csrcs_ GUARDED_BY(_criticalSectionRTCPSender); - // Full intra request - uint8_t _sequenceNumberFIR GUARDED_BY(_criticalSectionRTCPSender); + // Full intra request + uint8_t _sequenceNumberFIR GUARDED_BY(_criticalSectionRTCPSender); - // REMB - uint32_t _rembBitrate GUARDED_BY(_criticalSectionRTCPSender); - std::vector remb_ssrcs_ GUARDED_BY(_criticalSectionRTCPSender); + // REMB + uint32_t _rembBitrate GUARDED_BY(_criticalSectionRTCPSender); + std::vector remb_ssrcs_ GUARDED_BY(_criticalSectionRTCPSender); - TMMBRHelp _tmmbrHelp GUARDED_BY(_criticalSectionRTCPSender); - uint32_t _tmmbr_Send GUARDED_BY(_criticalSectionRTCPSender); - uint32_t _packetOH_Send GUARDED_BY(_criticalSectionRTCPSender); + TMMBRHelp _tmmbrHelp GUARDED_BY(_criticalSectionRTCPSender); + uint32_t _tmmbr_Send GUARDED_BY(_criticalSectionRTCPSender); + uint32_t _packetOH_Send GUARDED_BY(_criticalSectionRTCPSender); - // APP - bool _appSend GUARDED_BY(_criticalSectionRTCPSender); - uint8_t _appSubType GUARDED_BY(_criticalSectionRTCPSender); - uint32_t _appName GUARDED_BY(_criticalSectionRTCPSender); - uint8_t* _appData GUARDED_BY(_criticalSectionRTCPSender); - uint16_t _appLength GUARDED_BY(_criticalSectionRTCPSender); + // APP + bool _appSend GUARDED_BY(_criticalSectionRTCPSender); + uint8_t _appSubType GUARDED_BY(_criticalSectionRTCPSender); + uint32_t _appName GUARDED_BY(_criticalSectionRTCPSender); + rtc::scoped_ptr _appData GUARDED_BY(_criticalSectionRTCPSender); + uint16_t _appLength GUARDED_BY(_criticalSectionRTCPSender); - // True if sending of XR Receiver reference time report is enabled. - bool xrSendReceiverReferenceTimeEnabled_ - GUARDED_BY(_criticalSectionRTCPSender); + // True if sending of XR Receiver reference time report is enabled. + bool xrSendReceiverReferenceTimeEnabled_ + GUARDED_BY(_criticalSectionRTCPSender); - // XR VoIP metric - bool _xrSendVoIPMetric GUARDED_BY(_criticalSectionRTCPSender); - RTCPVoIPMetric _xrVoIPMetric GUARDED_BY(_criticalSectionRTCPSender); + // XR VoIP metric + bool _xrSendVoIPMetric GUARDED_BY(_criticalSectionRTCPSender); + RTCPVoIPMetric _xrVoIPMetric GUARDED_BY(_criticalSectionRTCPSender); - RtcpPacketTypeCounterObserver* const packet_type_counter_observer_; - RtcpPacketTypeCounter packet_type_counter_ - GUARDED_BY(_criticalSectionRTCPSender); + RtcpPacketTypeCounterObserver* const packet_type_counter_observer_; + RtcpPacketTypeCounter packet_type_counter_ + GUARDED_BY(_criticalSectionRTCPSender); - RTCPUtility::NackStats nack_stats_ GUARDED_BY(_criticalSectionRTCPSender); + RTCPUtility::NackStats nack_stats_ GUARDED_BY(_criticalSectionRTCPSender); }; } // namespace webrtc diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc index 611e0c090e..559f726da7 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc @@ -500,12 +500,6 @@ void ModuleRtpRtcpImpl::SetRTCPStatus(const RTCPMethod method) { rtcp_receiver_.SetRTCPStatus(method); } -// Only for internal test. -uint32_t ModuleRtpRtcpImpl::LastSendReport( - int64_t& last_rtcptime) { - return rtcp_sender_.LastSendReport(last_rtcptime); -} - int32_t ModuleRtpRtcpImpl::SetCNAME(const char c_name[RTCP_CNAME_SIZE]) { return rtcp_sender_.SetCNAME(c_name); } diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h index 77256b7fcd..d7267e7b70 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h +++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h @@ -342,9 +342,6 @@ class ModuleRtpRtcpImpl : public RtpRtcp { // Get remote SequenceNumber. uint16_t RemoteSequenceNumber() const; - // Only for internal testing. - uint32_t LastSendReport(int64_t& last_rtcptime); - RTPSender rtp_sender_; RTCPSender rtcp_sender_;