Revert "Refactor FEC code to use COW buffers"

This reverts commit 7325bc3917e6dd4c92e7a18fd879ba91f0b2851f.

Reason for revert: FecTest.UlpfecTest is consistently failing.

Original change's description:
> Refactor FEC code to use COW buffers
> 
> This refactoring helps to reduce unnecessary memcpy calls on the receive
> side.
> 
> This CL is the first stage of refactoring: it only replaces
> |uint8 data[IP_PACKET_SIZE]| with |rtc::CopyOnWriteBuffer data| and does
> necessary changes.
> 
> A follow-up CL will remove length field of the Packet class.
> 
> 
> Bug: webrtc:10750
> Change-Id: Ie233da83ff33f6370f511955e4c65d59522389a7
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/144881
> Reviewed-by: Artem Titov <titovartem@webrtc.org>
> Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#28539}

TBR=brandtr@webrtc.org,ilnik@webrtc.org,asapersson@webrtc.org,stefan@webrtc.org,titovartem@webrtc.org

Change-Id: I07c34256a76174f09a0d27eacbae6488e66f4b43
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:10750
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/145340
Reviewed-by: Qingsi Wang <qingsi@webrtc.org>
Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28545}
diff --git a/modules/rtp_rtcp/source/fec_test_helper.cc b/modules/rtp_rtcp/source/fec_test_helper.cc
index 8823e8b..1da057e 100644
--- a/modules/rtp_rtcp/source/fec_test_helper.cc
+++ b/modules/rtp_rtcp/source/fec_test_helper.cc
@@ -54,7 +54,6 @@
     std::unique_ptr<ForwardErrorCorrection::Packet> media_packet(
         new ForwardErrorCorrection::Packet());
     media_packet->length = random_->Rand(min_packet_size_, max_packet_size_);
-    media_packet->data.SetSize(media_packet->length);
 
     // Generate random values for the first 2 bytes
     media_packet->data[0] = random_->Rand<uint8_t>();
@@ -121,18 +120,16 @@
     size_t length) {
   std::unique_ptr<AugmentedPacket> packet(new AugmentedPacket());
 
-  packet->data.SetSize(length + kRtpHeaderSize);
   for (size_t i = 0; i < length; ++i)
     packet->data[i + kRtpHeaderSize] = offset + i;
   packet->length = length + kRtpHeaderSize;
-  packet->data.SetSize(packet->length);
   packet->header.headerLength = kRtpHeaderSize;
   packet->header.markerBit = (num_packets_ == 1);
   packet->header.payloadType = kVp8PayloadType;
   packet->header.sequenceNumber = seq_num_;
   packet->header.timestamp = timestamp_;
   packet->header.ssrc = ssrc_;
-  WriteRtpHeader(packet->header, packet->data.data());
+  WriteRtpHeader(packet->header, packet->data);
   ++seq_num_;
   --num_packets_;
 
@@ -170,10 +167,9 @@
 
   std::unique_ptr<AugmentedPacket> packet_with_rtp_header(
       new AugmentedPacket());
-  packet_with_rtp_header->data.SetSize(kRtpHeaderSize + packet.length);
-  WriteRtpHeader(header, packet_with_rtp_header->data.data());
-  memcpy(packet_with_rtp_header->data.data() + kRtpHeaderSize,
-         packet.data.cdata(), packet.length);
+  WriteRtpHeader(header, packet_with_rtp_header->data);
+  memcpy(packet_with_rtp_header->data + kRtpHeaderSize, packet.data,
+         packet.length);
   packet_with_rtp_header->length = kRtpHeaderSize + packet.length;
 
   return packet_with_rtp_header;
@@ -189,12 +185,11 @@
   const size_t kHeaderLength = packet.header.headerLength;
   red_packet->header = packet.header;
   red_packet->length = packet.length + 1;  // 1 byte RED header.
-  red_packet->data.SetSize(packet.length + 1);
   // Copy RTP header.
-  memcpy(red_packet->data.data(), packet.data.cdata(), kHeaderLength);
+  memcpy(red_packet->data, packet.data, kHeaderLength);
   SetRedHeader(red_packet->data[1] & 0x7f, kHeaderLength, red_packet.get());
-  memcpy(red_packet->data.data() + kHeaderLength + 1,
-         packet.data.cdata() + kHeaderLength, packet.length - kHeaderLength);
+  memcpy(red_packet->data + kHeaderLength + 1, packet.data + kHeaderLength,
+         packet.length - kHeaderLength);
 
   return red_packet;
 }
@@ -208,10 +203,8 @@
 
   red_packet->data[1] &= ~0x80;  // Clear marker bit.
   const size_t kHeaderLength = red_packet->header.headerLength;
-  red_packet->data.SetSize(kHeaderLength + 1 + packet.length);
   SetRedHeader(kFecPayloadType, kHeaderLength, red_packet.get());
-  memcpy(red_packet->data.data() + kHeaderLength + 1, packet.data.cdata(),
-         packet.length);
+  memcpy(red_packet->data + kHeaderLength + 1, packet.data, packet.length);
   red_packet->length = kHeaderLength + 1 + packet.length;
 
   return red_packet;
diff --git a/modules/rtp_rtcp/source/flexfec_header_reader_writer.cc b/modules/rtp_rtcp/source/flexfec_header_reader_writer.cc
index 04b48ca..e3cb0e9 100644
--- a/modules/rtp_rtcp/source/flexfec_header_reader_writer.cc
+++ b/modules/rtp_rtcp/source/flexfec_header_reader_writer.cc
@@ -125,7 +125,7 @@
     RTC_LOG(LS_WARNING) << "Discarding truncated FlexFEC packet.";
     return false;
   }
-  uint8_t* const packet_mask = fec_packet->pkt->data.data() + kPacketMaskOffset;
+  uint8_t* const packet_mask = fec_packet->pkt->data + kPacketMaskOffset;
   bool k_bit0 = (packet_mask[0] & 0x80) != 0;
   uint16_t mask_part0 = ByteReader<uint16_t>::ReadBigEndian(&packet_mask[0]);
   // Shift away K-bit 0, implicitly clearing the last bit.
@@ -260,8 +260,7 @@
   //
   // We treat the mask parts as unsigned integers with host order endianness
   // in order to simplify the bit shifting between bytes.
