Add support for fragmentation in RtcpPacket.

If the buffer becomes full an OnPacketReady callback will be used to
send the packets created so far. On success the buffer can be reused.
The same callback will be called when the last packet has beed created.

Also made some changes to RawPacket. Buffer will now be heap-allocated
rather than (potentially) stack-allocated, but on the plus side it can
now be allocted with variable size and also avoids one memcpy.

BUG=

patch from issue 56429004 at patchset 160001 (http://crrev.com/56429004#ps160001)

R=asapersson@webrtc.org

Review URL: https://codereview.webrtc.org/1165113002

Cr-Commit-Position: refs/heads/master@{#9390}
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc
index f44021e..07ce336 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 @@
                size_t* pos) {
   CreateHeader(length, PT_BYE, length, buffer, pos);
   AssignUWord32(buffer, pos, bye.SenderSSRC);
-  for (std::vector<uint32_t>::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 CreateNack(const RTCPPacketRTPFBNACK& nack,
                 const std::vector<RTCPPacketRTPFBNACKItem>& nack_fields,
+                size_t start_index,
+                size_t end_index,
                 size_t length,
                 uint8_t* buffer,
                 size_t* pos) {
@@ -399,10 +400,10 @@
   CreateHeader(kFmt, PT_RTPFB, length, buffer, pos);
   AssignUWord32(buffer, pos, nack.SenderSSRC);
   AssignUWord32(buffer, pos, nack.MediaSSRC);
-  for (std::vector<RTCPPacketRTPFBNACKItem>::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 @@
   appended_packets_.push_back(packet);
 }
 
-RawPacket RtcpPacket::Build() const {
+rtc::scoped_ptr<RawPacket> 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<RawPacket> 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<RtcpPacket*>::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 @@
   chunk.name = cname;
   chunk.null_octets = null_octets;
   chunks_.push_back(chunk);
+  return true;
 }
 
 size_t Sdes::BlockLength() const {
@@ -843,63 +902,95 @@
   // Chunk:
   // SSRC/CSRC (4 bytes) | CNAME (1 byte) | length (1 byte) | name | padding.
   size_t length = kHeaderLength;
-  for (std::vector<Chunk>::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 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 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 @@
   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 @@
   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 150b5b4..ffa3e0d 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_packet.h
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet.h
@@ -16,6 +16,7 @@
 #include <string>
 #include <vector>
 
+#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 @@
 
   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<RawPacket> 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<RtcpPacket*> appended_packets_;
 };
@@ -90,9 +121,10 @@
   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 @@
   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 @@
   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 @@
 
   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 @@
 
   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 @@
   };
 
  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 @@
   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 @@
   }
 
  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 @@
   }
 
  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 @@
   }
 
  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 @@
   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<RTCPUtility::RTCPPacketRTPFBNACKItem> nack_fields_;
@@ -654,9 +694,10 @@
   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 @@
   }
 
  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 @@
   }
 
  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 @@
   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 @@
   }
 
  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 @@
   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 @@
   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<RTCPUtility::RTCPPacketXRDLRRReportBlockItem> dlrr_block_;
 
@@ -1074,27 +1124,24 @@
 //  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<uint8_t[]> 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 c0ba307..f2ff1cc 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 @@
   ReceiverReport rr;
   rr.From(kSenderSsrc);
 
-  RawPacket packet = rr.Build();
+  rtc::scoped_ptr<RawPacket> 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 @@
 
   ReceiverReport rr;
   rr.From(kSenderSsrc);
-  rr.WithReportBlock(&rb);
+  EXPECT_TRUE(rr.WithReportBlock(&rb));
 
-  RawPacket packet = rr.Build();
+  rtc::scoped_ptr<RawPacket> 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 @@
 
   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<RawPacket> 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 @@
   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 @@
   sr.WithPacketCount(0x44444444);
   sr.WithOctetCount(0x55555555);
 
-  RawPacket packet = sr.Build();
+  rtc::scoped_ptr<RawPacket> 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 @@
 
   SenderReport sr;
   sr.From(kSenderSsrc);
-  sr.WithReportBlock(&rb);
+  EXPECT_TRUE(sr.WithReportBlock(&rb));
 
-  RawPacket packet = sr.Build();
+  rtc::scoped_ptr<RawPacket> 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 @@
 
   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<RawPacket> 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 @@
   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<RawPacket> 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<RawPacket> 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, 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<RawPacket> 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 @@
   name += 'e';
   app.WithName(name);
 
-  RawPacket packet = app.Build();
+  rtc::scoped_ptr<RawPacket> 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 @@
   const size_t kDataLength = sizeof(kData) / sizeof(kData[0]);
   app.WithData((const uint8_t*)kData, kDataLength);
 
