From 242e22b055940be70b1df3031e2363b0d02397b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Spr=C3=A5ng?= Date: Mon, 11 May 2015 10:17:43 +0200 Subject: [PATCH] Refactor RTCP sender The main purpose of this CL is to clean up RTCPSender::PrepareRTCP, but it has quite a few ramifications. Notable changes: * Removed the rtcpPacketTypeFlags bit vector and don't assume RTCPPacketType values have a single unique bit set. This will allow making this an enum class once rtcp_receiver has been overhauled. * Flags are now stored in a map that is a member of the class. This meant we could remove some bool flags (eg send_remb_) which was previously masked into rtcpPacketTypeFlags and then masked out again when testing if a remb packet should be sent. * Make all build methods, eg. BuildREMB(), have the same signature. An RtcpContext struct was introduced for this purpose. This allowed the use of a map from RTCPPacketType to method pointer. Instead of 18 consecutive if-statements, there is now a single loop. The context class also allowed some simplifications in the build methods themselves. * A few minor simplifications and cleanups. The next step is to gradually replace the builder methods with the builders from the new RtcpPacket classes. BUG=2450 R=asapersson@webrtc.org, pbos@webrtc.org Review URL: https://webrtc-codereview.appspot.com/48329004 Cr-Commit-Position: refs/heads/master@{#9166} --- webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h | 15 +- .../rtp_rtcp/interface/rtp_rtcp_defines.h | 51 +- webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h | 5 +- .../modules/rtp_rtcp/source/rtcp_receiver.cc | 83 +- webrtc/modules/rtp_rtcp/source/rtcp_sender.cc | 1637 ++++++++--------- webrtc/modules/rtp_rtcp/source/rtcp_sender.h | 270 +-- .../modules/rtp_rtcp/source/rtcp_utility.cc | 208 +-- webrtc/modules/rtp_rtcp/source/rtcp_utility.h | 781 ++++---- .../modules/rtp_rtcp/source/rtp_rtcp_impl.cc | 11 +- .../modules/rtp_rtcp/source/rtp_rtcp_impl.h | 5 +- .../rtp_rtcp/source/rtp_rtcp_impl_unittest.cc | 5 +- webrtc/test/rtcp_packet_parser.cc | 63 +- webrtc/video/call_perf_tests.cc | 4 +- webrtc/video/end_to_end_tests.cc | 43 +- webrtc/video/video_send_stream_tests.cc | 8 +- 15 files changed, 1508 insertions(+), 1681 deletions(-) diff --git a/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h b/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h index fb47a2bb0..34ab74e71 100644 --- a/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h +++ b/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h @@ -11,6 +11,7 @@ #ifndef WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_RTCP_H_ #define WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_RTCP_H_ +#include #include #include "webrtc/modules/interface/module.h" @@ -390,12 +391,20 @@ class RtpRtcp : public Module { /* * Force a send of a RTCP packet - * normal SR and RR are triggered via the process function + * periodic SR and RR are triggered via the process function * * return -1 on failure else 0 */ - virtual int32_t SendRTCP( - uint32_t rtcpPacketType = kRtcpReport) = 0; + virtual int32_t SendRTCP(RTCPPacketType rtcpPacketType) = 0; + + /* + * Force a send of a RTCP packet with more than one packet type. + * periodic SR and RR are triggered via the process function + * + * return -1 on failure else 0 + */ + virtual int32_t SendCompoundRTCP( + const std::set& rtcpPacketTypes) = 0; /* * Good state of RTP receiver inform sender diff --git a/webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h b/webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h index 8431fe3b5..158776276 100644 --- a/webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h +++ b/webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h @@ -88,26 +88,27 @@ enum RTCPAppSubTypes kAppSubtypeBwe = 0x00 }; -enum RTCPPacketType -{ - kRtcpReport = 0x0001, - kRtcpSr = 0x0002, - kRtcpRr = 0x0004, - kRtcpBye = 0x0008, - kRtcpPli = 0x0010, - kRtcpNack = 0x0020, - kRtcpFir = 0x0040, - kRtcpTmmbr = 0x0080, - kRtcpTmmbn = 0x0100, - kRtcpSrReq = 0x0200, - kRtcpXrVoipMetric = 0x0400, - kRtcpApp = 0x0800, - kRtcpSli = 0x4000, - kRtcpRpsi = 0x8000, - kRtcpRemb = 0x10000, - kRtcpTransmissionTimeOffset = 0x20000, - kRtcpXrReceiverReferenceTime = 0x40000, - kRtcpXrDlrrReportBlock = 0x80000 +// TODO(sprang): Make this an enum class once rtcp_receiver has been cleaned up. +enum RTCPPacketType : uint32_t { + kRtcpReport = 0x0001, + kRtcpSr = 0x0002, + kRtcpRr = 0x0004, + kRtcpSdes = 0x0008, + kRtcpBye = 0x0010, + kRtcpPli = 0x0020, + kRtcpNack = 0x0040, + kRtcpFir = 0x0080, + kRtcpTmmbr = 0x0100, + kRtcpTmmbn = 0x0200, + kRtcpSrReq = 0x0400, + kRtcpXrVoipMetric = 0x0800, + kRtcpApp = 0x1000, + kRtcpSli = 0x4000, + kRtcpRpsi = 0x8000, + kRtcpRemb = 0x10000, + kRtcpTransmissionTimeOffset = 0x20000, + kRtcpXrReceiverReferenceTime = 0x40000, + kRtcpXrDlrrReportBlock = 0x80000 }; enum KeyFrameRequestMethod @@ -129,12 +130,12 @@ enum NACKMethod kNackRtcp = 2 }; -enum RetransmissionMode { - kRetransmitOff = 0x0, - kRetransmitFECPackets = 0x1, - kRetransmitBaseLayer = 0x2, +enum RetransmissionMode : uint8_t { + kRetransmitOff = 0x0, + kRetransmitFECPackets = 0x1, + kRetransmitBaseLayer = 0x2, kRetransmitHigherLayers = 0x4, - kRetransmitAllPackets = 0xFF + kRetransmitAllPackets = 0xFF }; enum RtxMode { diff --git a/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h b/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h index 0097d56e9..0a4ceef1b 100644 --- a/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h +++ b/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h @@ -156,8 +156,9 @@ class MockRtpRtcp : public RtpRtcp { int64_t* avgRTT, int64_t* minRTT, int64_t* maxRTT)); - MOCK_METHOD1(SendRTCP, - int32_t(uint32_t rtcpPacketType)); + MOCK_METHOD1(SendRTCP, int32_t(RTCPPacketType packetType)); + MOCK_METHOD1(SendCompoundRTCP, + int32_t(const std::set& packetTypes)); MOCK_METHOD1(SendRTCPReferencePictureSelection, int32_t(const uint64_t pictureID)); MOCK_METHOD1(SendRTCPSliceLossIndication, diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc index f50ce1782..55974bf74 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc @@ -285,69 +285,68 @@ RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation, } RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin(); - while (pktType != RTCPUtility::kRtcpNotValidCode) - { + while (pktType != RTCPPacketTypes::kInvalid) { // Each "case" is responsible for iterate the parser to the // next top level packet. switch (pktType) { - case RTCPUtility::kRtcpSrCode: - case RTCPUtility::kRtcpRrCode: + case RTCPPacketTypes::kSr: + case RTCPPacketTypes::kRr: HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation); break; - case RTCPUtility::kRtcpSdesCode: + case RTCPPacketTypes::kSdes: HandleSDES(*rtcpParser); break; - case RTCPUtility::kRtcpXrHeaderCode: + case RTCPPacketTypes::kXrHeader: HandleXrHeader(*rtcpParser, rtcpPacketInformation); break; - case RTCPUtility::kRtcpXrReceiverReferenceTimeCode: + case RTCPPacketTypes::kXrReceiverReferenceTime: HandleXrReceiveReferenceTime(*rtcpParser, rtcpPacketInformation); break; - case RTCPUtility::kRtcpXrDlrrReportBlockCode: + case RTCPPacketTypes::kXrDlrrReportBlock: HandleXrDlrrReportBlock(*rtcpParser, rtcpPacketInformation); break; - case RTCPUtility::kRtcpXrVoipMetricCode: + case RTCPPacketTypes::kXrVoipMetric: HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation); break; - case RTCPUtility::kRtcpByeCode: + case RTCPPacketTypes::kBye: HandleBYE(*rtcpParser); break; - case RTCPUtility::kRtcpRtpfbNackCode: + case RTCPPacketTypes::kRtpfbNack: HandleNACK(*rtcpParser, rtcpPacketInformation); break; - case RTCPUtility::kRtcpRtpfbTmmbrCode: + case RTCPPacketTypes::kRtpfbTmmbr: HandleTMMBR(*rtcpParser, rtcpPacketInformation); break; - case RTCPUtility::kRtcpRtpfbTmmbnCode: + case RTCPPacketTypes::kRtpfbTmmbn: HandleTMMBN(*rtcpParser, rtcpPacketInformation); break; - case RTCPUtility::kRtcpRtpfbSrReqCode: + case RTCPPacketTypes::kRtpfbSrReq: HandleSR_REQ(*rtcpParser, rtcpPacketInformation); break; - case RTCPUtility::kRtcpPsfbPliCode: + case RTCPPacketTypes::kPsfbPli: HandlePLI(*rtcpParser, rtcpPacketInformation); break; - case RTCPUtility::kRtcpPsfbSliCode: + case RTCPPacketTypes::kPsfbSli: HandleSLI(*rtcpParser, rtcpPacketInformation); break; - case RTCPUtility::kRtcpPsfbRpsiCode: + case RTCPPacketTypes::kPsfbRpsi: HandleRPSI(*rtcpParser, rtcpPacketInformation); break; - case RTCPUtility::kRtcpExtendedIjCode: + case RTCPPacketTypes::kExtendedIj: HandleIJ(*rtcpParser, rtcpPacketInformation); break; - case RTCPUtility::kRtcpPsfbFirCode: + case RTCPPacketTypes::kPsfbFir: HandleFIR(*rtcpParser, rtcpPacketInformation); break; - case RTCPUtility::kRtcpPsfbAppCode: + case RTCPPacketTypes::kPsfbApp: HandlePsfbApp(*rtcpParser, rtcpPacketInformation); break; - case RTCPUtility::kRtcpAppCode: + case RTCPPacketTypes::kApp: // generic application messages HandleAPP(*rtcpParser, rtcpPacketInformation); break; - case RTCPUtility::kRtcpAppItemCode: + case RTCPPacketTypes::kAppItem: // generic application messages HandleAPPItem(*rtcpParser, rtcpPacketInformation); break; @@ -374,7 +373,8 @@ RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser, RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType(); const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet(); - assert((rtcpPacketType == RTCPUtility::kRtcpRrCode) || (rtcpPacketType == RTCPUtility::kRtcpSrCode)); + assert((rtcpPacketType == RTCPPacketTypes::kRr) || + (rtcpPacketType == RTCPPacketTypes::kSr)); // SR.SenderSSRC // The synchronization source identifier for the originator of this SR packet @@ -382,7 +382,9 @@ RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser, // rtcpPacket.RR.SenderSSRC // The source of the packet sender, same as of SR? or is this a CE? - const uint32_t remoteSSRC = (rtcpPacketType == RTCPUtility::kRtcpRrCode) ? rtcpPacket.RR.SenderSSRC:rtcpPacket.SR.SenderSSRC; + const uint32_t remoteSSRC = (rtcpPacketType == RTCPPacketTypes::kRr) + ? rtcpPacket.RR.SenderSSRC + : rtcpPacket.SR.SenderSSRC; rtcpPacketInformation.remoteSSRC = remoteSSRC; @@ -393,8 +395,7 @@ RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser, return; } - if (rtcpPacketType == RTCPUtility::kRtcpSrCode) - { + if (rtcpPacketType == RTCPPacketTypes::kSr) { TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "SR", "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_); @@ -434,8 +435,7 @@ RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser, rtcpPacketType = rtcpParser.Iterate(); - while (rtcpPacketType == RTCPUtility::kRtcpReportBlockItemCode) - { + while (rtcpPacketType == RTCPPacketTypes::kReportBlockItem) { HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC); rtcpPacketType = rtcpParser.Iterate(); } @@ -756,7 +756,7 @@ int32_t RTCPReceiver::BoundingSet(bool &tmmbrOwner, TMMBRSet* boundingSetRec) { // no need for critsect we have _criticalSectionRTCPReceiver void RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser) { RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate(); - while (pktType == RTCPUtility::kRtcpSdesChunkCode) { + while (pktType == RTCPPacketTypes::kSdesChunk) { HandleSDESChunk(rtcpParser); pktType = rtcpParser.Iterate(); } @@ -792,7 +792,7 @@ void RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser, rtcpPacketInformation.ResetNACKPacketIdArray(); RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate(); - while (pktType == RTCPUtility::kRtcpRtpfbNackItemCode) { + while (pktType == RTCPPacketTypes::kRtpfbNackItem) { HandleNACKItem(rtcpPacket, rtcpPacketInformation); pktType = rtcpParser.Iterate(); } @@ -896,7 +896,7 @@ void RTCPReceiver::HandleXrDlrrReportBlock( // Iterate through sub-block(s), if any. RTCPUtility::RTCPPacketTypes packet_type = parser.Iterate(); - while (packet_type == RTCPUtility::kRtcpXrDlrrReportBlockItemCode) { + while (packet_type == RTCPPacketTypes::kXrDlrrReportBlockItem) { HandleXrDlrrReportBlockItem(packet, rtcpPacketInformation); packet_type = parser.Iterate(); } @@ -1029,7 +1029,7 @@ void RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser, ptrReceiveInfo->VerifyAndAllocateTMMBRSet((uint32_t)maxNumOfTMMBRBlocks); RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate(); - while (pktType == RTCPUtility::kRtcpRtpfbTmmbrItemCode) { + while (pktType == RTCPPacketTypes::kRtpfbTmmbrItem) { HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC); pktType = rtcpParser.Iterate(); } @@ -1074,7 +1074,7 @@ void RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser, ptrReceiveInfo->VerifyAndAllocateBoundingSet((uint32_t)maxNumOfTMMBNBlocks); RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate(); - while (pktType == RTCPUtility::kRtcpRtpfbTmmbnItemCode) { + while (pktType == RTCPPacketTypes::kRtpfbTmmbnItem) { HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket); pktType = rtcpParser.Iterate(); } @@ -1101,7 +1101,7 @@ void RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser, RTCPPacketInformation& rtcpPacketInformation) { const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet(); RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate(); - while (pktType == RTCPUtility::kRtcpPsfbSliItemCode) { + while (pktType == RTCPPacketTypes::kPsfbSliItem) { HandleSLIItem(rtcpPacket, rtcpPacketInformation); pktType = rtcpParser.Iterate(); } @@ -1121,8 +1121,7 @@ RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser, { const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet(); RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate(); - if(pktType == RTCPUtility::kRtcpPsfbRpsiCode) - { + if (pktType == RTCPPacketTypes::kPsfbRpsi) { rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi; // received signal that we have a confirmed reference picture if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0) { @@ -1148,9 +1147,9 @@ RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser, void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser, RTCPPacketInformation& rtcpPacketInformation) { RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate(); - if (pktType == RTCPUtility::kRtcpPsfbRembCode) { + if (pktType == RTCPPacketTypes::kPsfbRemb) { pktType = rtcpParser.Iterate(); - if (pktType == RTCPUtility::kRtcpPsfbRembItemCode) { + if (pktType == RTCPPacketTypes::kPsfbRembItem) { HandleREMBItem(rtcpParser, rtcpPacketInformation); rtcpParser.Iterate(); } @@ -1163,7 +1162,7 @@ void RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser, const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet(); RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate(); - while (pktType == RTCPUtility::kRtcpExtendedIjItemCode) { + while (pktType == RTCPPacketTypes::kExtendedIjItem) { HandleIJItem(rtcpPacket, rtcpPacketInformation); pktType = rtcpParser.Iterate(); } @@ -1193,7 +1192,7 @@ void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser, GetReceiveInformation(rtcpPacket.FIR.SenderSSRC); RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate(); - while (pktType == RTCPUtility::kRtcpPsfbFirItemCode) { + while (pktType == RTCPPacketTypes::kPsfbFirItem) { HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation); pktType = rtcpParser.Iterate(); } @@ -1367,8 +1366,8 @@ void RTCPReceiver::TriggerCallbacksFromRTCPPacket( _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate( rtcpPacketInformation.receiverEstimatedMaxBitrate); } - if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr || - rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr) { + if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) || + (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr)) { int64_t now = _clock->TimeInMilliseconds(); _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport( rtcpPacketInformation.report_blocks, diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc index b8cdbe801..e2ad3f0cc 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc @@ -30,34 +30,34 @@ namespace webrtc { using RTCPUtility::RTCPCnameInformation; NACKStringBuilder::NACKStringBuilder() - : _stream(""), _count(0), _prevNack(0), _consecutive(false) { + : 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; + if (count_ == 0) { + stream_ << nack; + } else if (nack == prevNack_ + 1) { + consecutive_ = true; } else { - if (_consecutive) { - _stream << "-" << _prevNack; - _consecutive = false; + if (consecutive_) { + stream_ << "-" << prevNack_; + consecutive_ = false; } - _stream << "," << nack; + stream_ << "," << nack; } - _count++; - _prevNack = nack; + count_++; + prevNack_ = nack; } std::string NACKStringBuilder::GetResult() { - if (_consecutive) { - _stream << "-" << _prevNack; - _consecutive = false; + if (consecutive_) { + stream_ << "-" << prevNack_; + consecutive_ = false; } - return _stream.str(); + return stream_.str(); } RTCPSender::FeedbackState::FeedbackState() @@ -73,66 +73,111 @@ RTCPSender::FeedbackState::FeedbackState() module(nullptr) { } +struct RTCPSender::RtcpContext { + RtcpContext(const FeedbackState& feedback_state, + int32_t nack_size, + const uint16_t* nack_list, + bool repeat, + uint64_t picture_id, + uint8_t* buffer, + uint32_t buffer_size) + : feedback_state(feedback_state), + nack_size(nack_size), + nack_list(nack_list), + repeat(repeat), + picture_id(picture_id), + buffer(buffer), + buffer_size(buffer_size), + ntp_sec(0), + ntp_frac(0), + jitter_transmission_offset(0), + position(0) {} + + uint8_t* AllocateData(uint32_t bytes) { + DCHECK_LE(position + bytes, buffer_size); + uint8_t* ptr = &buffer[position]; + position += bytes; + return ptr; + } + + const FeedbackState& feedback_state; + int32_t nack_size; + const uint16_t* nack_list; + bool repeat; + uint64_t picture_id; + uint8_t* buffer; + uint32_t buffer_size; + uint32_t ntp_sec; + uint32_t ntp_frac; + uint32_t jitter_transmission_offset; + uint32_t position; +}; + RTCPSender::RTCPSender( int32_t id, bool audio, Clock* clock, ReceiveStatistics* receive_statistics, RtcpPacketTypeCounterObserver* packet_type_counter_observer) - : _id(id), - _audio(audio), - _clock(clock), - _method(kRtcpOff), - _criticalSectionTransport( + : id_(id), + audio_(audio), + clock_(clock), + method_(kRtcpOff), + critical_section_transport_( CriticalSectionWrapper::CreateCriticalSection()), - _cbTransport(NULL), + cbTransport_(nullptr), - _criticalSectionRTCPSender( + critical_section_rtcp_sender_( CriticalSectionWrapper::CreateCriticalSection()), - _usingNack(false), - _sending(false), - _sendTMMBN(false), - _REMB(false), - _sendREMB(false), - _TMMBR(false), - _IJ(false), - _nextTimeToSendRTCP(0), + using_nack_(false), + sending_(false), + remb_enabled_(false), + extended_jitter_report_enabled_(false), + next_time_to_send_rtcp_(0), start_timestamp_(0), last_rtp_timestamp_(0), last_frame_capture_time_ms_(-1), - _SSRC(0), - _remoteSSRC(0), - _CNAME(), + ssrc_(0), + remote_ssrc_(0), receive_statistics_(receive_statistics), - internal_report_blocks_(), - external_report_blocks_(), - _csrcCNAMEs(), - _lastSendReport(), - _lastRTCPTime(), - last_xr_rr_(), + sequence_number_fir_(0), - _sequenceNumberFIR(0), + remb_bitrate_(0), - _rembBitrate(0), + tmmbr_help_(), + tmmbr_send_(0), + packet_oh_send_(0), - _tmmbrHelp(), - _tmmbr_Send(0), - _packetOH_Send(0), + app_sub_type_(0), + app_data_(nullptr), + app_length_(0), - _appSend(false), - _appSubType(0), - _appName(), - _appData(nullptr), - _appLength(0), - - xrSendReceiverReferenceTimeEnabled_(false), - _xrSendVoIPMetric(false), - _xrVoIPMetric(), + xr_send_receiver_reference_time_enabled_(false), 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(last_send_report_, 0, sizeof(last_send_report_)); + memset(last_rtcp_time_, 0, sizeof(last_rtcp_time_)); + + builders_[kRtcpSr] = &RTCPSender::BuildSR; + builders_[kRtcpRr] = &RTCPSender::BuildRR; + builders_[kRtcpSdes] = &RTCPSender::BuildSDEC; + builders_[kRtcpTransmissionTimeOffset] = + &RTCPSender::BuildExtendedJitterReport; + builders_[kRtcpPli] = &RTCPSender::BuildPLI; + builders_[kRtcpFir] = &RTCPSender::BuildFIR; + builders_[kRtcpSli] = &RTCPSender::BuildSLI; + builders_[kRtcpRpsi] = &RTCPSender::BuildRPSI; + builders_[kRtcpRemb] = &RTCPSender::BuildREMB; + builders_[kRtcpBye] = &RTCPSender::BuildBYE; + builders_[kRtcpApp] = &RTCPSender::BuildAPP; + builders_[kRtcpTmmbr] = &RTCPSender::BuildTMMBR; + builders_[kRtcpTmmbn] = &RTCPSender::BuildTMMBN; + builders_[kRtcpNack] = &RTCPSender::BuildNACK; + builders_[kRtcpXrVoipMetric] = &RTCPSender::BuildVoIPMetric; + builders_[kRtcpXrReceiverReferenceTime] = + &RTCPSender::BuildReceiverReferenceTime; + builders_[kRtcpXrDlrrReportBlock] = &RTCPSender::BuildDlrr; } RTCPSender::~RTCPSender() { @@ -142,50 +187,50 @@ RTCPSender::~RTCPSender() { for (auto it : external_report_blocks_) delete it.second; - for (auto it : _csrcCNAMEs) + for (auto it : csrc_cnames_) delete it.second; } int32_t RTCPSender::RegisterSendTransport(Transport* outgoingTransport) { - CriticalSectionScoped lock(_criticalSectionTransport.get()); - _cbTransport = outgoingTransport; + CriticalSectionScoped lock(critical_section_transport_.get()); + cbTransport_ = outgoingTransport; return 0; } RTCPMethod RTCPSender::Status() const { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - return _method; + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); + return method_; } void RTCPSender::SetRTCPStatus(RTCPMethod method) { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - _method = method; + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); + method_ = method; if (method == kRtcpOff) return; - _nextTimeToSendRTCP = - _clock->TimeInMilliseconds() + - (_audio ? RTCP_INTERVAL_AUDIO_MS / 2 : RTCP_INTERVAL_VIDEO_MS / 2); + next_time_to_send_rtcp_ = + clock_->TimeInMilliseconds() + + (audio_ ? RTCP_INTERVAL_AUDIO_MS / 2 : RTCP_INTERVAL_VIDEO_MS / 2); } bool RTCPSender::Sending() const { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - return _sending; + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); + return sending_; } int32_t RTCPSender::SetSendingStatus(const FeedbackState& feedback_state, bool sending) { bool sendRTCPBye = false; { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); - if (_method != kRtcpOff) { - if (sending == false && _sending == true) { + if (method_ != kRtcpOff) { + if (sending == false && sending_ == true) { // Trigger RTCP bye sendRTCPBye = true; } } - _sending = sending; + sending_ = sending; } if (sendRTCPBye) return SendRTCP(feedback_state, kRtcpBye); @@ -193,115 +238,120 @@ int32_t RTCPSender::SetSendingStatus(const FeedbackState& feedback_state, } bool RTCPSender::REMB() const { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - return _REMB; + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); + return remb_enabled_; } void RTCPSender::SetREMBStatus(bool enable) { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - _REMB = enable; + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); + remb_enabled_ = enable; } void RTCPSender::SetREMBData(uint32_t bitrate, const std::vector& ssrcs) { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - _rembBitrate = bitrate; + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); + remb_bitrate_ = bitrate; remb_ssrcs_ = ssrcs; - _sendREMB = true; + if (remb_enabled_) + SetFlag(kRtcpRemb, false); // Send a REMB immediately if we have a new REMB. The frequency of REMBs is // throttled by the caller. - _nextTimeToSendRTCP = _clock->TimeInMilliseconds(); + next_time_to_send_rtcp_ = clock_->TimeInMilliseconds(); } bool RTCPSender::TMMBR() const { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - return _TMMBR; + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); + return IsFlagPresent(RTCPPacketType::kRtcpTmmbr); } void RTCPSender::SetTMMBRStatus(bool enable) { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - _TMMBR = enable; + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); + if (enable) { + SetFlag(RTCPPacketType::kRtcpTmmbr, false); + } else { + ConsumeFlag(RTCPPacketType::kRtcpTmmbr, true); + } } bool RTCPSender::IJ() const { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - return _IJ; + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); + return extended_jitter_report_enabled_; } void RTCPSender::SetIJStatus(bool enable) { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - _IJ = enable; + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); + extended_jitter_report_enabled_ = enable; } void RTCPSender::SetStartTimestamp(uint32_t start_timestamp) { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); start_timestamp_ = start_timestamp; } void RTCPSender::SetLastRtpTime(uint32_t rtp_timestamp, int64_t capture_time_ms) { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); last_rtp_timestamp_ = rtp_timestamp; if (capture_time_ms < 0) { // We don't currently get a capture time from VoiceEngine. - last_frame_capture_time_ms_ = _clock->TimeInMilliseconds(); + last_frame_capture_time_ms_ = clock_->TimeInMilliseconds(); } else { last_frame_capture_time_ms_ = capture_time_ms; } } void RTCPSender::SetSSRC(uint32_t ssrc) { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); - if (_SSRC != 0) { + 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; + next_time_to_send_rtcp_ = clock_->TimeInMilliseconds() + 100; } - _SSRC = ssrc; + ssrc_ = ssrc; } void RTCPSender::SetRemoteSSRC(uint32_t ssrc) { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - _remoteSSRC = ssrc; + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); + remote_ssrc_ = ssrc; } int32_t RTCPSender::SetCNAME(const char cName[RTCP_CNAME_SIZE]) { if (!cName) return -1; - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - _CNAME[RTCP_CNAME_SIZE - 1] = 0; - strncpy(_CNAME, cName, RTCP_CNAME_SIZE - 1); + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); + cname_[RTCP_CNAME_SIZE - 1] = 0; + strncpy(cname_, cName, RTCP_CNAME_SIZE - 1); return 0; } int32_t RTCPSender::AddMixedCNAME(uint32_t SSRC, const char cName[RTCP_CNAME_SIZE]) { assert(cName); - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - if (_csrcCNAMEs.size() >= kRtpCsrcSize) { + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); + if (csrc_cnames_.size() >= kRtpCsrcSize) { return -1; } RTCPCnameInformation* ptr = new RTCPCnameInformation(); ptr->name[RTCP_CNAME_SIZE - 1] = 0; strncpy(ptr->name, cName, RTCP_CNAME_SIZE - 1); - _csrcCNAMEs[SSRC] = ptr; + csrc_cnames_[SSRC] = ptr; return 0; } int32_t RTCPSender::RemoveMixedCNAME(uint32_t SSRC) { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); std::map::iterator it = - _csrcCNAMEs.find(SSRC); + csrc_cnames_.find(SSRC); - if (it == _csrcCNAMEs.end()) + if (it == csrc_cnames_.end()) return -1; delete it->second; - _csrcCNAMEs.erase(it); + csrc_cnames_.erase(it); return 0; } @@ -364,23 +414,23 @@ 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.get()); + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); - if (_method == kRtcpOff) + if (method_ == kRtcpOff) return false; - if (!_audio && sendKeyframeBeforeRTP) { + 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) { + if (now >= next_time_to_send_rtcp_) { return true; } else if (now < 0x0000ffff && - _nextTimeToSendRTCP > 0xffff0000) { // 65 sec margin + next_time_to_send_rtcp_ > 0xffff0000) { // 65 sec margin // wrap return true; } @@ -388,15 +438,15 @@ From RFC 3550 } int64_t RTCPSender::SendTimeOfSendReport(uint32_t sendReport) { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); // This is only saved when we are the sender - if ((_lastSendReport[0] == 0) || (sendReport == 0)) { + if ((last_send_report_[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]; + if (last_send_report_[i] == sendReport) + return last_rtcp_time_[i]; } } return 0; @@ -404,7 +454,7 @@ int64_t RTCPSender::SendTimeOfSendReport(uint32_t sendReport) { bool RTCPSender::SendTimeOfXrRrReport(uint32_t mid_ntp, int64_t* time_ms) const { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); if (last_xr_rr_.empty()) { return false; @@ -420,7 +470,7 @@ bool RTCPSender::SendTimeOfXrRrReport(uint32_t mid_ntp, int32_t RTCPSender::AddExternalReportBlock( uint32_t SSRC, const RTCPReportBlock* reportBlock) { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); return AddReportBlock(SSRC, &external_report_blocks_, reportBlock); } @@ -447,7 +497,7 @@ int32_t RTCPSender::AddReportBlock( } int32_t RTCPSender::RemoveExternalReportBlock(uint32_t SSRC) { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); std::map::iterator it = external_report_blocks_.find(SSRC); @@ -460,203 +510,190 @@ int32_t RTCPSender::RemoveExternalReportBlock(uint32_t SSRC) { return 0; } -int32_t RTCPSender::BuildSR(const FeedbackState& feedback_state, - uint8_t* rtcpbuffer, - int32_t pos, - uint32_t NTPsec, - uint32_t NTPfrac) { +RTCPSender::BuildResult RTCPSender::BuildSR(RtcpContext* ctx) { // sanity - if (pos + 52 >= IP_PACKET_SIZE) { + if (ctx->position + 52 >= IP_PACKET_SIZE) { LOG(LS_WARNING) << "Failed to build Sender Report."; - return -2; + return BuildResult::kTruncated; } uint32_t RTPtime; - uint32_t posNumberOfReportBlocks = pos; - rtcpbuffer[pos++] = 0x80; + uint32_t posNumberOfReportBlocks = ctx->position; + *ctx->AllocateData(1) = 0x80; // Sender report - rtcpbuffer[pos++] = 200; + *ctx->AllocateData(1) = 200; for (int i = (RTCP_NUMBER_OF_SR - 2); i >= 0; i--) { // shift old - _lastSendReport[i + 1] = _lastSendReport[i]; - _lastRTCPTime[i + 1] = _lastRTCPTime[i]; + last_send_report_[i + 1] = last_send_report_[i]; + last_rtcp_time_[i + 1] = last_rtcp_time_[i]; } - _lastRTCPTime[0] = Clock::NtpToMs(NTPsec, NTPfrac); - _lastSendReport[0] = (NTPsec << 16) + (NTPfrac >> 16); + last_rtcp_time_[0] = Clock::NtpToMs(ctx->ntp_sec, ctx->ntp_frac); + last_send_report_[0] = (ctx->ntp_sec << 16) + (ctx->ntp_frac >> 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); + (clock_->TimeInMilliseconds() - last_frame_capture_time_ms_) * + (ctx->feedback_state.frequency_hz / 1000); // Add sender data // Save for our length field - pos++; - pos++; + ctx->AllocateData(2); // Add our own SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), ssrc_); // NTP - ByteWriter::WriteBigEndian(rtcpbuffer + pos, NTPsec); - pos += 4; - ByteWriter::WriteBigEndian(rtcpbuffer + pos, NTPfrac); - pos += 4; - ByteWriter::WriteBigEndian(rtcpbuffer + pos, RTPtime); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), ctx->ntp_sec); + ByteWriter::WriteBigEndian(ctx->AllocateData(4), ctx->ntp_frac); + ByteWriter::WriteBigEndian(ctx->AllocateData(4), RTPtime); // sender's packet count - ByteWriter::WriteBigEndian(rtcpbuffer + pos, - feedback_state.packets_sent); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), + ctx->feedback_state.packets_sent); // sender's octet count - ByteWriter::WriteBigEndian(rtcpbuffer + pos, - feedback_state.media_bytes_sent); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), + ctx->feedback_state.media_bytes_sent); uint8_t numberOfReportBlocks = 0; - int32_t retVal = WriteAllReportBlocksToBuffer( - rtcpbuffer, pos, &numberOfReportBlocks, NTPsec, NTPfrac); - if (retVal < 0) - return retVal; + BuildResult result = WriteAllReportBlocksToBuffer(ctx, &numberOfReportBlocks); + switch (result) { + case BuildResult::kError: + case BuildResult::kTruncated: + case BuildResult::kAborted: + return result; + case BuildResult::kSuccess: + break; + default: + abort(); + } - pos = retVal; - rtcpbuffer[posNumberOfReportBlocks] += numberOfReportBlocks; + ctx->buffer[posNumberOfReportBlocks] += numberOfReportBlocks; - uint16_t len = static_cast((pos / 4) - 1); - ByteWriter::WriteBigEndian(rtcpbuffer + 2, len); - return pos; + uint16_t len = static_cast((ctx->position / 4) - 1); + ByteWriter::WriteBigEndian(&ctx->buffer[2], len); + + return BuildResult::kSuccess; } -int32_t RTCPSender::BuildSDEC(uint8_t* rtcpbuffer, int32_t pos) { - size_t lengthCname = strlen(_CNAME); +RTCPSender::BuildResult RTCPSender::BuildSDEC(RtcpContext* ctx) { + size_t lengthCname = strlen(cname_); assert(lengthCname < RTCP_CNAME_SIZE); // sanity - if(pos + 12 + lengthCname >= IP_PACKET_SIZE) { + if (ctx->position + 12 + lengthCname >= IP_PACKET_SIZE) { LOG(LS_WARNING) << "Failed to build SDEC."; - return -2; + return BuildResult::kTruncated; } // SDEC Source Description // We always need to add SDES CNAME - size_t size = 0x80 + 1 + _csrcCNAMEs.size(); + size_t size = 0x80 + 1 + csrc_cnames_.size(); DCHECK_LE(size, std::numeric_limits::max()); - rtcpbuffer[pos++] = static_cast(size); - rtcpbuffer[pos++] = 202; + *ctx->AllocateData(1) = static_cast(size); + *ctx->AllocateData(1) = 202; // handle SDES length later on - uint32_t SDESLengthPos = pos; - pos++; - pos++; + uint32_t SDESLengthPos = ctx->position; + ctx->AllocateData(2); // Add our own SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), ssrc_); // CNAME = 1 - rtcpbuffer[pos++] = 1; + *ctx->AllocateData(1) = 1; DCHECK_LE(lengthCname, std::numeric_limits::max()); - rtcpbuffer[pos++] = static_cast(lengthCname); + *ctx->AllocateData(1) = static_cast(lengthCname); uint16_t SDESLength = 10; - memcpy(&rtcpbuffer[pos], _CNAME, lengthCname); - pos += lengthCname; + memcpy(ctx->AllocateData(lengthCname), cname_, 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; - } - while ((pos % 4) != 0) { - padding++; - rtcpbuffer[pos++] = 0; - } + do { + ++padding; + *ctx->AllocateData(1) = 0; + } while ((ctx->position % 4) != 0); SDESLength += padding; - for (auto it = _csrcCNAMEs.begin(); it != _csrcCNAMEs.end(); ++it) { + for (auto it = csrc_cnames_.begin(); it != csrc_cnames_.end(); ++it) { RTCPCnameInformation* cname = it->second; uint32_t SSRC = it->first; // Add SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, SSRC); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), SSRC); // CNAME = 1 - rtcpbuffer[pos++] = 1; + *ctx->AllocateData(1) = 1; size_t length = strlen(cname->name); assert(length < RTCP_CNAME_SIZE); - rtcpbuffer[pos++]= static_cast(length); + *ctx->AllocateData(1) = static_cast(length); SDESLength += 6; - memcpy(&rtcpbuffer[pos],cname->name, length); + memcpy(ctx->AllocateData(length), cname->name, length); - pos += length; SDESLength += length; 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; - } - while((pos % 4) != 0){ - padding++; - rtcpbuffer[pos++] = 0; - } + do { + ++padding; + *ctx->AllocateData(1) = 0; + } while ((ctx->position % 4) != 0); SDESLength += padding; } // in 32-bit words minus one and we don't count the header uint16_t buffer_length = (SDESLength / 4) - 1; - ByteWriter::WriteBigEndian(rtcpbuffer + SDESLengthPos, + ByteWriter::WriteBigEndian(&ctx->buffer[SDESLengthPos], buffer_length); - return pos; + return BuildResult::kSuccess; } -int32_t RTCPSender::BuildRR(uint8_t* rtcpbuffer, - int32_t pos, - uint32_t NTPsec, - uint32_t NTPfrac) { +RTCPSender::BuildResult RTCPSender::BuildRR(RtcpContext* ctx) { // sanity one block - if (pos + 32 >= IP_PACKET_SIZE) - return -2; + if (ctx->position + 32 >= IP_PACKET_SIZE) + return BuildResult::kTruncated; - uint32_t posNumberOfReportBlocks = pos; + uint32_t posNumberOfReportBlocks = ctx->position; - rtcpbuffer[pos++] = 0x80; - rtcpbuffer[pos++] = 201; + *ctx->AllocateData(1) = 0x80; + *ctx->AllocateData(1) = 201; // Save for our length field - pos += 2; + uint32_t len_pos = ctx->position; + ctx->AllocateData(2); // Add our own SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), ssrc_); uint8_t numberOfReportBlocks = 0; - int retVal = WriteAllReportBlocksToBuffer( - rtcpbuffer, pos, &numberOfReportBlocks, NTPsec, NTPfrac); - if (retVal < 0) - return pos; + BuildResult result = WriteAllReportBlocksToBuffer(ctx, &numberOfReportBlocks); + switch (result) { + case BuildResult::kError: + case BuildResult::kTruncated: + case BuildResult::kAborted: + return result; + case BuildResult::kSuccess: + break; + default: + abort(); + } - pos = retVal; - rtcpbuffer[posNumberOfReportBlocks] += numberOfReportBlocks; + ctx->buffer[posNumberOfReportBlocks] += numberOfReportBlocks; - uint16_t len = uint16_t((pos) / 4 - 1); - ByteWriter::WriteBigEndian(rtcpbuffer + 2, len); - return pos; + uint16_t len = uint16_t((ctx->position) / 4 - 1); + ByteWriter::WriteBigEndian(&ctx->buffer[len_pos], len); + + return BuildResult::kSuccess; } // From RFC 5450: Transmission Time Offsets in RTP Streams. @@ -677,96 +714,102 @@ 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( - uint8_t* rtcpbuffer, - int32_t pos, - const uint32_t jitterTransmissionTimeOffset) { +RTCPSender::BuildResult RTCPSender::BuildExtendedJitterReport( + RtcpContext* ctx) { 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; + return BuildResult::kError; } // sanity - if (pos + 8 >= IP_PACKET_SIZE) - return -2; + if (ctx->position + 8 >= IP_PACKET_SIZE) + return BuildResult::kTruncated; // add picture loss indicator uint8_t RC = 1; - rtcpbuffer[pos++] = 0x80 + RC; - rtcpbuffer[pos++] = 195; + *ctx->AllocateData(1) = 0x80 + RC; + *ctx->AllocateData(1) = 195; // Used fixed length of 2 - rtcpbuffer[pos++] = 0; - rtcpbuffer[pos++] = 1; + *ctx->AllocateData(1) = 0; + *ctx->AllocateData(1) = 1; // Add inter-arrival jitter - ByteWriter::WriteBigEndian(rtcpbuffer + pos, - jitterTransmissionTimeOffset); - pos += 4; - return pos; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), + ctx->jitter_transmission_offset); + return BuildResult::kSuccess; } -int32_t RTCPSender::BuildPLI(uint8_t* rtcpbuffer, int32_t pos) { +RTCPSender::BuildResult RTCPSender::BuildPLI(RtcpContext* ctx) { // sanity - if (pos + 12 >= IP_PACKET_SIZE) - return -2; + if (ctx->position + 12 >= IP_PACKET_SIZE) + return BuildResult::kTruncated; // add picture loss indicator uint8_t FMT = 1; - rtcpbuffer[pos++] = 0x80 + FMT; - rtcpbuffer[pos++] = 206; + *ctx->AllocateData(1) = 0x80 + FMT; + *ctx->AllocateData(1) = 206; // Used fixed length of 2 - rtcpbuffer[pos++] = 0; - rtcpbuffer[pos++] = 2; + *ctx->AllocateData(1) = 0; + *ctx->AllocateData(1) = 2; // Add our own SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), ssrc_); // Add the remote SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _remoteSSRC); - pos += 4; - return pos; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), remote_ssrc_); + + 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); + + return BuildResult::kSuccess; } -int32_t RTCPSender::BuildFIR(uint8_t* rtcpbuffer, int32_t pos, bool repeat) { +RTCPSender::BuildResult RTCPSender::BuildFIR(RtcpContext* ctx) { // sanity - if (pos + 20 >= IP_PACKET_SIZE) - return -2; + if (ctx->position + 20 >= IP_PACKET_SIZE) + return BuildResult::kTruncated; - if (!repeat) - _sequenceNumberFIR++; // do not increase if repetition + if (!ctx->repeat) + sequence_number_fir_++; // do not increase if repetition // add full intra request indicator uint8_t FMT = 4; - rtcpbuffer[pos++] = 0x80 + FMT; - rtcpbuffer[pos++] = 206; + *ctx->AllocateData(1) = 0x80 + FMT; + *ctx->AllocateData(1) = 206; //Length of 4 - rtcpbuffer[pos++] = 0; - rtcpbuffer[pos++] = 4; + *ctx->AllocateData(1) = 0; + *ctx->AllocateData(1) = 4; // Add our own SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), ssrc_); // RFC 5104 4.3.1.2. Semantics // SSRC of media source - ByteWriter::WriteBigEndian(&rtcpbuffer[pos], 0); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), 0); // Additional Feedback Control Information (FCI) - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _remoteSSRC); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), remote_ssrc_); - rtcpbuffer[pos++] = _sequenceNumberFIR; - rtcpbuffer[pos++] = 0; - rtcpbuffer[pos++] = 0; - rtcpbuffer[pos++] = 0; - return pos; + *ctx->AllocateData(1) = sequence_number_fir_; + *ctx->AllocateData(1) = 0; + *ctx->AllocateData(1) = 0; + *ctx->AllocateData(1) = 0; + + 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); + + return BuildResult::kSuccess; } /* @@ -776,37 +819,33 @@ int32_t RTCPSender::BuildFIR(uint8_t* rtcpbuffer, int32_t pos, bool repeat) { | First | Number | PictureID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -int32_t RTCPSender::BuildSLI(uint8_t* rtcpbuffer, - int32_t pos, - uint8_t pictureID) { +RTCPSender::BuildResult RTCPSender::BuildSLI(RtcpContext* ctx) { // sanity - if (pos + 16 >= IP_PACKET_SIZE) - return -2; + if (ctx->position + 16 >= IP_PACKET_SIZE) + return BuildResult::kTruncated; // add slice loss indicator uint8_t FMT = 2; - rtcpbuffer[pos++] = 0x80 + FMT; - rtcpbuffer[pos++] = 206; + *ctx->AllocateData(1) = 0x80 + FMT; + *ctx->AllocateData(1) = 206; // Used fixed length of 3 - rtcpbuffer[pos++] = 0; - rtcpbuffer[pos++] = 3; + *ctx->AllocateData(1) = 0; + *ctx->AllocateData(1) = 3; // Add our own SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), ssrc_); // Add the remote SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _remoteSSRC); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), remote_ssrc_); // 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; + uint32_t sliField = (0x1fff << 6) + (0x3f & ctx->picture_id); + ByteWriter::WriteBigEndian(ctx->AllocateData(4), sliField); + + return BuildResult::kSuccess; } /* @@ -821,23 +860,23 @@ int32_t RTCPSender::BuildSLI(uint8_t* rtcpbuffer, /* * Note: not generic made for VP8 */ -int32_t RTCPSender::BuildRPSI(uint8_t* rtcpbuffer, - int32_t pos, - uint64_t pictureID, - uint8_t payloadType) { +RTCPSender::BuildResult RTCPSender::BuildRPSI(RtcpContext* ctx) { + if (ctx->feedback_state.send_payload_type == 0xFF) + return BuildResult::kError; + // sanity - if (pos + 24 >= IP_PACKET_SIZE) - return -2; + if (ctx->position + 24 >= IP_PACKET_SIZE) + return BuildResult::kTruncated; // add Reference Picture Selection Indication uint8_t FMT = 3; - rtcpbuffer[pos++] = 0x80 + FMT; - rtcpbuffer[pos++] = 206; + *ctx->AllocateData(1) = 0x80 + FMT; + *ctx->AllocateData(1) = 206; // calc length uint32_t bitsRequired = 7; uint8_t bytesRequired = 1; - while ((pictureID >> bitsRequired) > 0) { + while ((ctx->picture_id >> bitsRequired) > 0) { bitsRequired += 7; bytesRequired++; } @@ -848,104 +887,98 @@ int32_t RTCPSender::BuildRPSI(uint8_t* rtcpbuffer, } else if (bytesRequired > 2) { size = 4; } - rtcpbuffer[pos++] = 0; - rtcpbuffer[pos++] = size; + *ctx->AllocateData(1) = 0; + *ctx->AllocateData(1) = size; // Add our own SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), ssrc_); // Add the remote SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _remoteSSRC); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), remote_ssrc_); // 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++; + *ctx->AllocateData(1) = paddingBytes * 8; // padding can be 0, 8, 16 or 24 // add payload type - rtcpbuffer[pos] = payloadType; - pos++; + *ctx->AllocateData(1) = ctx->feedback_state.send_payload_type; // add picture ID for (int i = bytesRequired - 1; i > 0; --i) { - rtcpbuffer[pos] = 0x80 | static_cast(pictureID >> (i * 7)); - pos++; + *ctx->AllocateData(1) = + 0x80 | static_cast(ctx->picture_id >> (i * 7)); } // add last byte of picture ID - rtcpbuffer[pos] = static_cast(pictureID & 0x7f); - pos++; + *ctx->AllocateData(1) = static_cast(ctx->picture_id & 0x7f); // add padding for (int j = 0; j < paddingBytes; j++) { - rtcpbuffer[pos] = 0; - pos++; + *ctx->AllocateData(1) = 0; } - return pos; + + return BuildResult::kSuccess; } -int32_t RTCPSender::BuildREMB(uint8_t* rtcpbuffer, int32_t pos) { +RTCPSender::BuildResult RTCPSender::BuildREMB(RtcpContext* ctx) { // sanity - if (pos + 20 + 4 * remb_ssrcs_.size() >= IP_PACKET_SIZE) - return -2; + if (ctx->position + 20 + 4 * remb_ssrcs_.size() >= IP_PACKET_SIZE) + return BuildResult::kTruncated; // add application layer feedback uint8_t FMT = 15; - rtcpbuffer[pos++] = 0x80 + FMT; - rtcpbuffer[pos++] = 206; + *ctx->AllocateData(1) = 0x80 + FMT; + *ctx->AllocateData(1) = 206; - rtcpbuffer[pos++] = 0; - rtcpbuffer[pos++] = static_cast(remb_ssrcs_.size() + 4); + *ctx->AllocateData(1) = 0; + *ctx->AllocateData(1) = static_cast(remb_ssrcs_.size() + 4); // Add our own SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), ssrc_); // Remote SSRC must be 0 - ByteWriter::WriteBigEndian(rtcpbuffer + pos, 0); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), 0); - rtcpbuffer[pos++] = 'R'; - rtcpbuffer[pos++] = 'E'; - rtcpbuffer[pos++] = 'M'; - rtcpbuffer[pos++] = 'B'; + *ctx->AllocateData(1) = 'R'; + *ctx->AllocateData(1) = 'E'; + *ctx->AllocateData(1) = 'M'; + *ctx->AllocateData(1) = 'B'; - rtcpbuffer[pos++] = remb_ssrcs_.size(); + *ctx->AllocateData(1) = 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)) { + if (remb_bitrate_ <= (0x3FFFFu << 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); + const uint32_t brMantissa = (remb_bitrate_ >> brExp); + *ctx->AllocateData(1) = + static_cast((brExp << 2) + ((brMantissa >> 16) & 0x03)); + *ctx->AllocateData(1) = static_cast(brMantissa >> 8); + *ctx->AllocateData(1) = static_cast(brMantissa); - for (size_t i = 0; i < remb_ssrcs_.size(); i++) { - ByteWriter::WriteBigEndian(rtcpbuffer + pos, remb_ssrcs_[i]); - pos += 4; - } - return pos; + for (size_t i = 0; i < remb_ssrcs_.size(); i++) + ByteWriter::WriteBigEndian(ctx->AllocateData(4), remb_ssrcs_[i]); + + TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), + "RTCPSender::REMB"); + + return BuildResult::kSuccess; } void RTCPSender::SetTargetBitrate(unsigned int target_bitrate) { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - _tmmbr_Send = target_bitrate / 1000; + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); + tmmbr_send_ = target_bitrate / 1000; } -int32_t RTCPSender::BuildTMMBR(ModuleRtpRtcpImpl* rtp_rtcp_module, - uint8_t* rtcpbuffer, - int32_t pos) { - if (rtp_rtcp_module == NULL) - return -1; +RTCPSender::BuildResult RTCPSender::BuildTMMBR(RtcpContext* ctx) { + if (ctx->feedback_state.module == NULL) + return BuildResult::kError; // 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 @@ -954,70 +987,67 @@ int32_t RTCPSender::BuildTMMBR(ModuleRtpRtcpImpl* rtp_rtcp_module, // get current bounding set from RTCP receiver bool tmmbrOwner = false; // store in candidateSet, allocates one extra slot - TMMBRSet* candidateSet = _tmmbrHelp.CandidateSet(); + TMMBRSet* candidateSet = tmmbr_help_.CandidateSet(); - // holding _criticalSectionRTCPSender while calling RTCPreceiver which - // will accuire _criticalSectionRTCPReceiver is a potental deadlock but + // holding critical_section_rtcp_sender_ 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); + ctx->feedback_state.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) { + if (candidateSet->Tmmbr(i) == tmmbr_send_ && + candidateSet->PacketOH(i) == packet_oh_send_) { // do not send the same tuple - return 0; + return BuildResult::kAborted; } } if (!tmmbrOwner) { // use received bounding set as candidate set // add current tuple - candidateSet->SetEntry(lengthOfBoundingSet, _tmmbr_Send, _packetOH_Send, - _SSRC); + candidateSet->SetEntry(lengthOfBoundingSet, tmmbr_send_, packet_oh_send_, + ssrc_); int numCandidates = lengthOfBoundingSet + 1; // find bounding set TMMBRSet* boundingSet = NULL; - int numBoundingSet = _tmmbrHelp.FindTMMBRBoundingSet(boundingSet); + int numBoundingSet = tmmbr_help_.FindTMMBRBoundingSet(boundingSet); if (numBoundingSet > 0 || numBoundingSet <= numCandidates) - tmmbrOwner = _tmmbrHelp.IsOwner(_SSRC, numBoundingSet); + tmmbrOwner = tmmbr_help_.IsOwner(ssrc_, numBoundingSet); if (!tmmbrOwner) { // did not enter bounding set, no meaning to send this request - return 0; + return BuildResult::kAborted; } } } - if (_tmmbr_Send) { + if (tmmbr_send_) { // sanity - if (pos + 20 >= IP_PACKET_SIZE) - return -2; + if (ctx->position + 20 >= IP_PACKET_SIZE) + return BuildResult::kTruncated; // add TMMBR indicator uint8_t FMT = 3; - rtcpbuffer[pos++] = 0x80 + FMT; - rtcpbuffer[pos++] = 205; + *ctx->AllocateData(1) = 0x80 + FMT; + *ctx->AllocateData(1) = 205; // Length of 4 - rtcpbuffer[pos++] = 0; - rtcpbuffer[pos++] = 4; + *ctx->AllocateData(1) = 0; + *ctx->AllocateData(1) = 4; // Add our own SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), ssrc_); // RFC 5104 4.2.1.2. Semantics // SSRC of media source - ByteWriter::WriteBigEndian(&rtcpbuffer[pos], 0); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), 0); // Additional Feedback Control Information (FCI) - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _remoteSSRC); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), remote_ssrc_); - uint32_t bitRate = _tmmbr_Send * 1000; + uint32_t bitRate = tmmbr_send_ * 1000; uint32_t mmbrExp = 0; for (uint32_t i = 0; i < 64; i++) { if (bitRate <= (0x1FFFFu << i)) { @@ -1027,54 +1057,50 @@ int32_t RTCPSender::BuildTMMBR(ModuleRtpRtcpImpl* rtp_rtcp_module, } uint32_t mmbrMantissa = (bitRate >> mmbrExp); - rtcpbuffer[pos++] = + *ctx->AllocateData(1) = 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); + *ctx->AllocateData(1) = static_cast(mmbrMantissa >> 7); + *ctx->AllocateData(1) = static_cast( + (mmbrMantissa << 1) + ((packet_oh_send_ >> 8) & 0x01)); + *ctx->AllocateData(1) = static_cast(packet_oh_send_); } - return pos; + return BuildResult::kSuccess; } -int32_t RTCPSender::BuildTMMBN(uint8_t* rtcpbuffer, int32_t pos) { - TMMBRSet* boundingSet = _tmmbrHelp.BoundingSetToSend(); +RTCPSender::BuildResult RTCPSender::BuildTMMBN(RtcpContext* ctx) { + TMMBRSet* boundingSet = tmmbr_help_.BoundingSetToSend(); if (boundingSet == NULL) - return -1; + return BuildResult::kError; // sanity - if (pos + 12 + boundingSet->lengthOfSet() * 8 >= IP_PACKET_SIZE) { + if (ctx->position + 12 + boundingSet->lengthOfSet() * 8 >= IP_PACKET_SIZE) { LOG(LS_WARNING) << "Failed to build TMMBN."; - return -2; + return BuildResult::kTruncated; } uint8_t FMT = 4; // add TMMBN indicator - rtcpbuffer[pos++] = 0x80 + FMT; - rtcpbuffer[pos++] = 205; + *ctx->AllocateData(1) = 0x80 + FMT; + *ctx->AllocateData(1) = 205; // Add length later - int posLength = pos; - pos++; - pos++; + int posLength = ctx->position; + ctx->AllocateData(2); // Add our own SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), ssrc_); // RFC 5104 4.2.2.2. Semantics // SSRC of media source - ByteWriter::WriteBigEndian(&rtcpbuffer[pos], 0); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), 0); // 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; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), tmmbrSSRC); uint32_t bitRate = boundingSet->Tmmbr(n) * 1000; uint32_t mmbrExp = 0; @@ -1087,95 +1113,88 @@ int32_t RTCPSender::BuildTMMBN(uint8_t* rtcpbuffer, int32_t pos) { uint32_t mmbrMantissa = (bitRate >> mmbrExp); uint32_t measuredOH = boundingSet->PacketOH(n); - rtcpbuffer[pos++] = + *ctx->AllocateData(1) = 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); + *ctx->AllocateData(1) = static_cast(mmbrMantissa >> 7); + *ctx->AllocateData(1) = static_cast((mmbrMantissa << 1) + + ((measuredOH >> 8) & 0x01)); + *ctx->AllocateData(1) = static_cast(measuredOH); numBoundingSet++; } } uint16_t length = static_cast(2 + 2 * numBoundingSet); - rtcpbuffer[posLength++] = static_cast(length >> 8); - rtcpbuffer[posLength] = static_cast(length); - return pos; + ctx->buffer[posLength++] = static_cast(length >> 8); + ctx->buffer[posLength] = static_cast(length); + + return BuildResult::kSuccess; } -int32_t RTCPSender::BuildAPP(uint8_t* rtcpbuffer, int32_t pos) { +RTCPSender::BuildResult RTCPSender::BuildAPP(RtcpContext* ctx) { // sanity - if (_appData == NULL) { + if (app_data_ == NULL) { LOG(LS_WARNING) << "Failed to build app specific."; - return -1; + return BuildResult::kError; } - if (pos + 12 + _appLength >= IP_PACKET_SIZE) { + if (ctx->position + 12 + app_length_ >= IP_PACKET_SIZE) { LOG(LS_WARNING) << "Failed to build app specific."; - return -2; + return BuildResult::kTruncated; } - rtcpbuffer[pos++] = 0x80 + _appSubType; + *ctx->AllocateData(1) = 0x80 + app_sub_type_; // Add APP ID - rtcpbuffer[pos++] = 204; + *ctx->AllocateData(1) = 204; - uint16_t length = (_appLength >> 2) + 2; // include SSRC and name - rtcpbuffer[pos++] = static_cast(length >> 8); - rtcpbuffer[pos++] = static_cast(length); + uint16_t length = (app_length_ >> 2) + 2; // include SSRC and name + *ctx->AllocateData(1) = static_cast(length >> 8); + *ctx->AllocateData(1) = static_cast(length); // Add our own SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), ssrc_); // Add our application name - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _appName); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), app_name_); // Add the data - memcpy(rtcpbuffer + pos, _appData.get(), _appLength); - pos += _appLength; - return pos; + memcpy(ctx->AllocateData(app_length_), app_data_.get(), app_length_); + + return BuildResult::kSuccess; } -int32_t RTCPSender::BuildNACK(uint8_t* rtcpbuffer, - int32_t pos, - int32_t nackSize, - const uint16_t* nackList, - std::string* nackString) { +RTCPSender::BuildResult RTCPSender::BuildNACK(RtcpContext* ctx) { // sanity - if (pos + 16 >= IP_PACKET_SIZE) { + if (ctx->position + 16 >= IP_PACKET_SIZE) { LOG(LS_WARNING) << "Failed to build NACK."; - return -2; + return BuildResult::kTruncated; } - // int size, uint16_t* nackList + // int size, uint16_t* nack_list // add nack list uint8_t FMT = 1; - rtcpbuffer[pos++] = 0x80 + FMT; - rtcpbuffer[pos++] = 205; + *ctx->AllocateData(1) = 0x80 + FMT; + *ctx->AllocateData(1) = 205; - rtcpbuffer[pos++] = 0; - int nackSizePos = pos; - rtcpbuffer[pos++] = 3; // setting it to one kNACK signal as default + *ctx->AllocateData(1) = 0; + int nack_size_pos_ = ctx->position; + *ctx->AllocateData(1) = 3; // setting it to one kNACK signal as default // Add our own SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), ssrc_); // Add the remote SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _remoteSSRC); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), remote_ssrc_); // 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); + std::min(kRtcpMaxNackFields, (IP_PACKET_SIZE - ctx->position) / 4); int i = 0; - while (i < nackSize && numOfNackFields < maxNackFields) { - uint16_t nack = nackList[i++]; + while (i < ctx->nack_size && numOfNackFields < maxNackFields) { + uint16_t nack = ctx->nack_list[i++]; uint16_t bitmask = 0; - while (i < nackSize) { - int shift = static_cast(nackList[i] - nack) - 1; + while (i < ctx->nack_size) { + int shift = static_cast(ctx->nack_list[i] - nack) - 1; if (shift >= 0 && shift <= 15) { bitmask |= (1 << shift); ++i; @@ -1184,81 +1203,79 @@ int32_t RTCPSender::BuildNACK(uint8_t* rtcpbuffer, } } // 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; + assert(ctx->position + 4 < IP_PACKET_SIZE); + ByteWriter::WriteBigEndian(ctx->AllocateData(2), nack); + ByteWriter::WriteBigEndian(ctx->AllocateData(2), bitmask); numOfNackFields++; } - rtcpbuffer[nackSizePos] = static_cast(2 + numOfNackFields); + ctx->buffer[nack_size_pos_] = static_cast(2 + numOfNackFields); - if (i != nackSize) + if (i != ctx->nack_size) 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]); + stringBuilder.PushNACK(ctx->nack_list[idx]); + nack_stats_.ReportRequest(ctx->nack_list[idx]); } - *nackString = stringBuilder.GetResult(); packet_type_counter_.nack_requests = nack_stats_.requests(); packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests(); - return pos; + + TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), + "RTCPSender::NACK", "nacks", + TRACE_STR_COPY(stringBuilder.GetResult().c_str())); + ++packet_type_counter_.nack_packets; + TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_NACKCount", + ssrc_, packet_type_counter_.nack_packets); + + return BuildResult::kSuccess; } -int32_t RTCPSender::BuildBYE(uint8_t* rtcpbuffer, int32_t pos) { +RTCPSender::BuildResult RTCPSender::BuildBYE(RtcpContext* ctx) { // sanity - if (pos + 8 >= IP_PACKET_SIZE) { - return -2; - } + if (ctx->position + 8 >= IP_PACKET_SIZE) + return BuildResult::kTruncated; // Add a bye packet // Number of SSRC + CSRCs. - rtcpbuffer[pos++] = static_cast(0x80 + 1 + csrcs_.size()); - rtcpbuffer[pos++] = 203; + *ctx->AllocateData(1) = static_cast(0x80 + 1 + csrcs_.size()); + *ctx->AllocateData(1) = 203; // length - rtcpbuffer[pos++] = 0; - rtcpbuffer[pos++] = static_cast(1 + csrcs_.size()); + *ctx->AllocateData(1) = 0; + *ctx->AllocateData(1) = static_cast(1 + csrcs_.size()); // Add our own SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), ssrc_); // add CSRCs - for (size_t i = 0; i < csrcs_.size(); i++) { - ByteWriter::WriteBigEndian(rtcpbuffer + pos, csrcs_[i]); - pos += 4; - } + for (size_t i = 0; i < csrcs_.size(); i++) + ByteWriter::WriteBigEndian(ctx->AllocateData(4), csrcs_[i]); - return pos; + return BuildResult::kSuccess; } -int32_t RTCPSender::BuildReceiverReferenceTime(uint8_t* buffer, - int32_t pos, - uint32_t ntp_sec, - uint32_t ntp_frac) { +RTCPSender::BuildResult RTCPSender::BuildReceiverReferenceTime( + RtcpContext* ctx) { const int kRrTimeBlockLength = 20; - if (pos + kRrTimeBlockLength >= IP_PACKET_SIZE) - return -2; + if (ctx->position + kRrTimeBlockLength >= IP_PACKET_SIZE) + return BuildResult::kTruncated; 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))); + RTCPUtility::MidNtp(ctx->ntp_sec, ctx->ntp_frac), + Clock::NtpToMs(ctx->ntp_sec, ctx->ntp_frac))); // Add XR header. - buffer[pos++] = 0x80; - buffer[pos++] = 207; - buffer[pos++] = 0; // XR packet length. - buffer[pos++] = 4; // XR packet length. + *ctx->AllocateData(1) = 0x80; + *ctx->AllocateData(1) = 207; + ByteWriter::WriteBigEndian(ctx->AllocateData(2), + 4); // XR packet length. // Add our own SSRC. - ByteWriter::WriteBigEndian(buffer + pos, _SSRC); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), ssrc_); // 0 1 2 3 // 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 @@ -1271,36 +1288,31 @@ int32_t RTCPSender::BuildReceiverReferenceTime(uint8_t* buffer, // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // Add Receiver Reference Time Report block. - buffer[pos++] = 4; // BT. - buffer[pos++] = 0; // Reserved. - buffer[pos++] = 0; // Block length. - buffer[pos++] = 2; // Block length. + *ctx->AllocateData(1) = 4; // BT. + *ctx->AllocateData(1) = 0; // Reserved. + ByteWriter::WriteBigEndian(ctx->AllocateData(2), + 2); // Block length. // NTP timestamp. - ByteWriter::WriteBigEndian(buffer + pos, ntp_sec); - pos += 4; - ByteWriter::WriteBigEndian(buffer + pos, ntp_frac); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), ctx->ntp_sec); + ByteWriter::WriteBigEndian(ctx->AllocateData(4), ctx->ntp_frac); - return pos; + return BuildResult::kSuccess; } -int32_t RTCPSender::BuildDlrr(uint8_t* buffer, - int32_t pos, - const RtcpReceiveTimeInfo& info) { +RTCPSender::BuildResult RTCPSender::BuildDlrr(RtcpContext* ctx) { const int kDlrrBlockLength = 24; - if (pos + kDlrrBlockLength >= IP_PACKET_SIZE) - return -2; + if (ctx->position + kDlrrBlockLength >= IP_PACKET_SIZE) + return BuildResult::kTruncated; // Add XR header. - buffer[pos++] = 0x80; - buffer[pos++] = 207; - buffer[pos++] = 0; // XR packet length. - buffer[pos++] = 5; // XR packet length. + *ctx->AllocateData(1) = 0x80; + *ctx->AllocateData(1) = 207; + ByteWriter::WriteBigEndian(ctx->AllocateData(2), + 5); // XR packet length. // Add our own SSRC. - ByteWriter::WriteBigEndian(buffer + pos, _SSRC); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), ssrc_); // 0 1 2 3 // 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 @@ -1318,198 +1330,181 @@ int32_t RTCPSender::BuildDlrr(uint8_t* buffer, // : ... : 2 // Add DLRR sub block. - buffer[pos++] = 5; // BT. - buffer[pos++] = 0; // Reserved. - buffer[pos++] = 0; // Block length. - buffer[pos++] = 3; // Block length. + *ctx->AllocateData(1) = 5; // BT. + *ctx->AllocateData(1) = 0; // Reserved. + ByteWriter::WriteBigEndian(ctx->AllocateData(2), + 3); // Block length. // NTP timestamp. - ByteWriter::WriteBigEndian(buffer + pos, info.sourceSSRC); - pos += 4; - ByteWriter::WriteBigEndian(buffer + pos, info.lastRR); - pos += 4; - ByteWriter::WriteBigEndian(buffer + pos, info.delaySinceLastRR); - pos += 4; - return pos; + const RtcpReceiveTimeInfo& info = ctx->feedback_state.last_xr_rr; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), info.sourceSSRC); + ByteWriter::WriteBigEndian(ctx->AllocateData(4), info.lastRR); + ByteWriter::WriteBigEndian(ctx->AllocateData(4), + info.delaySinceLastRR); + + return BuildResult::kSuccess; } -int32_t RTCPSender::BuildVoIPMetric(uint8_t* rtcpbuffer, int32_t pos) { +// TODO(sprang): Add a unit test for this, or remove if the code isn't used. +RTCPSender::BuildResult RTCPSender::BuildVoIPMetric(RtcpContext* ctx) { // sanity - if (pos + 44 >= IP_PACKET_SIZE) - return -2; + if (ctx->position + 44 >= IP_PACKET_SIZE) + return BuildResult::kTruncated; // Add XR header - rtcpbuffer[pos++] = 0x80; - rtcpbuffer[pos++] = 207; + *ctx->AllocateData(1) = 0x80; + *ctx->AllocateData(1) = 207; - uint32_t XRLengthPos = pos; + uint32_t XRLengthPos = ctx->position; // handle length later on - pos++; - pos++; + ctx->AllocateData(2); // Add our own SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _SSRC); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), ssrc_); // Add a VoIP metrics block - rtcpbuffer[pos++] = 7; - rtcpbuffer[pos++] = 0; - rtcpbuffer[pos++] = 0; - rtcpbuffer[pos++] = 8; + *ctx->AllocateData(1) = 7; + *ctx->AllocateData(1) = 0; + ByteWriter::WriteBigEndian(ctx->AllocateData(2), 8); // Add the remote SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + pos, _remoteSSRC); - pos += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), remote_ssrc_); - rtcpbuffer[pos++] = _xrVoIPMetric.lossRate; - rtcpbuffer[pos++] = _xrVoIPMetric.discardRate; - rtcpbuffer[pos++] = _xrVoIPMetric.burstDensity; - rtcpbuffer[pos++] = _xrVoIPMetric.gapDensity; + *ctx->AllocateData(1) = xr_voip_metric_.lossRate; + *ctx->AllocateData(1) = xr_voip_metric_.discardRate; + *ctx->AllocateData(1) = xr_voip_metric_.burstDensity; + *ctx->AllocateData(1) = xr_voip_metric_.gapDensity; - 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); + ByteWriter::WriteBigEndian(ctx->AllocateData(2), + xr_voip_metric_.burstDuration); + ByteWriter::WriteBigEndian(ctx->AllocateData(2), + xr_voip_metric_.gapDuration); - 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); + ByteWriter::WriteBigEndian(ctx->AllocateData(2), + xr_voip_metric_.roundTripDelay); + ByteWriter::WriteBigEndian(ctx->AllocateData(2), + xr_voip_metric_.endSystemDelay); - rtcpbuffer[pos++] = _xrVoIPMetric.signalLevel; - rtcpbuffer[pos++] = _xrVoIPMetric.noiseLevel; - rtcpbuffer[pos++] = _xrVoIPMetric.RERL; - rtcpbuffer[pos++] = _xrVoIPMetric.Gmin; + *ctx->AllocateData(1) = xr_voip_metric_.signalLevel; + *ctx->AllocateData(1) = xr_voip_metric_.noiseLevel; + *ctx->AllocateData(1) = xr_voip_metric_.RERL; + *ctx->AllocateData(1) = xr_voip_metric_.Gmin; - rtcpbuffer[pos++] = _xrVoIPMetric.Rfactor; - rtcpbuffer[pos++] = _xrVoIPMetric.extRfactor; - rtcpbuffer[pos++] = _xrVoIPMetric.MOSLQ; - rtcpbuffer[pos++] = _xrVoIPMetric.MOSCQ; + *ctx->AllocateData(1) = xr_voip_metric_.Rfactor; + *ctx->AllocateData(1) = xr_voip_metric_.extRfactor; + *ctx->AllocateData(1) = xr_voip_metric_.MOSLQ; + *ctx->AllocateData(1) = xr_voip_metric_.MOSCQ; - rtcpbuffer[pos++] = _xrVoIPMetric.RXconfig; - rtcpbuffer[pos++] = 0; // reserved - rtcpbuffer[pos++] = static_cast(_xrVoIPMetric.JBnominal >> 8); - rtcpbuffer[pos++] = static_cast(_xrVoIPMetric.JBnominal); + *ctx->AllocateData(1) = xr_voip_metric_.RXconfig; + *ctx->AllocateData(1) = 0; // reserved - 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); + ByteWriter::WriteBigEndian(ctx->AllocateData(2), + xr_voip_metric_.JBnominal); + ByteWriter::WriteBigEndian(ctx->AllocateData(2), + xr_voip_metric_.JBmax); + ByteWriter::WriteBigEndian(ctx->AllocateData(2), + xr_voip_metric_.JBabsMax); - rtcpbuffer[XRLengthPos] = 0; - rtcpbuffer[XRLengthPos + 1] = 10; - return pos; + ByteWriter::WriteBigEndian(&ctx->buffer[XRLengthPos], 10); + + return BuildResult::kSuccess; } int32_t RTCPSender::SendRTCP(const FeedbackState& feedback_state, - uint32_t packetTypeFlags, - int32_t nackSize, - const uint16_t* nackList, + RTCPPacketType packetType, + int32_t nack_size, + const uint16_t* nack_list, bool repeat, uint64_t pictureID) { + return SendCompoundRTCP( + feedback_state, std::set(&packetType, &packetType + 1), + nack_size, nack_list, repeat, pictureID); +} + +int32_t RTCPSender::SendCompoundRTCP( + const FeedbackState& feedback_state, + const std::set& packetTypes, + int32_t nack_size, + const uint16_t* nack_list, + bool repeat, + uint64_t pictureID) { { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - if (_method == kRtcpOff) { + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); + if (method_ == kRtcpOff) { LOG(LS_WARNING) << "Can't send rtcp if it is disabled."; return -1; } } uint8_t rtcp_buffer[IP_PACKET_SIZE]; - int rtcp_length = PrepareRTCP(feedback_state, - packetTypeFlags, - nackSize, - nackList, - repeat, - pictureID, - rtcp_buffer, - IP_PACKET_SIZE); - if (rtcp_length < 0) - return -1; + int rtcp_length = + PrepareRTCP(feedback_state, packetTypes, nack_size, nack_list, repeat, + pictureID, rtcp_buffer, IP_PACKET_SIZE); // Sanity don't send empty packets. - if (rtcp_length == 0) - return -1; + if (rtcp_length <= 0) + return -1; return SendToNetwork(rtcp_buffer, static_cast(rtcp_length)); } int RTCPSender::PrepareRTCP(const FeedbackState& feedback_state, - uint32_t packetTypeFlags, - int32_t nackSize, - const uint16_t* nackList, + const std::set& packetTypes, + int32_t nack_size, + const uint16_t* nack_list, bool repeat, uint64_t pictureID, uint8_t* rtcp_buffer, int buffer_size) { - uint32_t rtcpPacketTypeFlags = packetTypeFlags; - // Collect the received information. - uint32_t NTPsec = 0; - uint32_t NTPfrac = 0; - uint32_t jitterTransmissionOffset = 0; - int position = 0; + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); + RtcpContext context(feedback_state, nack_size, nack_list, repeat, pictureID, + rtcp_buffer, buffer_size); + + // Add all flags as volatile. Non volatile entries will not be overwritten + // and all new volatile flags added will be consumed by the end of this call. + SetFlags(packetTypes, true); if (packet_type_counter_.first_packet_time_ms == -1) - packet_type_counter_.first_packet_time_ms = _clock->TimeInMilliseconds(); + 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; + bool generate_report; + if (IsFlagPresent(kRtcpSr) || IsFlagPresent(kRtcpRr)) { + // Report type already explicitly set, don't automatically populate. + generate_report = true; + DCHECK(ConsumeFlag(kRtcpReport) == false); + } else { + generate_report = + (ConsumeFlag(kRtcpReport) && method_ == kRtcpNonCompound) || + method_ == kRtcpCompound; + if (generate_report) + SetFlag(sending_ ? kRtcpSr : kRtcpRr, true); } - 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) { - rtcpPacketTypeFlags |= kRtcpXrVoipMetric; - _xrSendVoIPMetric = false; - } - // Set when having received a TMMBR. - if (_sendTMMBN) { - rtcpPacketTypeFlags |= kRtcpTmmbn; - _sendTMMBN = false; - } - if (rtcpPacketTypeFlags & kRtcpReport) { - if (xrSendReceiverReferenceTimeEnabled_ && !_sending) - rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime; + if (IsFlagPresent(kRtcpSr) || (IsFlagPresent(kRtcpRr) && cname_[0] != 0)) + SetFlag(kRtcpSdes, true); + + // We need to send our NTP even if we haven't received any reports. + clock_->CurrentNtp(context.ntp_sec, context.ntp_frac); + + if (generate_report) { + if (!sending_ && xr_send_receiver_reference_time_enabled_) + SetFlag(kRtcpXrReceiverReferenceTime, true); 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 ((rtcpPacketTypeFlags & kRtcpRr) || (rtcpPacketTypeFlags & kRtcpSr)) { - // generate next time to send a RTCP report + SetFlag(kRtcpXrDlrrReportBlock, true); + + // generate next time to send an RTCP report // seeded from RTP constructor int32_t random = rand() % 1000; int32_t timeToNext = RTCP_INTERVAL_AUDIO_MS; - if (_audio) { + if (audio_) { timeToNext = (RTCP_INTERVAL_AUDIO_MS / 2) + (RTCP_INTERVAL_AUDIO_MS * random / 1000); } else { uint32_t minIntervalMs = RTCP_INTERVAL_AUDIO_MS; - if (_sending) { + 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) @@ -1519,259 +1514,58 @@ int RTCPSender::PrepareRTCP(const FeedbackState& feedback_state, minIntervalMs = RTCP_INTERVAL_VIDEO_MS; timeToNext = (minIntervalMs / 2) + (minIntervalMs * random / 1000); } - _nextTimeToSendRTCP = _clock->TimeInMilliseconds() + timeToNext; - } + next_time_to_send_rtcp_ = clock_->TimeInMilliseconds() + timeToNext; - // If the data does not fit in the packet we fill it as much as possible. - int32_t buildVal = 0; - - // We need to send our NTP even if we haven't received any reports. - _clock->CurrentNtp(NTPsec, NTPfrac); - if (ShouldSendReportBlocks(rtcpPacketTypeFlags)) { StatisticianMap statisticians = receive_statistics_->GetActiveStatisticians(); if (!statisticians.empty()) { 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, + &context.ntp_sec, &context.ntp_frac)) { AddReportBlock(it->first, &internal_report_blocks_, &report_block); } } - if (_IJ && !statisticians.empty()) - rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset; + if (extended_jitter_report_enabled_) + SetFlag(kRtcpTransmissionTimeOffset, true); } } - if (rtcpPacketTypeFlags & kRtcpSr) { - buildVal = BuildSR(feedback_state, rtcp_buffer, position, NTPsec, NTPfrac); - switch (buildVal) { - case -1: - return -1; - case -2: - return position; - default: - position = buildVal; + auto it = report_flags_.begin(); + while (it != report_flags_.end()) { + auto builder = builders_.find(it->type); + DCHECK(builder != builders_.end()); + if (it->is_volatile) { + report_flags_.erase(it++); + } else { + ++it; } - buildVal = BuildSDEC(rtcp_buffer, position); - switch (buildVal) { - case -1: + + uint32_t start_position = context.position; + BuildResult result = (*this.*(builder->second))(&context); + switch (result) { + case BuildResult::kError: return -1; - case -2: - return position; + case BuildResult::kTruncated: + return context.position; + case BuildResult::kAborted: + context.position = start_position; + FALLTHROUGH(); + case BuildResult::kSuccess: + continue; default: - position = buildVal; - } - } else if (rtcpPacketTypeFlags & kRtcpRr) { - buildVal = BuildRR(rtcp_buffer, position, NTPsec, NTPfrac); - switch (buildVal) { - case -1: - return -1; - case -2: - return position; - 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); - switch (buildVal) { - case -1: - return -1; - case -2: - return position; - default: - position = buildVal; - } - } - if (rtcpPacketTypeFlags & kRtcpPli) { - buildVal = BuildPLI(rtcp_buffer, position); - switch (buildVal) { - case -1: - return -1; - case -2: - return position; - 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); - switch (buildVal) { - case -1: - return -1; - case -2: - return position; - 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, pictureID); - switch (buildVal) { - case -1: - return -1; - case -2: - return position; - default: - position = buildVal; - } - } - 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; - case -2: - return position; - default: - position = buildVal; - } - } - if (rtcpPacketTypeFlags & kRtcpRemb) { - buildVal = BuildREMB(rtcp_buffer, position); - switch (buildVal) { - case -1: - return -1; - case -2: - return position; - default: - position = buildVal; - } - TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), - "RTCPSender::REMB"); - } - if (rtcpPacketTypeFlags & kRtcpBye) { - buildVal = BuildBYE(rtcp_buffer, position); - switch (buildVal) { - case -1: - return -1; - case -2: - return position; - default: - position = buildVal; - } - } - if (rtcpPacketTypeFlags & kRtcpApp) { - buildVal = BuildAPP(rtcp_buffer, position); - switch (buildVal) { - case -1: - return -1; - case -2: - return position; - default: - position = buildVal; - } - } - if (rtcpPacketTypeFlags & kRtcpTmmbr) { - switch (buildVal = - BuildTMMBR(feedback_state.module, rtcp_buffer, position)) { - case -1: - return -1; - case -2: - return position; - default: - position = buildVal; - } - } - if (rtcpPacketTypeFlags & kRtcpTmmbn) { - buildVal = BuildTMMBN(rtcp_buffer, position); - switch (buildVal) { - case -1: - return -1; - case -2: - return position; - default: - position = buildVal; - } - } - if (rtcpPacketTypeFlags & kRtcpNack) { - std::string nackString; - switch (buildVal = BuildNACK(rtcp_buffer, position, nackSize, nackList, - &nackString)) { - case -1: - return -1; - case -2: - return position; - 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); - switch (buildVal) { - case -1: - return -1; - case -2: - return position; - default: - position = buildVal; - } - } - if (rtcpPacketTypeFlags & kRtcpXrReceiverReferenceTime) { - buildVal = - BuildReceiverReferenceTime(rtcp_buffer, position, NTPsec, NTPfrac); - switch (buildVal) { - case -1: - return -1; - case -2: - return position; - default: - position = buildVal; - } - } - if (rtcpPacketTypeFlags & kRtcpXrDlrrReportBlock) { - switch (buildVal = - BuildDlrr(rtcp_buffer, position, feedback_state.last_xr_rr)) { - case -1: - return -1; - case -2: - return position; - default: - position = buildVal; + abort(); } } if (packet_type_counter_observer_ != NULL) { packet_type_counter_observer_->RtcpPacketTypesCounterUpdated( - _remoteSSRC, packet_type_counter_); + remote_ssrc_, packet_type_counter_); } - return position; -} + DCHECK(AllVolatileFlagsConsumed()); -bool RTCPSender::ShouldSendReportBlocks(uint32_t rtcp_packet_type) const { - return Status() == kRtcpCompound || - (rtcp_packet_type & kRtcpReport) || - (rtcp_packet_type & kRtcpSr) || - (rtcp_packet_type & kRtcpRr); + return context.position; } bool RTCPSender::PrepareReport(const FeedbackState& feedback_state, @@ -1789,7 +1583,7 @@ bool RTCPSender::PrepareReport(const FeedbackState& feedback_state, report_block->jitter = stats.jitter; // get our NTP as late as possible to avoid a race - _clock->CurrentNtp(*ntp_secs, *ntp_frac); + clock_->CurrentNtp(*ntp_secs, *ntp_frac); // Delay since last received report uint32_t delaySinceLastReceivedSR = 0; @@ -1812,9 +1606,9 @@ bool RTCPSender::PrepareReport(const FeedbackState& feedback_state, } int32_t RTCPSender::SendToNetwork(const uint8_t* dataBuffer, size_t length) { - CriticalSectionScoped lock(_criticalSectionTransport.get()); - if (_cbTransport) { - if (_cbTransport->SendRTCPPacket(_id, dataBuffer, length) > 0) + CriticalSectionScoped lock(critical_section_transport_.get()); + if (cbTransport_) { + if (cbTransport_->SendRTCPPacket(id_, dataBuffer, length) > 0) return 0; } return -1; @@ -1822,7 +1616,7 @@ int32_t RTCPSender::SendToNetwork(const uint8_t* dataBuffer, size_t length) { void RTCPSender::SetCsrcs(const std::vector& csrcs) { assert(csrcs.size() <= kRtpCsrcSize); - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); csrcs_ = csrcs; } @@ -1834,59 +1628,56 @@ int32_t RTCPSender::SetApplicationSpecificData(uint8_t subType, LOG(LS_ERROR) << "Failed to SetApplicationSpecificData."; return -1; } - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); - _appSend = true; - _appSubType = subType; - _appName = name; - _appData.reset(new uint8_t[length]); - _appLength = length; - memcpy(_appData.get(), data, length); + SetFlag(kRtcpApp, true); + app_sub_type_ = subType; + app_name_ = name; + app_data_.reset(new uint8_t[length]); + app_length_ = length; + memcpy(app_data_.get(), data, length); return 0; } int32_t RTCPSender::SetRTCPVoIPMetrics(const RTCPVoIPMetric* VoIPMetric) { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - memcpy(&_xrVoIPMetric, VoIPMetric, sizeof(RTCPVoIPMetric)); + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); + memcpy(&xr_voip_metric_, VoIPMetric, sizeof(RTCPVoIPMetric)); - _xrSendVoIPMetric = true; + SetFlag(kRtcpXrVoipMetric, true); return 0; } void RTCPSender::SendRtcpXrReceiverReferenceTime(bool enable) { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - xrSendReceiverReferenceTimeEnabled_ = enable; + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); + xr_send_receiver_reference_time_enabled_ = enable; } bool RTCPSender::RtcpXrReceiverReferenceTime() const { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); - return xrSendReceiverReferenceTimeEnabled_; + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); + return xr_send_receiver_reference_time_enabled_; } -// called under critsect _criticalSectionRTCPSender -int32_t RTCPSender::WriteAllReportBlocksToBuffer(uint8_t* rtcpbuffer, - int pos, - uint8_t* numberOfReportBlocks, - uint32_t NTPsec, - uint32_t NTPfrac) { +// called under critsect critical_section_rtcp_sender_ +RTCPSender::BuildResult RTCPSender::WriteAllReportBlocksToBuffer( + RtcpContext* ctx, + uint8_t* numberOfReportBlocks) { *numberOfReportBlocks = external_report_blocks_.size(); *numberOfReportBlocks += internal_report_blocks_.size(); - if ((pos + *numberOfReportBlocks * 24) >= IP_PACKET_SIZE) { + if ((ctx->position + *numberOfReportBlocks * 24) >= IP_PACKET_SIZE) { LOG(LS_WARNING) << "Can't fit all report blocks."; - return -1; + return BuildResult::kError; } - pos = WriteReportBlocksToBuffer(rtcpbuffer, pos, internal_report_blocks_); + WriteReportBlocksToBuffer(ctx, internal_report_blocks_); while (!internal_report_blocks_.empty()) { delete internal_report_blocks_.begin()->second; internal_report_blocks_.erase(internal_report_blocks_.begin()); } - pos = WriteReportBlocksToBuffer(rtcpbuffer, pos, external_report_blocks_); - return pos; + WriteReportBlocksToBuffer(ctx, external_report_blocks_); + return BuildResult::kSuccess; } -int32_t RTCPSender::WriteReportBlocksToBuffer( - uint8_t* rtcpbuffer, - int32_t position, +void RTCPSender::WriteReportBlocksToBuffer( + RtcpContext* ctx, const std::map& report_blocks) { std::map::const_iterator it = report_blocks.begin(); @@ -1895,49 +1686,73 @@ int32_t RTCPSender::WriteReportBlocksToBuffer( RTCPReportBlock* reportBlock = it->second; if (reportBlock) { // Remote SSRC - ByteWriter::WriteBigEndian(rtcpbuffer + position, remoteSSRC); - position += 4; + ByteWriter::WriteBigEndian(ctx->AllocateData(4), remoteSSRC); // fraction lost - rtcpbuffer[position++] = reportBlock->fractionLost; + *ctx->AllocateData(1) = reportBlock->fractionLost; // cumulative loss - ByteWriter::WriteBigEndian(rtcpbuffer + position, + ByteWriter::WriteBigEndian(ctx->AllocateData(3), reportBlock->cumulativeLost); - position += 3; // extended highest seq_no, contain the highest sequence number received - ByteWriter::WriteBigEndian(rtcpbuffer + position, + ByteWriter::WriteBigEndian(ctx->AllocateData(4), reportBlock->extendedHighSeqNum); - position += 4; // Jitter - ByteWriter::WriteBigEndian(rtcpbuffer + position, + ByteWriter::WriteBigEndian(ctx->AllocateData(4), reportBlock->jitter); - position += 4; - ByteWriter::WriteBigEndian(rtcpbuffer + position, + ByteWriter::WriteBigEndian(ctx->AllocateData(4), reportBlock->lastSR); - position += 4; - ByteWriter::WriteBigEndian(rtcpbuffer + position, + ByteWriter::WriteBigEndian(ctx->AllocateData(4), reportBlock->delaySinceLastSR); - position += 4; } } - return position; } // no callbacks allowed inside this function int32_t RTCPSender::SetTMMBN(const TMMBRSet* boundingSet, uint32_t maxBitrateKbit) { - CriticalSectionScoped lock(_criticalSectionRTCPSender.get()); + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); - if (0 == _tmmbrHelp.SetTMMBRBoundingSetToSend(boundingSet, maxBitrateKbit)) { - _sendTMMBN = true; + if (0 == tmmbr_help_.SetTMMBRBoundingSetToSend(boundingSet, maxBitrateKbit)) { + SetFlag(kRtcpTmmbn, true); return 0; } return -1; } +void RTCPSender::SetFlag(RTCPPacketType type, bool is_volatile) { + report_flags_.insert(ReportFlag(type, is_volatile)); +} + +void RTCPSender::SetFlags(const std::set& types, + bool is_volatile) { + for (RTCPPacketType type : types) + SetFlag(type, is_volatile); +} + +bool RTCPSender::IsFlagPresent(RTCPPacketType type) const { + return report_flags_.find(ReportFlag(type, false)) != report_flags_.end(); +} + +bool RTCPSender::ConsumeFlag(RTCPPacketType type, bool forced) { + auto it = report_flags_.find(ReportFlag(type, false)); + if (it == report_flags_.end()) + return false; + if (it->is_volatile || forced) + report_flags_.erase((it)); + return true; +} + +bool RTCPSender::AllVolatileFlagsConsumed() const { + for (const ReportFlag& flag : report_flags_) { + if (flag.is_volatile) + return false; + } + return true; +} + } // namespace webrtc diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender.h b/webrtc/modules/rtp_rtcp/source/rtcp_sender.h index dbdee0c12..57fbe2b7a 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.h +++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.h @@ -12,6 +12,7 @@ #define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_SENDER_H_ #include +#include #include #include @@ -40,10 +41,10 @@ class NACKStringBuilder { std::string GetResult(); private: - std::ostringstream _stream; - int _count; - uint16_t _prevNack; - bool _consecutive; + std::ostringstream stream_; + int count_; + uint16_t prevNack_; + bool consecutive_; }; class RTCPSender { @@ -107,12 +108,19 @@ public: bool TimeToSendRTCPReport(bool sendKeyframeBeforeRTP = false) const; int32_t SendRTCP(const FeedbackState& feedback_state, - uint32_t rtcpPacketTypeFlags, + RTCPPacketType packetType, int32_t nackSize = 0, const uint16_t* nackList = 0, bool repeat = false, uint64_t pictureID = 0); + int32_t SendCompoundRTCP(const FeedbackState& feedback_state, + const std::set& packetTypes, + 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); @@ -150,18 +158,36 @@ public: void SetTargetBitrate(unsigned int target_bitrate); private: + struct RtcpContext; + + // The BuildResult indicates the outcome of a call to a builder method, + // constructing a part of an RTCP packet: + // + // kError + // Building RTCP packet failed, propagate error out to caller. + // kAbort + // The (partial) block being build should not be included. Reset current + // buffer position to the state before the method call and proceed to the + // next packet type. + // kTruncated + // There is not enough room in the buffer to fit the data being constructed. + // (IP packet is full). Proceed to the next packet type, and call this + // method again when a new buffer has been allocated. + // TODO(sprang): Actually allocate multiple packets if needed. + // kSuccess + // Data has been successfully placed in the buffer. + + enum class BuildResult { kError, kAborted, kTruncated, kSuccess }; + int32_t SendToNetwork(const uint8_t* dataBuffer, size_t length); - int32_t WriteAllReportBlocksToBuffer(uint8_t* rtcpbuffer, - int pos, - uint8_t* numberOfReportBlocks, - uint32_t NTPsec, - uint32_t NTPfrac) - EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + RTCPSender::BuildResult WriteAllReportBlocksToBuffer( + RtcpContext* context, + uint8_t* numberOfReportBlocks) + EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); - int32_t WriteReportBlocksToBuffer( - uint8_t* rtcpbuffer, - int32_t position, + void WriteReportBlocksToBuffer( + RtcpContext* context, const std::map& report_blocks); int32_t AddReportBlock(uint32_t SSRC, @@ -174,21 +200,8 @@ private: uint32_t* ntp_secs, uint32_t* ntp_frac); - 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, - int32_t pos, - uint32_t NTPsec, - uint32_t NTPfrac) - EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); - int PrepareRTCP(const FeedbackState& feedback_state, - uint32_t packetTypeFlags, + const std::set& packetTypes, int32_t nackSize, const uint16_t* nackList, bool repeat, @@ -196,135 +209,142 @@ private: uint8_t* rtcp_buffer, int buffer_size); - bool ShouldSendReportBlocks(uint32_t rtcp_packet_type) const; - - int32_t BuildExtendedJitterReport(uint8_t* rtcpbuffer, - int32_t pos, - uint32_t jitterTransmissionTimeOffset) - 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, - 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); + BuildResult BuildSR(RtcpContext* context) + EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); + BuildResult BuildRR(RtcpContext* context) + EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); + BuildResult BuildExtendedJitterReport(RtcpContext* context) + EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); + BuildResult BuildSDEC(RtcpContext* context) + EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); + BuildResult BuildPLI(RtcpContext* context) + EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); + BuildResult BuildREMB(RtcpContext* context) + EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); + BuildResult BuildTMMBR(RtcpContext* context) + EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); + BuildResult BuildTMMBN(RtcpContext* context) + EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); + BuildResult BuildAPP(RtcpContext* context) + EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); + BuildResult BuildVoIPMetric(RtcpContext* context) + EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); + BuildResult BuildBYE(RtcpContext* context) + EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); + BuildResult BuildFIR(RtcpContext* context) + EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); + BuildResult BuildSLI(RtcpContext* context) + EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); + BuildResult BuildRPSI(RtcpContext* context) + EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); + BuildResult BuildNACK(RtcpContext* context) + EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); + BuildResult BuildReceiverReferenceTime(RtcpContext* context) + EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); + BuildResult BuildDlrr(RtcpContext* context) + EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); 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(critical_section_rtcp_sender_); - rtc::scoped_ptr _criticalSectionTransport; - Transport* _cbTransport GUARDED_BY(_criticalSectionTransport); + rtc::scoped_ptr critical_section_transport_; + Transport* cbTransport_ GUARDED_BY(critical_section_transport_); - 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); + rtc::scoped_ptr critical_section_rtcp_sender_; + bool using_nack_ GUARDED_BY(critical_section_rtcp_sender_); + bool sending_ GUARDED_BY(critical_section_rtcp_sender_); + bool remb_enabled_ GUARDED_BY(critical_section_rtcp_sender_); + bool extended_jitter_report_enabled_ GUARDED_BY(critical_section_rtcp_sender_); - int64_t _nextTimeToSendRTCP GUARDED_BY(_criticalSectionRTCPSender); + int64_t next_time_to_send_rtcp_ GUARDED_BY(critical_section_rtcp_sender_); - 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); + uint32_t start_timestamp_ GUARDED_BY(critical_section_rtcp_sender_); + uint32_t last_rtp_timestamp_ GUARDED_BY(critical_section_rtcp_sender_); + int64_t last_frame_capture_time_ms_ GUARDED_BY(critical_section_rtcp_sender_); + uint32_t ssrc_ GUARDED_BY(critical_section_rtcp_sender_); // SSRC that we receive on our RTP channel - uint32_t _remoteSSRC GUARDED_BY(_criticalSectionRTCPSender); - char _CNAME[RTCP_CNAME_SIZE] GUARDED_BY(_criticalSectionRTCPSender); + uint32_t remote_ssrc_ GUARDED_BY(critical_section_rtcp_sender_); + char cname_[RTCP_CNAME_SIZE] GUARDED_BY(critical_section_rtcp_sender_); - ReceiveStatistics* receive_statistics_ GUARDED_BY(_criticalSectionRTCPSender); + ReceiveStatistics* receive_statistics_ + GUARDED_BY(critical_section_rtcp_sender_); std::map internal_report_blocks_ - GUARDED_BY(_criticalSectionRTCPSender); + GUARDED_BY(critical_section_rtcp_sender_); std::map external_report_blocks_ - GUARDED_BY(_criticalSectionRTCPSender); - std::map _csrcCNAMEs - GUARDED_BY(_criticalSectionRTCPSender); + GUARDED_BY(critical_section_rtcp_sender_); + std::map csrc_cnames_ + GUARDED_BY(critical_section_rtcp_sender_); // 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); + uint32_t last_send_report_[RTCP_NUMBER_OF_SR] GUARDED_BY( + critical_section_rtcp_sender_); // allow packet loss and RTT above 1 sec + int64_t last_rtcp_time_[RTCP_NUMBER_OF_SR] GUARDED_BY( + critical_section_rtcp_sender_); // Sent XR receiver reference time report. // . - std::map last_xr_rr_ GUARDED_BY(_criticalSectionRTCPSender); + std::map last_xr_rr_ + GUARDED_BY(critical_section_rtcp_sender_); // send CSRCs - std::vector csrcs_ GUARDED_BY(_criticalSectionRTCPSender); + std::vector csrcs_ GUARDED_BY(critical_section_rtcp_sender_); // Full intra request - uint8_t _sequenceNumberFIR GUARDED_BY(_criticalSectionRTCPSender); + uint8_t sequence_number_fir_ GUARDED_BY(critical_section_rtcp_sender_); // REMB - uint32_t _rembBitrate GUARDED_BY(_criticalSectionRTCPSender); - std::vector remb_ssrcs_ GUARDED_BY(_criticalSectionRTCPSender); + uint32_t remb_bitrate_ GUARDED_BY(critical_section_rtcp_sender_); + std::vector remb_ssrcs_ GUARDED_BY(critical_section_rtcp_sender_); - TMMBRHelp _tmmbrHelp GUARDED_BY(_criticalSectionRTCPSender); - uint32_t _tmmbr_Send GUARDED_BY(_criticalSectionRTCPSender); - uint32_t _packetOH_Send GUARDED_BY(_criticalSectionRTCPSender); + TMMBRHelp tmmbr_help_ GUARDED_BY(critical_section_rtcp_sender_); + uint32_t tmmbr_send_ GUARDED_BY(critical_section_rtcp_sender_); + uint32_t packet_oh_send_ GUARDED_BY(critical_section_rtcp_sender_); // 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); + uint8_t app_sub_type_ GUARDED_BY(critical_section_rtcp_sender_); + uint32_t app_name_ GUARDED_BY(critical_section_rtcp_sender_); + rtc::scoped_ptr app_data_ GUARDED_BY(critical_section_rtcp_sender_); + uint16_t app_length_ GUARDED_BY(critical_section_rtcp_sender_); // True if sending of XR Receiver reference time report is enabled. - bool xrSendReceiverReferenceTimeEnabled_ - GUARDED_BY(_criticalSectionRTCPSender); + bool xr_send_receiver_reference_time_enabled_ + GUARDED_BY(critical_section_rtcp_sender_); // XR VoIP metric - bool _xrSendVoIPMetric GUARDED_BY(_criticalSectionRTCPSender); - RTCPVoIPMetric _xrVoIPMetric GUARDED_BY(_criticalSectionRTCPSender); + RTCPVoIPMetric xr_voip_metric_ GUARDED_BY(critical_section_rtcp_sender_); RtcpPacketTypeCounterObserver* const packet_type_counter_observer_; RtcpPacketTypeCounter packet_type_counter_ - GUARDED_BY(_criticalSectionRTCPSender); + GUARDED_BY(critical_section_rtcp_sender_); - RTCPUtility::NackStats nack_stats_ GUARDED_BY(_criticalSectionRTCPSender); + RTCPUtility::NackStats nack_stats_ GUARDED_BY(critical_section_rtcp_sender_); + + void SetFlag(RTCPPacketType type, bool is_volatile) + EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); + void SetFlags(const std::set& types, bool is_volatile) + EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); + bool IsFlagPresent(RTCPPacketType type) const + EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); + bool ConsumeFlag(RTCPPacketType type, bool forced = false) + EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); + bool AllVolatileFlagsConsumed() const + EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); + struct ReportFlag { + ReportFlag(RTCPPacketType type, bool is_volatile) + : type(type), is_volatile(is_volatile) {} + bool operator<(const ReportFlag& flag) const { return type < flag.type; } + bool operator==(const ReportFlag& flag) const { return type == flag.type; } + const RTCPPacketType type; + const bool is_volatile; + }; + + std::set report_flags_ GUARDED_BY(critical_section_rtcp_sender_); + + typedef BuildResult (RTCPSender::*Builder)(RtcpContext*); + std::map builders_; }; } // namespace webrtc diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_utility.cc b/webrtc/modules/rtp_rtcp/source/rtcp_utility.cc index 042338963..4e37cf371 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_utility.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_utility.cc @@ -49,9 +49,9 @@ RTCPUtility::RTCPParserV2::RTCPParserV2(const uint8_t* rtcpData, _validPacket(false), _ptrRTCPData(rtcpData), _ptrRTCPBlockEnd(NULL), - _state(State_TopLevel), + _state(ParseState::State_TopLevel), _numberOfBlocks(0), - _packetType(kRtcpNotValidCode) { + _packetType(RTCPPacketTypes::kInvalid) { Validate(); } @@ -88,58 +88,58 @@ RTCPUtility::RTCPPacketTypes RTCPUtility::RTCPParserV2::Iterate() { // Reset packet type - _packetType = kRtcpNotValidCode; + _packetType = RTCPPacketTypes::kInvalid; if (IsValid()) { switch (_state) { - case State_TopLevel: + case ParseState::State_TopLevel: IterateTopLevel(); break; - case State_ReportBlockItem: + case ParseState::State_ReportBlockItem: IterateReportBlockItem(); break; - case State_SDESChunk: + case ParseState::State_SDESChunk: IterateSDESChunk(); break; - case State_BYEItem: + case ParseState::State_BYEItem: IterateBYEItem(); break; - case State_ExtendedJitterItem: + case ParseState::State_ExtendedJitterItem: IterateExtendedJitterItem(); break; - case State_RTPFB_NACKItem: + case ParseState::State_RTPFB_NACKItem: IterateNACKItem(); break; - case State_RTPFB_TMMBRItem: + case ParseState::State_RTPFB_TMMBRItem: IterateTMMBRItem(); break; - case State_RTPFB_TMMBNItem: + case ParseState::State_RTPFB_TMMBNItem: IterateTMMBNItem(); break; - case State_PSFB_SLIItem: + case ParseState::State_PSFB_SLIItem: IterateSLIItem(); break; - case State_PSFB_RPSIItem: + case ParseState::State_PSFB_RPSIItem: IterateRPSIItem(); break; - case State_PSFB_FIRItem: + case ParseState::State_PSFB_FIRItem: IterateFIRItem(); break; - case State_PSFB_AppItem: + case ParseState::State_PSFB_AppItem: IteratePsfbAppItem(); break; - case State_PSFB_REMBItem: + case ParseState::State_PSFB_REMBItem: IteratePsfbREMBItem(); break; - case State_XRItem: + case ParseState::State_XRItem: IterateXrItem(); break; - case State_XR_DLLRItem: + case ParseState::State_XR_DLLRItem: IterateXrDlrrItem(); break; - case State_AppItem: + case ParseState::State_AppItem: IterateAppItem(); break; default: @@ -515,7 +515,7 @@ RTCPUtility::RTCPParserV2::ParseRR() _ptrRTCPData += 4; // Skip header - _packetType = kRtcpRrCode; + _packetType = RTCPPacketTypes::kRr; _packet.RR.SenderSSRC = *_ptrRTCPData++ << 24; _packet.RR.SenderSSRC += *_ptrRTCPData++ << 16; @@ -525,7 +525,7 @@ RTCPUtility::RTCPParserV2::ParseRR() _packet.RR.NumberOfReportBlocks = _numberOfBlocks; // State transition - _state = State_ReportBlockItem; + _state = ParseState::State_ReportBlockItem; return true; } @@ -543,7 +543,7 @@ RTCPUtility::RTCPParserV2::ParseSR() _ptrRTCPData += 4; // Skip header - _packetType = kRtcpSrCode; + _packetType = RTCPPacketTypes::kSr; _packet.SR.SenderSSRC = *_ptrRTCPData++ << 24; _packet.SR.SenderSSRC += *_ptrRTCPData++ << 16; @@ -580,11 +580,11 @@ RTCPUtility::RTCPParserV2::ParseSR() // State transition if(_numberOfBlocks != 0) { - _state = State_ReportBlockItem; + _state = ParseState::State_ReportBlockItem; }else { // don't go to state report block item if 0 report blocks - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); } return true; @@ -597,7 +597,7 @@ RTCPUtility::RTCPParserV2::ParseReportBlockItem() if (length < 24 || _numberOfBlocks <= 0) { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; @@ -634,7 +634,7 @@ RTCPUtility::RTCPParserV2::ParseReportBlockItem() _packet.ReportBlockItem.DelayLastSR += *_ptrRTCPData++; _numberOfBlocks--; - _packetType = kRtcpReportBlockItemCode; + _packetType = RTCPPacketTypes::kReportBlockItem; return true; } @@ -665,10 +665,10 @@ RTCPUtility::RTCPParserV2::ParseIJ() _ptrRTCPData += 4; // Skip header - _packetType = kRtcpExtendedIjCode; + _packetType = RTCPPacketTypes::kExtendedIj; // State transition - _state = State_ExtendedJitterItem; + _state = ParseState::State_ExtendedJitterItem; return true; } @@ -679,7 +679,7 @@ RTCPUtility::RTCPParserV2::ParseIJItem() if (length < 4 || _numberOfBlocks <= 0) { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; } @@ -690,7 +690,7 @@ RTCPUtility::RTCPParserV2::ParseIJItem() _packet.ExtendedJitterReportItem.Jitter += *_ptrRTCPData++; _numberOfBlocks--; - _packetType = kRtcpExtendedIjItemCode; + _packetType = RTCPPacketTypes::kExtendedIjItem; return true; } @@ -701,15 +701,15 @@ RTCPUtility::RTCPParserV2::ParseSDES() if (length < 8) { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; } _ptrRTCPData += 4; // Skip header - _state = State_SDESChunk; - _packetType = kRtcpSdesCode; + _state = ParseState::State_SDESChunk; + _packetType = RTCPPacketTypes::kSdes; return true; } @@ -718,7 +718,7 @@ RTCPUtility::RTCPParserV2::ParseSDESChunk() { if(_numberOfBlocks <= 0) { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; @@ -731,7 +731,7 @@ RTCPUtility::RTCPParserV2::ParseSDESChunk() const ptrdiff_t dataLen = _ptrRTCPBlockEnd - _ptrRTCPData; if (dataLen < 4) { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; @@ -749,7 +749,7 @@ RTCPUtility::RTCPParserV2::ParseSDESChunk() return true; } } - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; @@ -790,7 +790,7 @@ RTCPUtility::RTCPParserV2::ParseSDESItem() // Sanity if ((_ptrRTCPData + len) >= _ptrRTCPBlockEnd) { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; @@ -802,7 +802,7 @@ RTCPUtility::RTCPParserV2::ParseSDESItem() if ((c < ' ') || (c > '{') || (c == '%') || (c == '\\')) { // Illegal char - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; @@ -811,7 +811,7 @@ RTCPUtility::RTCPParserV2::ParseSDESItem() } // Make sure we are null terminated. _packet.CName.CName[i] = 0; - _packetType = kRtcpSdesChunkCode; + _packetType = RTCPPacketTypes::kSdesChunk; foundCName = true; } @@ -821,7 +821,7 @@ RTCPUtility::RTCPParserV2::ParseSDESItem() } // No end tag found! - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; @@ -832,7 +832,7 @@ RTCPUtility::RTCPParserV2::ParseBYE() { _ptrRTCPData += 4; // Skip header - _state = State_BYEItem; + _state = ParseState::State_BYEItem; return ParseBYEItem(); } @@ -843,13 +843,13 @@ RTCPUtility::RTCPParserV2::ParseBYEItem() const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; if (length < 4 || _numberOfBlocks == 0) { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; } - _packetType = kRtcpByeCode; + _packetType = RTCPPacketTypes::kBye; _packet.BYE.SenderSSRC = *_ptrRTCPData++ << 24; _packet.BYE.SenderSSRC += *_ptrRTCPData++ << 16; @@ -894,8 +894,8 @@ bool RTCPUtility::RTCPParserV2::ParseXr() _packet.XR.OriginatorSSRC += *_ptrRTCPData++ << 8; _packet.XR.OriginatorSSRC += *_ptrRTCPData++; - _packetType = kRtcpXrHeaderCode; - _state = State_XRItem; + _packetType = RTCPPacketTypes::kXrHeader; + _state = ParseState::State_XRItem; return true; } @@ -915,7 +915,7 @@ bool RTCPUtility::RTCPParserV2::ParseXrItem() { const int kBlockHeaderLengthInBytes = 4; const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; if (length < kBlockHeaderLengthInBytes) { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; } @@ -956,7 +956,7 @@ bool RTCPUtility::RTCPParserV2::ParseXrReceiverReferenceTimeItem( const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; if (block_length_4bytes != kBlockLengthIn4Bytes || length < kBlockLengthInBytes) { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; } @@ -971,8 +971,8 @@ bool RTCPUtility::RTCPParserV2::ParseXrReceiverReferenceTimeItem( _packet.XRReceiverReferenceTimeItem.NTPLeastSignificant+= *_ptrRTCPData++<<8; _packet.XRReceiverReferenceTimeItem.NTPLeastSignificant+= *_ptrRTCPData++; - _packetType = kRtcpXrReceiverReferenceTimeCode; - _state = State_XRItem; + _packetType = RTCPPacketTypes::kXrReceiverReferenceTime; + _state = ParseState::State_XRItem; return true; } @@ -997,25 +997,25 @@ bool RTCPUtility::RTCPParserV2::ParseXrDlrr(int block_length_4bytes) { const int kSubBlockLengthIn4Bytes = 3; if (block_length_4bytes < 0 || (block_length_4bytes % kSubBlockLengthIn4Bytes) != 0) { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; } - _packetType = kRtcpXrDlrrReportBlockCode; - _state = State_XR_DLLRItem; + _packetType = RTCPPacketTypes::kXrDlrrReportBlock; + _state = ParseState::State_XR_DLLRItem; _numberOfBlocks = block_length_4bytes / kSubBlockLengthIn4Bytes; return true; } bool RTCPUtility::RTCPParserV2::ParseXrDlrrItem() { if (_numberOfBlocks == 0) { - _state = State_XRItem; + _state = ParseState::State_XRItem; return false; } const int kSubBlockLengthInBytes = 12; const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; if (length < kSubBlockLengthInBytes) { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; } @@ -1035,9 +1035,9 @@ bool RTCPUtility::RTCPParserV2::ParseXrDlrrItem() { _packet.XRDLRRReportBlockItem.DelayLastRR += *_ptrRTCPData++ << 8; _packet.XRDLRRReportBlockItem.DelayLastRR += *_ptrRTCPData++; - _packetType = kRtcpXrDlrrReportBlockItemCode; + _packetType = RTCPPacketTypes::kXrDlrrReportBlockItem; --_numberOfBlocks; - _state = State_XR_DLLRItem; + _state = ParseState::State_XR_DLLRItem; return true; } /* VoIP Metrics Report Block. @@ -1070,7 +1070,7 @@ bool RTCPUtility::RTCPParserV2::ParseXrVoipMetricItem(int block_length_4bytes) { const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; if (block_length_4bytes != kBlockLengthIn4Bytes || length < kBlockLengthInBytes) { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; } @@ -1117,8 +1117,8 @@ bool RTCPUtility::RTCPParserV2::ParseXrVoipMetricItem(int block_length_4bytes) { _packet.XRVOIPMetricItem.JBabsMax = *_ptrRTCPData++ << 8; _packet.XRVOIPMetricItem.JBabsMax += *_ptrRTCPData++; - _packetType = kRtcpXrVoipMetricCode; - _state = State_XRItem; + _packetType = RTCPPacketTypes::kXrVoipMetric; + _state = ParseState::State_XRItem; return true; } @@ -1127,13 +1127,13 @@ bool RTCPUtility::RTCPParserV2::ParseXrUnsupportedBlockType( const int32_t kBlockLengthInBytes = block_length_4bytes * 4; const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; if (length < kBlockLengthInBytes) { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; } // Skip block. _ptrRTCPData += kBlockLengthInBytes; - _state = State_XRItem; + _state = ParseState::State_XRItem; return false; } @@ -1171,11 +1171,11 @@ RTCPUtility::RTCPParserV2::ParseFBCommon(const RTCPCommonHeader& header) case 1: { // NACK - _packetType = kRtcpRtpfbNackCode; + _packetType = RTCPPacketTypes::kRtpfbNack; _packet.NACK.SenderSSRC = senderSSRC; _packet.NACK.MediaSSRC = mediaSSRC; - _state = State_RTPFB_NACKItem; + _state = ParseState::State_RTPFB_NACKItem; return true; } @@ -1188,22 +1188,22 @@ RTCPUtility::RTCPParserV2::ParseFBCommon(const RTCPCommonHeader& header) case 3: { // TMMBR - _packetType = kRtcpRtpfbTmmbrCode; + _packetType = RTCPPacketTypes::kRtpfbTmmbr; _packet.TMMBR.SenderSSRC = senderSSRC; _packet.TMMBR.MediaSSRC = mediaSSRC; - _state = State_RTPFB_TMMBRItem; + _state = ParseState::State_RTPFB_TMMBRItem; return true; } case 4: { // TMMBN - _packetType = kRtcpRtpfbTmmbnCode; + _packetType = RTCPPacketTypes::kRtpfbTmmbn; _packet.TMMBN.SenderSSRC = senderSSRC; _packet.TMMBN.MediaSSRC = mediaSSRC; - _state = State_RTPFB_TMMBNItem; + _state = ParseState::State_RTPFB_TMMBNItem; return true; } @@ -1212,7 +1212,7 @@ RTCPUtility::RTCPParserV2::ParseFBCommon(const RTCPCommonHeader& header) // RTCP-SR-REQ Rapid Synchronisation of RTP Flows // draft-perkins-avt-rapid-rtp-sync-03.txt // trigger a new RTCP SR - _packetType = kRtcpRtpfbSrReqCode; + _packetType = RTCPPacketTypes::kRtpfbSrReq; // Note: No state transition, SR REQ is empty! return true; @@ -1230,7 +1230,7 @@ RTCPUtility::RTCPParserV2::ParseFBCommon(const RTCPCommonHeader& header) { case 1: // PLI - _packetType = kRtcpPsfbPliCode; + _packetType = RTCPPacketTypes::kPsfbPli; _packet.PLI.SenderSSRC = senderSSRC; _packet.PLI.MediaSSRC = mediaSSRC; @@ -1238,34 +1238,34 @@ RTCPUtility::RTCPParserV2::ParseFBCommon(const RTCPCommonHeader& header) return true; case 2: // SLI - _packetType = kRtcpPsfbSliCode; + _packetType = RTCPPacketTypes::kPsfbSli; _packet.SLI.SenderSSRC = senderSSRC; _packet.SLI.MediaSSRC = mediaSSRC; - _state = State_PSFB_SLIItem; + _state = ParseState::State_PSFB_SLIItem; return true; case 3: - _packetType = kRtcpPsfbRpsiCode; + _packetType = RTCPPacketTypes::kPsfbRpsi; _packet.RPSI.SenderSSRC = senderSSRC; _packet.RPSI.MediaSSRC = mediaSSRC; - _state = State_PSFB_RPSIItem; + _state = ParseState::State_PSFB_RPSIItem; return true; case 4: // FIR - _packetType = kRtcpPsfbFirCode; + _packetType = RTCPPacketTypes::kPsfbFir; _packet.FIR.SenderSSRC = senderSSRC; _packet.FIR.MediaSSRC = mediaSSRC; - _state = State_PSFB_FIRItem; + _state = ParseState::State_PSFB_FIRItem; return true; case 15: - _packetType = kRtcpPsfbAppCode; + _packetType = RTCPPacketTypes::kPsfbApp; _packet.PSFBAPP.SenderSSRC = senderSSRC; _packet.PSFBAPP.MediaSSRC = mediaSSRC; - _state = State_PSFB_AppItem; + _state = ParseState::State_PSFB_AppItem; return true; default: break; @@ -1298,19 +1298,19 @@ bool RTCPUtility::RTCPParserV2::ParseRPSIItem() { const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; if (length < 4) { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; } if (length > 2 + RTCP_RPSI_DATA_SIZE) { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; } - _packetType = kRtcpPsfbRpsiCode; + _packetType = RTCPPacketTypes::kPsfbRpsi; uint8_t padding_bits = *_ptrRTCPData++; _packet.RPSI.PayloadType = *_ptrRTCPData++; @@ -1332,13 +1332,13 @@ RTCPUtility::RTCPParserV2::ParseNACKItem() if (length < 4) { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; } - _packetType = kRtcpRtpfbNackItemCode; + _packetType = RTCPPacketTypes::kRtpfbNackItem; _packet.NACKItem.PacketID = *_ptrRTCPData++ << 8; _packet.NACKItem.PacketID += *_ptrRTCPData++; @@ -1356,41 +1356,41 @@ RTCPUtility::RTCPParserV2::ParsePsfbAppItem() if (length < 4) { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; } if(*_ptrRTCPData++ != 'R') { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; } if(*_ptrRTCPData++ != 'E') { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; } if(*_ptrRTCPData++ != 'M') { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; } if(*_ptrRTCPData++ != 'B') { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; } - _packetType = kRtcpPsfbRembCode; - _state = State_PSFB_REMBItem; + _packetType = RTCPPacketTypes::kPsfbRemb; + _state = ParseState::State_PSFB_REMBItem; return true; } @@ -1401,7 +1401,7 @@ RTCPUtility::RTCPParserV2::ParsePsfbREMBItem() if (length < 4) { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; @@ -1420,13 +1420,13 @@ RTCPUtility::RTCPParserV2::ParsePsfbREMBItem() const ptrdiff_t length_ssrcs = _ptrRTCPBlockEnd - _ptrRTCPData; if (length_ssrcs < 4 * _packet.REMBItem.NumberOfSSRCs) { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; } - _packetType = kRtcpPsfbRembItemCode; + _packetType = RTCPPacketTypes::kPsfbRembItem; for (int i = 0; i < _packet.REMBItem.NumberOfSSRCs; i++) { @@ -1447,13 +1447,13 @@ RTCPUtility::RTCPParserV2::ParseTMMBRItem() if (length < 8) { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; } - _packetType = kRtcpRtpfbTmmbrItemCode; + _packetType = RTCPPacketTypes::kRtpfbTmmbrItem; _packet.TMMBRItem.SSRC = *_ptrRTCPData++ << 24; _packet.TMMBRItem.SSRC += *_ptrRTCPData++ << 16; @@ -1486,13 +1486,13 @@ RTCPUtility::RTCPParserV2::ParseTMMBNItem() if (length < 8) { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; } - _packetType = kRtcpRtpfbTmmbnItemCode; + _packetType = RTCPPacketTypes::kRtpfbTmmbnItem; _packet.TMMBNItem.SSRC = *_ptrRTCPData++ << 24; _packet.TMMBNItem.SSRC += *_ptrRTCPData++ << 16; @@ -1532,12 +1532,12 @@ RTCPUtility::RTCPParserV2::ParseSLIItem() if (length < 4) { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; } - _packetType = kRtcpPsfbSliItemCode; + _packetType = RTCPPacketTypes::kPsfbSliItem; uint32_t buffer; buffer = *_ptrRTCPData++ << 24; @@ -1561,13 +1561,13 @@ RTCPUtility::RTCPParserV2::ParseFIRItem() if (length < 8) { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; } - _packetType = kRtcpPsfbFirItemCode; + _packetType = RTCPPacketTypes::kPsfbFirItem; _packet.FIRItem.SSRC = *_ptrRTCPData++ << 24; _packet.FIRItem.SSRC += *_ptrRTCPData++ << 16; @@ -1604,12 +1604,12 @@ RTCPUtility::RTCPParserV2::ParseAPP( const RTCPCommonHeader& header) length = _ptrRTCPBlockEnd - _ptrRTCPData; - _packetType = kRtcpAppCode; + _packetType = RTCPPacketTypes::kApp; _packet.APP.SubType = header.IC; _packet.APP.Name = name; - _state = State_AppItem; + _state = ParseState::State_AppItem; return true; } @@ -1619,12 +1619,12 @@ RTCPUtility::RTCPParserV2::ParseAPPItem() const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; if (length < 4) { - _state = State_TopLevel; + _state = ParseState::State_TopLevel; EndCurrentBlock(); return false; } - _packetType = kRtcpAppItemCode; + _packetType = RTCPPacketTypes::kAppItem; if(length > kRtcpAppCode_DATA_SIZE) { diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_utility.h b/webrtc/modules/rtp_rtcp/source/rtcp_utility.h index 804e8b947..fcafe5960 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_utility.h +++ b/webrtc/modules/rtp_rtcp/source/rtcp_utility.h @@ -1,12 +1,12 @@ /* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ +* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. +* +* Use of this source code is governed by a BSD-style license +* that can be found in the LICENSE file in the root of the source +* tree. An additional intellectual property rights grant can be found +* in the file PATENTS. All contributing project authors may +* be found in the AUTHORS file in the root of the source tree. +*/ #ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_UTILITY_H_ #define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_UTILITY_H_ @@ -42,463 +42,428 @@ class NackStats { uint32_t unique_requests_; }; - uint32_t MidNtp(uint32_t ntp_sec, uint32_t ntp_frac); +uint32_t MidNtp(uint32_t ntp_sec, uint32_t ntp_frac); - // CNAME - struct RTCPCnameInformation - { - char name[RTCP_CNAME_SIZE]; - }; - struct RTCPPacketRR - { - uint32_t SenderSSRC; - uint8_t NumberOfReportBlocks; - }; - struct RTCPPacketSR - { - uint32_t SenderSSRC; - uint8_t NumberOfReportBlocks; +// CNAME +struct RTCPCnameInformation { + char name[RTCP_CNAME_SIZE]; +}; +struct RTCPPacketRR { + uint32_t SenderSSRC; + uint8_t NumberOfReportBlocks; +}; +struct RTCPPacketSR { + uint32_t SenderSSRC; + uint8_t NumberOfReportBlocks; - // sender info - uint32_t NTPMostSignificant; - uint32_t NTPLeastSignificant; - uint32_t RTPTimestamp; - uint32_t SenderPacketCount; - uint32_t SenderOctetCount; - }; - struct RTCPPacketReportBlockItem - { - // report block - uint32_t SSRC; - uint8_t FractionLost; - uint32_t CumulativeNumOfPacketsLost; - uint32_t ExtendedHighestSequenceNumber; - uint32_t Jitter; - uint32_t LastSR; - uint32_t DelayLastSR; - }; - struct RTCPPacketSDESCName - { - // RFC3550 - uint32_t SenderSSRC; - char CName[RTCP_CNAME_SIZE]; - }; + // sender info + uint32_t NTPMostSignificant; + uint32_t NTPLeastSignificant; + uint32_t RTPTimestamp; + uint32_t SenderPacketCount; + uint32_t SenderOctetCount; +}; +struct RTCPPacketReportBlockItem { + // report block + uint32_t SSRC; + uint8_t FractionLost; + uint32_t CumulativeNumOfPacketsLost; + uint32_t ExtendedHighestSequenceNumber; + uint32_t Jitter; + uint32_t LastSR; + uint32_t DelayLastSR; +}; +struct RTCPPacketSDESCName { + // RFC3550 + uint32_t SenderSSRC; + char CName[RTCP_CNAME_SIZE]; +}; - struct RTCPPacketExtendedJitterReportItem - { - // RFC 5450 - uint32_t Jitter; - }; +struct RTCPPacketExtendedJitterReportItem { + // RFC 5450 + uint32_t Jitter; +}; - struct RTCPPacketBYE - { - uint32_t SenderSSRC; - }; - struct RTCPPacketXR - { - // RFC 3611 - uint32_t OriginatorSSRC; - }; - struct RTCPPacketXRReceiverReferenceTimeItem - { - // RFC 3611 4.4 - uint32_t NTPMostSignificant; - uint32_t NTPLeastSignificant; - }; - struct RTCPPacketXRDLRRReportBlockItem - { - // RFC 3611 4.5 - uint32_t SSRC; - uint32_t LastRR; - uint32_t DelayLastRR; - }; - struct RTCPPacketXRVOIPMetricItem - { - // RFC 3611 4.7 - uint32_t SSRC; - uint8_t lossRate; - uint8_t discardRate; - uint8_t burstDensity; - uint8_t gapDensity; - uint16_t burstDuration; - uint16_t gapDuration; - uint16_t roundTripDelay; - uint16_t endSystemDelay; - uint8_t signalLevel; - uint8_t noiseLevel; - uint8_t RERL; - uint8_t Gmin; - uint8_t Rfactor; - uint8_t extRfactor; - uint8_t MOSLQ; - uint8_t MOSCQ; - uint8_t RXconfig; - uint16_t JBnominal; - uint16_t JBmax; - uint16_t JBabsMax; - }; +struct RTCPPacketBYE { + uint32_t SenderSSRC; +}; +struct RTCPPacketXR { + // RFC 3611 + uint32_t OriginatorSSRC; +}; +struct RTCPPacketXRReceiverReferenceTimeItem { + // RFC 3611 4.4 + uint32_t NTPMostSignificant; + uint32_t NTPLeastSignificant; +}; +struct RTCPPacketXRDLRRReportBlockItem { + // RFC 3611 4.5 + uint32_t SSRC; + uint32_t LastRR; + uint32_t DelayLastRR; +}; +struct RTCPPacketXRVOIPMetricItem { + // RFC 3611 4.7 + uint32_t SSRC; + uint8_t lossRate; + uint8_t discardRate; + uint8_t burstDensity; + uint8_t gapDensity; + uint16_t burstDuration; + uint16_t gapDuration; + uint16_t roundTripDelay; + uint16_t endSystemDelay; + uint8_t signalLevel; + uint8_t noiseLevel; + uint8_t RERL; + uint8_t Gmin; + uint8_t Rfactor; + uint8_t extRfactor; + uint8_t MOSLQ; + uint8_t MOSCQ; + uint8_t RXconfig; + uint16_t JBnominal; + uint16_t JBmax; + uint16_t JBabsMax; +}; - struct RTCPPacketRTPFBNACK - { - uint32_t SenderSSRC; - uint32_t MediaSSRC; - }; - struct RTCPPacketRTPFBNACKItem - { - // RFC4585 - uint16_t PacketID; - uint16_t BitMask; - }; +struct RTCPPacketRTPFBNACK { + uint32_t SenderSSRC; + uint32_t MediaSSRC; +}; +struct RTCPPacketRTPFBNACKItem { + // RFC4585 + uint16_t PacketID; + uint16_t BitMask; +}; - struct RTCPPacketRTPFBTMMBR - { - uint32_t SenderSSRC; - uint32_t MediaSSRC; // zero! - }; - struct RTCPPacketRTPFBTMMBRItem - { - // RFC5104 - uint32_t SSRC; - uint32_t MaxTotalMediaBitRate; // In Kbit/s - uint32_t MeasuredOverhead; - }; +struct RTCPPacketRTPFBTMMBR { + uint32_t SenderSSRC; + uint32_t MediaSSRC; // zero! +}; +struct RTCPPacketRTPFBTMMBRItem { + // RFC5104 + uint32_t SSRC; + uint32_t MaxTotalMediaBitRate; // In Kbit/s + uint32_t MeasuredOverhead; +}; - struct RTCPPacketRTPFBTMMBN - { - uint32_t SenderSSRC; - uint32_t MediaSSRC; // zero! - }; - struct RTCPPacketRTPFBTMMBNItem - { - // RFC5104 - uint32_t SSRC; // "Owner" - uint32_t MaxTotalMediaBitRate; - uint32_t MeasuredOverhead; - }; +struct RTCPPacketRTPFBTMMBN { + uint32_t SenderSSRC; + uint32_t MediaSSRC; // zero! +}; +struct RTCPPacketRTPFBTMMBNItem { + // RFC5104 + uint32_t SSRC; // "Owner" + uint32_t MaxTotalMediaBitRate; + uint32_t MeasuredOverhead; +}; - struct RTCPPacketPSFBFIR - { - uint32_t SenderSSRC; - uint32_t MediaSSRC; // zero! - }; - struct RTCPPacketPSFBFIRItem - { - // RFC5104 - uint32_t SSRC; - uint8_t CommandSequenceNumber; - }; +struct RTCPPacketPSFBFIR { + uint32_t SenderSSRC; + uint32_t MediaSSRC; // zero! +}; +struct RTCPPacketPSFBFIRItem { + // RFC5104 + uint32_t SSRC; + uint8_t CommandSequenceNumber; +}; - struct RTCPPacketPSFBPLI - { - // RFC4585 - uint32_t SenderSSRC; - uint32_t MediaSSRC; - }; +struct RTCPPacketPSFBPLI { + // RFC4585 + uint32_t SenderSSRC; + uint32_t MediaSSRC; +}; - struct RTCPPacketPSFBSLI - { - // RFC4585 - uint32_t SenderSSRC; - uint32_t MediaSSRC; - }; - struct RTCPPacketPSFBSLIItem - { - // RFC4585 - uint16_t FirstMB; - uint16_t NumberOfMB; - uint8_t PictureId; - }; - struct RTCPPacketPSFBRPSI - { - // RFC4585 - uint32_t SenderSSRC; - uint32_t MediaSSRC; - uint8_t PayloadType; - uint16_t NumberOfValidBits; - uint8_t NativeBitString[RTCP_RPSI_DATA_SIZE]; - }; - struct RTCPPacketPSFBAPP - { - uint32_t SenderSSRC; - uint32_t MediaSSRC; - }; - struct RTCPPacketPSFBREMBItem - { - uint32_t BitRate; - uint8_t NumberOfSSRCs; - uint32_t SSRCs[MAX_NUMBER_OF_REMB_FEEDBACK_SSRCS]; - }; - // generic name APP - struct RTCPPacketAPP - { - uint8_t SubType; - uint32_t Name; - uint8_t Data[kRtcpAppCode_DATA_SIZE]; - uint16_t Size; - }; +struct RTCPPacketPSFBSLI { + // RFC4585 + uint32_t SenderSSRC; + uint32_t MediaSSRC; +}; +struct RTCPPacketPSFBSLIItem { + // RFC4585 + uint16_t FirstMB; + uint16_t NumberOfMB; + uint8_t PictureId; +}; +struct RTCPPacketPSFBRPSI { + // RFC4585 + uint32_t SenderSSRC; + uint32_t MediaSSRC; + uint8_t PayloadType; + uint16_t NumberOfValidBits; + uint8_t NativeBitString[RTCP_RPSI_DATA_SIZE]; +}; +struct RTCPPacketPSFBAPP { + uint32_t SenderSSRC; + uint32_t MediaSSRC; +}; +struct RTCPPacketPSFBREMBItem { + uint32_t BitRate; + uint8_t NumberOfSSRCs; + uint32_t SSRCs[MAX_NUMBER_OF_REMB_FEEDBACK_SSRCS]; +}; +// generic name APP +struct RTCPPacketAPP { + uint8_t SubType; + uint32_t Name; + uint8_t Data[kRtcpAppCode_DATA_SIZE]; + uint16_t Size; +}; - union RTCPPacket - { - RTCPPacketRR RR; - RTCPPacketSR SR; - RTCPPacketReportBlockItem ReportBlockItem; +union RTCPPacket { + RTCPPacketRR RR; + RTCPPacketSR SR; + RTCPPacketReportBlockItem ReportBlockItem; - RTCPPacketSDESCName CName; - RTCPPacketBYE BYE; + RTCPPacketSDESCName CName; + RTCPPacketBYE BYE; - RTCPPacketExtendedJitterReportItem ExtendedJitterReportItem; + RTCPPacketExtendedJitterReportItem ExtendedJitterReportItem; - RTCPPacketRTPFBNACK NACK; - RTCPPacketRTPFBNACKItem NACKItem; + RTCPPacketRTPFBNACK NACK; + RTCPPacketRTPFBNACKItem NACKItem; - RTCPPacketPSFBPLI PLI; - RTCPPacketPSFBSLI SLI; - RTCPPacketPSFBSLIItem SLIItem; - RTCPPacketPSFBRPSI RPSI; - RTCPPacketPSFBAPP PSFBAPP; - RTCPPacketPSFBREMBItem REMBItem; + RTCPPacketPSFBPLI PLI; + RTCPPacketPSFBSLI SLI; + RTCPPacketPSFBSLIItem SLIItem; + RTCPPacketPSFBRPSI RPSI; + RTCPPacketPSFBAPP PSFBAPP; + RTCPPacketPSFBREMBItem REMBItem; - RTCPPacketRTPFBTMMBR TMMBR; - RTCPPacketRTPFBTMMBRItem TMMBRItem; - RTCPPacketRTPFBTMMBN TMMBN; - RTCPPacketRTPFBTMMBNItem TMMBNItem; - RTCPPacketPSFBFIR FIR; - RTCPPacketPSFBFIRItem FIRItem; + RTCPPacketRTPFBTMMBR TMMBR; + RTCPPacketRTPFBTMMBRItem TMMBRItem; + RTCPPacketRTPFBTMMBN TMMBN; + RTCPPacketRTPFBTMMBNItem TMMBNItem; + RTCPPacketPSFBFIR FIR; + RTCPPacketPSFBFIRItem FIRItem; - RTCPPacketXR XR; - RTCPPacketXRReceiverReferenceTimeItem XRReceiverReferenceTimeItem; - RTCPPacketXRDLRRReportBlockItem XRDLRRReportBlockItem; - RTCPPacketXRVOIPMetricItem XRVOIPMetricItem; + RTCPPacketXR XR; + RTCPPacketXRReceiverReferenceTimeItem XRReceiverReferenceTimeItem; + RTCPPacketXRDLRRReportBlockItem XRDLRRReportBlockItem; + RTCPPacketXRVOIPMetricItem XRVOIPMetricItem; - RTCPPacketAPP APP; - }; + RTCPPacketAPP APP; +}; - enum RTCPPacketTypes - { - kRtcpNotValidCode, +enum class RTCPPacketTypes { + kInvalid, - // RFC3550 - kRtcpRrCode, - kRtcpSrCode, - kRtcpReportBlockItemCode, + // RFC3550 + kRr, + kSr, + kReportBlockItem, - kRtcpSdesCode, - kRtcpSdesChunkCode, - kRtcpByeCode, + kSdes, + kSdesChunk, + kBye, - // RFC5450 - kRtcpExtendedIjCode, - kRtcpExtendedIjItemCode, + // RFC5450 + kExtendedIj, + kExtendedIjItem, - // RFC4585 - kRtcpRtpfbNackCode, - kRtcpRtpfbNackItemCode, + // RFC4585 + kRtpfbNack, + kRtpfbNackItem, - kRtcpPsfbPliCode, - kRtcpPsfbRpsiCode, - kRtcpPsfbSliCode, - kRtcpPsfbSliItemCode, - kRtcpPsfbAppCode, - kRtcpPsfbRembCode, - kRtcpPsfbRembItemCode, + kPsfbPli, + kPsfbRpsi, + kPsfbSli, + kPsfbSliItem, + kPsfbApp, + kPsfbRemb, + kPsfbRembItem, - // RFC5104 - kRtcpRtpfbTmmbrCode, - kRtcpRtpfbTmmbrItemCode, - kRtcpRtpfbTmmbnCode, - kRtcpRtpfbTmmbnItemCode, - kRtcpPsfbFirCode, - kRtcpPsfbFirItemCode, + // RFC5104 + kRtpfbTmmbr, + kRtpfbTmmbrItem, + kRtpfbTmmbn, + kRtpfbTmmbnItem, + kPsfbFir, + kPsfbFirItem, - // draft-perkins-avt-rapid-rtp-sync - kRtcpRtpfbSrReqCode, + // draft-perkins-avt-rapid-rtp-sync + kRtpfbSrReq, - // RFC 3611 - kRtcpXrHeaderCode, - kRtcpXrReceiverReferenceTimeCode, - kRtcpXrDlrrReportBlockCode, - kRtcpXrDlrrReportBlockItemCode, - kRtcpXrVoipMetricCode, + // RFC 3611 + kXrHeader, + kXrReceiverReferenceTime, + kXrDlrrReportBlock, + kXrDlrrReportBlockItem, + kXrVoipMetric, - kRtcpAppCode, - kRtcpAppItemCode, - }; + kApp, + kAppItem, +}; - struct RTCPRawPacket - { - const uint8_t* _ptrPacketBegin; - const uint8_t* _ptrPacketEnd; - }; +struct RTCPRawPacket { + const uint8_t* _ptrPacketBegin; + const uint8_t* _ptrPacketEnd; +}; - struct RTCPModRawPacket - { - uint8_t* _ptrPacketBegin; - uint8_t* _ptrPacketEnd; - }; +struct RTCPModRawPacket { + uint8_t* _ptrPacketBegin; + uint8_t* _ptrPacketEnd; +}; - struct RTCPCommonHeader - { - uint8_t V; // Version - bool P; // Padding - uint8_t IC; // Item count/subtype - uint8_t PT; // Packet Type - uint16_t LengthInOctets; - }; +struct RTCPCommonHeader { + uint8_t V; // Version + bool P; // Padding + uint8_t IC; // Item count/subtype + uint8_t PT; // Packet Type + uint16_t LengthInOctets; +}; - enum RTCPPT - { - PT_IJ = 195, - PT_SR = 200, - PT_RR = 201, - PT_SDES = 202, - PT_BYE = 203, - PT_APP = 204, - PT_RTPFB = 205, - PT_PSFB = 206, - PT_XR = 207 - }; +enum RTCPPT : uint8_t { + PT_IJ = 195, + PT_SR = 200, + PT_RR = 201, + PT_SDES = 202, + PT_BYE = 203, + PT_APP = 204, + PT_RTPFB = 205, + PT_PSFB = 206, + PT_XR = 207 +}; - // Extended report blocks, RFC 3611. - enum RtcpXrBlockType { - kBtReceiverReferenceTime = 4, - kBtDlrr = 5, - kBtVoipMetric = 7 - }; +// Extended report blocks, RFC 3611. +enum RtcpXrBlockType : uint8_t { + kBtReceiverReferenceTime = 4, + kBtDlrr = 5, + kBtVoipMetric = 7 +}; - bool RTCPParseCommonHeader( const uint8_t* ptrDataBegin, - const uint8_t* ptrDataEnd, - RTCPCommonHeader& parsedHeader); +bool RTCPParseCommonHeader(const uint8_t* ptrDataBegin, + const uint8_t* ptrDataEnd, + RTCPCommonHeader& parsedHeader); - class RTCPParserV2 - { - public: - RTCPParserV2(const uint8_t* rtcpData, - size_t rtcpDataLength, - bool rtcpReducedSizeEnable); // Set to true, to allow non-compound RTCP! - ~RTCPParserV2(); +class RTCPParserV2 { + public: + RTCPParserV2( + const uint8_t* rtcpData, + size_t rtcpDataLength, + bool rtcpReducedSizeEnable); // Set to true, to allow non-compound RTCP! + ~RTCPParserV2(); - RTCPPacketTypes PacketType() const; - const RTCPPacket& Packet() const; - const RTCPRawPacket& RawPacket() const; - ptrdiff_t LengthLeft() const; + RTCPPacketTypes PacketType() const; + const RTCPPacket& Packet() const; + const RTCPRawPacket& RawPacket() const; + ptrdiff_t LengthLeft() const; - bool IsValid() const; + bool IsValid() const; - RTCPPacketTypes Begin(); - RTCPPacketTypes Iterate(); + RTCPPacketTypes Begin(); + RTCPPacketTypes Iterate(); - private: - enum ParseState - { - State_TopLevel, // Top level packet - State_ReportBlockItem, // SR/RR report block - State_SDESChunk, // SDES chunk - State_BYEItem, // BYE item - State_ExtendedJitterItem, // Extended jitter report item - State_RTPFB_NACKItem, // NACK FCI item - State_RTPFB_TMMBRItem, // TMMBR FCI item - State_RTPFB_TMMBNItem, // TMMBN FCI item - State_PSFB_SLIItem, // SLI FCI item - State_PSFB_RPSIItem, // RPSI FCI item - State_PSFB_FIRItem, // FIR FCI item - State_PSFB_AppItem, // Application specific FCI item - State_PSFB_REMBItem, // Application specific REMB item - State_XRItem, - State_XR_DLLRItem, - State_AppItem - }; + private: + enum class ParseState { + State_TopLevel, // Top level packet + State_ReportBlockItem, // SR/RR report block + State_SDESChunk, // SDES chunk + State_BYEItem, // BYE item + State_ExtendedJitterItem, // Extended jitter report item + State_RTPFB_NACKItem, // NACK FCI item + State_RTPFB_TMMBRItem, // TMMBR FCI item + State_RTPFB_TMMBNItem, // TMMBN FCI item + State_PSFB_SLIItem, // SLI FCI item + State_PSFB_RPSIItem, // RPSI FCI item + State_PSFB_FIRItem, // FIR FCI item + State_PSFB_AppItem, // Application specific FCI item + State_PSFB_REMBItem, // Application specific REMB item + State_XRItem, + State_XR_DLLRItem, + State_AppItem + }; - private: - void IterateTopLevel(); - void IterateReportBlockItem(); - void IterateSDESChunk(); - void IterateBYEItem(); - void IterateExtendedJitterItem(); - void IterateNACKItem(); - void IterateTMMBRItem(); - void IterateTMMBNItem(); - void IterateSLIItem(); - void IterateRPSIItem(); - void IterateFIRItem(); - void IteratePsfbAppItem(); - void IteratePsfbREMBItem(); - void IterateAppItem(); - void IterateXrItem(); - void IterateXrDlrrItem(); + private: + void IterateTopLevel(); + void IterateReportBlockItem(); + void IterateSDESChunk(); + void IterateBYEItem(); + void IterateExtendedJitterItem(); + void IterateNACKItem(); + void IterateTMMBRItem(); + void IterateTMMBNItem(); + void IterateSLIItem(); + void IterateRPSIItem(); + void IterateFIRItem(); + void IteratePsfbAppItem(); + void IteratePsfbREMBItem(); + void IterateAppItem(); + void IterateXrItem(); + void IterateXrDlrrItem(); - void Validate(); - void EndCurrentBlock(); + void Validate(); + void EndCurrentBlock(); - bool ParseRR(); - bool ParseSR(); - bool ParseReportBlockItem(); + bool ParseRR(); + bool ParseSR(); + bool ParseReportBlockItem(); - bool ParseSDES(); - bool ParseSDESChunk(); - bool ParseSDESItem(); + bool ParseSDES(); + bool ParseSDESChunk(); + bool ParseSDESItem(); - bool ParseBYE(); - bool ParseBYEItem(); + bool ParseBYE(); + bool ParseBYEItem(); - bool ParseIJ(); - bool ParseIJItem(); + bool ParseIJ(); + bool ParseIJItem(); - bool ParseXr(); - bool ParseXrItem(); - bool ParseXrReceiverReferenceTimeItem(int block_length_4bytes); - bool ParseXrDlrr(int block_length_4bytes); - bool ParseXrDlrrItem(); - bool ParseXrVoipMetricItem(int block_length_4bytes); - bool ParseXrUnsupportedBlockType(int block_length_4bytes); + bool ParseXr(); + bool ParseXrItem(); + bool ParseXrReceiverReferenceTimeItem(int block_length_4bytes); + bool ParseXrDlrr(int block_length_4bytes); + bool ParseXrDlrrItem(); + bool ParseXrVoipMetricItem(int block_length_4bytes); + bool ParseXrUnsupportedBlockType(int block_length_4bytes); - bool ParseFBCommon(const RTCPCommonHeader& header); - bool ParseNACKItem(); - bool ParseTMMBRItem(); - bool ParseTMMBNItem(); - bool ParseSLIItem(); - bool ParseRPSIItem(); - bool ParseFIRItem(); - bool ParsePsfbAppItem(); - bool ParsePsfbREMBItem(); + bool ParseFBCommon(const RTCPCommonHeader& header); + bool ParseNACKItem(); + bool ParseTMMBRItem(); + bool ParseTMMBNItem(); + bool ParseSLIItem(); + bool ParseRPSIItem(); + bool ParseFIRItem(); + bool ParsePsfbAppItem(); + bool ParsePsfbREMBItem(); - bool ParseAPP(const RTCPCommonHeader& header); - bool ParseAPPItem(); + bool ParseAPP(const RTCPCommonHeader& header); + bool ParseAPPItem(); - private: - const uint8_t* const _ptrRTCPDataBegin; - const bool _RTCPReducedSizeEnable; - const uint8_t* const _ptrRTCPDataEnd; + private: + const uint8_t* const _ptrRTCPDataBegin; + const bool _RTCPReducedSizeEnable; + const uint8_t* const _ptrRTCPDataEnd; - bool _validPacket; - const uint8_t* _ptrRTCPData; - const uint8_t* _ptrRTCPBlockEnd; + bool _validPacket; + const uint8_t* _ptrRTCPData; + const uint8_t* _ptrRTCPBlockEnd; - ParseState _state; - uint8_t _numberOfBlocks; + ParseState _state; + uint8_t _numberOfBlocks; - RTCPPacketTypes _packetType; - RTCPPacket _packet; - }; + RTCPPacketTypes _packetType; + RTCPPacket _packet; +}; - class RTCPPacketIterator - { - public: - RTCPPacketIterator(uint8_t* rtcpData, - size_t rtcpDataLength); - ~RTCPPacketIterator(); +class RTCPPacketIterator { + public: + RTCPPacketIterator(uint8_t* rtcpData, size_t rtcpDataLength); + ~RTCPPacketIterator(); - const RTCPCommonHeader* Begin(); - const RTCPCommonHeader* Iterate(); - const RTCPCommonHeader* Current(); + const RTCPCommonHeader* Begin(); + const RTCPCommonHeader* Iterate(); + const RTCPCommonHeader* Current(); - private: - uint8_t* const _ptrBegin; - uint8_t* const _ptrEnd; + private: + uint8_t* const _ptrBegin; + uint8_t* const _ptrEnd; - uint8_t* _ptrBlock; + uint8_t* _ptrBlock; - RTCPCommonHeader _header; - }; + RTCPCommonHeader _header; +}; } // RTCPUtility } // namespace webrtc #endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_UTILITY_H_ diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc index 559f726da..935929558 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc @@ -556,8 +556,15 @@ int32_t ModuleRtpRtcpImpl::ResetSendDataCountersRTP() { // Force a send of an RTCP packet. // Normal SR and RR are triggered via the process function. -int32_t ModuleRtpRtcpImpl::SendRTCP(uint32_t rtcp_packet_type) { - return rtcp_sender_.SendRTCP(GetFeedbackState(), rtcp_packet_type); +int32_t ModuleRtpRtcpImpl::SendRTCP(RTCPPacketType packet_type) { + return rtcp_sender_.SendRTCP(GetFeedbackState(), packet_type); +} + +// Force a send of an RTCP packet. +// Normal SR and RR are triggered via the process function. +int32_t ModuleRtpRtcpImpl::SendCompoundRTCP( + const std::set& packet_types) { + return rtcp_sender_.SendCompoundRTCP(GetFeedbackState(), packet_types); } int32_t ModuleRtpRtcpImpl::SetRTCPApplicationSpecificData( diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h index d7267e7b7..e8c9a2148 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h +++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h @@ -161,7 +161,10 @@ class ModuleRtpRtcpImpl : public RtpRtcp { // Force a send of an RTCP packet. // Normal SR and RR are triggered via the process function. - int32_t SendRTCP(uint32_t rtcp_packet_type = kRtcpReport) override; + int32_t SendRTCP(RTCPPacketType rtcpPacketType) override; + + int32_t SendCompoundRTCP( + const std::set& rtcpPacketTypes) override; int32_t ResetSendDataCountersRTP() override; diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc index 3eb05a9b8..3cff2a4d3 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc @@ -373,7 +373,10 @@ TEST_F(RtpRtcpImplTest, RtcpPacketTypeCounter_FirAndPli) { EXPECT_EQ(1U, sender_.RtcpReceived().fir_packets); // Receive module sends a FIR and PLI. - EXPECT_EQ(0, receiver_.impl_->SendRTCP(kRtcpFir | kRtcpPli)); + std::set packet_types; + packet_types.insert(kRtcpFir); + packet_types.insert(kRtcpPli); + EXPECT_EQ(0, receiver_.impl_->SendCompoundRTCP(packet_types)); EXPECT_EQ(2U, receiver_.RtcpSent().fir_packets); EXPECT_EQ(1U, receiver_.RtcpSent().pli_packets); // Send module receives the FIR and PLI. diff --git a/webrtc/test/rtcp_packet_parser.cc b/webrtc/test/rtcp_packet_parser.cc index b9e430fe9..8ce249e0b 100644 --- a/webrtc/test/rtcp_packet_parser.cc +++ b/webrtc/test/rtcp_packet_parser.cc @@ -15,6 +15,8 @@ namespace webrtc { namespace test { +using namespace RTCPUtility; + RtcpPacketParser::RtcpPacketParser() {} RtcpPacketParser::~RtcpPacketParser() {} @@ -24,98 +26,97 @@ void RtcpPacketParser::Parse(const void *data, size_t len) { RTCPUtility::RTCPParserV2 parser(packet, len, true); EXPECT_TRUE(parser.IsValid()); for (RTCPUtility::RTCPPacketTypes type = parser.Begin(); - type != RTCPUtility::kRtcpNotValidCode; - type = parser.Iterate()) { + type != RTCPPacketTypes::kInvalid; type = parser.Iterate()) { switch (type) { - case RTCPUtility::kRtcpSrCode: + case RTCPPacketTypes::kSr: sender_report_.Set(parser.Packet().SR); break; - case RTCPUtility::kRtcpRrCode: + case RTCPPacketTypes::kRr: receiver_report_.Set(parser.Packet().RR); break; - case RTCPUtility::kRtcpReportBlockItemCode: + case RTCPPacketTypes::kReportBlockItem: report_block_.Set(parser.Packet().ReportBlockItem); ++report_blocks_per_ssrc_[parser.Packet().ReportBlockItem.SSRC]; break; - case RTCPUtility::kRtcpSdesCode: + case RTCPPacketTypes::kSdes: sdes_.Set(); break; - case RTCPUtility::kRtcpSdesChunkCode: + case RTCPPacketTypes::kSdesChunk: sdes_chunk_.Set(parser.Packet().CName); break; - case RTCPUtility::kRtcpByeCode: + case RTCPPacketTypes::kBye: bye_.Set(parser.Packet().BYE); break; - case RTCPUtility::kRtcpAppCode: + case RTCPPacketTypes::kApp: app_.Set(parser.Packet().APP); break; - case RTCPUtility::kRtcpAppItemCode: + case RTCPPacketTypes::kAppItem: app_item_.Set(parser.Packet().APP); break; - case RTCPUtility::kRtcpExtendedIjCode: + case RTCPPacketTypes::kExtendedIj: ij_.Set(); break; - case RTCPUtility::kRtcpExtendedIjItemCode: + case RTCPPacketTypes::kExtendedIjItem: ij_item_.Set(parser.Packet().ExtendedJitterReportItem); break; - case RTCPUtility::kRtcpPsfbPliCode: + case RTCPPacketTypes::kPsfbPli: pli_.Set(parser.Packet().PLI); break; - case RTCPUtility::kRtcpPsfbSliCode: + case RTCPPacketTypes::kPsfbSli: sli_.Set(parser.Packet().SLI); break; - case RTCPUtility::kRtcpPsfbSliItemCode: + case RTCPPacketTypes::kPsfbSliItem: sli_item_.Set(parser.Packet().SLIItem); break; - case RTCPUtility::kRtcpPsfbRpsiCode: + case RTCPPacketTypes::kPsfbRpsi: rpsi_.Set(parser.Packet().RPSI); break; - case RTCPUtility::kRtcpPsfbFirCode: + case RTCPPacketTypes::kPsfbFir: fir_.Set(parser.Packet().FIR); break; - case RTCPUtility::kRtcpPsfbFirItemCode: + case RTCPPacketTypes::kPsfbFirItem: fir_item_.Set(parser.Packet().FIRItem); break; - case RTCPUtility::kRtcpRtpfbNackCode: + case RTCPPacketTypes::kRtpfbNack: nack_.Set(parser.Packet().NACK); nack_item_.Clear(); break; - case RTCPUtility::kRtcpRtpfbNackItemCode: + case RTCPPacketTypes::kRtpfbNackItem: nack_item_.Set(parser.Packet().NACKItem); break; - case RTCPUtility::kRtcpPsfbAppCode: + case RTCPPacketTypes::kPsfbApp: psfb_app_.Set(parser.Packet().PSFBAPP); break; - case RTCPUtility::kRtcpPsfbRembItemCode: + case RTCPPacketTypes::kPsfbRembItem: remb_item_.Set(parser.Packet().REMBItem); break; - case RTCPUtility::kRtcpRtpfbTmmbrCode: + case RTCPPacketTypes::kRtpfbTmmbr: tmmbr_.Set(parser.Packet().TMMBR); break; - case RTCPUtility::kRtcpRtpfbTmmbrItemCode: + case RTCPPacketTypes::kRtpfbTmmbrItem: tmmbr_item_.Set(parser.Packet().TMMBRItem); break; - case RTCPUtility::kRtcpRtpfbTmmbnCode: + case RTCPPacketTypes::kRtpfbTmmbn: tmmbn_.Set(parser.Packet().TMMBN); tmmbn_items_.Clear(); break; - case RTCPUtility::kRtcpRtpfbTmmbnItemCode: + case RTCPPacketTypes::kRtpfbTmmbnItem: tmmbn_items_.Set(parser.Packet().TMMBNItem); break; - case RTCPUtility::kRtcpXrHeaderCode: + case RTCPPacketTypes::kXrHeader: xr_header_.Set(parser.Packet().XR); dlrr_items_.Clear(); break; - case RTCPUtility::kRtcpXrReceiverReferenceTimeCode: + case RTCPPacketTypes::kXrReceiverReferenceTime: rrtr_.Set(parser.Packet().XRReceiverReferenceTimeItem); break; - case RTCPUtility::kRtcpXrDlrrReportBlockCode: + case RTCPPacketTypes::kXrDlrrReportBlock: dlrr_.Set(); break; - case RTCPUtility::kRtcpXrDlrrReportBlockItemCode: + case RTCPPacketTypes::kXrDlrrReportBlockItem: dlrr_items_.Set(parser.Packet().XRDLRRReportBlockItem); break; - case RTCPUtility::kRtcpXrVoipMetricCode: + case RTCPPacketTypes::kXrVoipMetric: voip_metric_.Set(parser.Packet().XRVOIPMetricItem); break; default: diff --git a/webrtc/video/call_perf_tests.cc b/webrtc/video/call_perf_tests.cc index fc1aefc87..5df1fd3ff 100644 --- a/webrtc/video/call_perf_tests.cc +++ b/webrtc/video/call_perf_tests.cc @@ -66,9 +66,9 @@ class SyncRtcpObserver : public test::RtpRtcpObserver { EXPECT_TRUE(parser.IsValid()); for (RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); - packet_type != RTCPUtility::kRtcpNotValidCode; + packet_type != RTCPUtility::RTCPPacketTypes::kInvalid; packet_type = parser.Iterate()) { - if (packet_type == RTCPUtility::kRtcpSrCode) { + if (packet_type == RTCPUtility::RTCPPacketTypes::kSr) { const RTCPUtility::RTCPPacket& packet = parser.Packet(); RtcpMeasurement ntp_rtp_pair( packet.SR.NTPMostSignificant, diff --git a/webrtc/video/end_to_end_tests.cc b/webrtc/video/end_to_end_tests.cc index 1b4e990cd..6236483bf 100644 --- a/webrtc/video/end_to_end_tests.cc +++ b/webrtc/video/end_to_end_tests.cc @@ -418,8 +418,8 @@ TEST_F(EndToEndTest, ReceivesAndRetransmitsNack) { EXPECT_TRUE(parser.IsValid()); RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); - while (packet_type != RTCPUtility::kRtcpNotValidCode) { - if (packet_type == RTCPUtility::kRtcpRtpfbNackCode) { + while (packet_type != RTCPUtility::RTCPPacketTypes::kInvalid) { + if (packet_type == RTCPUtility::RTCPPacketTypes::kRtpfbNack) { --nacks_left_; break; } @@ -929,12 +929,12 @@ void EndToEndTest::ReceivesPliAndRecovers(int rtp_history_ms) { EXPECT_TRUE(parser.IsValid()); for (RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); - packet_type != RTCPUtility::kRtcpNotValidCode; + packet_type != RTCPUtility::RTCPPacketTypes::kInvalid; packet_type = parser.Iterate()) { if (!nack_enabled_) - EXPECT_NE(packet_type, RTCPUtility::kRtcpRtpfbNackCode); + EXPECT_NE(packet_type, RTCPUtility::RTCPPacketTypes::kRtpfbNack); - if (packet_type == RTCPUtility::kRtcpPsfbPliCode) { + if (packet_type == RTCPUtility::RTCPPacketTypes::kPsfbPli) { received_pli_ = true; break; } @@ -1070,9 +1070,9 @@ void EndToEndTest::RespectsRtcpMode(newapi::RtcpMode rtcp_mode) { RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); bool has_report_block = false; - while (packet_type != RTCPUtility::kRtcpNotValidCode) { - EXPECT_NE(RTCPUtility::kRtcpSrCode, packet_type); - if (packet_type == RTCPUtility::kRtcpRrCode) { + while (packet_type != RTCPUtility::RTCPPacketTypes::kInvalid) { + EXPECT_NE(RTCPUtility::RTCPPacketTypes::kSr, packet_type); + if (packet_type == RTCPUtility::RTCPPacketTypes::kRr) { has_report_block = true; break; } @@ -1336,12 +1336,12 @@ TEST_F(EndToEndTest, ReceiveStreamSendsRemb) { bool received_psfb = false; bool received_remb = false; RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); - while (packet_type != RTCPUtility::kRtcpNotValidCode) { - if (packet_type == RTCPUtility::kRtcpPsfbRembCode) { + while (packet_type != RTCPUtility::RTCPPacketTypes::kInvalid) { + if (packet_type == RTCPUtility::RTCPPacketTypes::kPsfbRemb) { const RTCPUtility::RTCPPacket& packet = parser.Packet(); EXPECT_EQ(packet.PSFBAPP.SenderSSRC, kReceiverLocalSsrc); received_psfb = true; - } else if (packet_type == RTCPUtility::kRtcpPsfbRembItemCode) { + } else if (packet_type == RTCPUtility::RTCPPacketTypes::kPsfbRembItem) { const RTCPUtility::RTCPPacket& packet = parser.Packet(); EXPECT_GT(packet.REMBItem.BitRate, 0u); EXPECT_EQ(packet.REMBItem.NumberOfSSRCs, 1u); @@ -1700,15 +1700,16 @@ void EndToEndTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) { EXPECT_TRUE(parser.IsValid()); RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); - while (packet_type != RTCPUtility::kRtcpNotValidCode) { - if (packet_type == RTCPUtility::kRtcpRrCode) { + while (packet_type != RTCPUtility::RTCPPacketTypes::kInvalid) { + if (packet_type == RTCPUtility::RTCPPacketTypes::kRr) { ++sent_rtcp_rr_; } else if (packet_type == - RTCPUtility::kRtcpXrReceiverReferenceTimeCode) { + RTCPUtility::RTCPPacketTypes::kXrReceiverReferenceTime) { ++sent_rtcp_rrtr_; } - EXPECT_NE(packet_type, RTCPUtility::kRtcpSrCode); - EXPECT_NE(packet_type, RTCPUtility::kRtcpXrDlrrReportBlockItemCode); + EXPECT_NE(packet_type, RTCPUtility::RTCPPacketTypes::kSr); + EXPECT_NE(packet_type, + RTCPUtility::RTCPPacketTypes::kXrDlrrReportBlockItem); packet_type = parser.Iterate(); } return SEND_PACKET; @@ -1719,13 +1720,15 @@ void EndToEndTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) { EXPECT_TRUE(parser.IsValid()); RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); - while (packet_type != RTCPUtility::kRtcpNotValidCode) { - if (packet_type == RTCPUtility::kRtcpSrCode) { + while (packet_type != RTCPUtility::RTCPPacketTypes::kInvalid) { + if (packet_type == RTCPUtility::RTCPPacketTypes::kSr) { ++sent_rtcp_sr_; - } else if (packet_type == RTCPUtility::kRtcpXrDlrrReportBlockItemCode) { + } else if (packet_type == + RTCPUtility::RTCPPacketTypes::kXrDlrrReportBlockItem) { ++sent_rtcp_dlrr_; } - EXPECT_NE(packet_type, RTCPUtility::kRtcpXrReceiverReferenceTimeCode); + EXPECT_NE(packet_type, + RTCPUtility::RTCPPacketTypes::kXrReceiverReferenceTime); packet_type = parser.Iterate(); } if (sent_rtcp_sr_ > kNumRtcpReportPacketsToObserve && diff --git a/webrtc/video/video_send_stream_tests.cc b/webrtc/video/video_send_stream_tests.cc index 547c81179..a02e8782f 100644 --- a/webrtc/video/video_send_stream_tests.cc +++ b/webrtc/video/video_send_stream_tests.cc @@ -104,8 +104,8 @@ TEST_F(VideoSendStreamTest, SupportsCName) { EXPECT_TRUE(parser.IsValid()); RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); - while (packet_type != RTCPUtility::kRtcpNotValidCode) { - if (packet_type == RTCPUtility::kRtcpSdesChunkCode) { + while (packet_type != RTCPUtility::RTCPPacketTypes::kInvalid) { + if (packet_type == RTCPUtility::RTCPPacketTypes::kSdesChunk) { EXPECT_EQ(parser.Packet().CName.CName, kCName); observation_complete_->Set(); } @@ -1514,8 +1514,8 @@ TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) { EXPECT_TRUE(parser.IsValid()); RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); - while (packet_type != RTCPUtility::kRtcpNotValidCode) { - if (packet_type == RTCPUtility::kRtcpSrCode) { + while (packet_type != RTCPUtility::RTCPPacketTypes::kInvalid) { + if (packet_type == RTCPUtility::RTCPPacketTypes::kSr) { // Only compare sent media bytes if SenderPacketCount matches the // number of sent rtp packets (a new rtp packet could be sent before // the rtcp packet).