diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc index f44021ece..07ce33620 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc @@ -10,6 +10,7 @@ #include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h" +#include "webrtc/base/checks.h" #include "webrtc/modules/rtp_rtcp/source/byte_io.h" #include "webrtc/system_wrappers/interface/logging.h" @@ -290,10 +291,8 @@ void CreateBye(const RTCPPacketBYE& bye, size_t* pos) { CreateHeader(length, PT_BYE, length, buffer, pos); AssignUWord32(buffer, pos, bye.SenderSSRC); - for (std::vector::const_iterator it = csrcs.begin(); - it != csrcs.end(); ++it) { - AssignUWord32(buffer, pos, *it); - } + for (uint32_t csrc : csrcs) + AssignUWord32(buffer, pos, csrc); } // Application-Defined packet (APP) (RFC 3550). @@ -392,6 +391,8 @@ void CreateSli(const RTCPPacketPSFBSLI& sli, void CreateNack(const RTCPPacketRTPFBNACK& nack, const std::vector& nack_fields, + size_t start_index, + size_t end_index, size_t length, uint8_t* buffer, size_t* pos) { @@ -399,10 +400,10 @@ void CreateNack(const RTCPPacketRTPFBNACK& nack, CreateHeader(kFmt, PT_RTPFB, length, buffer, pos); AssignUWord32(buffer, pos, nack.SenderSSRC); AssignUWord32(buffer, pos, nack.MediaSSRC); - for (std::vector::const_iterator - it = nack_fields.begin(); it != nack_fields.end(); ++it) { - AssignUWord16(buffer, pos, (*it).PacketID); - AssignUWord16(buffer, pos, (*it).BitMask); + for (size_t i = start_index; i < end_index; ++i) { + const RTCPPacketRTPFBNACKItem& nack_item = nack_fields[i]; + AssignUWord16(buffer, pos, nack_item.PacketID); + AssignUWord16(buffer, pos, nack_item.BitMask); } } @@ -727,105 +728,162 @@ void RtcpPacket::Append(RtcpPacket* packet) { appended_packets_.push_back(packet); } -RawPacket RtcpPacket::Build() const { +rtc::scoped_ptr RtcpPacket::Build() const { size_t length = 0; - uint8_t packet[IP_PACKET_SIZE]; - CreateAndAddAppended(packet, &length, IP_PACKET_SIZE); - return RawPacket(packet, length); + rtc::scoped_ptr packet(new RawPacket(IP_PACKET_SIZE)); + + class PacketVerifier : public PacketReadyCallback { + public: + explicit PacketVerifier(RawPacket* packet) + : called_(false), packet_(packet) {} + virtual ~PacketVerifier() {} + void OnPacketReady(uint8_t* data, size_t length) override { + CHECK(!called_) << "Fragmentation not supported."; + called_ = true; + packet_->SetLength(length); + } + + private: + bool called_; + RawPacket* const packet_; + } verifier(packet.get()); + CreateAndAddAppended(packet->MutableBuffer(), &length, packet->BufferLength(), + &verifier); + OnBufferFull(packet->MutableBuffer(), &length, &verifier); + return packet; } -void RtcpPacket::Build(uint8_t* packet, - size_t* length, - size_t max_length) const { - *length = 0; - CreateAndAddAppended(packet, length, max_length); +bool RtcpPacket::Build(PacketReadyCallback* callback) const { + uint8_t buffer[IP_PACKET_SIZE]; + return BuildExternalBuffer(buffer, IP_PACKET_SIZE, callback); } -void RtcpPacket::CreateAndAddAppended(uint8_t* packet, - size_t* length, - size_t max_length) const { - Create(packet, length, max_length); - for (std::vector::const_iterator it = appended_packets_.begin(); - it != appended_packets_.end(); ++it) { - (*it)->CreateAndAddAppended(packet, length, max_length); +bool RtcpPacket::BuildExternalBuffer(uint8_t* buffer, + size_t max_length, + PacketReadyCallback* callback) const { + size_t index = 0; + if (!CreateAndAddAppended(buffer, &index, max_length, callback)) + return false; + return OnBufferFull(buffer, &index, callback); +} + +bool RtcpPacket::CreateAndAddAppended(uint8_t* packet, + size_t* index, + size_t max_length, + PacketReadyCallback* callback) const { + if (!Create(packet, index, max_length, callback)) + return false; + for (RtcpPacket* appended : appended_packets_) { + if (!appended->CreateAndAddAppended(packet, index, max_length, callback)) + return false; } + return true; } -void Empty::Create(uint8_t* packet, size_t* length, size_t max_length) const { +bool RtcpPacket::OnBufferFull(uint8_t* packet, + size_t* index, + RtcpPacket::PacketReadyCallback* callback) const { + if (*index == 0) + return false; + callback->OnPacketReady(packet, *index); + *index = 0; + return true; } -void SenderReport::Create(uint8_t* packet, - size_t* length, - size_t max_length) const { - if (*length + BlockLength() > max_length) { - LOG(LS_WARNING) << "Max packet size reached."; - return; +bool Empty::Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const { + return true; +} + +bool SenderReport::Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const { + while (*index + BlockLength() > max_length) { + if (!OnBufferFull(packet, index, callback)) + return false; } - CreateSenderReport(sr_, BlockToHeaderLength(BlockLength()), packet, length); - CreateReportBlocks(report_blocks_, packet, length); + CreateSenderReport(sr_, BlockToHeaderLength(BlockLength()), packet, index); + CreateReportBlocks(report_blocks_, packet, index); + return true; } -void SenderReport::WithReportBlock(ReportBlock* block) { +bool SenderReport::WithReportBlock(ReportBlock* block) { assert(block); if (report_blocks_.size() >= kMaxNumberOfReportBlocks) { LOG(LS_WARNING) << "Max report blocks reached."; - return; + return false; } report_blocks_.push_back(block->report_block_); sr_.NumberOfReportBlocks = report_blocks_.size(); + return true; } -void ReceiverReport::Create(uint8_t* packet, - size_t* length, - size_t max_length) const { - if (*length + BlockLength() > max_length) { - LOG(LS_WARNING) << "Max packet size reached."; - return; +bool ReceiverReport::Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const { + while (*index + BlockLength() > max_length) { + if (!OnBufferFull(packet, index, callback)) + return false; } - CreateReceiverReport(rr_, BlockToHeaderLength(BlockLength()), packet, length); - CreateReportBlocks(report_blocks_, packet, length); + CreateReceiverReport(rr_, BlockToHeaderLength(BlockLength()), packet, index); + CreateReportBlocks(report_blocks_, packet, index); + return true; } -void ReceiverReport::WithReportBlock(ReportBlock* block) { +bool ReceiverReport::WithReportBlock(ReportBlock* block) { assert(block); if (report_blocks_.size() >= kMaxNumberOfReportBlocks) { LOG(LS_WARNING) << "Max report blocks reached."; - return; + return false; } report_blocks_.push_back(block->report_block_); rr_.NumberOfReportBlocks = report_blocks_.size(); + return true; } -void Ij::Create(uint8_t* packet, size_t* length, size_t max_length) const { - if (*length + BlockLength() > max_length) { - LOG(LS_WARNING) << "Max packet size reached."; - return; +bool Ij::Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const { + while (*index + BlockLength() > max_length) { + if (!OnBufferFull(packet, index, callback)) + return false; } - CreateIj(ij_items_, packet, length); + CreateIj(ij_items_, packet, index); + return true; } -void Ij::WithJitterItem(uint32_t jitter) { +bool Ij::WithJitterItem(uint32_t jitter) { if (ij_items_.size() >= kMaxNumberOfIjItems) { LOG(LS_WARNING) << "Max inter-arrival jitter items reached."; - return; + return false; } ij_items_.push_back(jitter); + return true; } -void Sdes::Create(uint8_t* packet, size_t* length, size_t max_length) const { +bool Sdes::Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const { assert(!chunks_.empty()); - if (*length + BlockLength() > max_length) { - LOG(LS_WARNING) << "Max packet size reached."; - return; + while (*index + BlockLength() > max_length) { + if (!OnBufferFull(packet, index, callback)) + return false; } - CreateSdes(chunks_, BlockToHeaderLength(BlockLength()), packet, length); + CreateSdes(chunks_, BlockToHeaderLength(BlockLength()), packet, index); + return true; } -void Sdes::WithCName(uint32_t ssrc, std::string cname) { +bool Sdes::WithCName(uint32_t ssrc, const std::string& cname) { assert(cname.length() <= 0xff); if (chunks_.size() >= kMaxNumberOfChunks) { LOG(LS_WARNING) << "Max SDES chunks reached."; - return; + return false; } // In each chunk, the list of items must be terminated by one or more null // octets. The next chunk must start on a 32-bit boundary. @@ -836,6 +894,7 @@ void Sdes::WithCName(uint32_t ssrc, std::string cname) { chunk.name = cname; chunk.null_octets = null_octets; chunks_.push_back(chunk); + return true; } size_t Sdes::BlockLength() const { @@ -843,63 +902,95 @@ size_t Sdes::BlockLength() const { // Chunk: // SSRC/CSRC (4 bytes) | CNAME (1 byte) | length (1 byte) | name | padding. size_t length = kHeaderLength; - for (std::vector::const_iterator it = chunks_.begin(); - it != chunks_.end(); ++it) { - length += 6 + (*it).name.length() + (*it).null_octets; - } + for (const Chunk& chunk : chunks_) + length += 6 + chunk.name.length() + chunk.null_octets; assert(length % 4 == 0); return length; } -void Bye::Create(uint8_t* packet, size_t* length, size_t max_length) const { - if (*length + BlockLength() > max_length) { - LOG(LS_WARNING) << "Max packet size reached."; - return; +bool Bye::Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const { + while (*index + BlockLength() > max_length) { + if (!OnBufferFull(packet, index, callback)) + return false; } - CreateBye(bye_, csrcs_, BlockToHeaderLength(BlockLength()), packet, length); + CreateBye(bye_, csrcs_, BlockToHeaderLength(BlockLength()), packet, index); + return true; } -void Bye::WithCsrc(uint32_t csrc) { +bool Bye::WithCsrc(uint32_t csrc) { if (csrcs_.size() >= kMaxNumberOfCsrcs) { LOG(LS_WARNING) << "Max CSRC size reached."; - return; + return false; } csrcs_.push_back(csrc); + return true; } -void App::Create(uint8_t* packet, size_t* length, size_t max_length) const { - if (*length + BlockLength() > max_length) { - LOG(LS_WARNING) << "Max packet size reached."; - return; +bool App::Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const { + while (*index + BlockLength() > max_length) { + if (!OnBufferFull(packet, index, callback)) + return false; } - CreateApp(app_, ssrc_, BlockToHeaderLength(BlockLength()), packet, length); + CreateApp(app_, ssrc_, BlockToHeaderLength(BlockLength()), packet, index); + return true; } -void Pli::Create(uint8_t* packet, size_t* length, size_t max_length) const { - if (*length + BlockLength() > max_length) { - LOG(LS_WARNING) << "Max packet size reached."; - return; +bool Pli::Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const { + while (*index + BlockLength() > max_length) { + if (!OnBufferFull(packet, index, callback)) + return false; } - CreatePli(pli_, BlockToHeaderLength(BlockLength()), packet, length); + CreatePli(pli_, BlockToHeaderLength(BlockLength()), packet, index); + return true; } -void Sli::Create(uint8_t* packet, size_t* length, size_t max_length) const { - if (*length + BlockLength() > max_length) { - LOG(LS_WARNING) << "Max packet size reached."; - return; +bool Sli::Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const { + while (*index + BlockLength() > max_length) { + if (!OnBufferFull(packet, index, callback)) + return false; } - CreateSli(sli_, sli_item_, BlockToHeaderLength(BlockLength()), packet, - length); + CreateSli(sli_, sli_item_, BlockToHeaderLength(BlockLength()), packet, index); + return true; } -void Nack::Create(uint8_t* packet, size_t* length, size_t max_length) const { +bool Nack::Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const { assert(!nack_fields_.empty()); - if (*length + BlockLength() > max_length) { - LOG(LS_WARNING) << "Max packet size reached."; - return; - } - CreateNack(nack_, nack_fields_, BlockToHeaderLength(BlockLength()), packet, - length); + // If nack list can't fit in packet, try to fragment. + size_t nack_index = 0; + do { + size_t bytes_left_in_buffer = max_length - *index; + if (bytes_left_in_buffer < kCommonFbFmtLength + 4) { + if (!OnBufferFull(packet, index, callback)) + return false; + continue; + } + int64_t num_nack_fields = + std::min((bytes_left_in_buffer - kCommonFbFmtLength) / 4, + nack_fields_.size() - nack_index); + + CreateNack(nack_, nack_fields_, nack_index, nack_index + num_nack_fields, + BlockToHeaderLength((num_nack_fields * 4) + kCommonFbFmtLength), + packet, index); + + nack_index += num_nack_fields; + } while (nack_index < nack_fields_.size()); + + return true; } void Nack::WithList(const uint16_t* nack_list, int length) { @@ -926,14 +1017,18 @@ void Nack::WithList(const uint16_t* nack_list, int length) { } } -void Rpsi::Create(uint8_t* packet, size_t* length, size_t max_length) const { +bool Rpsi::Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const { assert(rpsi_.NumberOfValidBits > 0); - if (*length + BlockLength() > max_length) { - LOG(LS_WARNING) << "Max packet size reached."; - return; + while (*index + BlockLength() > max_length) { + if (!OnBufferFull(packet, index, callback)) + return false; } CreateRpsi(rpsi_, padding_bytes_, BlockToHeaderLength(BlockLength()), packet, - length); + index); + return true; } void Rpsi::WithPictureId(uint64_t picture_id) { @@ -963,22 +1058,29 @@ void Rpsi::WithPictureId(uint64_t picture_id) { } } -void Fir::Create(uint8_t* packet, size_t* length, size_t max_length) const { - if (*length + BlockLength() > max_length) { - LOG(LS_WARNING) << "Max packet size reached."; - return; +bool Fir::Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const { + while (*index + BlockLength() > max_length) { + if (!OnBufferFull(packet, index, callback)) + return false; } - CreateFir(fir_, fir_item_, BlockToHeaderLength(BlockLength()), packet, - length); + CreateFir(fir_, fir_item_, BlockToHeaderLength(BlockLength()), packet, index); + return true; } -void Remb::Create(uint8_t* packet, size_t* length, size_t max_length) const { - if (*length + BlockLength() > max_length) { - LOG(LS_WARNING) << "Max packet size reached."; - return; +bool Remb::Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const { + while (*index + BlockLength() > max_length) { + if (!OnBufferFull(packet, index, callback)) + return false; } CreateRemb(remb_, remb_item_, BlockToHeaderLength(BlockLength()), packet, - length); + index); + return true; } void Remb::AppliesTo(uint32_t ssrc) { @@ -989,74 +1091,89 @@ void Remb::AppliesTo(uint32_t ssrc) { remb_item_.SSRCs[remb_item_.NumberOfSSRCs++] = ssrc; } -void Tmmbr::Create(uint8_t* packet, size_t* length, size_t max_length) const { - if (*length + BlockLength() > max_length) { - LOG(LS_WARNING) << "Max packet size reached."; - return; +bool Tmmbr::Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const { + while (*index + BlockLength() > max_length) { + if (!OnBufferFull(packet, index, callback)) + return false; } CreateTmmbr(tmmbr_, tmmbr_item_, BlockToHeaderLength(BlockLength()), packet, - length); + index); + return true; } -void Tmmbn::WithTmmbr(uint32_t ssrc, uint32_t bitrate_kbps, uint16_t overhead) { +bool Tmmbn::WithTmmbr(uint32_t ssrc, uint32_t bitrate_kbps, uint16_t overhead) { assert(overhead <= 0x1ff); if (tmmbn_items_.size() >= kMaxNumberOfTmmbrs) { LOG(LS_WARNING) << "Max TMMBN size reached."; - return; + return false; } RTCPPacketRTPFBTMMBRItem tmmbn_item; tmmbn_item.SSRC = ssrc; tmmbn_item.MaxTotalMediaBitRate = bitrate_kbps; tmmbn_item.MeasuredOverhead = overhead; tmmbn_items_.push_back(tmmbn_item); + return true; } -void Tmmbn::Create(uint8_t* packet, size_t* length, size_t max_length) const { - if (*length + BlockLength() > max_length) { - LOG(LS_WARNING) << "Max packet size reached."; - return; +bool Tmmbn::Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const { + while (*index + BlockLength() > max_length) { + if (!OnBufferFull(packet, index, callback)) + return false; } CreateTmmbn(tmmbn_, tmmbn_items_, BlockToHeaderLength(BlockLength()), packet, - length); + index); + return true; } -void Xr::Create(uint8_t* packet, size_t* length, size_t max_length) const { - if (*length + BlockLength() > max_length) { - LOG(LS_WARNING) << "Max packet size reached."; - return; +bool Xr::Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const { + while (*index + BlockLength() > max_length) { + if (!OnBufferFull(packet, index, callback)) + return false; } - CreateXrHeader(xr_header_, BlockToHeaderLength(BlockLength()), packet, - length); - CreateRrtr(rrtr_blocks_, packet, length); - CreateDlrr(dlrr_blocks_, packet, length); - CreateVoipMetric(voip_metric_blocks_, packet, length); + CreateXrHeader(xr_header_, BlockToHeaderLength(BlockLength()), packet, index); + CreateRrtr(rrtr_blocks_, packet, index); + CreateDlrr(dlrr_blocks_, packet, index); + CreateVoipMetric(voip_metric_blocks_, packet, index); + return true; } -void Xr::WithRrtr(Rrtr* rrtr) { +bool Xr::WithRrtr(Rrtr* rrtr) { assert(rrtr); if (rrtr_blocks_.size() >= kMaxNumberOfRrtrBlocks) { LOG(LS_WARNING) << "Max RRTR blocks reached."; - return; + return false; } rrtr_blocks_.push_back(rrtr->rrtr_block_); + return true; } -void Xr::WithDlrr(Dlrr* dlrr) { +bool Xr::WithDlrr(Dlrr* dlrr) { assert(dlrr); if (dlrr_blocks_.size() >= kMaxNumberOfDlrrBlocks) { LOG(LS_WARNING) << "Max DLRR blocks reached."; - return; + return false; } dlrr_blocks_.push_back(dlrr->dlrr_block_); + return true; } -void Xr::WithVoipMetric(VoipMetric* voip_metric) { +bool Xr::WithVoipMetric(VoipMetric* voip_metric) { assert(voip_metric); if (voip_metric_blocks_.size() >= kMaxNumberOfVoipMetricBlocks) { LOG(LS_WARNING) << "Max Voip Metric blocks reached."; - return; + return false; } voip_metric_blocks_.push_back(voip_metric->metric_); + return true; } size_t Xr::DlrrLength() const { @@ -1072,18 +1189,51 @@ size_t Xr::DlrrLength() const { return length; } -void Dlrr::WithDlrrItem(uint32_t ssrc, +bool Dlrr::WithDlrrItem(uint32_t ssrc, uint32_t last_rr, uint32_t delay_last_rr) { if (dlrr_block_.size() >= kMaxNumberOfDlrrItems) { LOG(LS_WARNING) << "Max DLRR items reached."; - return; + return false; } RTCPPacketXRDLRRReportBlockItem dlrr; dlrr.SSRC = ssrc; dlrr.LastRR = last_rr; dlrr.DelayLastRR = delay_last_rr; dlrr_block_.push_back(dlrr); + return true; +} + +RawPacket::RawPacket(size_t buffer_length) + : buffer_length_(buffer_length), length_(0) { + buffer_.reset(new uint8_t[buffer_length]); +} + +RawPacket::RawPacket(const uint8_t* packet, size_t packet_length) + : buffer_length_(packet_length), length_(packet_length) { + buffer_.reset(new uint8_t[packet_length]); + memcpy(buffer_.get(), packet, packet_length); +} + +const uint8_t* RawPacket::Buffer() const { + return buffer_.get(); +} + +uint8_t* RawPacket::MutableBuffer() { + return buffer_.get(); +} + +size_t RawPacket::BufferLength() const { + return buffer_length_; +} + +size_t RawPacket::Length() const { + return length_; +} + +void RawPacket::SetLength(size_t length) { + assert(length <= buffer_length_); + length_ = length; } } // namespace rtcp diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet.h index 150b5b409..ffa3e0daf 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_packet.h +++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet.h @@ -16,6 +16,7 @@ #include #include +#include "webrtc/base/scoped_ptr.h" #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h" #include "webrtc/typedefs.h" @@ -23,8 +24,8 @@ namespace webrtc { namespace rtcp { -enum { kCommonFbFmtLength = 12 }; -enum { kReportBlockLength = 24 }; +static const int kCommonFbFmtLength = 12; +static const int kReportBlockLength = 24; class Dlrr; class RawPacket; @@ -64,21 +65,51 @@ class RtcpPacket { void Append(RtcpPacket* packet); - RawPacket Build() const; + // Callback used to signal that an RTCP packet is ready. Note that this may + // not contain all data in this RtcpPacket; if a packet cannot fit in + // max_length bytes, it will be fragmented and multiple calls to this + // callback will be made. + class PacketReadyCallback { + public: + PacketReadyCallback() {} + virtual ~PacketReadyCallback() {} - void Build(uint8_t* packet, size_t* length, size_t max_length) const; + virtual void OnPacketReady(uint8_t* data, size_t length) = 0; + }; + + // Convenience method mostly used for test. Max length of IP_PACKET_SIZE is + // used, will cause assertion error if fragmentation occurs. + rtc::scoped_ptr Build() const; + + // Returns true if all calls to Create succeeded. A buffer of size + // IP_PACKET_SIZE will be allocated and reused between calls to callback. + bool Build(PacketReadyCallback* callback) const; + + // Returns true if all calls to Create succeeded. Provided buffer reference + // will be used for all calls to callback. + bool BuildExternalBuffer(uint8_t* buffer, + size_t max_length, + PacketReadyCallback* callback) const; protected: RtcpPacket() : kHeaderLength(4) {} - virtual void Create( - uint8_t* packet, size_t* length, size_t max_length) const = 0; + virtual bool Create(uint8_t* packet, + size_t* index, + size_t max_length, + PacketReadyCallback* callback) const = 0; + + bool OnBufferFull(uint8_t* packet, + size_t* index, + RtcpPacket::PacketReadyCallback* callback) const; const size_t kHeaderLength; private: - void CreateAndAddAppended( - uint8_t* packet, size_t* length, size_t max_length) const; + bool CreateAndAddAppended(uint8_t* packet, + size_t* index, + size_t max_length, + PacketReadyCallback* callback) const; std::vector appended_packets_; }; @@ -90,9 +121,10 @@ class Empty : public RtcpPacket { virtual ~Empty() {} protected: - void Create(uint8_t* packet, - size_t* length, - size_t max_length) const override; + bool Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const override; private: DISALLOW_COPY_AND_ASSIGN(Empty); @@ -202,15 +234,16 @@ class SenderReport : public RtcpPacket { void WithOctetCount(uint32_t octet_count) { sr_.SenderOctetCount = octet_count; } - void WithReportBlock(ReportBlock* block); + bool WithReportBlock(ReportBlock* block); protected: - void Create(uint8_t* packet, - size_t* length, - size_t max_length) const override; + bool Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const override; private: - enum { kMaxNumberOfReportBlocks = 0x1f }; + static const int kMaxNumberOfReportBlocks = 0x1f; size_t BlockLength() const { const size_t kSrHeaderLength = 8; @@ -249,15 +282,16 @@ class ReceiverReport : public RtcpPacket { void From(uint32_t ssrc) { rr_.SenderSSRC = ssrc; } - void WithReportBlock(ReportBlock* block); + bool WithReportBlock(ReportBlock* block); protected: - void Create(uint8_t* packet, - size_t* length, - size_t max_length) const override; + bool Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const override; private: - enum { kMaxNumberOfReportBlocks = 0x1f }; + static const int kMaxNumberOfReportBlocks = 0x1F; size_t BlockLength() const { const size_t kRrHeaderLength = 8; @@ -295,15 +329,16 @@ class Ij : public RtcpPacket { virtual ~Ij() {} - void WithJitterItem(uint32_t jitter); + bool WithJitterItem(uint32_t jitter); protected: - void Create(uint8_t* packet, - size_t* length, - size_t max_length) const override; + bool Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const override; private: - enum { kMaxNumberOfIjItems = 0x1f }; + static const int kMaxNumberOfIjItems = 0x1f; size_t BlockLength() const { return kHeaderLength + 4 * ij_items_.size(); @@ -346,7 +381,7 @@ class Sdes : public RtcpPacket { virtual ~Sdes() {} - void WithCName(uint32_t ssrc, std::string cname); + bool WithCName(uint32_t ssrc, const std::string& cname); struct Chunk { uint32_t ssrc; @@ -355,12 +390,13 @@ class Sdes : public RtcpPacket { }; protected: - void Create(uint8_t* packet, - size_t* length, - size_t max_length) const override; + bool Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const override; private: - enum { kMaxNumberOfChunks = 0x1f }; + static const int kMaxNumberOfChunks = 0x1f; size_t BlockLength() const; @@ -394,15 +430,19 @@ class Bye : public RtcpPacket { void From(uint32_t ssrc) { bye_.SenderSSRC = ssrc; } - void WithCsrc(uint32_t csrc); + + bool WithCsrc(uint32_t csrc); + + // TODO(sprang): Add support for reason field? protected: - void Create(uint8_t* packet, - size_t* length, - size_t max_length) const override; + bool Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const override; private: - enum { kMaxNumberOfCsrcs = 0x1f - 1 }; + static const int kMaxNumberOfCsrcs = 0x1f - 1; // First item is sender SSRC. size_t BlockLength() const { size_t source_count = 1 + csrcs_.size(); @@ -458,9 +498,10 @@ class App : public RtcpPacket { } protected: - void Create(uint8_t* packet, - size_t* length, - size_t max_length) const override; + bool Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const override; private: size_t BlockLength() const { @@ -509,9 +550,10 @@ class Pli : public RtcpPacket { } protected: - void Create(uint8_t* packet, - size_t* length, - size_t max_length) const override; + bool Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const override; private: size_t BlockLength() const { @@ -561,9 +603,10 @@ class Sli : public RtcpPacket { } protected: - void Create(uint8_t* packet, - size_t* length, - size_t max_length) const override; + bool Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const override; private: size_t BlockLength() const { @@ -603,15 +646,12 @@ class Nack : public RtcpPacket { void WithList(const uint16_t* nack_list, int length); protected: - void Create(uint8_t* packet, - size_t* length, - size_t max_length) const override; + bool Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const override; private: - size_t BlockLength() const { - size_t fci_length = 4 * nack_fields_.size(); - return kCommonFbFmtLength + fci_length; - } RTCPUtility::RTCPPacketRTPFBNACK nack_; std::vector nack_fields_; @@ -654,9 +694,10 @@ class Rpsi : public RtcpPacket { void WithPictureId(uint64_t picture_id); protected: - void Create(uint8_t* packet, - size_t* length, - size_t max_length) const override; + bool Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const override; private: size_t BlockLength() const { @@ -702,9 +743,10 @@ class Fir : public RtcpPacket { } protected: - void Create(uint8_t* packet, - size_t* length, - size_t max_length) const override; + bool Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const override; private: size_t BlockLength() const { @@ -752,9 +794,10 @@ class Tmmbr : public RtcpPacket { } protected: - void Create(uint8_t* packet, - size_t* length, - size_t max_length) const override; + bool Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const override; private: size_t BlockLength() const { @@ -791,15 +834,17 @@ class Tmmbn : public RtcpPacket { void From(uint32_t ssrc) { tmmbn_.SenderSSRC = ssrc; } - void WithTmmbr(uint32_t ssrc, uint32_t bitrate_kbps, uint16_t overhead); + // Max 50 TMMBR can be added per TMMBN. + bool WithTmmbr(uint32_t ssrc, uint32_t bitrate_kbps, uint16_t overhead); protected: - void Create(uint8_t* packet, - size_t* length, - size_t max_length) const override; + bool Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const override; private: - enum { kMaxNumberOfTmmbrs = 50 }; + static const int kMaxNumberOfTmmbrs = 50; size_t BlockLength() const { const size_t kFciLen = 8; @@ -850,12 +895,13 @@ class Remb : public RtcpPacket { } protected: - void Create(uint8_t* packet, - size_t* length, - size_t max_length) const override; + bool Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const override; private: - enum { kMaxNumberOfSsrcs = 0xff }; + static const int kMaxNumberOfSsrcs = 0xff; size_t BlockLength() const { return (remb_item_.NumberOfSSRCs + 5) * 4; @@ -893,19 +939,22 @@ class Xr : public RtcpPacket { void From(uint32_t ssrc) { xr_header_.OriginatorSSRC = ssrc; } - void WithRrtr(Rrtr* rrtr); - void WithDlrr(Dlrr* dlrr); - void WithVoipMetric(VoipMetric* voip_metric); + + // Max 50 items of each of {Rrtr, Dlrr, VoipMetric} allowed per Xr. + bool WithRrtr(Rrtr* rrtr); + bool WithDlrr(Dlrr* dlrr); + bool WithVoipMetric(VoipMetric* voip_metric); protected: - void Create(uint8_t* packet, - size_t* length, - size_t max_length) const override; + bool Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const override; private: - enum { kMaxNumberOfRrtrBlocks = 50 }; - enum { kMaxNumberOfDlrrBlocks = 50 }; - enum { kMaxNumberOfVoipMetricBlocks = 50 }; + static const int kMaxNumberOfRrtrBlocks = 50; + static const int kMaxNumberOfDlrrBlocks = 50; + static const int kMaxNumberOfVoipMetricBlocks = 50; size_t BlockLength() const { const size_t kXrHeaderLength = 8; @@ -987,11 +1036,12 @@ class Dlrr { Dlrr() {} ~Dlrr() {} - void WithDlrrItem(uint32_t ssrc, uint32_t last_rr, uint32_t delay_last_rr); + // Max 100 DLRR Items can be added per DLRR report block. + bool WithDlrrItem(uint32_t ssrc, uint32_t last_rr, uint32_t delay_last_rr); private: friend class Xr; - enum { kMaxNumberOfDlrrItems = 100 }; + static const int kMaxNumberOfDlrrItems = 100; std::vector dlrr_block_; @@ -1074,27 +1124,24 @@ class VoipMetric { // RawPacket raw_packet(buffer, length); // // To access the raw packet: -// raw_packet.buffer(); - pointer to the raw packet -// raw_packet.buffer_length(); - the length of the raw packet +// raw_packet.Buffer(); - pointer to the raw packet +// raw_packet.BufferLength(); - the length of the raw packet class RawPacket { public: - RawPacket(const uint8_t* packet, size_t length) { - assert(length <= IP_PACKET_SIZE); - memcpy(buffer_, packet, length); - buffer_length_ = length; - } + explicit RawPacket(size_t buffer_length); + RawPacket(const uint8_t* packet, size_t packet_length); - const uint8_t* buffer() { - return buffer_; - } - size_t buffer_length() const { - return buffer_length_; - } + const uint8_t* Buffer() const; + uint8_t* MutableBuffer(); + size_t BufferLength() const; + size_t Length() const; + void SetLength(size_t length); private: - size_t buffer_length_; - uint8_t buffer_[IP_PACKET_SIZE]; + const size_t buffer_length_; + size_t length_; + rtc::scoped_ptr buffer_; }; } // namespace rtcp diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet_unittest.cc index c0ba3075d..f2ff1ccb0 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_packet_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet_unittest.cc @@ -10,11 +10,14 @@ * This file includes unit tests for the RtcpPacket. */ +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h" #include "webrtc/test/rtcp_packet_parser.h" +using ::testing::ElementsAre; + using webrtc::rtcp::App; using webrtc::rtcp::Bye; using webrtc::rtcp::Dlrr; @@ -48,9 +51,9 @@ TEST(RtcpPacketTest, Rr) { ReceiverReport rr; rr.From(kSenderSsrc); - RawPacket packet = rr.Build(); + rtc::scoped_ptr packet(rr.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.receiver_report()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.receiver_report()->Ssrc()); EXPECT_EQ(0, parser.report_block()->num_packets()); @@ -68,11 +71,11 @@ TEST(RtcpPacketTest, RrWithOneReportBlock) { ReceiverReport rr; rr.From(kSenderSsrc); - rr.WithReportBlock(&rb); + EXPECT_TRUE(rr.WithReportBlock(&rb)); - RawPacket packet = rr.Build(); + rtc::scoped_ptr packet(rr.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.receiver_report()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.receiver_report()->Ssrc()); EXPECT_EQ(1, parser.report_block()->num_packets()); @@ -93,12 +96,12 @@ TEST(RtcpPacketTest, RrWithTwoReportBlocks) { ReceiverReport rr; rr.From(kSenderSsrc); - rr.WithReportBlock(&rb1); - rr.WithReportBlock(&rb2); + EXPECT_TRUE(rr.WithReportBlock(&rb1)); + EXPECT_TRUE(rr.WithReportBlock(&rb2)); - RawPacket packet = rr.Build(); + rtc::scoped_ptr packet(rr.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.receiver_report()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.receiver_report()->Ssrc()); EXPECT_EQ(2, parser.report_block()->num_packets()); @@ -106,6 +109,19 @@ TEST(RtcpPacketTest, RrWithTwoReportBlocks) { EXPECT_EQ(1, parser.report_blocks_per_ssrc(kRemoteSsrc + 1)); } +TEST(RtcpPacketTest, RrWithTooManyReportBlocks) { + ReceiverReport rr; + rr.From(kSenderSsrc); + const int kMaxReportBlocks = (1 << 5) - 1; + ReportBlock rb; + for (int i = 0; i < kMaxReportBlocks; ++i) { + rb.To(kRemoteSsrc + i); + EXPECT_TRUE(rr.WithReportBlock(&rb)); + } + rb.To(kRemoteSsrc + kMaxReportBlocks); + EXPECT_FALSE(rr.WithReportBlock(&rb)); +} + TEST(RtcpPacketTest, Sr) { SenderReport sr; sr.From(kSenderSsrc); @@ -115,9 +131,9 @@ TEST(RtcpPacketTest, Sr) { sr.WithPacketCount(0x44444444); sr.WithOctetCount(0x55555555); - RawPacket packet = sr.Build(); + rtc::scoped_ptr packet(sr.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.sender_report()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.sender_report()->Ssrc()); @@ -135,11 +151,11 @@ TEST(RtcpPacketTest, SrWithOneReportBlock) { SenderReport sr; sr.From(kSenderSsrc); - sr.WithReportBlock(&rb); + EXPECT_TRUE(sr.WithReportBlock(&rb)); - RawPacket packet = sr.Build(); + rtc::scoped_ptr packet(sr.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.sender_report()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.sender_report()->Ssrc()); EXPECT_EQ(1, parser.report_block()->num_packets()); @@ -154,12 +170,12 @@ TEST(RtcpPacketTest, SrWithTwoReportBlocks) { SenderReport sr; sr.From(kSenderSsrc); - sr.WithReportBlock(&rb1); - sr.WithReportBlock(&rb2); + EXPECT_TRUE(sr.WithReportBlock(&rb1)); + EXPECT_TRUE(sr.WithReportBlock(&rb2)); - RawPacket packet = sr.Build(); + rtc::scoped_ptr packet(sr.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.sender_report()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.sender_report()->Ssrc()); EXPECT_EQ(2, parser.report_block()->num_packets()); @@ -167,23 +183,36 @@ TEST(RtcpPacketTest, SrWithTwoReportBlocks) { EXPECT_EQ(1, parser.report_blocks_per_ssrc(kRemoteSsrc + 1)); } +TEST(RtcpPacketTest, SrWithTooManyReportBlocks) { + SenderReport sr; + sr.From(kSenderSsrc); + const int kMaxReportBlocks = (1 << 5) - 1; + ReportBlock rb; + for (int i = 0; i < kMaxReportBlocks; ++i) { + rb.To(kRemoteSsrc + i); + EXPECT_TRUE(sr.WithReportBlock(&rb)); + } + rb.To(kRemoteSsrc + kMaxReportBlocks); + EXPECT_FALSE(sr.WithReportBlock(&rb)); +} + TEST(RtcpPacketTest, IjNoItem) { Ij ij; - RawPacket packet = ij.Build(); + rtc::scoped_ptr packet(ij.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.ij()->num_packets()); EXPECT_EQ(0, parser.ij_item()->num_packets()); } TEST(RtcpPacketTest, IjOneItem) { Ij ij; - ij.WithJitterItem(0x11111111); + EXPECT_TRUE(ij.WithJitterItem(0x11111111)); - RawPacket packet = ij.Build(); + rtc::scoped_ptr packet(ij.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.ij()->num_packets()); EXPECT_EQ(1, parser.ij_item()->num_packets()); EXPECT_EQ(0x11111111U, parser.ij_item()->Jitter()); @@ -191,17 +220,26 @@ TEST(RtcpPacketTest, IjOneItem) { TEST(RtcpPacketTest, IjTwoItems) { Ij ij; - ij.WithJitterItem(0x11111111); - ij.WithJitterItem(0x22222222); + EXPECT_TRUE(ij.WithJitterItem(0x11111111)); + EXPECT_TRUE(ij.WithJitterItem(0x22222222)); - RawPacket packet = ij.Build(); + rtc::scoped_ptr packet(ij.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.ij()->num_packets()); EXPECT_EQ(2, parser.ij_item()->num_packets()); EXPECT_EQ(0x22222222U, parser.ij_item()->Jitter()); } +TEST(RtcpPacketTest, IjTooManyItems) { + Ij ij; + const int kMaxIjItems = (1 << 5) - 1; + for (int i = 0; i < kMaxIjItems; ++i) { + EXPECT_TRUE(ij.WithJitterItem(i)); + } + EXPECT_FALSE(ij.WithJitterItem(kMaxIjItems)); +} + TEST(RtcpPacketTest, AppWithNoData) { App app; app.WithSubType(30); @@ -211,9 +249,9 @@ TEST(RtcpPacketTest, AppWithNoData) { name += 'e'; app.WithName(name); - RawPacket packet = app.Build(); + rtc::scoped_ptr packet(app.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.app()->num_packets()); EXPECT_EQ(30U, parser.app()->SubType()); EXPECT_EQ(name, parser.app()->Name()); @@ -233,9 +271,9 @@ TEST(RtcpPacketTest, App) { const size_t kDataLength = sizeof(kData) / sizeof(kData[0]); app.WithData((const uint8_t*)kData, kDataLength); - RawPacket packet = app.Build(); + rtc::scoped_ptr packet(app.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.app()->num_packets()); EXPECT_EQ(30U, parser.app()->SubType()); EXPECT_EQ(name, parser.app()->Name()); @@ -247,11 +285,11 @@ TEST(RtcpPacketTest, App) { TEST(RtcpPacketTest, SdesWithOneChunk) { Sdes sdes; - sdes.WithCName(kSenderSsrc, "alice@host"); + EXPECT_TRUE(sdes.WithCName(kSenderSsrc, "alice@host")); - RawPacket packet = sdes.Build(); + rtc::scoped_ptr packet(sdes.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.sdes()->num_packets()); EXPECT_EQ(1, parser.sdes_chunk()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.sdes_chunk()->Ssrc()); @@ -260,29 +298,41 @@ TEST(RtcpPacketTest, SdesWithOneChunk) { TEST(RtcpPacketTest, SdesWithMultipleChunks) { Sdes sdes; - sdes.WithCName(kSenderSsrc, "a"); - sdes.WithCName(kSenderSsrc + 1, "ab"); - sdes.WithCName(kSenderSsrc + 2, "abc"); - sdes.WithCName(kSenderSsrc + 3, "abcd"); - sdes.WithCName(kSenderSsrc + 4, "abcde"); - sdes.WithCName(kSenderSsrc + 5, "abcdef"); + EXPECT_TRUE(sdes.WithCName(kSenderSsrc, "a")); + EXPECT_TRUE(sdes.WithCName(kSenderSsrc + 1, "ab")); + EXPECT_TRUE(sdes.WithCName(kSenderSsrc + 2, "abc")); + EXPECT_TRUE(sdes.WithCName(kSenderSsrc + 3, "abcd")); + EXPECT_TRUE(sdes.WithCName(kSenderSsrc + 4, "abcde")); + EXPECT_TRUE(sdes.WithCName(kSenderSsrc + 5, "abcdef")); - RawPacket packet = sdes.Build(); + rtc::scoped_ptr packet(sdes.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.sdes()->num_packets()); EXPECT_EQ(6, parser.sdes_chunk()->num_packets()); EXPECT_EQ(kSenderSsrc + 5, parser.sdes_chunk()->Ssrc()); EXPECT_EQ("abcdef", parser.sdes_chunk()->Cname()); } +TEST(RtcpPacketTest, SdesWithTooManyChunks) { + Sdes sdes; + const int kMaxChunks = (1 << 5) - 1; + for (int i = 0; i < kMaxChunks; ++i) { + uint32_t ssrc = kSenderSsrc + i; + std::ostringstream oss; + oss << "cname" << i; + EXPECT_TRUE(sdes.WithCName(ssrc, oss.str())); + } + EXPECT_FALSE(sdes.WithCName(kSenderSsrc + kMaxChunks, "foo")); +} + TEST(RtcpPacketTest, CnameItemWithEmptyString) { Sdes sdes; - sdes.WithCName(kSenderSsrc, ""); + EXPECT_TRUE(sdes.WithCName(kSenderSsrc, "")); - RawPacket packet = sdes.Build(); + rtc::scoped_ptr packet(sdes.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.sdes()->num_packets()); EXPECT_EQ(1, parser.sdes_chunk()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.sdes_chunk()->Ssrc()); @@ -294,9 +344,9 @@ TEST(RtcpPacketTest, Pli) { pli.From(kSenderSsrc); pli.To(kRemoteSsrc); - RawPacket packet = pli.Build(); + rtc::scoped_ptr packet(pli.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.pli()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.pli()->Ssrc()); EXPECT_EQ(kRemoteSsrc, parser.pli()->MediaSsrc()); @@ -313,9 +363,9 @@ TEST(RtcpPacketTest, Sli) { sli.WithNumberOfMb(kNumberOfMb); sli.WithPictureId(kPictureId); - RawPacket packet = sli.Build(); + rtc::scoped_ptr packet(sli.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.sli()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.sli()->Ssrc()); EXPECT_EQ(kRemoteSsrc, parser.sli()->MediaSsrc()); @@ -332,9 +382,9 @@ TEST(RtcpPacketTest, Nack) { nack.From(kSenderSsrc); nack.To(kRemoteSsrc); nack.WithList(kList, kListLength); - RawPacket packet = nack.Build(); + rtc::scoped_ptr packet(nack.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.nack()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.nack()->Ssrc()); EXPECT_EQ(kRemoteSsrc, parser.nack()->MediaSsrc()); @@ -353,9 +403,9 @@ TEST(RtcpPacketTest, NackWithWrap) { nack.From(kSenderSsrc); nack.To(kRemoteSsrc); nack.WithList(kList, kListLength); - RawPacket packet = nack.Build(); + rtc::scoped_ptr packet(nack.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.nack()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.nack()->Ssrc()); EXPECT_EQ(kRemoteSsrc, parser.nack()->MediaSsrc()); @@ -367,6 +417,62 @@ TEST(RtcpPacketTest, NackWithWrap) { } } +TEST(RtcpPacketTest, NackFragmented) { + Nack nack; + const uint16_t kList[] = {1, 100, 200, 300, 400}; + const uint16_t kListLength = sizeof(kList) / sizeof(kList[0]); + nack.From(kSenderSsrc); + nack.To(kRemoteSsrc); + nack.WithList(kList, kListLength); + + class Verifier : public rtcp::RtcpPacket::PacketReadyCallback { + public: + void OnPacketReady(uint8_t* data, size_t length) override { + ++packets_created_; + RtcpPacketParser parser; + parser.Parse(data, length); + EXPECT_EQ(1, parser.nack()->num_packets()); + EXPECT_EQ(kSenderSsrc, parser.nack()->Ssrc()); + EXPECT_EQ(kRemoteSsrc, parser.nack()->MediaSsrc()); + switch (packets_created_) { + case 1: + EXPECT_THAT(parser.nack_item()->last_nack_list(), + ElementsAre(1, 100, 200)); + break; + case 2: + EXPECT_THAT(parser.nack_item()->last_nack_list(), + ElementsAre(300, 400)); + break; + default: + ADD_FAILURE() << "Unexpected packet count: " << packets_created_; + } + } + int packets_created_ = 0; + } verifier; + const size_t kBufferSize = 12 + (3 * 4); // Fits common header + 3 nack items + uint8_t buffer[kBufferSize]; + EXPECT_TRUE(nack.BuildExternalBuffer(buffer, kBufferSize, &verifier)); + EXPECT_EQ(2, verifier.packets_created_); +} + +TEST(RtcpPacketTest, NackWithTooSmallBuffer) { + const uint16_t kList[] = {1}; + const size_t kMinNackBlockSize = 16; + Nack nack; + nack.From(kSenderSsrc); + nack.To(kRemoteSsrc); + nack.WithList(kList, 1); + class Verifier : public rtcp::RtcpPacket::PacketReadyCallback { + public: + void OnPacketReady(uint8_t* data, size_t length) override { + ADD_FAILURE() << "Buffer should be too small."; + } + } verifier; + uint8_t buffer[kMinNackBlockSize - 1]; + EXPECT_FALSE( + nack.BuildExternalBuffer(buffer, kMinNackBlockSize - 1, &verifier)); +} + TEST(RtcpPacketTest, Rpsi) { Rpsi rpsi; // 1000001 (7 bits = 1 byte in native string). @@ -375,9 +481,9 @@ TEST(RtcpPacketTest, Rpsi) { rpsi.WithPayloadType(100); rpsi.WithPictureId(kPictureId); - RawPacket packet = rpsi.Build(); + rtc::scoped_ptr packet(rpsi.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(100, parser.rpsi()->PayloadType()); EXPECT_EQ(kNumberOfValidBytes * 8, parser.rpsi()->NumberOfValidBits()); EXPECT_EQ(kPictureId, parser.rpsi()->PictureId()); @@ -390,9 +496,9 @@ TEST(RtcpPacketTest, RpsiWithTwoByteNativeString) { const uint16_t kNumberOfValidBytes = 2; rpsi.WithPictureId(kPictureId); - RawPacket packet = rpsi.Build(); + rtc::scoped_ptr packet(rpsi.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(kNumberOfValidBytes * 8, parser.rpsi()->NumberOfValidBits()); EXPECT_EQ(kPictureId, parser.rpsi()->PictureId()); } @@ -404,9 +510,9 @@ TEST(RtcpPacketTest, RpsiWithThreeByteNativeString) { const uint16_t kNumberOfValidBytes = 3; rpsi.WithPictureId(kPictureId); - RawPacket packet = rpsi.Build(); + rtc::scoped_ptr packet(rpsi.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(kNumberOfValidBytes * 8, parser.rpsi()->NumberOfValidBits()); EXPECT_EQ(kPictureId, parser.rpsi()->PictureId()); } @@ -418,9 +524,9 @@ TEST(RtcpPacketTest, RpsiWithFourByteNativeString) { const uint16_t kNumberOfValidBytes = 4; rpsi.WithPictureId(kPictureId); - RawPacket packet = rpsi.Build(); + rtc::scoped_ptr packet(rpsi.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(kNumberOfValidBytes * 8, parser.rpsi()->NumberOfValidBits()); EXPECT_EQ(kPictureId, parser.rpsi()->PictureId()); } @@ -433,9 +539,9 @@ TEST(RtcpPacketTest, RpsiWithMaxPictureId) { const uint16_t kNumberOfValidBytes = 10; rpsi.WithPictureId(kPictureId); - RawPacket packet = rpsi.Build(); + rtc::scoped_ptr packet(rpsi.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(kNumberOfValidBytes * 8, parser.rpsi()->NumberOfValidBits()); EXPECT_EQ(kPictureId, parser.rpsi()->PictureId()); } @@ -446,9 +552,9 @@ TEST(RtcpPacketTest, Fir) { fir.To(kRemoteSsrc); fir.WithCommandSeqNum(123); - RawPacket packet = fir.Build(); + rtc::scoped_ptr packet(fir.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.fir()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.fir()->Ssrc()); EXPECT_EQ(1, parser.fir_item()->num_packets()); @@ -461,12 +567,12 @@ TEST(RtcpPacketTest, AppendPacket) { ReportBlock rb; ReceiverReport rr; rr.From(kSenderSsrc); - rr.WithReportBlock(&rb); + EXPECT_TRUE(rr.WithReportBlock(&rb)); rr.Append(&fir); - RawPacket packet = rr.Build(); + rtc::scoped_ptr packet(rr.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.receiver_report()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.receiver_report()->Ssrc()); EXPECT_EQ(1, parser.report_block()->num_packets()); @@ -479,9 +585,9 @@ TEST(RtcpPacketTest, AppendPacketOnEmpty) { rr.From(kSenderSsrc); empty.Append(&rr); - RawPacket packet = empty.Build(); + rtc::scoped_ptr packet(empty.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.receiver_report()->num_packets()); EXPECT_EQ(0, parser.report_block()->num_packets()); } @@ -492,16 +598,16 @@ TEST(RtcpPacketTest, AppendPacketWithOwnAppendedPacket) { ReportBlock rb; ReceiverReport rr; - rr.WithReportBlock(&rb); + EXPECT_TRUE(rr.WithReportBlock(&rb)); rr.Append(&fir); SenderReport sr; sr.Append(&bye); sr.Append(&rr); - RawPacket packet = sr.Build(); + rtc::scoped_ptr packet(sr.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.sender_report()->num_packets()); EXPECT_EQ(1, parser.receiver_report()->num_packets()); EXPECT_EQ(1, parser.report_block()->num_packets()); @@ -513,9 +619,9 @@ TEST(RtcpPacketTest, Bye) { Bye bye; bye.From(kSenderSsrc); - RawPacket packet = bye.Build(); + rtc::scoped_ptr packet(bye.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.bye()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.bye()->Ssrc()); } @@ -524,76 +630,118 @@ TEST(RtcpPacketTest, ByeWithCsrcs) { Fir fir; Bye bye; bye.From(kSenderSsrc); - bye.WithCsrc(0x22222222); - bye.WithCsrc(0x33333333); + EXPECT_TRUE(bye.WithCsrc(0x22222222)); + EXPECT_TRUE(bye.WithCsrc(0x33333333)); bye.Append(&fir); - RawPacket packet = bye.Build(); + rtc::scoped_ptr packet(bye.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.bye()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.bye()->Ssrc()); EXPECT_EQ(1, parser.fir()->num_packets()); } +TEST(RtcpPacketTest, ByeWithTooManyCsrcs) { + Bye bye; + bye.From(kSenderSsrc); + const int kMaxCsrcs = (1 << 5) - 2; // 5 bit len, first item is sender SSRC. + for (int i = 0; i < kMaxCsrcs; ++i) { + EXPECT_TRUE(bye.WithCsrc(i)); + } + EXPECT_FALSE(bye.WithCsrc(kMaxCsrcs)); +} + TEST(RtcpPacketTest, BuildWithInputBuffer) { Fir fir; ReportBlock rb; ReceiverReport rr; rr.From(kSenderSsrc); - rr.WithReportBlock(&rb); + EXPECT_TRUE(rr.WithReportBlock(&rb)); rr.Append(&fir); const size_t kRrLength = 8; const size_t kReportBlockLength = 24; const size_t kFirLength = 20; - size_t len = 0; - uint8_t packet[kRrLength + kReportBlockLength + kFirLength]; - rr.Build(packet, &len, kRrLength + kReportBlockLength + kFirLength); + class Verifier : public rtcp::RtcpPacket::PacketReadyCallback { + public: + void OnPacketReady(uint8_t* data, size_t length) override { + RtcpPacketParser parser; + parser.Parse(data, length); + EXPECT_EQ(1, parser.receiver_report()->num_packets()); + EXPECT_EQ(1, parser.report_block()->num_packets()); + EXPECT_EQ(1, parser.fir()->num_packets()); + ++packets_created_; + } - RtcpPacketParser parser; - parser.Parse(packet, len); - EXPECT_EQ(1, parser.receiver_report()->num_packets()); - EXPECT_EQ(1, parser.report_block()->num_packets()); - EXPECT_EQ(1, parser.fir()->num_packets()); + int packets_created_ = 0; + } verifier; + const size_t kBufferSize = kRrLength + kReportBlockLength + kFirLength; + uint8_t buffer[kBufferSize]; + EXPECT_TRUE(rr.BuildExternalBuffer(buffer, kBufferSize, &verifier)); + EXPECT_EQ(1, verifier.packets_created_); } TEST(RtcpPacketTest, BuildWithTooSmallBuffer) { ReportBlock rb; ReceiverReport rr; rr.From(kSenderSsrc); - rr.WithReportBlock(&rb); + EXPECT_TRUE(rr.WithReportBlock(&rb)); const size_t kRrLength = 8; const size_t kReportBlockLength = 24; // No packet. - size_t len = 0; - uint8_t packet[kRrLength + kReportBlockLength - 1]; - rr.Build(packet, &len, kRrLength + kReportBlockLength - 1); - EXPECT_EQ(0U, len); + class Verifier : public rtcp::RtcpPacket::PacketReadyCallback { + void OnPacketReady(uint8_t* data, size_t length) override { + ADD_FAILURE() << "Packet should not fit within max size."; + } + } verifier; + const size_t kBufferSize = kRrLength + kReportBlockLength - 1; + uint8_t buffer[kBufferSize]; + EXPECT_FALSE(rr.BuildExternalBuffer(buffer, kBufferSize, &verifier)); } -TEST(RtcpPacketTest, BuildWithTooSmallBuffer_LastBlockFits) { +TEST(RtcpPacketTest, BuildWithTooSmallBuffer_FragmentedSend) { Fir fir; ReportBlock rb; ReceiverReport rr; rr.From(kSenderSsrc); - rr.WithReportBlock(&rb); + EXPECT_TRUE(rr.WithReportBlock(&rb)); rr.Append(&fir); const size_t kRrLength = 8; const size_t kReportBlockLength = 24; - size_t len = 0; - uint8_t packet[kRrLength + kReportBlockLength - 1]; - rr.Build(packet, &len, kRrLength + kReportBlockLength - 1); - RtcpPacketParser parser; - parser.Parse(packet, len); - EXPECT_EQ(0, parser.receiver_report()->num_packets()); - EXPECT_EQ(0, parser.report_block()->num_packets()); - EXPECT_EQ(1, parser.fir()->num_packets()); + class Verifier : public rtcp::RtcpPacket::PacketReadyCallback { + public: + void OnPacketReady(uint8_t* data, size_t length) override { + RtcpPacketParser parser; + parser.Parse(data, length); + switch (packets_created_++) { + case 0: + EXPECT_EQ(1, parser.receiver_report()->num_packets()); + EXPECT_EQ(1, parser.report_block()->num_packets()); + EXPECT_EQ(0, parser.fir()->num_packets()); + break; + case 1: + EXPECT_EQ(0, parser.receiver_report()->num_packets()); + EXPECT_EQ(0, parser.report_block()->num_packets()); + EXPECT_EQ(1, parser.fir()->num_packets()); + break; + default: + ADD_FAILURE() << "OnPacketReady not expected to be called " + << packets_created_ << " times."; + } + } + + int packets_created_ = 0; + } verifier; + const size_t kBufferSize = kRrLength + kReportBlockLength; + uint8_t buffer[kBufferSize]; + EXPECT_TRUE(rr.BuildExternalBuffer(buffer, kBufferSize, &verifier)); + EXPECT_EQ(2, verifier.packets_created_); } TEST(RtcpPacketTest, Remb) { @@ -604,9 +752,9 @@ TEST(RtcpPacketTest, Remb) { remb.AppliesTo(kRemoteSsrc + 2); remb.WithBitrateBps(261011); - RawPacket packet = remb.Build(); + rtc::scoped_ptr packet(remb.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.psfb_app()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.psfb_app()->Ssrc()); EXPECT_EQ(1, parser.remb_item()->num_packets()); @@ -624,9 +772,9 @@ TEST(RtcpPacketTest, Tmmbr) { tmmbr.WithBitrateKbps(312); tmmbr.WithOverhead(60); - RawPacket packet = tmmbr.Build(); + rtc::scoped_ptr packet(tmmbr.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.tmmbr()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.tmmbr()->Ssrc()); EXPECT_EQ(1, parser.tmmbr_item()->num_packets()); @@ -638,9 +786,9 @@ TEST(RtcpPacketTest, TmmbnWithNoItem) { Tmmbn tmmbn; tmmbn.From(kSenderSsrc); - RawPacket packet = tmmbn.Build(); + rtc::scoped_ptr packet(tmmbn.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.tmmbn()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.tmmbn()->Ssrc()); EXPECT_EQ(0, parser.tmmbn_items()->num_packets()); @@ -649,11 +797,11 @@ TEST(RtcpPacketTest, TmmbnWithNoItem) { TEST(RtcpPacketTest, TmmbnWithOneItem) { Tmmbn tmmbn; tmmbn.From(kSenderSsrc); - tmmbn.WithTmmbr(kRemoteSsrc, 312, 60); + EXPECT_TRUE(tmmbn.WithTmmbr(kRemoteSsrc, 312, 60)); - RawPacket packet = tmmbn.Build(); + rtc::scoped_ptr packet(tmmbn.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.tmmbn()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.tmmbn()->Ssrc()); EXPECT_EQ(1, parser.tmmbn_items()->num_packets()); @@ -665,12 +813,12 @@ TEST(RtcpPacketTest, TmmbnWithOneItem) { TEST(RtcpPacketTest, TmmbnWithTwoItems) { Tmmbn tmmbn; tmmbn.From(kSenderSsrc); - tmmbn.WithTmmbr(kRemoteSsrc, 312, 60); - tmmbn.WithTmmbr(kRemoteSsrc + 1, 1288, 40); + EXPECT_TRUE(tmmbn.WithTmmbr(kRemoteSsrc, 312, 60)); + EXPECT_TRUE(tmmbn.WithTmmbr(kRemoteSsrc + 1, 1288, 40)); - RawPacket packet = tmmbn.Build(); + rtc::scoped_ptr packet(tmmbn.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.tmmbn()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.tmmbn()->Ssrc()); EXPECT_EQ(2, parser.tmmbn_items()->num_packets()); @@ -682,13 +830,23 @@ TEST(RtcpPacketTest, TmmbnWithTwoItems) { EXPECT_EQ(40U, parser.tmmbn_items()->Overhead(1)); } +TEST(RtcpPacketTest, TmmbnWithTooManyItems) { + Tmmbn tmmbn; + tmmbn.From(kSenderSsrc); + const int kMaxTmmbrItems = 50; + for (int i = 0; i < kMaxTmmbrItems; ++i) + EXPECT_TRUE(tmmbn.WithTmmbr(kRemoteSsrc + i, 312, 60)); + + EXPECT_FALSE(tmmbn.WithTmmbr(kRemoteSsrc + kMaxTmmbrItems, 312, 60)); +} + TEST(RtcpPacketTest, XrWithNoReportBlocks) { Xr xr; xr.From(kSenderSsrc); - RawPacket packet = xr.Build(); + rtc::scoped_ptr packet(xr.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.xr_header()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.xr_header()->Ssrc()); } @@ -699,11 +857,11 @@ TEST(RtcpPacketTest, XrWithRrtr) { rrtr.WithNtpFrac(0x22222222); Xr xr; xr.From(kSenderSsrc); - xr.WithRrtr(&rrtr); + EXPECT_TRUE(xr.WithRrtr(&rrtr)); - RawPacket packet = xr.Build(); + rtc::scoped_ptr packet(xr.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.xr_header()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.xr_header()->Ssrc()); EXPECT_EQ(1, parser.rrtr()->num_packets()); @@ -720,12 +878,12 @@ TEST(RtcpPacketTest, XrWithTwoRrtrBlocks) { rrtr2.WithNtpFrac(0x44444444); Xr xr; xr.From(kSenderSsrc); - xr.WithRrtr(&rrtr1); - xr.WithRrtr(&rrtr2); + EXPECT_TRUE(xr.WithRrtr(&rrtr1)); + EXPECT_TRUE(xr.WithRrtr(&rrtr2)); - RawPacket packet = xr.Build(); + rtc::scoped_ptr packet(xr.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.xr_header()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.xr_header()->Ssrc()); EXPECT_EQ(2, parser.rrtr()->num_packets()); @@ -735,14 +893,14 @@ TEST(RtcpPacketTest, XrWithTwoRrtrBlocks) { TEST(RtcpPacketTest, XrWithDlrrWithOneSubBlock) { Dlrr dlrr; - dlrr.WithDlrrItem(0x11111111, 0x22222222, 0x33333333); + EXPECT_TRUE(dlrr.WithDlrrItem(0x11111111, 0x22222222, 0x33333333)); Xr xr; xr.From(kSenderSsrc); - xr.WithDlrr(&dlrr); + EXPECT_TRUE(xr.WithDlrr(&dlrr)); - RawPacket packet = xr.Build(); + rtc::scoped_ptr packet(xr.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.xr_header()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.xr_header()->Ssrc()); EXPECT_EQ(1, parser.dlrr()->num_packets()); @@ -754,15 +912,15 @@ TEST(RtcpPacketTest, XrWithDlrrWithOneSubBlock) { TEST(RtcpPacketTest, XrWithDlrrWithTwoSubBlocks) { Dlrr dlrr; - dlrr.WithDlrrItem(0x11111111, 0x22222222, 0x33333333); - dlrr.WithDlrrItem(0x44444444, 0x55555555, 0x66666666); + EXPECT_TRUE(dlrr.WithDlrrItem(0x11111111, 0x22222222, 0x33333333)); + EXPECT_TRUE(dlrr.WithDlrrItem(0x44444444, 0x55555555, 0x66666666)); Xr xr; xr.From(kSenderSsrc); - xr.WithDlrr(&dlrr); + EXPECT_TRUE(xr.WithDlrr(&dlrr)); - RawPacket packet = xr.Build(); + rtc::scoped_ptr packet(xr.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.xr_header()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.xr_header()->Ssrc()); EXPECT_EQ(1, parser.dlrr()->num_packets()); @@ -775,19 +933,27 @@ TEST(RtcpPacketTest, XrWithDlrrWithTwoSubBlocks) { EXPECT_EQ(0x66666666U, parser.dlrr_items()->DelayLastRr(1)); } +TEST(RtcpPacketTest, DlrrWithTooManySubBlocks) { + const int kMaxItems = 100; + Dlrr dlrr; + for (int i = 0; i < kMaxItems; ++i) + EXPECT_TRUE(dlrr.WithDlrrItem(i, i, i)); + EXPECT_FALSE(dlrr.WithDlrrItem(kMaxItems, kMaxItems, kMaxItems)); +} + TEST(RtcpPacketTest, XrWithTwoDlrrBlocks) { Dlrr dlrr1; - dlrr1.WithDlrrItem(0x11111111, 0x22222222, 0x33333333); + EXPECT_TRUE(dlrr1.WithDlrrItem(0x11111111, 0x22222222, 0x33333333)); Dlrr dlrr2; - dlrr2.WithDlrrItem(0x44444444, 0x55555555, 0x66666666); + EXPECT_TRUE(dlrr2.WithDlrrItem(0x44444444, 0x55555555, 0x66666666)); Xr xr; xr.From(kSenderSsrc); - xr.WithDlrr(&dlrr1); - xr.WithDlrr(&dlrr2); + EXPECT_TRUE(xr.WithDlrr(&dlrr1)); + EXPECT_TRUE(xr.WithDlrr(&dlrr2)); - RawPacket packet = xr.Build(); + rtc::scoped_ptr packet(xr.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.xr_header()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.xr_header()->Ssrc()); EXPECT_EQ(2, parser.dlrr()->num_packets()); @@ -826,11 +992,11 @@ TEST(RtcpPacketTest, XrWithVoipMetric) { Xr xr; xr.From(kSenderSsrc); - xr.WithVoipMetric(&metric); + EXPECT_TRUE(xr.WithVoipMetric(&metric)); - RawPacket packet = xr.Build(); + rtc::scoped_ptr packet(xr.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.xr_header()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.xr_header()->Ssrc()); EXPECT_EQ(1, parser.voip_metric()->num_packets()); @@ -860,17 +1026,17 @@ TEST(RtcpPacketTest, XrWithVoipMetric) { TEST(RtcpPacketTest, XrWithMultipleReportBlocks) { Rrtr rrtr; Dlrr dlrr; - dlrr.WithDlrrItem(1, 2, 3); + EXPECT_TRUE(dlrr.WithDlrrItem(1, 2, 3)); VoipMetric metric; Xr xr; xr.From(kSenderSsrc); - xr.WithRrtr(&rrtr); - xr.WithDlrr(&dlrr); - xr.WithVoipMetric(&metric); + EXPECT_TRUE(xr.WithRrtr(&rrtr)); + EXPECT_TRUE(xr.WithDlrr(&dlrr)); + EXPECT_TRUE(xr.WithVoipMetric(&metric)); - RawPacket packet = xr.Build(); + rtc::scoped_ptr packet(xr.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.xr_header()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.xr_header()->Ssrc()); EXPECT_EQ(1, parser.rrtr()->num_packets()); @@ -885,17 +1051,37 @@ TEST(RtcpPacketTest, DlrrWithoutItemNotIncludedInPacket) { VoipMetric metric; Xr xr; xr.From(kSenderSsrc); - xr.WithRrtr(&rrtr); - xr.WithDlrr(&dlrr); - xr.WithVoipMetric(&metric); + EXPECT_TRUE(xr.WithRrtr(&rrtr)); + EXPECT_TRUE(xr.WithDlrr(&dlrr)); + EXPECT_TRUE(xr.WithVoipMetric(&metric)); - RawPacket packet = xr.Build(); + rtc::scoped_ptr packet(xr.Build()); RtcpPacketParser parser; - parser.Parse(packet.buffer(), packet.buffer_length()); + parser.Parse(packet->Buffer(), packet->Length()); EXPECT_EQ(1, parser.xr_header()->num_packets()); EXPECT_EQ(kSenderSsrc, parser.xr_header()->Ssrc()); EXPECT_EQ(1, parser.rrtr()->num_packets()); EXPECT_EQ(0, parser.dlrr()->num_packets()); EXPECT_EQ(1, parser.voip_metric()->num_packets()); } + +TEST(RtcpPacketTest, XrWithTooManyBlocks) { + const int kMaxBlocks = 50; + Xr xr; + + Rrtr rrtr; + for (int i = 0; i < kMaxBlocks; ++i) + EXPECT_TRUE(xr.WithRrtr(&rrtr)); + EXPECT_FALSE(xr.WithRrtr(&rrtr)); + + Dlrr dlrr; + for (int i = 0; i < kMaxBlocks; ++i) + EXPECT_TRUE(xr.WithDlrr(&dlrr)); + EXPECT_FALSE(xr.WithDlrr(&dlrr)); + + VoipMetric voip_metric; + for (int i = 0; i < kMaxBlocks; ++i) + EXPECT_TRUE(xr.WithVoipMetric(&voip_metric)); + EXPECT_FALSE(xr.WithVoipMetric(&voip_metric)); +} } // namespace webrtc diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc index 1082b3020..ad1970ce7 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc @@ -155,8 +155,8 @@ TEST_F(RtcpReceiverTest, InjectSrPacket) { const uint32_t kSenderSsrc = 0x10203; rtcp::SenderReport sr; sr.From(kSenderSsrc); - rtcp::RawPacket p = sr.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(sr.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); // The parser will note the remote SSRC on a SR from other than his // expected peer, but will not flag that he's gotten a packet. EXPECT_EQ(kSenderSsrc, rtcp_packet_info_.remoteSSRC); @@ -169,8 +169,8 @@ TEST_F(RtcpReceiverTest, InjectSrPacketFromExpectedPeer) { rtcp_receiver_->SetRemoteSSRC(kSenderSsrc); rtcp::SenderReport sr; sr.From(kSenderSsrc); - rtcp::RawPacket p = sr.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(sr.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); EXPECT_EQ(kSenderSsrc, rtcp_packet_info_.remoteSSRC); EXPECT_EQ(kRtcpSr, rtcp_packet_info_.rtcpPacketTypeFlags); } @@ -179,8 +179,8 @@ TEST_F(RtcpReceiverTest, InjectRrPacket) { const uint32_t kSenderSsrc = 0x10203; rtcp::ReceiverReport rr; rr.From(kSenderSsrc); - rtcp::RawPacket p = rr.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(rr.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); EXPECT_EQ(kSenderSsrc, rtcp_packet_info_.remoteSSRC); EXPECT_EQ(kRtcpRr, rtcp_packet_info_.rtcpPacketTypeFlags); ASSERT_EQ(0u, rtcp_packet_info_.report_blocks.size()); @@ -198,8 +198,8 @@ TEST_F(RtcpReceiverTest, InjectRrPacketWithReportBlockNotToUsIgnored) { rtcp::ReceiverReport rr; rr.From(kSenderSsrc); rr.WithReportBlock(&rb); - rtcp::RawPacket p = rr.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(rr.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); EXPECT_EQ(kSenderSsrc, rtcp_packet_info_.remoteSSRC); EXPECT_EQ(kRtcpRr, rtcp_packet_info_.rtcpPacketTypeFlags); ASSERT_EQ(0u, rtcp_packet_info_.report_blocks.size()); @@ -221,8 +221,8 @@ TEST_F(RtcpReceiverTest, InjectRrPacketWithOneReportBlock) { rtcp::ReceiverReport rr; rr.From(kSenderSsrc); rr.WithReportBlock(&rb); - rtcp::RawPacket p = rr.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(rr.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); EXPECT_EQ(kSenderSsrc, rtcp_packet_info_.remoteSSRC); EXPECT_EQ(kRtcpRr, rtcp_packet_info_.rtcpPacketTypeFlags); ASSERT_EQ(1u, rtcp_packet_info_.report_blocks.size()); @@ -258,8 +258,8 @@ TEST_F(RtcpReceiverTest, InjectRrPacketWithTwoReportBlocks) { rr1.WithReportBlock(&rb1); rr1.WithReportBlock(&rb2); - rtcp::RawPacket p1 = rr1.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p1.buffer(), p1.buffer_length())); + rtc::scoped_ptr p1(rr1.Build()); + EXPECT_EQ(0, InjectRtcpPacket(p1->Buffer(), p1->Length())); ASSERT_EQ(2u, rtcp_packet_info_.report_blocks.size()); EXPECT_EQ(10, rtcp_packet_info_.report_blocks.front().fractionLost); EXPECT_EQ(0, rtcp_packet_info_.report_blocks.back().fractionLost); @@ -281,8 +281,8 @@ TEST_F(RtcpReceiverTest, InjectRrPacketWithTwoReportBlocks) { rr2.WithReportBlock(&rb3); rr2.WithReportBlock(&rb4); - rtcp::RawPacket p2 = rr2.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p2.buffer(), p2.buffer_length())); + rtc::scoped_ptr p2(rr2.Build()); + EXPECT_EQ(0, InjectRtcpPacket(p2->Buffer(), p2->Length())); ASSERT_EQ(2u, rtcp_packet_info_.report_blocks.size()); EXPECT_EQ(kFracLost[0], rtcp_packet_info_.report_blocks.front().fractionLost); EXPECT_EQ(kFracLost[1], rtcp_packet_info_.report_blocks.back().fractionLost); @@ -320,8 +320,8 @@ TEST_F(RtcpReceiverTest, InjectRrPacketsFromTwoRemoteSsrcs) { rr1.From(kSenderSsrc1); rr1.WithReportBlock(&rb1); - rtcp::RawPacket p1 = rr1.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p1.buffer(), p1.buffer_length())); + rtc::scoped_ptr p1(rr1.Build()); + EXPECT_EQ(0, InjectRtcpPacket(p1->Buffer(), p1->Length())); ASSERT_EQ(1u, rtcp_packet_info_.report_blocks.size()); EXPECT_EQ(kFracLost[0], rtcp_packet_info_.report_blocks.front().fractionLost); @@ -342,8 +342,8 @@ TEST_F(RtcpReceiverTest, InjectRrPacketsFromTwoRemoteSsrcs) { rtcp::ReceiverReport rr2; rr2.From(kSenderSsrc2); rr2.WithReportBlock(&rb2); - rtcp::RawPacket p2 = rr2.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p2.buffer(), p2.buffer_length())); + rtc::scoped_ptr p2(rr2.Build()); + EXPECT_EQ(0, InjectRtcpPacket(p2->Buffer(), p2->Length())); ASSERT_EQ(1u, rtcp_packet_info_.report_blocks.size()); EXPECT_EQ(kFracLost[1], rtcp_packet_info_.report_blocks.front().fractionLost); @@ -375,8 +375,8 @@ TEST_F(RtcpReceiverTest, GetRtt) { rtcp::ReceiverReport rr; rr.From(kSenderSsrc); rr.WithReportBlock(&rb); - rtcp::RawPacket p = rr.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(rr.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); EXPECT_EQ(kSenderSsrc, rtcp_packet_info_.remoteSSRC); EXPECT_EQ(kRtcpRr, rtcp_packet_info_.rtcpPacketTypeFlags); EXPECT_EQ(1u, rtcp_packet_info_.report_blocks.size()); @@ -388,8 +388,8 @@ TEST_F(RtcpReceiverTest, GetRtt) { TEST_F(RtcpReceiverTest, InjectIjWithNoItem) { rtcp::Ij ij; - rtcp::RawPacket p = ij.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(ij.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); EXPECT_EQ(0U, rtcp_packet_info_.rtcpPacketTypeFlags); } @@ -397,8 +397,8 @@ TEST_F(RtcpReceiverTest, InjectIjWithOneItem) { rtcp::Ij ij; ij.WithJitterItem(0x11111111); - rtcp::RawPacket p = ij.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(ij.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); EXPECT_EQ(kRtcpTransmissionTimeOffset, rtcp_packet_info_.rtcpPacketTypeFlags); EXPECT_EQ(0x11111111U, rtcp_packet_info_.interArrivalJitter); } @@ -412,8 +412,8 @@ TEST_F(RtcpReceiverTest, InjectAppWithNoData) { name += 'e'; app.WithName(name); - rtcp::RawPacket p = app.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(app.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); EXPECT_EQ(kRtcpApp, rtcp_packet_info_.rtcpPacketTypeFlags); EXPECT_EQ(30, rtcp_packet_info_.applicationSubType); EXPECT_EQ(name, rtcp_packet_info_.applicationName); @@ -432,8 +432,8 @@ TEST_F(RtcpReceiverTest, InjectAppWithData) { const size_t kDataLength = sizeof(kData) / sizeof(kData[0]); app.WithData((const uint8_t*)kData, kDataLength); - rtcp::RawPacket p = app.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(app.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); EXPECT_EQ(kRtcpApp, rtcp_packet_info_.rtcpPacketTypeFlags); EXPECT_EQ(30, rtcp_packet_info_.applicationSubType); EXPECT_EQ(name, rtcp_packet_info_.applicationName); @@ -445,8 +445,8 @@ TEST_F(RtcpReceiverTest, InjectSdesWithOneChunk) { rtcp::Sdes sdes; sdes.WithCName(kSenderSsrc, "alice@host"); - rtcp::RawPacket p = sdes.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(sdes.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); char cName[RTCP_CNAME_SIZE]; EXPECT_EQ(0, rtcp_receiver_->CNAME(kSenderSsrc, cName)); EXPECT_EQ(0, strncmp(cName, "alice@host", RTCP_CNAME_SIZE)); @@ -457,16 +457,16 @@ TEST_F(RtcpReceiverTest, InjectByePacket_RemovesCname) { rtcp::Sdes sdes; sdes.WithCName(kSenderSsrc, "alice@host"); - rtcp::RawPacket p = sdes.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(sdes.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); char cName[RTCP_CNAME_SIZE]; EXPECT_EQ(0, rtcp_receiver_->CNAME(kSenderSsrc, cName)); // Verify that BYE removes the CNAME. rtcp::Bye bye; bye.From(kSenderSsrc); - rtcp::RawPacket p2 = bye.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p2.buffer(), p2.buffer_length())); + rtc::scoped_ptr p2(bye.Build()); + EXPECT_EQ(0, InjectRtcpPacket(p2->Buffer(), p2->Length())); EXPECT_EQ(-1, rtcp_receiver_->CNAME(kSenderSsrc, cName)); } @@ -487,8 +487,8 @@ TEST_F(RtcpReceiverTest, InjectByePacket_RemovesReportBlocks) { rr.WithReportBlock(&rb1); rr.WithReportBlock(&rb2); - rtcp::RawPacket p1 = rr.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p1.buffer(), p1.buffer_length())); + rtc::scoped_ptr p1(rr.Build()); + EXPECT_EQ(0, InjectRtcpPacket(p1->Buffer(), p1->Length())); ASSERT_EQ(2u, rtcp_packet_info_.report_blocks.size()); std::vector received_blocks; rtcp_receiver_->StatisticsReceived(&received_blocks); @@ -497,14 +497,14 @@ TEST_F(RtcpReceiverTest, InjectByePacket_RemovesReportBlocks) { // Verify that BYE removes the report blocks. rtcp::Bye bye; bye.From(kSenderSsrc); - rtcp::RawPacket p2 = bye.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p2.buffer(), p2.buffer_length())); + rtc::scoped_ptr p2(bye.Build()); + EXPECT_EQ(0, InjectRtcpPacket(p2->Buffer(), p2->Length())); received_blocks.clear(); rtcp_receiver_->StatisticsReceived(&received_blocks); EXPECT_TRUE(received_blocks.empty()); // Inject packet. - EXPECT_EQ(0, InjectRtcpPacket(p1.buffer(), p1.buffer_length())); + EXPECT_EQ(0, InjectRtcpPacket(p1->Buffer(), p1->Length())); ASSERT_EQ(2u, rtcp_packet_info_.report_blocks.size()); received_blocks.clear(); rtcp_receiver_->StatisticsReceived(&received_blocks); @@ -519,8 +519,8 @@ TEST_F(RtcpReceiverTest, InjectPliPacket) { rtcp::Pli pli; pli.To(kSourceSsrc); - rtcp::RawPacket p = pli.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(pli.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); EXPECT_EQ(kRtcpPli, rtcp_packet_info_.rtcpPacketTypeFlags); } @@ -532,8 +532,8 @@ TEST_F(RtcpReceiverTest, PliPacketNotToUsIgnored) { rtcp::Pli pli; pli.To(kSourceSsrc + 1); - rtcp::RawPacket p = pli.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(pli.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); EXPECT_EQ(0U, rtcp_packet_info_.rtcpPacketTypeFlags); } @@ -545,8 +545,8 @@ TEST_F(RtcpReceiverTest, InjectFirPacket) { rtcp::Fir fir; fir.To(kSourceSsrc); - rtcp::RawPacket p = fir.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(fir.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); EXPECT_EQ(kRtcpFir, rtcp_packet_info_.rtcpPacketTypeFlags); } @@ -558,16 +558,16 @@ TEST_F(RtcpReceiverTest, FirPacketNotToUsIgnored) { rtcp::Fir fir; fir.To(kSourceSsrc + 1); - rtcp::RawPacket p = fir.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(fir.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); EXPECT_EQ(0U, rtcp_packet_info_.rtcpPacketTypeFlags); } TEST_F(RtcpReceiverTest, InjectSliPacket) { rtcp::Sli sli; sli.WithPictureId(40); - rtcp::RawPacket p = sli.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(sli.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); EXPECT_EQ(kRtcpSli, rtcp_packet_info_.rtcpPacketTypeFlags); EXPECT_EQ(40, rtcp_packet_info_.sliPictureId); } @@ -575,8 +575,8 @@ TEST_F(RtcpReceiverTest, InjectSliPacket) { TEST_F(RtcpReceiverTest, XrPacketWithZeroReportBlocksIgnored) { rtcp::Xr xr; xr.From(0x2345); - rtcp::RawPacket p = xr.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(xr.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); EXPECT_EQ(0U, rtcp_packet_info_.rtcpPacketTypeFlags); } @@ -593,8 +593,8 @@ TEST_F(RtcpReceiverTest, InjectXrVoipPacket) { rtcp::Xr xr; xr.From(0x2345); xr.WithVoipMetric(&voip_metric); - rtcp::RawPacket p = xr.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(xr.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); ASSERT_TRUE(rtcp_packet_info_.VoIPMetric != NULL); EXPECT_EQ(kLossRate, rtcp_packet_info_.VoIPMetric->lossRate); EXPECT_EQ(kRtcpXrVoipMetric, rtcp_packet_info_.rtcpPacketTypeFlags); @@ -611,8 +611,8 @@ TEST_F(RtcpReceiverTest, XrVoipPacketNotToUsIgnored) { rtcp::Xr xr; xr.From(0x2345); xr.WithVoipMetric(&voip_metric); - rtcp::RawPacket p = xr.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(xr.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); EXPECT_EQ(0U, rtcp_packet_info_.rtcpPacketTypeFlags); } @@ -624,8 +624,8 @@ TEST_F(RtcpReceiverTest, InjectXrReceiverReferenceTimePacket) { xr.From(0x2345); xr.WithRrtr(&rrtr); - rtcp::RawPacket p = xr.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(xr.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); EXPECT_EQ(kRtcpXrReceiverReferenceTime, rtcp_packet_info_.rtcpPacketTypeFlags); } @@ -641,8 +641,8 @@ TEST_F(RtcpReceiverTest, XrDlrrPacketNotToUsIgnored) { rtcp::Xr xr; xr.From(0x2345); xr.WithDlrr(&dlrr); - rtcp::RawPacket p = xr.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(xr.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); EXPECT_EQ(0U, rtcp_packet_info_.rtcpPacketTypeFlags); EXPECT_FALSE(rtcp_packet_info_.xr_dlrr_item); } @@ -658,8 +658,8 @@ TEST_F(RtcpReceiverTest, InjectXrDlrrPacketWithSubBlock) { rtcp::Xr xr; xr.From(0x2345); xr.WithDlrr(&dlrr); - rtcp::RawPacket p = xr.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(xr.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); // The parser should note the DLRR report block item, but not flag the packet // since the RTT is not estimated. EXPECT_TRUE(rtcp_packet_info_.xr_dlrr_item); @@ -678,8 +678,8 @@ TEST_F(RtcpReceiverTest, InjectXrDlrrPacketWithMultipleSubBlocks) { rtcp::Xr xr; xr.From(0x2345); xr.WithDlrr(&dlrr); - rtcp::RawPacket p = xr.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(xr.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); // The parser should note the DLRR report block item, but not flag the packet // since the RTT is not estimated. EXPECT_TRUE(rtcp_packet_info_.xr_dlrr_item); @@ -701,8 +701,8 @@ TEST_F(RtcpReceiverTest, InjectXrPacketWithMultipleReportBlocks) { xr.WithRrtr(&rrtr); xr.WithDlrr(&dlrr); xr.WithVoipMetric(&metric); - rtcp::RawPacket p = xr.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(xr.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); EXPECT_EQ(static_cast(kRtcpXrReceiverReferenceTime + kRtcpXrVoipMetric), rtcp_packet_info_.rtcpPacketTypeFlags); @@ -729,13 +729,13 @@ TEST_F(RtcpReceiverTest, InjectXrPacketWithUnknownReportBlock) { xr.WithRrtr(&rrtr); xr.WithDlrr(&dlrr); xr.WithVoipMetric(&metric); - rtcp::RawPacket p = xr.Build(); + rtc::scoped_ptr packet(xr.Build()); // Modify the DLRR block to have an unsupported block type, from 5 to 6. - uint8_t* buffer = const_cast(p.buffer()); + uint8_t* buffer = const_cast(packet->Buffer()); EXPECT_EQ(5, buffer[20]); buffer[20] = 6; - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); EXPECT_EQ(static_cast(kRtcpXrReceiverReferenceTime + kRtcpXrVoipMetric), rtcp_packet_info_.rtcpPacketTypeFlags); @@ -764,8 +764,8 @@ TEST_F(RtcpReceiverTest, GetLastReceivedXrReferenceTimeInfo) { rtcp::Xr xr; xr.From(kSenderSsrc); xr.WithRrtr(&rrtr); - rtcp::RawPacket p = xr.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(xr.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); EXPECT_EQ(kRtcpXrReceiverReferenceTime, rtcp_packet_info_.rtcpPacketTypeFlags); @@ -803,15 +803,15 @@ TEST_F(RtcpReceiverTest, ReceiveReportTimeout) { rtcp::ReceiverReport rr1; rr1.From(kSenderSsrc); rr1.WithReportBlock(&rb1); - rtcp::RawPacket p1 = rr1.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p1.buffer(), p1.buffer_length())); + rtc::scoped_ptr p1(rr1.Build()); + EXPECT_EQ(0, InjectRtcpPacket(p1->Buffer(), p1->Length())); system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs - 1); EXPECT_FALSE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs)); EXPECT_FALSE(rtcp_receiver_->RtcpRrSequenceNumberTimeout(kRtcpIntervalMs)); // Add a RR with the same extended max as the previous RR to trigger a // sequence number timeout, but not a RR timeout. - EXPECT_EQ(0, InjectRtcpPacket(p1.buffer(), p1.buffer_length())); + EXPECT_EQ(0, InjectRtcpPacket(p1->Buffer(), p1->Length())); system_clock_.AdvanceTimeMilliseconds(2); EXPECT_FALSE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs)); EXPECT_TRUE(rtcp_receiver_->RtcpRrSequenceNumberTimeout(kRtcpIntervalMs)); @@ -832,14 +832,14 @@ TEST_F(RtcpReceiverTest, ReceiveReportTimeout) { rtcp::ReceiverReport rr2; rr2.From(kSenderSsrc); rr2.WithReportBlock(&rb2); - rtcp::RawPacket p2 = rr2.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p2.buffer(), p2.buffer_length())); + rtc::scoped_ptr p2(rr2.Build()); + EXPECT_EQ(0, InjectRtcpPacket(p2->Buffer(), p2->Length())); EXPECT_FALSE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs)); EXPECT_FALSE(rtcp_receiver_->RtcpRrSequenceNumberTimeout(kRtcpIntervalMs)); // Verify we can get a timeout again once we've received new RR. system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs); - EXPECT_EQ(0, InjectRtcpPacket(p2.buffer(), p2.buffer_length())); + EXPECT_EQ(0, InjectRtcpPacket(p2->Buffer(), p2->Length())); system_clock_.AdvanceTimeMilliseconds(kRtcpIntervalMs + 1); EXPECT_FALSE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs)); EXPECT_TRUE(rtcp_receiver_->RtcpRrSequenceNumberTimeout(kRtcpIntervalMs)); @@ -867,8 +867,8 @@ TEST_F(RtcpReceiverTest, TmmbrPacketAccepted) { rtcp::SenderReport sr; sr.From(kSenderSsrc); sr.Append(&tmmbr); - rtcp::RawPacket p = sr.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(sr.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); EXPECT_EQ(1, rtcp_receiver_->TMMBRReceived(0, 0, NULL)); TMMBRSet candidate_set; @@ -890,12 +890,12 @@ TEST_F(RtcpReceiverTest, TmmbrPacketNotForUsIgnored) { rtcp::SenderReport sr; sr.From(kSenderSsrc); sr.Append(&tmmbr); - rtcp::RawPacket p = sr.Build(); + rtc::scoped_ptr packet(sr.Build()); std::set ssrcs; ssrcs.insert(kMediaFlowSsrc); rtcp_receiver_->SetSsrcs(kMediaFlowSsrc, ssrcs); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); EXPECT_EQ(0, rtcp_receiver_->TMMBRReceived(0, 0, NULL)); } @@ -914,9 +914,9 @@ TEST_F(RtcpReceiverTest, TmmbrPacketZeroRateIgnored) { rtcp::SenderReport sr; sr.From(kSenderSsrc); sr.Append(&tmmbr); - rtcp::RawPacket p = sr.Build(); + rtc::scoped_ptr packet(sr.Build()); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); EXPECT_EQ(0, rtcp_receiver_->TMMBRReceived(0, 0, NULL)); } @@ -938,8 +938,8 @@ TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) { rtcp::SenderReport sr; sr.From(ssrc); sr.Append(&tmmbr); - rtcp::RawPacket p = sr.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length())); + rtc::scoped_ptr packet(sr.Build()); + EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); // 5 seconds between each packet. system_clock_.AdvanceTimeMilliseconds(5000); } @@ -1009,8 +1009,8 @@ TEST_F(RtcpReceiverTest, Callbacks) { rtcp::ReceiverReport rr1; rr1.From(kSenderSsrc); rr1.WithReportBlock(&rb1); - rtcp::RawPacket p1 = rr1.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p1.buffer(), p1.buffer_length())); + rtc::scoped_ptr p1(rr1.Build()); + EXPECT_EQ(0, InjectRtcpPacket(p1->Buffer(), p1->Length())); EXPECT_TRUE(callback.Matches(kSourceSsrc, kSequenceNumber, kFractionLoss, kCumulativeLoss, kJitter)); @@ -1027,8 +1027,8 @@ TEST_F(RtcpReceiverTest, Callbacks) { rtcp::ReceiverReport rr2; rr2.From(kSenderSsrc); rr2.WithReportBlock(&rb2); - rtcp::RawPacket p2 = rr2.Build(); - EXPECT_EQ(0, InjectRtcpPacket(p2.buffer(), p2.buffer_length())); + rtc::scoped_ptr p2(rr2.Build()); + EXPECT_EQ(0, InjectRtcpPacket(p2->Buffer(), p2->Length())); EXPECT_TRUE(callback.Matches(kSourceSsrc, kSequenceNumber, kFractionLoss, kCumulativeLoss, kJitter)); } 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 3cff2a4d3..12630f79a 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc @@ -218,9 +218,9 @@ class RtpRtcpImplTest : public ::testing::Test { nack.From(sender ? kReceiverSsrc : kSenderSsrc); nack.To(sender ? kSenderSsrc : kReceiverSsrc); nack.WithList(list, kListLength); - rtcp::RawPacket packet = nack.Build(); - EXPECT_EQ(0, module->impl_->IncomingRtcpPacket(packet.buffer(), - packet.buffer_length())); + rtc::scoped_ptr packet(nack.Build()); + EXPECT_EQ(0, module->impl_->IncomingRtcpPacket(packet->Buffer(), + packet->Length())); } };