-  uint8_t* const written_packet_mask =
-      fec_packet->data.data() + kPacketMaskOffset;
+  uint8_t* const written_packet_mask = fec_packet->data + kPacketMaskOffset;
   if (packet_mask_size == kUlpfecPacketMaskSizeLBitSet) {
     // The packet mask is 48 bits long.
     uint16_t tmp_mask_part0 =
diff --git a/modules/rtp_rtcp/source/flexfec_header_reader_writer_unittest.cc b/modules/rtp_rtcp/source/flexfec_header_reader_writer_unittest.cc
index 7c1e4db..81d0cb3 100644
--- a/modules/rtp_rtcp/source/flexfec_header_reader_writer_unittest.cc
+++ b/modules/rtp_rtcp/source/flexfec_header_reader_writer_unittest.cc
@@ -78,7 +78,6 @@
   FlexfecHeaderWriter writer;
   rtc::scoped_refptr<Packet> written_packet(new Packet());
   written_packet->length = kMediaPacketLength;
-  written_packet->data.SetSize(kMediaPacketLength);
   for (size_t i = 0; i < written_packet->length; ++i) {
     written_packet->data[i] = i;  // Actual content doesn't matter.
   }
@@ -92,7 +91,7 @@
   std::unique_ptr<ReceivedFecPacket> read_packet(new ReceivedFecPacket());
   read_packet->ssrc = kFlexfecSsrc;
   read_packet->pkt = rtc::scoped_refptr<Packet>(new Packet());
-  read_packet->pkt->data = written_packet.data;
+  memcpy(read_packet->pkt->data, written_packet.data, written_packet.length);
   read_packet->pkt->length = written_packet.length;
   EXPECT_TRUE(reader.ReadFecHeader(read_packet.get()));
   return read_packet;
@@ -113,17 +112,16 @@
   EXPECT_EQ(read_packet.pkt->length - expected_fec_header_size,
             read_packet.protection_length);
   // Ensure that the K-bits are removed and the packet mask has been packed.
-  EXPECT_THAT(
-      ::testing::make_tuple(read_packet.pkt->data.cdata() + packet_mask_offset,
-                            read_packet.packet_mask_size),
-      ::testing::ElementsAreArray(expected_packet_mask,
-                                  expected_packet_mask_size));
+  EXPECT_THAT(::testing::make_tuple(read_packet.pkt->data + packet_mask_offset,
+                                    read_packet.packet_mask_size),
+              ::testing::ElementsAreArray(expected_packet_mask,
+                                          expected_packet_mask_size));
 }
 
 void VerifyFinalizedHeaders(const uint8_t* expected_packet_mask,
                             size_t expected_packet_mask_size,
                             const Packet& written_packet) {
-  const uint8_t* packet = written_packet.data.cdata();
+  const uint8_t* packet = written_packet.data;
   EXPECT_EQ(0x00, packet[0] & 0x80);  // F bit clear.
   EXPECT_EQ(0x00, packet[0] & 0x40);  // R bit clear.
   EXPECT_EQ(0x01, packet[8]);         // SSRCCount = 1.
@@ -150,17 +148,17 @@
   EXPECT_EQ(written_packet.length - expected_fec_header_size,
             read_packet.protection_length);
   // Verify that the call to ReadFecHeader did normalize the packet masks.
-  EXPECT_THAT(::testing::make_tuple(
-                  read_packet.pkt->data.cdata() + kFlexfecPacketMaskOffset,
-                  read_packet.packet_mask_size),
-              ::testing::ElementsAreArray(expected_packet_mask,
-                                          expected_packet_mask_size));
+  EXPECT_THAT(
+      ::testing::make_tuple(read_packet.pkt->data + kFlexfecPacketMaskOffset,
+                            read_packet.packet_mask_size),
+      ::testing::ElementsAreArray(expected_packet_mask,
+                                  expected_packet_mask_size));
   // Verify that the call to ReadFecHeader did not tamper with the payload.
   EXPECT_THAT(::testing::make_tuple(
-                  read_packet.pkt->data.cdata() + read_packet.fec_header_size,
+                  read_packet.pkt->data + read_packet.fec_header_size,
                   read_packet.pkt->length - read_packet.fec_header_size),
               ::testing::ElementsAreArray(
-                  written_packet.data.cdata() + expected_fec_header_size,
+                  written_packet.data + expected_fec_header_size,
                   written_packet.length - expected_fec_header_size));
 }
 
@@ -184,7 +182,7 @@
   const size_t packet_length = sizeof(kPacketData);
   ReceivedFecPacket read_packet;
   read_packet.pkt = rtc::scoped_refptr<Packet>(new Packet());
-  read_packet.pkt->data.SetData(kPacketData, packet_length);
+  memcpy(read_packet.pkt->data, kPacketData, packet_length);
   read_packet.pkt->length = packet_length;
 
   FlexfecHeaderReader reader;
@@ -216,7 +214,7 @@
   const size_t packet_length = sizeof(kPacketData);
   ReceivedFecPacket read_packet;
   read_packet.pkt = rtc::scoped_refptr<Packet>(new Packet());
-  read_packet.pkt->data.SetData(kPacketData, packet_length);
+  memcpy(read_packet.pkt->data, kPacketData, packet_length);
   read_packet.pkt->length = packet_length;
 
   FlexfecHeaderReader reader;
@@ -255,7 +253,7 @@
   const size_t packet_length = sizeof(kPacketData);
   ReceivedFecPacket read_packet;
   read_packet.pkt = rtc::scoped_refptr<Packet>(new Packet());
-  read_packet.pkt->data.SetData(kPacketData, packet_length);
+  memcpy(read_packet.pkt->data, kPacketData, packet_length);
   read_packet.pkt->length = packet_length;
 
   FlexfecHeaderReader reader;
@@ -275,7 +273,6 @@
   read_packet.ssrc = kFlexfecSsrc;
   read_packet.pkt = std::move(written_packet);
   read_packet.pkt->length = 12;
-  read_packet.pkt->data.SetSize(read_packet.pkt->length);
 
   FlexfecHeaderReader reader;
   EXPECT_FALSE(reader.ReadFecHeader(&read_packet));
@@ -291,7 +288,6 @@
   read_packet.ssrc = kFlexfecSsrc;
   read_packet.pkt = std::move(written_packet);
   read_packet.pkt->length = 18;
-  read_packet.pkt->data.SetSize(read_packet.pkt->length);
 
   FlexfecHeaderReader reader;
   EXPECT_FALSE(reader.ReadFecHeader(&read_packet));
@@ -308,7 +304,6 @@
   read_packet.ssrc = kFlexfecSsrc;
   read_packet.pkt = std::move(written_packet);
   read_packet.pkt->length = 20;
-  read_packet.pkt->data.SetSize(read_packet.pkt->length);
 
   FlexfecHeaderReader reader;
   EXPECT_FALSE(reader.ReadFecHeader(&read_packet));
@@ -325,7 +320,6 @@
   read_packet.ssrc = kFlexfecSsrc;
   read_packet.pkt = std::move(written_packet);
   read_packet.pkt->length = 24;
-  read_packet.pkt->data.SetSize(read_packet.pkt->length);
 
   FlexfecHeaderReader reader;
   EXPECT_FALSE(reader.ReadFecHeader(&read_packet));
@@ -337,7 +331,6 @@
   constexpr uint8_t kUlpfecPacketMask[] = {0x11, 0x02};
   Packet written_packet;
   written_packet.length = kMediaPacketLength;
-  written_packet.data.SetSize(written_packet.length);
   for (size_t i = 0; i < written_packet.length; ++i) {
     written_packet.data[i] = i;
   }
@@ -356,7 +349,6 @@
   constexpr uint8_t kUlpfecPacketMask[] = {0x91, 0x02, 0x08, 0x44, 0x00, 0x84};
   Packet written_packet;
   written_packet.length = kMediaPacketLength;
-  written_packet.data.SetSize(written_packet.length);
   for (size_t i = 0; i < written_packet.length; ++i) {
     written_packet.data[i] = i;
   }
@@ -379,7 +371,6 @@
   constexpr uint8_t kUlpfecPacketMask[] = {0x22, 0x22, 0x44, 0x44, 0x44, 0x41};
   Packet written_packet;
   written_packet.length = kMediaPacketLength;
-  written_packet.data.SetSize(written_packet.length);
   for (size_t i = 0; i < written_packet.length; ++i) {
     written_packet.data[i] = i;
   }
diff --git a/modules/rtp_rtcp/source/flexfec_receiver.cc b/modules/rtp_rtcp/source/flexfec_receiver.cc
index da7bda1..4c788f4 100644
--- a/modules/rtp_rtcp/source/flexfec_receiver.cc
+++ b/modules/rtp_rtcp/source/flexfec_receiver.cc
@@ -107,12 +107,12 @@
     ++packet_counter_.num_fec_packets;
 
     // Insert packet payload into erasure code.
+    // TODO(brandtr): Remove this memcpy when the FEC packet classes
+    // are using COW buffers internally.
     received_packet->pkt = rtc::scoped_refptr<ForwardErrorCorrection::Packet>(
         new ForwardErrorCorrection::Packet());
-    // TODO(ilnik): after slice capability is added to COW, use it here instead
-    // of initializing COW buffer with ArrayView.
     auto payload = packet.payload();