-  RawPacket packet = app.Build();
+  rtc::scoped_ptr<RawPacket> 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, SdesWithOneChunk) {
   Sdes sdes;
-  sdes.WithCName(kSenderSsrc, "alice@host");
+  EXPECT_TRUE(sdes.WithCName(kSenderSsrc, "alice@host"));
 
-  RawPacket packet = sdes.Build();
+  rtc::scoped_ptr<RawPacket> 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, 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<RawPacket> 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<RawPacket> 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 @@
   pli.From(kSenderSsrc);
   pli.To(kRemoteSsrc);
 
-  RawPacket packet = pli.Build();
+  rtc::scoped_ptr<RawPacket> 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 @@
   sli.WithNumberOfMb(kNumberOfMb);
   sli.WithPictureId(kPictureId);
 
-  RawPacket packet = sli.Build();
+  rtc::scoped_ptr<RawPacket> 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 @@
   nack.From(kSenderSsrc);
   nack.To(kRemoteSsrc);
   nack.WithList(kList, kListLength);
-  RawPacket packet = nack.Build();
+  rtc::scoped_ptr<RawPacket> 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 @@
   nack.From(kSenderSsrc);
   nack.To(kRemoteSsrc);
   nack.WithList(kList, kListLength);
-  RawPacket packet = nack.Build();
+  rtc::scoped_ptr<RawPacket> 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, 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 @@
   rpsi.WithPayloadType(100);
   rpsi.WithPictureId(kPictureId);
 
-  RawPacket packet = rpsi.Build();
+  rtc::scoped_ptr<RawPacket> 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 @@
   const uint16_t kNumberOfValidBytes = 2;
   rpsi.WithPictureId(kPictureId);
 
-  RawPacket packet = rpsi.Build();
+  rtc::scoped_ptr<RawPacket> 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 @@
   const uint16_t kNumberOfValidBytes = 3;
   rpsi.WithPictureId(kPictureId);
 
-  RawPacket packet = rpsi.Build();
+  rtc::scoped_ptr<RawPacket> 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 @@
   const uint16_t kNumberOfValidBytes = 4;
   rpsi.WithPictureId(kPictureId);
 
-  RawPacket packet = rpsi.Build();
+  rtc::scoped_ptr<RawPacket> 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 @@
   const uint16_t kNumberOfValidBytes = 10;
   rpsi.WithPictureId(kPictureId);
 
-  RawPacket packet = rpsi.Build();
+  rtc::scoped_ptr<RawPacket> 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 @@
   fir.To(kRemoteSsrc);
   fir.WithCommandSeqNum(123);
 
-  RawPacket packet = fir.Build();
+  rtc::scoped_ptr<RawPacket> 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 @@
   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<RawPacket> 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 @@
   rr.From(kSenderSsrc);
   empty.Append(&rr);
 
-  RawPacket packet = empty.Build();
+  rtc::scoped_ptr<RawPacket> 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 @@
   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<RawPacket> 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 @@
   Bye bye;
   bye.From(kSenderSsrc);
 
-  RawPacket packet = bye.Build();
+  rtc::scoped_ptr<RawPacket> 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 @@
   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<RawPacket> 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 @@
   remb.AppliesTo(kRemoteSsrc + 2);
   remb.WithBitrateBps(261011);
 
-  RawPacket packet = remb.Build();
+  rtc::scoped_ptr<RawPacket> 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 @@
   tmmbr.WithBitrateKbps(312);
   tmmbr.WithOverhead(60);
 
-  RawPacket packet = tmmbr.Build();
+  rtc::scoped_ptr<RawPacket> 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 @@
   Tmmbn tmmbn;
   tmmbn.From(kSenderSsrc);
 
-  RawPacket packet = tmmbn.Build();
+  rtc::scoped_ptr<RawPacket> 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, 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<RawPacket> 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, 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<RawPacket> 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 @@
   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<RawPacket> 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 @@
   rrtr.WithNtpFrac(0x22222222);
   Xr xr;
   xr.From(kSenderSsrc);
-  xr.WithRrtr(&rrtr);
+  EXPECT_TRUE(xr.WithRrtr(&rrtr));
 
-  RawPacket packet = xr.Build();
+  rtc::scoped_ptr<RawPacket> 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 @@
   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<RawPacket> 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, 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<RawPacket> 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, 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<RawPacket> 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 @@
   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<RawPacket> 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 @@
 
   Xr xr;
   xr.From(kSenderSsrc);
-  xr.WithVoipMetric(&metric);
+  EXPECT_TRUE(xr.WithVoipMetric(&metric));
 
-  RawPacket packet = xr.Build();
+  rtc::scoped_ptr<RawPacket> 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, 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<RawPacket> 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 @@
   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<RawPacket> 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 1082b30..ad1970c 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 @@
   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<rtcp::RawPacket> 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 @@
   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<rtcp::RawPacket> 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 @@
   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<rtcp::RawPacket> 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 @@
   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<rtcp::RawPacket> 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 @@
   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<rtcp::RawPacket> 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 @@
   rr1.WithReportBlock(&rb1);
   rr1.WithReportBlock(&rb2);
 
-  rtcp::RawPacket p1 = rr1.Build();
-  EXPECT_EQ(0, InjectRtcpPacket(p1.buffer(), p1.buffer_length()));
+  rtc::scoped_ptr<rtcp::RawPacket> 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 @@
   rr2.WithReportBlock(&rb3);
   rr2.WithReportBlock(&rb4);
 
-  rtcp::RawPacket p2 = rr2.Build();
-  EXPECT_EQ(0, InjectRtcpPacket(p2.buffer(), p2.buffer_length()));
+  rtc::scoped_ptr<rtcp::RawPacket> 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 @@
   rr1.From(kSenderSsrc1);
   rr1.WithReportBlock(&rb1);
 
-  rtcp::RawPacket p1 = rr1.Build();
-  EXPECT_EQ(0, InjectRtcpPacket(p1.buffer(), p1.buffer_length()));
+  rtc::scoped_ptr<rtcp::RawPacket> 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 @@
   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<rtcp::RawPacket> 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 @@
   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<rtcp::RawPacket> 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, InjectIjWithNoItem) {
   rtcp::Ij ij;
-  rtcp::RawPacket p = ij.Build();
-  EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length()));
+  rtc::scoped_ptr<rtcp::RawPacket> packet(ij.Build());
+  EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length()));
   EXPECT_EQ(0U, rtcp_packet_info_.rtcpPacketTypeFlags);
 }
 