-    received_packet->pkt->data.SetData(payload.data(), payload.size());
+    memcpy(received_packet->pkt->data, payload.data(), payload.size());
     received_packet->pkt->length = payload.size();
   } else {
     // This is a media packet, or a FlexFEC packet belonging to some
@@ -123,13 +123,11 @@
     received_packet->is_fec = false;
 
     // Insert entire packet into erasure code.
-    // Create a copy and fill with zeros all mutable extensions.
     received_packet->pkt = rtc::scoped_refptr<ForwardErrorCorrection::Packet>(
         new ForwardErrorCorrection::Packet());
-    RtpPacketReceived packet_copy(packet);
-    packet_copy.ZeroMutableExtensions();
-    received_packet->pkt->data = packet_copy.Buffer();
-    received_packet->pkt->length = received_packet->pkt->data.size();
+    // Create a copy and fill with zeros all mutable extensions.
+    packet.CopyAndZeroMutableExtensions(received_packet->pkt->data);
+    received_packet->pkt->length = packet.size();
   }
 
   ++packet_counter_.num_packets;
@@ -163,14 +161,14 @@
     // Set this flag first, since OnRecoveredPacket may end up here
     // again, with the same packet.
     recovered_packet->returned = true;
-    RTC_CHECK_GT(recovered_packet->pkt->data.size(), 0);
+    RTC_CHECK(recovered_packet->pkt);
     recovered_packet_receiver_->OnRecoveredPacket(
-        recovered_packet->pkt->data.cdata(), recovered_packet->pkt->length);
+        recovered_packet->pkt->data, recovered_packet->pkt->length);
     // Periodically log the incoming packets.
     int64_t now_ms = clock_->TimeInMilliseconds();
     if (now_ms - last_recovered_packet_ms_ > kPacketLogIntervalMs) {
       uint32_t media_ssrc =
-          ForwardErrorCorrection::ParseSsrc(recovered_packet->pkt->data.data());
+          ForwardErrorCorrection::ParseSsrc(recovered_packet->pkt->data);
       RTC_LOG(LS_VERBOSE) << "Recovered media packet with SSRC: " << media_ssrc
                           << " from FlexFEC stream with SSRC: " << ssrc_ << ".";
       last_recovered_packet_ms_ = now_ms;
diff --git a/modules/rtp_rtcp/source/flexfec_receiver_unittest.cc b/modules/rtp_rtcp/source/flexfec_receiver_unittest.cc
index 1542e74..3d77d7b 100644
--- a/modules/rtp_rtcp/source/flexfec_receiver_unittest.cc
+++ b/modules/rtp_rtcp/source/flexfec_receiver_unittest.cc
@@ -39,7 +39,7 @@
 
 RtpPacketReceived ParsePacket(const Packet& packet) {
   RtpPacketReceived parsed_packet;
-  EXPECT_TRUE(parsed_packet.Parse(packet.data));
+  EXPECT_TRUE(parsed_packet.Parse(packet.data, packet.length));
   return parsed_packet;
 }
 
@@ -241,8 +241,8 @@
   media_it++;
   EXPECT_CALL(recovered_packet_receiver_,
               OnRecoveredPacket(_, (*media_it)->length))
-      .With(Args<0, 1>(
-          ElementsAreArray((*media_it)->data.cdata(), (*media_it)->length)));
+      .With(
+          Args<0, 1>(ElementsAreArray((*media_it)->data, (*media_it)->length)));
   receiver_.OnRtpPacket(ParsePacket(*packet_with_rtp_header));
 }
 
@@ -263,8 +263,8 @@
   auto media_it = media_packets.begin();
   EXPECT_CALL(recovered_packet_receiver_,
               OnRecoveredPacket(_, (*media_it)->length))
-      .With(Args<0, 1>(
-          ElementsAreArray((*media_it)->data.cdata(), (*media_it)->length)));
+      .With(
+          Args<0, 1>(ElementsAreArray((*media_it)->data, (*media_it)->length)));
   receiver_.OnRtpPacket(ParsePacket(*packet_with_rtp_header));
 
   // Receive second FEC packet and recover second lost media packet.
@@ -273,8 +273,8 @@
   media_it++;
   EXPECT_CALL(recovered_packet_receiver_,
               OnRecoveredPacket(_, (*media_it)->length))
-      .With(Args<0, 1>(
-          ElementsAreArray((*media_it)->data.cdata(), (*media_it)->length)));
+      .With(
+          Args<0, 1>(ElementsAreArray((*media_it)->data, (*media_it)->length)));
   receiver_.OnRtpPacket(ParsePacket(*packet_with_rtp_header));
 }
 
@@ -312,8 +312,8 @@
   media_it++;
   EXPECT_CALL(recovered_packet_receiver_,
               OnRecoveredPacket(_, (*media_it)->length))
-      .With(Args<0, 1>(
-          ElementsAreArray((*media_it)->data.cdata(), (*media_it)->length)));
+      .With(
+          Args<0, 1>(ElementsAreArray((*media_it)->data, (*media_it)->length)));
   receiver_.OnRtpPacket(ParsePacket(*packet_with_rtp_header));
 
   // Receive the FEC packet again, but do not call back.
@@ -366,7 +366,7 @@
     EXPECT_CALL(recovered_packet_receiver_,
                 OnRecoveredPacket(_, (*media_it)->length))
         .With(Args<0, 1>(
-            ElementsAreArray((*media_it)->data.cdata(), (*media_it)->length)));
+            ElementsAreArray((*media_it)->data, (*media_it)->length)));
     receiver_.OnRtpPacket(ParsePacket(*fec_packet_with_rtp_header));
     ++media_it;
   }
@@ -405,8 +405,8 @@
   media_it = media_packets.begin();
   EXPECT_CALL(recovered_packet_receiver_,
               OnRecoveredPacket(_, (*media_it)->length))
-      .With(Args<0, 1>(
-          ElementsAreArray((*media_it)->data.cdata(), (*media_it)->length)));
+      .With(
+          Args<0, 1>(ElementsAreArray((*media_it)->data, (*media_it)->length)));
   receiver_.OnRtpPacket(ParsePacket(*packet_with_rtp_header));
 }
 
@@ -534,12 +534,12 @@
   // Expect to recover lost media packets.
   EXPECT_CALL(recovered_packet_receiver_,
               OnRecoveredPacket(_, (*media_packet1)->length))
-      .With(Args<0, 1>(ElementsAreArray((*media_packet1)->data.cdata(),
-                                        (*media_packet1)->length)));
+      .With(Args<0, 1>(
+          ElementsAreArray((*media_packet1)->data, (*media_packet1)->length)));
   EXPECT_CALL(recovered_packet_receiver_,
               OnRecoveredPacket(_, (*media_packet4)->length))
-      .With(Args<0, 1>(ElementsAreArray((*media_packet4)->data.cdata(),
-                                        (*media_packet4)->length)));
+      .With(Args<0, 1>(
+          ElementsAreArray((*media_packet4)->data, (*media_packet4)->length)));
 
   // Add FEC packets.
   auto fec_it = fec_packets.begin();
@@ -636,8 +636,8 @@
   media_it++;
   EXPECT_CALL(recovered_packet_receiver_,
               OnRecoveredPacket(_, (*media_it)->length))
-      .With(Args<0, 1>(
-          ElementsAreArray((*media_it)->data.cdata(), (*media_it)->length)));
+      .With(
+          Args<0, 1>(ElementsAreArray((*media_it)->data, (*media_it)->length)));
   receiver_.OnRtpPacket(ParsePacket(*packet_with_rtp_header));
 
   // Check stats calculations.
diff --git a/modules/rtp_rtcp/source/flexfec_sender.cc b/modules/rtp_rtcp/source/flexfec_sender.cc
index 3fb51cd..038cef7 100644
--- a/modules/rtp_rtcp/source/flexfec_sender.cc
+++ b/modules/rtp_rtcp/source/flexfec_sender.cc
@@ -114,7 +114,7 @@
   // protection.
   RTC_DCHECK_EQ(packet.Ssrc(), protected_media_ssrc_);
   return ulpfec_generator_.AddRtpPacketAndGenerateFec(
-             packet.Buffer(), packet.headers_size()) == 0;
+             packet.data(), packet.payload_size(), packet.headers_size()) == 0;
 }
 
 bool FlexfecSender::FecAvailable() const {
@@ -154,7 +154,7 @@
 
     // RTP payload.
     uint8_t* payload = fec_packet_to_send->AllocatePayload(fec_packet->length);
-    memcpy(payload, fec_packet->data.cdata(), fec_packet->length);
+    memcpy(payload, fec_packet->data, fec_packet->length);
 
     fec_packets_to_send.push_back(std::move(fec_packet_to_send));
   }
diff --git a/modules/rtp_rtcp/source/flexfec_sender_unittest.cc b/modules/rtp_rtcp/source/flexfec_sender_unittest.cc
index 10ec2e7..c7291b0 100644
--- a/modules/rtp_rtcp/source/flexfec_sender_unittest.cc
+++ b/modules/rtp_rtcp/source/flexfec_sender_unittest.cc
@@ -62,7 +62,7 @@
     std::unique_ptr<AugmentedPacket> packet =
         packet_generator.NextPacket(i, kPayloadLength);
     RtpPacketToSend rtp_packet(nullptr);  // No header extensions.
-    rtp_packet.Parse(packet->data);
+    rtp_packet.Parse(packet->data, packet->length);
     EXPECT_TRUE(sender->AddRtpPacketAndGenerateFec(rtp_packet));
   }
   EXPECT_TRUE(sender->FecAvailable());
@@ -133,7 +133,7 @@
       std::unique_ptr<AugmentedPacket> packet =
           packet_generator.NextPacket(i, kPayloadLength);
       RtpPacketToSend rtp_packet(nullptr);
-      rtp_packet.Parse(packet->data);
+      rtp_packet.Parse(packet->data, packet->length);
       EXPECT_TRUE(sender.AddRtpPacketAndGenerateFec(rtp_packet));
     }
   }
@@ -173,7 +173,7 @@
       std::unique_ptr<AugmentedPacket> packet =
           packet_generator.NextPacket(i, kPayloadLength);
       RtpPacketToSend rtp_packet(nullptr);
-      rtp_packet.Parse(packet->data);
+      rtp_packet.Parse(packet->data, packet->length);
       EXPECT_TRUE(sender.AddRtpPacketAndGenerateFec(rtp_packet));
     }
     EXPECT_TRUE(sender.FecAvailable());
diff --git a/modules/rtp_rtcp/source/forward_error_correction.cc b/modules/rtp_rtcp/source/forward_error_correction.cc
index bfb4c2d..413c708 100644
--- a/modules/rtp_rtcp/source/forward_error_correction.cc
+++ b/modules/rtp_rtcp/source/forward_error_correction.cc
@@ -150,11 +150,9 @@
     return 0;
   }
   for (int i = 0; i < num_fec_packets; ++i) {
-    generated_fec_packets_[i].data.EnsureCapacity(IP_PACKET_SIZE);
-    memset(generated_fec_packets_[i].data.data(), 0, IP_PACKET_SIZE);
+    memset(generated_fec_packets_[i].data, 0, IP_PACKET_SIZE);
     // Use this as a marker for untouched packets.
     generated_fec_packets_[i].length = 0;
-    generated_fec_packets_[i].data.SetSize(0);
     fec_packets->push_back(&generated_fec_packets_[i]);
   }
 
@@ -179,9 +177,9 @@
   GenerateFecPayloads(media_packets, num_fec_packets);
   // TODO(brandtr): Generalize this when multistream protection support is
   // added.
-  const uint32_t media_ssrc = ParseSsrc(media_packets.front()->data.data());
+  const uint32_t media_ssrc = ParseSsrc(media_packets.front()->data);
   const uint16_t seq_num_base =
-      ParseSequenceNumber(media_packets.front()->data.data());
+      ParseSequenceNumber(media_packets.front()->data);
   FinalizeFecHeaders(num_fec_packets, media_ssrc, seq_num_base);
 
   return 0;
@@ -213,8 +211,7 @@
 
     size_t media_pkt_idx = 0;
     auto media_packets_it = media_packets.cbegin();
-    uint16_t prev_seq_num =
-        ParseSequenceNumber((*media_packets_it)->data.data());
+    uint16_t prev_seq_num = ParseSequenceNumber((*media_packets_it)->data);
     while (media_packets_it != media_packets.end()) {
       Packet* const media_packet = media_packets_it->get();
       // Should |media_packet| be protected by |fec_packet|?
@@ -228,7 +225,6 @@
           // with) is the identity operator, thus all prior XORs are
           // still correct even though we expand the packet length here.
           fec_packet->length = fec_packet_length;
-          fec_packet->data.SetSize(fec_packet->length);
         }
         if (first_protected_packet) {
           // Write P, X, CC, M, and PT recovery fields.
@@ -241,10 +237,8 @@
           // Write timestamp recovery field.
           memcpy(&fec_packet->data[4], &media_packet->data[4], 4);
           // Write payload.
-          if (media_payload_length > 0) {
-            memcpy(&fec_packet->data[fec_header_size],
-                   &media_packet->data[kRtpHeaderSize], media_payload_length);
-          }
+          memcpy(&fec_packet->data[fec_header_size],
+                 &media_packet->data[kRtpHeaderSize], media_payload_length);
         } else {
           XorHeaders(*media_packet, fec_packet);
           XorPayloads(*media_packet, media_payload_length, fec_header_size,
@@ -253,8 +247,7 @@
       }
       media_packets_it++;
       if (media_packets_it != media_packets.end()) {
-        uint16_t seq_num =
-            ParseSequenceNumber((*media_packets_it)->data.data());
+        uint16_t seq_num = ParseSequenceNumber((*media_packets_it)->data);
         media_pkt_idx += static_cast<uint16_t>(seq_num - prev_seq_num);
         prev_seq_num = seq_num;
       }
@@ -273,10 +266,8 @@
   if (num_media_packets <= 1) {
     return num_media_packets;
   }
-  uint16_t last_seq_num =
-      ParseSequenceNumber(media_packets.back()->data.data());
-  uint16_t first_seq_num =
-      ParseSequenceNumber(media_packets.front()->data.data());
+  uint16_t last_seq_num = ParseSequenceNumber(media_packets.back()->data);
+  uint16_t first_seq_num = ParseSequenceNumber(media_packets.front()->data);
   size_t total_missing_seq_nums =
       static_cast<uint16_t>(last_seq_num - first_seq_num) - num_media_packets +
       1;
@@ -309,7 +300,7 @@
       // We can only cover up to 48 packets.
       break;
     }
-    uint16_t seq_num = ParseSequenceNumber((*media_packets_it)->data.data());
+    uint16_t seq_num = ParseSequenceNumber((*media_packets_it)->data);
     const int num_zeros_to_insert =
         static_cast<uint16_t>(seq_num - prev_seq_num - 1);
     if (num_zeros_to_insert > 0) {
@@ -544,29 +535,25 @@
         << "for its own header.";
     return false;
   }
-  if (fec_packet.protection_length >
-      std::min(size_t{IP_PACKET_SIZE - kRtpHeaderSize},
-               IP_PACKET_SIZE - fec_packet.fec_header_size)) {
-    RTC_LOG(LS_WARNING) << "Incorrect protection length, dropping FEC packet.";
-    return false;
-  }
   // Initialize recovered packet data.
   recovered_packet->pkt = new Packet();
-  recovered_packet->pkt->data.SetSize(fec_packet.protection_length +
-                                      kRtpHeaderSize);
+  memset(recovered_packet->pkt->data, 0, IP_PACKET_SIZE);
   recovered_packet->returned = false;
   recovered_packet->was_recovered = true;
   // Copy bytes corresponding to minimum RTP header size.
   // Note that the sequence number and SSRC fields will be overwritten
   // at the end of packet recovery.
-  memcpy(recovered_packet->pkt->data.data(), fec_packet.pkt->data.cdata(),
-         kRtpHeaderSize);
+  memcpy(&recovered_packet->pkt->data, fec_packet.pkt->data, kRtpHeaderSize);
   // Copy remaining FEC payload.