@@ -397,8 +397,8 @@
   rtcp::Ij ij;
   ij.WithJitterItem(0x11111111);
 
-  rtcp::RawPacket p = ij.Build();
-  EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length()));
+  rtc::scoped_ptr<rtcp::RawPacket> 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 @@
   name += 'e';
   app.WithName(name);
 
-  rtcp::RawPacket p = app.Build();
-  EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length()));
+  rtc::scoped_ptr<rtcp::RawPacket> 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 @@
   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<rtcp::RawPacket> 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 @@
   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<rtcp::RawPacket> 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 @@
   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<rtcp::RawPacket> 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<rtcp::RawPacket> p2(bye.Build());
+  EXPECT_EQ(0, InjectRtcpPacket(p2->Buffer(), p2->Length()));
   EXPECT_EQ(-1, rtcp_receiver_->CNAME(kSenderSsrc, cName));
 }
 
@@ -487,8 +487,8 @@
   rr.WithReportBlock(&rb1);
   rr.WithReportBlock(&rb2);
 
-  rtcp::RawPacket p1 = rr.Build();
-  EXPECT_EQ(0, InjectRtcpPacket(p1.buffer(), p1.buffer_length()));
+  rtc::scoped_ptr<rtcp::RawPacket> p1(rr.Build());
+  EXPECT_EQ(0, InjectRtcpPacket(p1->Buffer(), p1->Length()));
   ASSERT_EQ(2u, rtcp_packet_info_.report_blocks.size());
   std::vector<RTCPReportBlock> received_blocks;
   rtcp_receiver_->StatisticsReceived(&received_blocks);
@@ -497,14 +497,14 @@
   // 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<rtcp::RawPacket> 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 @@
 
   rtcp::Pli pli;
   pli.To(kSourceSsrc);
-  rtcp::RawPacket p = pli.Build();
-  EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length()));
+  rtc::scoped_ptr<rtcp::RawPacket> packet(pli.Build());
+  EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length()));
   EXPECT_EQ(kRtcpPli, rtcp_packet_info_.rtcpPacketTypeFlags);
 }
 
@@ -532,8 +532,8 @@
 
   rtcp::Pli pli;
   pli.To(kSourceSsrc + 1);
-  rtcp::RawPacket p = pli.Build();
-  EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length()));
+  rtc::scoped_ptr<rtcp::RawPacket> packet(pli.Build());
+  EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length()));
   EXPECT_EQ(0U, rtcp_packet_info_.rtcpPacketTypeFlags);
 }
 
@@ -545,8 +545,8 @@
 
   rtcp::Fir fir;
   fir.To(kSourceSsrc);
-  rtcp::RawPacket p = fir.Build();
-  EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length()));
+  rtc::scoped_ptr<rtcp::RawPacket> packet(fir.Build());
+  EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length()));
   EXPECT_EQ(kRtcpFir, rtcp_packet_info_.rtcpPacketTypeFlags);
 }
 