-  if (fec_packet.protection_length > 0) {
-    memcpy(recovered_packet->pkt->data.data() + kRtpHeaderSize,
-           fec_packet.pkt->data.cdata() + fec_packet.fec_header_size,
-           fec_packet.protection_length);
+  if (fec_packet.protection_length >
+      std::min(sizeof(recovered_packet->pkt->data) - kRtpHeaderSize,
+               sizeof(fec_packet.pkt->data) - fec_packet.fec_header_size)) {
+    RTC_LOG(LS_WARNING) << "Incorrect protection length, dropping FEC packet.";
+    return false;
   }
+  memcpy(&recovered_packet->pkt->data[kRtpHeaderSize],
+         &fec_packet.pkt->data[fec_packet.fec_header_size],
+         fec_packet.protection_length);
   return true;
 }
 
@@ -577,16 +564,15 @@
   recovered_packet->pkt->data[0] |= 0x80;  // Set the 1st bit.
   recovered_packet->pkt->data[0] &= 0xbf;  // Clear the 2nd bit.
   // Recover the packet length, from temporary location.
-  const size_t new_size =
+  recovered_packet->pkt->length =
       ByteReader<uint16_t>::ReadBigEndian(&recovered_packet->pkt->data[2]) +
       kRtpHeaderSize;
-  if (new_size > size_t{IP_PACKET_SIZE - kRtpHeaderSize}) {
+  if (recovered_packet->pkt->length >
+      sizeof(recovered_packet->pkt->data) - kRtpHeaderSize) {
     RTC_LOG(LS_WARNING) << "The recovered packet had a length larger than a "
                         << "typical IP packet, and is thus dropped.";
     return false;
   }
-  recovered_packet->pkt->length = new_size;
-  recovered_packet->pkt->data.SetSize(new_size);
   // Set the SN field.
   ByteWriter<uint16_t>::WriteBigEndian(&recovered_packet->pkt->data[2],
                                        recovered_packet->seq_num);
@@ -623,8 +609,8 @@
                                          size_t dst_offset,
                                          Packet* dst) {
   // XOR the payload.
-  RTC_DCHECK_LE(kRtpHeaderSize + payload_length, src.data.size());
-  RTC_DCHECK_LE(dst_offset + payload_length, dst->data.size());
+  RTC_DCHECK_LE(kRtpHeaderSize + payload_length, sizeof(src.data));
+  RTC_DCHECK_LE(dst_offset + payload_length, sizeof(dst->data));
   for (size_t i = 0; i < payload_length; ++i) {
     dst->data[dst_offset + i] ^= src.data[kRtpHeaderSize + i];
   }
@@ -641,8 +627,7 @@
       recovered_packet->seq_num = protected_packet->seq_num;
     } else {
       XorHeaders(*protected_packet->pkt, recovered_packet->pkt);
-      XorPayloads(*protected_packet->pkt,
-                  protected_packet->pkt->length - kRtpHeaderSize,
+      XorPayloads(*protected_packet->pkt, protected_packet->pkt->length,
                   kRtpHeaderSize, recovered_packet->pkt);
     }
   }
diff --git a/modules/rtp_rtcp/source/forward_error_correction.h b/modules/rtp_rtcp/source/forward_error_correction.h
index c002647..ad2eef1 100644
--- a/modules/rtp_rtcp/source/forward_error_correction.h
+++ b/modules/rtp_rtcp/source/forward_error_correction.h
@@ -22,7 +22,6 @@
 #include "modules/include/module_fec_types.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "modules/rtp_rtcp/source/forward_error_correction_internal.h"
-#include "rtc_base/copy_on_write_buffer.h"
 
 namespace webrtc {
 
@@ -54,7 +53,7 @@
     virtual int32_t Release();
 
     size_t length;                 // Length of packet in bytes.
-    rtc::CopyOnWriteBuffer data;   // Packet data.
+    uint8_t data[IP_PACKET_SIZE];  // Packet data.
 
    private:
     int32_t ref_count_;  // Counts the number of references to a packet.
diff --git a/modules/rtp_rtcp/source/rtp_fec_unittest.cc b/modules/rtp_rtcp/source/rtp_fec_unittest.cc
index 7d3b054..1c248c8 100644
--- a/modules/rtp_rtcp/source/rtp_fec_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_fec_unittest.cc
@@ -121,7 +121,7 @@
           new ForwardErrorCorrection::ReceivedPacket());
       received_packet->pkt = new ForwardErrorCorrection::Packet();
       received_packet->pkt->length = packet->length;
-      received_packet->pkt->data = packet->data;
+      memcpy(received_packet->pkt->data, packet->data, packet->length);
       received_packet->is_fec = is_fec;
       if (!is_fec) {
         received_packet->ssrc = kMediaSsrc;
@@ -158,8 +158,7 @@
         if (media_packet->length != recovered_packet->pkt->length) {
           return false;
         }
-        if (memcmp(media_packet->data.cdata(),
-                   recovered_packet->pkt->data.cdata(),
+        if (memcmp(media_packet->data, recovered_packet->pkt->data,
                    media_packet->length) != 0) {
           return false;
         }
diff --git a/modules/rtp_rtcp/source/rtp_packet.cc b/modules/rtp_rtcp/source/rtp_packet.cc
index b9c7e54..5f919ff 100644
--- a/modules/rtp_rtcp/source/rtp_packet.cc
+++ b/modules/rtp_rtcp/source/rtp_packet.cc
@@ -157,7 +157,10 @@
   ByteWriter<uint32_t>::WriteBigEndian(WriteAt(8), ssrc);
 }
 
-void RtpPacket::ZeroMutableExtensions() {
+void RtpPacket::CopyAndZeroMutableExtensions(
+    rtc::ArrayView<uint8_t> buffer) const {
+  RTC_CHECK_GE(buffer.size(), buffer_.size());
+  memcpy(buffer.data(), buffer_.cdata(), buffer_.size());
   for (const ExtensionInfo& extension : extension_entries_) {
     switch (extensions_.GetType(extension.id)) {
       case RTPExtensionType::kRtpExtensionNone: {
@@ -167,9 +170,9 @@
       case RTPExtensionType::kRtpExtensionVideoTiming: {
         // Nullify 3 last entries: packetization delay and 2 network timestamps.
         // Each of them is 2 bytes.
-        memset(
-            WriteAt(extension.offset + VideoSendTiming::kPacerExitDeltaOffset),
-            0, 6);
+        memset(buffer.data() + extension.offset +
+                   VideoSendTiming::kPacerExitDeltaOffset,
+               0, 6);
         break;
       }
       case RTPExtensionType::kRtpExtensionTransportSequenceNumber:
@@ -177,7 +180,7 @@
       case RTPExtensionType::kRtpExtensionTransmissionTimeOffset:
       case RTPExtensionType::kRtpExtensionAbsoluteSendTime: {
         // Nullify whole extension, as it's filled in the pacer.
-        memset(WriteAt(extension.offset), 0, extension.length);
+        memset(buffer.data() + extension.offset, 0, extension.length);
         break;
       }
       case RTPExtensionType::kRtpExtensionAudioLevel:
diff --git a/modules/rtp_rtcp/source/rtp_packet.h b/modules/rtp_rtcp/source/rtp_packet.h
index 145f1d7..c49e070 100644
--- a/modules/rtp_rtcp/source/rtp_packet.h
+++ b/modules/rtp_rtcp/source/rtp_packet.h
@@ -89,9 +89,9 @@
   void SetTimestamp(uint32_t timestamp);
   void SetSsrc(uint32_t ssrc);
 
-  // Fills with zeroes mutable extensions,
+  // Copies the buffer with zero-ed mutable extensions,
   // which are modified after FEC protection is generated.
-  void ZeroMutableExtensions();
+  void CopyAndZeroMutableExtensions(rtc::ArrayView<uint8_t> buffer) const;
 
   // Removes extension of given |type|, returns false is extension was not
   // registered in packet's extension map or not present in the packet. Only
diff --git a/modules/rtp_rtcp/source/rtp_sender_video.cc b/modules/rtp_rtcp/source/rtp_sender_video.cc
index 0147994..632088b 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_video.cc
@@ -278,7 +278,8 @@
     if (ulpfec_enabled()) {
       if (protect_media_packet) {
         ulpfec_generator_.AddRtpPacketAndGenerateFec(
-            media_packet->Buffer(), media_packet->headers_size());
+            media_packet->data(), media_packet->payload_size(),
+            media_packet->headers_size());
       }
       uint16_t num_fec_packets = ulpfec_generator_.NumAvailableFecPackets();
       if (num_fec_packets > 0) {
diff --git a/modules/rtp_rtcp/source/ulpfec_generator.cc b/modules/rtp_rtcp/source/ulpfec_generator.cc
index 791fff9..ec9088c 100644
--- a/modules/rtp_rtcp/source/ulpfec_generator.cc
+++ b/modules/rtp_rtcp/source/ulpfec_generator.cc
@@ -133,9 +133,9 @@
   }
 }
 
-int UlpfecGenerator::AddRtpPacketAndGenerateFec(
-    const rtc::CopyOnWriteBuffer& data_buffer,
-    size_t rtp_header_length) {
+int UlpfecGenerator::AddRtpPacketAndGenerateFec(const uint8_t* data_buffer,
+                                                size_t payload_length,
+                                                size_t rtp_header_length) {
   RTC_DCHECK(generated_fec_packets_.empty());
   if (media_packets_.empty()) {
     params_ = new_params_;
@@ -146,9 +146,8 @@
     // Our packet masks can only protect up to |kUlpfecMaxMediaPackets| packets.
     std::unique_ptr<ForwardErrorCorrection::Packet> packet(
         new ForwardErrorCorrection::Packet());
-    RTC_DCHECK_GE(data_buffer.size(), rtp_header_length);
-    packet->data = data_buffer;
-    packet->length = packet->data.size();
+    packet->length = payload_length + rtp_header_length;
+    memcpy(packet->data, data_buffer, packet->length);
     media_packets_.push_back(std::move(packet));
     // Keep track of the RTP header length, so we can copy the RTP header
     // from |packet| to newly generated ULPFEC+RED packets.
@@ -227,12 +226,12 @@
     std::unique_ptr<RedPacket> red_packet(
         new RedPacket(last_media_packet_rtp_header_length_ +
                       kRedForFecHeaderLength + fec_packet->length));
-    red_packet->CreateHeader(last_media_packet->data.data(),
+    red_packet->CreateHeader(last_media_packet->data,
                              last_media_packet_rtp_header_length_,
                              red_payload_type, ulpfec_payload_type);
     red_packet->SetSeqNum(seq_num++);
     red_packet->ClearMarkerBit();
-    red_packet->AssignPayload(fec_packet->data.data(), fec_packet->length);
+    red_packet->AssignPayload(fec_packet->data, fec_packet->length);
     red_packets.push_back(std::move(red_packet));
   }
 
diff --git a/modules/rtp_rtcp/source/ulpfec_generator.h b/modules/rtp_rtcp/source/ulpfec_generator.h
index cdfa1ff..7b18c6e 100644
--- a/modules/rtp_rtcp/source/ulpfec_generator.h
+++ b/modules/rtp_rtcp/source/ulpfec_generator.h
@@ -58,7 +58,8 @@
   // Adds a media packet to the internal buffer. When enough media packets
   // have been added, the FEC packets are generated and stored internally.
   // These FEC packets are then obtained by calling GetFecPacketsAsRed().
-  int AddRtpPacketAndGenerateFec(const rtc::CopyOnWriteBuffer& data_buffer,
+  int AddRtpPacketAndGenerateFec(const uint8_t* data_buffer,
+                                 size_t payload_length,
                                  size_t rtp_header_length);
 
   // Returns true if there are generated FEC packets available.
diff --git a/modules/rtp_rtcp/source/ulpfec_generator_unittest.cc b/modules/rtp_rtcp/source/ulpfec_generator_unittest.cc
index 8c1c7ea..6880f79 100644
--- a/modules/rtp_rtcp/source/ulpfec_generator_unittest.cc
+++ b/modules/rtp_rtcp/source/ulpfec_generator_unittest.cc
@@ -90,9 +90,8 @@
       packet[1] &= ~0x80;
     }
     ByteWriter<uint16_t>::WriteBigEndian(&packet[2], p.seq_num);
-    ulpfec_generator_.AddRtpPacketAndGenerateFec(
-        rtc::CopyOnWriteBuffer(packet, p.payload_size + p.header_size),
-        p.header_size);
+    ulpfec_generator_.AddRtpPacketAndGenerateFec(packet, p.payload_size,
+                                                 p.header_size);
     size_t num_fec_packets = ulpfec_generator_.NumAvailableFecPackets();
     if (num_fec_packets > 0) {
       std::vector<std::unique_ptr<RedPacket>> fec_packets =
@@ -118,8 +117,8 @@
   for (size_t i = 0; i < kNumPackets; ++i) {
     std::unique_ptr<AugmentedPacket> packet =
         packet_generator_.NextPacket(i, 10);
-    EXPECT_EQ(0, ulpfec_generator_.AddRtpPacketAndGenerateFec(packet->data,
-                                                              kRtpHeaderSize));
+    EXPECT_EQ(0, ulpfec_generator_.AddRtpPacketAndGenerateFec(
+                     packet->data, packet->length, kRtpHeaderSize));
     last_timestamp = packet->header.timestamp;
   }
   EXPECT_TRUE(ulpfec_generator_.FecAvailable());
@@ -153,7 +152,7 @@
       std::unique_ptr<AugmentedPacket> packet =
           packet_generator_.NextPacket(i * kNumPackets + j, 10);
       EXPECT_EQ(0, ulpfec_generator_.AddRtpPacketAndGenerateFec(
-                       packet->data, kRtpHeaderSize));
+                       packet->data, packet->length, kRtpHeaderSize));
       last_timestamp = packet->header.timestamp;
     }
   }
@@ -182,7 +181,7 @@
     std::unique_ptr<AugmentedPacket> packet =
         packet_generator_.NextPacket(i, 10);
     EXPECT_EQ(0, ulpfec_generator_.AddRtpPacketAndGenerateFec(
-                     packet->data, kShortRtpHeaderLength));
+                     packet->data, packet->length, kShortRtpHeaderLength));
     EXPECT_FALSE(ulpfec_generator_.FecAvailable());
   }
 
@@ -191,7 +190,7 @@
   std::unique_ptr<AugmentedPacket> packet =
       packet_generator_.NextPacket(kUlpfecMaxMediaPackets, 10);
   EXPECT_EQ(0, ulpfec_generator_.AddRtpPacketAndGenerateFec(
-                   packet->data, kLongRtpHeaderLength));
+                   packet->data, packet->length, kLongRtpHeaderLength));
   EXPECT_TRUE(ulpfec_generator_.FecAvailable());
 
   // Ensure that the RED header is placed correctly, i.e. the correct
diff --git a/modules/rtp_rtcp/source/ulpfec_header_reader_writer_unittest.cc b/modules/rtp_rtcp/source/ulpfec_header_reader_writer_unittest.cc
index fb593b3..725f9a5 100644
--- a/modules/rtp_rtcp/source/ulpfec_header_reader_writer_unittest.cc
+++ b/modules/rtp_rtcp/source/ulpfec_header_reader_writer_unittest.cc
@@ -53,7 +53,6 @@
   UlpfecHeaderWriter writer;
   std::unique_ptr<Packet> written_packet(new Packet());
   written_packet->length = kMediaPacketLength;
-  written_packet->data.SetSize(written_packet->length);
   for (size_t i = 0; i < written_packet->length; ++i) {
     written_packet->data[i] = i;  // Actual content doesn't matter.
   }
@@ -67,7 +66,7 @@
   std::unique_ptr<ReceivedFecPacket> read_packet(new ReceivedFecPacket());
   read_packet->ssrc = kMediaSsrc;
   read_packet->pkt = rtc::scoped_refptr<Packet>(new Packet());
-  read_packet->pkt->data = written_packet.data;
+  memcpy(read_packet->pkt->data, written_packet.data, written_packet.length);
   read_packet->pkt->length = written_packet.length;
   EXPECT_TRUE(reader.ReadFecHeader(read_packet.get()));
   return read_packet;
@@ -90,8 +89,8 @@
                       &read_packet.pkt->data[read_packet.packet_mask_offset],
                       read_packet.packet_mask_size));
   // Verify that the call to ReadFecHeader did not tamper with the payload.