@@ -558,16 +558,16 @@
 
   rtcp::Fir fir;
   fir.To(kSourceSsrc + 1);
-  rtcp::RawPacket p = fir.Build();
-  EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length()));
+  rtc::scoped_ptr<rtcp::RawPacket> 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<rtcp::RawPacket> 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, XrPacketWithZeroReportBlocksIgnored) {
   rtcp::Xr xr;
   xr.From(0x2345);
-  rtcp::RawPacket p = xr.Build();
-  EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length()));
+  rtc::scoped_ptr<rtcp::RawPacket> packet(xr.Build());
+  EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length()));
   EXPECT_EQ(0U, rtcp_packet_info_.rtcpPacketTypeFlags);
 }
 
@@ -593,8 +593,8 @@
   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<rtcp::RawPacket> 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 @@
   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<rtcp::RawPacket> packet(xr.Build());
+  EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length()));
   EXPECT_EQ(0U, rtcp_packet_info_.rtcpPacketTypeFlags);
 }
 
@@ -624,8 +624,8 @@
   xr.From(0x2345);
   xr.WithRrtr(&rrtr);
 
-  rtcp::RawPacket p = xr.Build();
-  EXPECT_EQ(0, InjectRtcpPacket(p.buffer(), p.buffer_length()));
+  rtc::scoped_ptr<rtcp::RawPacket> packet(xr.Build());
+  EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length()));
   EXPECT_EQ(kRtcpXrReceiverReferenceTime,
             rtcp_packet_info_.rtcpPacketTypeFlags);
 }
@@ -641,8 +641,8 @@
   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<rtcp::RawPacket> 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 @@
   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<rtcp::RawPacket> 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 @@
   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<rtcp::RawPacket> 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 @@
   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<rtcp::RawPacket> packet(xr.Build());
+  EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length()));
   EXPECT_EQ(static_cast<unsigned int>(kRtcpXrReceiverReferenceTime +
                                       kRtcpXrVoipMetric),
             rtcp_packet_info_.rtcpPacketTypeFlags);
@@ -729,13 +729,13 @@
   xr.WithRrtr(&rrtr);
   xr.WithDlrr(&dlrr);
   xr.WithVoipMetric(&metric);
-  rtcp::RawPacket p = xr.Build();
+  rtc::scoped_ptr<rtcp::RawPacket> packet(xr.Build());
   // Modify the DLRR block to have an unsupported block type, from 5 to 6.
-  uint8_t* buffer = const_cast<uint8_t*>(p.buffer());
+  uint8_t* buffer = const_cast<uint8_t*>(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<unsigned int>(kRtcpXrReceiverReferenceTime +
                                       kRtcpXrVoipMetric),
             rtcp_packet_info_.rtcpPacketTypeFlags);
@@ -764,8 +764,8 @@
   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<rtcp::RawPacket> packet(xr.Build());
+  EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length()));
   EXPECT_EQ(kRtcpXrReceiverReferenceTime,
       rtcp_packet_info_.rtcpPacketTypeFlags);
 
@@ -803,15 +803,15 @@
   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<rtcp::RawPacket> 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 @@
   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<rtcp::RawPacket> 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 @@
   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<rtcp::RawPacket> 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 @@
   rtcp::SenderReport sr;
   sr.From(kSenderSsrc);
   sr.Append(&tmmbr);
-  rtcp::RawPacket p = sr.Build();
+  rtc::scoped_ptr<rtcp::RawPacket> packet(sr.Build());
 
   std::set<uint32_t> 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 @@
   rtcp::SenderReport sr;
   sr.From(kSenderSsrc);
   sr.Append(&tmmbr);
-  rtcp::RawPacket p = sr.Build();
+  rtc::scoped_ptr<rtcp::RawPacket> 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 @@
     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<rtcp::RawPacket> packet(sr.Build());
+    EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length()));
     // 5 seconds between each packet.
     system_clock_.AdvanceTimeMilliseconds(5000);
   }
@@ -1009,8 +1009,8 @@
   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<rtcp::RawPacket> p1(rr1.Build());
+  EXPECT_EQ(0, InjectRtcpPacket(p1->Buffer(), p1->Length()));
   EXPECT_TRUE(callback.Matches(kSourceSsrc, kSequenceNumber, kFractionLoss,
                                kCumulativeLoss, kJitter));
 
@@ -1027,8 +1027,8 @@
   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<rtcp::RawPacket> 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 3cff2a4..12630f7 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 @@
     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<rtcp::RawPacket> packet(nack.Build());
+    EXPECT_EQ(0, module->impl_->IncomingRtcpPacket(packet->Buffer(),
+                                                   packet->Length()));
   }
 };