-  EXPECT_EQ(0, memcmp(written_packet.data.data() + expected_fec_header_size,
-                      read_packet.pkt->data.cdata() + expected_fec_header_size,
+  EXPECT_EQ(0, memcmp(&written_packet.data[expected_fec_header_size],
+                      &read_packet.pkt->data[expected_fec_header_size],
                       written_packet.length - expected_fec_header_size));
 }
 
@@ -108,7 +107,7 @@
   const size_t packet_length = sizeof(packet);
   ReceivedFecPacket read_packet;
   read_packet.pkt = rtc::scoped_refptr<Packet>(new Packet());
-  read_packet.pkt->data.SetData(packet, packet_length);
+  memcpy(read_packet.pkt->data, packet, packet_length);
   read_packet.pkt->length = packet_length;
 
   UlpfecHeaderReader reader;
@@ -133,7 +132,7 @@
   const size_t packet_length = sizeof(packet);
   ReceivedFecPacket read_packet;
   read_packet.pkt = rtc::scoped_refptr<Packet>(new Packet());
-  read_packet.pkt->data.SetData(packet, packet_length);
+  memcpy(read_packet.pkt->data, packet, packet_length);
   read_packet.pkt->length = packet_length;
 
   UlpfecHeaderReader reader;
@@ -151,7 +150,6 @@
   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
   Packet written_packet;
   written_packet.length = kMediaPacketLength;
-  written_packet.data.SetSize(written_packet.length);
   for (size_t i = 0; i < written_packet.length; ++i) {
     written_packet.data[i] = i;
   }
@@ -160,7 +158,7 @@
   writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, packet_mask.get(),
                            packet_mask_size, &written_packet);
 
-  const uint8_t* packet = written_packet.data.cdata();
+  const uint8_t* packet = written_packet.data;
   EXPECT_EQ(0x00, packet[0] & 0x80);  // E bit.
   EXPECT_EQ(0x00, packet[0] & 0x40);  // L bit.
   EXPECT_EQ(kMediaStartSeqNum, ByteReader<uint16_t>::ReadBigEndian(packet + 2));
@@ -176,7 +174,6 @@
   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
   Packet written_packet;
   written_packet.length = kMediaPacketLength;
-  written_packet.data.SetSize(written_packet.length);
   for (size_t i = 0; i < written_packet.length; ++i) {
     written_packet.data[i] = i;
   }
@@ -185,7 +182,7 @@
   writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, packet_mask.get(),
                            packet_mask_size, &written_packet);
 
-  const uint8_t* packet = written_packet.data.cdata();
+  const uint8_t* packet = written_packet.data;
   EXPECT_EQ(0x00, packet[0] & 0x80);  // E bit.
   EXPECT_EQ(0x40, packet[0] & 0x40);  // L bit.
   EXPECT_EQ(kMediaStartSeqNum, ByteReader<uint16_t>::ReadBigEndian(packet + 2));
diff --git a/modules/rtp_rtcp/source/ulpfec_receiver_impl.cc b/modules/rtp_rtcp/source/ulpfec_receiver_impl.cc
index b950cbd..a5d6368 100644
--- a/modules/rtp_rtcp/source/ulpfec_receiver_impl.cc
+++ b/modules/rtp_rtcp/source/ulpfec_receiver_impl.cc
@@ -130,28 +130,26 @@
     ++packet_counter_.num_fec_packets;
 
     // everything behind the RED header
-    received_packet->pkt->data.SetData(
-        incoming_rtp_packet + header.headerLength + red_header_length,
-        payload_data_length - red_header_length);
+    memcpy(received_packet->pkt->data,
+           incoming_rtp_packet + header.headerLength + red_header_length,
+           payload_data_length - red_header_length);
     received_packet->pkt->length = payload_data_length - red_header_length;
     received_packet->ssrc =
         ByteReader<uint32_t>::ReadBigEndian(&incoming_rtp_packet[8]);
 
   } else {
-    received_packet->pkt->data.SetSize(header.headerLength +
-                                       payload_data_length - red_header_length);
     // Copy RTP header.
-    memcpy(received_packet->pkt->data.data(), incoming_rtp_packet,
+    memcpy(received_packet->pkt->data, incoming_rtp_packet,
            header.headerLength);
+
     // Set payload type.
     received_packet->pkt->data[1] &= 0x80;          // Reset RED payload type.
     received_packet->pkt->data[1] += payload_type;  // Set media payload type.
+
     // Copy payload data.
-    if (payload_data_length > red_header_length) {
-      memcpy(received_packet->pkt->data.data() + header.headerLength,
-             incoming_rtp_packet + header.headerLength + red_header_length,
-             payload_data_length - red_header_length);
-    }
+    memcpy(received_packet->pkt->data + header.headerLength,
+           incoming_rtp_packet + header.headerLength + red_header_length,
+           payload_data_length - red_header_length);
     received_packet->pkt->length =
         header.headerLength + payload_data_length - red_header_length;
   }
@@ -184,18 +182,16 @@
     if (!received_packet->is_fec) {
       ForwardErrorCorrection::Packet* packet = received_packet->pkt;
       crit_sect_.Leave();
-      recovered_packet_callback_->OnRecoveredPacket(packet->data.data(),
+      recovered_packet_callback_->OnRecoveredPacket(packet->data,
                                                     packet->length);
       crit_sect_.Enter();
-      // Create a packet with the buffer to modify it.
       RtpPacketReceived rtp_packet;
-      rtp_packet.Parse(packet->data);
+      // TODO(ilnik): move extension nullifying out of RtpPacket, so there's no
+      // need to create one here, and avoid two memcpy calls below.
+      rtp_packet.Parse(packet->data, packet->length);  // Does memcopy.
       rtp_packet.IdentifyExtensions(extensions_);
-      // Reset buffer reference, so zeroing would work on a buffer with a
-      // single reference.
-      packet->data = rtc::CopyOnWriteBuffer(0);
-      rtp_packet.ZeroMutableExtensions();
-      packet->data = rtp_packet.Buffer();
+      rtp_packet.CopyAndZeroMutableExtensions(  // Does memcopy.
+          rtc::MakeArrayView(packet->data, packet->length));
     }
     fec_->DecodeFec(*received_packet, &recovered_packets_);
   }
@@ -212,8 +208,7 @@
     // header, OnRecoveredPacket will recurse back here.
     recovered_packet->returned = true;
     crit_sect_.Leave();
-    recovered_packet_callback_->OnRecoveredPacket(packet->data.data(),
-                                                  packet->length);
+    recovered_packet_callback_->OnRecoveredPacket(packet->data, packet->length);
     crit_sect_.Enter();
   }
 
diff --git a/modules/rtp_rtcp/source/ulpfec_receiver_unittest.cc b/modules/rtp_rtcp/source/ulpfec_receiver_unittest.cc
index bbe616f..cd1798b 100644
--- a/modules/rtp_rtcp/source/ulpfec_receiver_unittest.cc
+++ b/modules/rtp_rtcp/source/ulpfec_receiver_unittest.cc
@@ -126,16 +126,16 @@
   std::unique_ptr<AugmentedPacket> red_packet(
       packet_generator_.BuildMediaRedPacket(*packet));
   EXPECT_EQ(0, receiver_fec_->AddReceivedRedPacket(
-                   red_packet->header, red_packet->data.cdata(),
-                   red_packet->length, kFecPayloadType));
+                   red_packet->header, red_packet->data, red_packet->length,
+                   kFecPayloadType));
 }
 
 void UlpfecReceiverTest::BuildAndAddRedFecPacket(Packet* packet) {
   std::unique_ptr<AugmentedPacket> red_packet(
       packet_generator_.BuildUlpfecRedPacket(*packet));
   EXPECT_EQ(0, receiver_fec_->AddReceivedRedPacket(
-                   red_packet->header, red_packet->data.cdata(),
-                   red_packet->length, kFecPayloadType));
+                   red_packet->header, red_packet->data, red_packet->length,
+                   kFecPayloadType));
 }
 
 void UlpfecReceiverTest::VerifyReconstructedMediaPacket(
@@ -145,7 +145,7 @@
   // content of |packet|, and that the same content is received |times| number
   // of times in a row.
   EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_, packet.length))
-      .With(Args<0, 1>(ElementsAreArray(packet.data.cdata(), packet.length)))
+      .With(Args<0, 1>(ElementsAreArray(packet.data, packet.length)))
       .Times(times);
 }
 
diff --git a/modules/rtp_rtcp/test/testFec/test_fec.cc b/modules/rtp_rtcp/test/testFec/test_fec.cc
index 434d3ac..3a893b3 100644
--- a/modules/rtp_rtcp/test/testFec/test_fec.cc
+++ b/modules/rtp_rtcp/test/testFec/test_fec.cc
@@ -70,7 +70,8 @@
           new ForwardErrorCorrection::ReceivedPacket());
       *duplicate_packet = *received_packet;
       duplicate_packet->pkt = new ForwardErrorCorrection::Packet();
-      duplicate_packet->pkt->data = received_packet->pkt->data;
+      memcpy(duplicate_packet->pkt->data, received_packet->pkt->data,
+             received_packet->pkt->length);
       duplicate_packet->pkt->length = received_packet->pkt->length;
 
       to_decode_list->push_back(std::move(duplicate_packet));
@@ -253,7 +254,6 @@
                   IP_PACKET_SIZE - 12 - 28 - fec->MaxPacketOverhead());
               media_packet->length =
                   random.Rand(kMinPacketSize, kMaxPacketSize);
-              media_packet->data.SetSize(media_packet->length);
 
               // Generate random values for the first 2 bytes.
               media_packet->data[0] = random.Rand<uint8_t>();
@@ -312,7 +312,8 @@
                         new ForwardErrorCorrection::ReceivedPacket());
                 received_packet->pkt = new ForwardErrorCorrection::Packet();
                 received_packet->pkt->length = media_packet->length;
-                received_packet->pkt->data = media_packet->data;
+                memcpy(received_packet->pkt->data, media_packet->data,
+                       media_packet->length);
                 received_packet->ssrc = media_ssrc;
                 received_packet->seq_num =
                     ByteReader<uint16_t>::ReadBigEndian(&media_packet->data[2]);
@@ -333,7 +334,8 @@
                         new ForwardErrorCorrection::ReceivedPacket());
                 received_packet->pkt = new ForwardErrorCorrection::Packet();
                 received_packet->pkt->length = fec_packet->length;
-                received_packet->pkt->data = fec_packet->data;
+                memcpy(received_packet->pkt->data, fec_packet->data,
+                       fec_packet->length);
                 received_packet->seq_num = fec_seq_num_offset + seq_num;
                 received_packet->is_fec = true;
                 received_packet->ssrc = fec_ssrc;
@@ -424,9 +426,8 @@
                 ASSERT_EQ(recovered_packet->pkt->length, media_packet->length)
                     << "Recovered packet length not identical to original "
                     << "media packet";
-                ASSERT_EQ(
-                    0, memcmp(recovered_packet->pkt->data.cdata(),
-                              media_packet->data.cdata(), media_packet->length))
+                ASSERT_EQ(0, memcmp(recovered_packet->pkt->data,
+                                    media_packet->data, media_packet->length))
                     << "Recovered packet payload not identical to original "
                     << "media packet";
                 recovered_packet_list.pop_front();
diff --git a/test/fuzzers/flexfec_header_reader_fuzzer.cc b/test/fuzzers/flexfec_header_reader_fuzzer.cc
index 2f4c498..c887d2e 100644
--- a/test/fuzzers/flexfec_header_reader_fuzzer.cc
+++ b/test/fuzzers/flexfec_header_reader_fuzzer.cc
@@ -25,8 +25,7 @@
   packet.pkt = rtc::scoped_refptr<Packet>(new Packet());
   const size_t packet_size =
       std::min(size, static_cast<size_t>(IP_PACKET_SIZE));
-  packet.pkt->data.SetSize(packet_size);
-  memcpy(packet.pkt->data.data(), data, packet_size);
+  memcpy(packet.pkt->data, data, packet_size);
   packet.pkt->length = packet_size;
 
   FlexfecHeaderReader flexfec_reader;
diff --git a/test/fuzzers/forward_error_correction_fuzzer.cc b/test/fuzzers/forward_error_correction_fuzzer.cc
index 3e674cd..1c37889 100644
--- a/test/fuzzers/forward_error_correction_fuzzer.cc
+++ b/test/fuzzers/forward_error_correction_fuzzer.cc
@@ -67,7 +67,7 @@
   received_packet.pkt = rtc::scoped_refptr<ForwardErrorCorrection::Packet>(
       new ForwardErrorCorrection::Packet());
   received_packet.pkt->length = kPacketSize;
-  uint8_t* packet_buffer = received_packet.pkt->data.data();
+  uint8_t* packet_buffer = received_packet.pkt->data;
   uint8_t reordering;
   uint16_t seq_num_diff;
   uint8_t packet_type;
diff --git a/test/fuzzers/ulpfec_generator_fuzzer.cc b/test/fuzzers/ulpfec_generator_fuzzer.cc
index be24895..ce9d8fd 100644
--- a/test/fuzzers/ulpfec_generator_fuzzer.cc
+++ b/test/fuzzers/ulpfec_generator_fuzzer.cc
@@ -15,7 +15,6 @@
 #include "modules/rtp_rtcp/source/fec_test_helper.h"
 #include "modules/rtp_rtcp/source/ulpfec_generator.h"
 #include "rtc_base/checks.h"
-#include "rtc_base/copy_on_write_buffer.h"
 
 namespace webrtc {
 
@@ -39,7 +38,9 @@
     size_t payload_size = data[i++] % 10;
     if (i + payload_size + rtp_header_length + 2 > size)
       break;
-    rtc::CopyOnWriteBuffer packet(&data[i], payload_size + rtp_header_length);
+    std::unique_ptr<uint8_t[]> packet(
+        new uint8_t[payload_size + rtp_header_length]);
+    memcpy(packet.get(), &data[i], payload_size + rtp_header_length);
 
     // Make sure sequence numbers are increasing.
     ByteWriter<uint16_t>::WriteBigEndian(&packet[2], seq_num++);
@@ -51,7 +52,8 @@
     // number became out of order.
     if (protect && IsNewerSequenceNumber(seq_num, prev_seq_num) &&
         seq_num < prev_seq_num + kUlpfecMaxMediaPackets) {
-      generator.AddRtpPacketAndGenerateFec(packet, rtp_header_length);
+      generator.AddRtpPacketAndGenerateFec(packet.get(), payload_size,
+                                           rtp_header_length);
       prev_seq_num = seq_num;
     }
     const size_t num_fec_packets = generator.NumAvailableFecPackets();
diff --git a/test/fuzzers/ulpfec_header_reader_fuzzer.cc b/test/fuzzers/ulpfec_header_reader_fuzzer.cc
index cf211f1..46fe67b 100644
--- a/test/fuzzers/ulpfec_header_reader_fuzzer.cc
+++ b/test/fuzzers/ulpfec_header_reader_fuzzer.cc
@@ -25,8 +25,7 @@
   packet.pkt = rtc::scoped_refptr<Packet>(new Packet());
   const size_t packet_size =
       std::min(size, static_cast<size_t>(IP_PACKET_SIZE));
-  packet.pkt->data.SetSize(packet_size);
-  memcpy(packet.pkt->data.data(), data, packet_size);
+  memcpy(packet.pkt->data, data, packet_size);
   packet.pkt->length = packet_size;
 
   UlpfecHeaderReader ulpfec_reader;