Pass and store PacketBuffer::Packet by unique_ptr

to avoid expensive move of the Packet and prepare PacketBuffer
to return list of packets as a frame.

Bug: None
Change-Id: I19f0452c52238228bbe28284ebb197491eb2bf4e
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/167063
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30404}
diff --git a/modules/video_coding/packet_buffer.cc b/modules/video_coding/packet_buffer.cc
index 675002c..6ebb9c4 100644
--- a/modules/video_coding/packet_buffer.cc
+++ b/modules/video_coding/packet_buffer.cc
@@ -79,7 +79,7 @@
 }
 
 PacketBuffer::InsertResult PacketBuffer::InsertPacket(
-    PacketBuffer::Packet* packet) {
+    std::unique_ptr<PacketBuffer::Packet> packet) {
   PacketBuffer::InsertResult result;
   rtc::CritScope lock(&crit_);
 
@@ -99,19 +99,19 @@
     first_seq_num_ = seq_num;
   }
 
-  if (buffer_[index].used) {
+  if (buffer_[index].used()) {
     // Duplicate packet, just delete the payload.
     if (buffer_[index].seq_num() == packet->seq_num) {
       return result;
     }
 
     // The packet buffer is full, try to expand the buffer.
-    while (ExpandBufferSize() && buffer_[seq_num % buffer_.size()].used) {
+    while (ExpandBufferSize() && buffer_[seq_num % buffer_.size()].used()) {
     }
     index = seq_num % buffer_.size();
 
     // Packet buffer is still full since we were unable to expand the buffer.
-    if (buffer_[index].used) {
+    if (buffer_[index].used()) {
       // Clear the buffer, delete payload, and return false to signal that a
       // new keyframe is needed.
       RTC_LOG(LS_WARNING) << "Clear PacketBuffer and request key frame.";
@@ -131,8 +131,7 @@
 
   StoredPacket& new_entry = buffer_[index];
   new_entry.continuous = false;
-  new_entry.used = true;
-  new_entry.data = std::move(*packet);
+  new_entry.packet = std::move(packet);
 
   UpdateMissingPackets(seq_num);
 
@@ -158,10 +157,9 @@
   size_t diff = ForwardDiff<uint16_t>(first_seq_num_, seq_num);
   size_t iterations = std::min(diff, buffer_.size());
   for (size_t i = 0; i < iterations; ++i) {
-    size_t index = first_seq_num_ % buffer_.size();
-    if (AheadOf<uint16_t>(seq_num, buffer_[index].seq_num())) {
-      buffer_[index].data.video_payload = {};
-      buffer_[index].used = false;
+    StoredPacket& stored = buffer_[first_seq_num_ % buffer_.size()];
+    if (stored.used() && AheadOf<uint16_t>(seq_num, stored.seq_num())) {
+      stored.packet = nullptr;
     }
     ++first_seq_num_;
   }
@@ -186,8 +184,7 @@
   for (size_t i = 0; i < iterations; ++i) {
     size_t index = seq_num % buffer_.size();
     RTC_DCHECK_EQ(buffer_[index].seq_num(), seq_num);
-    buffer_[index].data.video_payload = {};
-    buffer_[index].used = false;
+    buffer_[index].packet = nullptr;
 
     ++seq_num;
   }
@@ -196,8 +193,7 @@
 void PacketBuffer::Clear() {
   rtc::CritScope lock(&crit_);
   for (StoredPacket& entry : buffer_) {
-    entry.data.video_payload = {};
-    entry.used = false;
+    entry.packet = nullptr;
   }
 
   first_packet_received_ = false;
@@ -236,7 +232,7 @@
   size_t new_size = std::min(max_size_, 2 * buffer_.size());
   std::vector<StoredPacket> new_buffer(new_size);
   for (StoredPacket& entry : buffer_) {
-    if (entry.used) {
+    if (entry.used()) {
       new_buffer[entry.seq_num() % new_size] = std::move(entry);
     }
   }
@@ -251,17 +247,17 @@
   const StoredPacket& entry = buffer_[index];
   const StoredPacket& prev_entry = buffer_[prev_index];
 
-  if (!entry.used)
+  if (!entry.used())
     return false;
   if (entry.seq_num() != seq_num)
     return false;
   if (entry.frame_begin())
     return true;
-  if (!prev_entry.used)
+  if (!prev_entry.used())
     return false;
   if (prev_entry.seq_num() != static_cast<uint16_t>(entry.seq_num() - 1))
     return false;
-  if (prev_entry.data.timestamp != entry.data.timestamp)
+  if (prev_entry.packet->timestamp != entry.packet->timestamp)
     return false;
   if (prev_entry.continuous)
     return true;
@@ -285,10 +281,10 @@
       // the |frame_begin| flag is set.
       int start_index = index;
       size_t tested_packets = 0;
-      int64_t frame_timestamp = buffer_[start_index].data.timestamp;
+      int64_t frame_timestamp = buffer_[start_index].packet->timestamp;
 
       // Identify H.264 keyframes by means of SPS, PPS, and IDR.
-      bool is_h264 = buffer_[start_index].data.codec() == kVideoCodecH264;
+      bool is_h264 = buffer_[start_index].packet->codec() == kVideoCodecH264;
       bool has_h264_sps = false;
       bool has_h264_pps = false;
       bool has_h264_idr = false;
@@ -303,7 +299,7 @@
 
         if (is_h264) {
           const auto* h264_header = absl::get_if<RTPVideoHeaderH264>(
-              &buffer_[start_index].data.video_header.video_type_header);
+              &buffer_[start_index].packet->video_header.video_type_header);
           if (!h264_header || h264_header->nalus_length >= kMaxNalusPerPacket)
             return found_frames;
 
@@ -324,10 +320,10 @@
             // smallest index and valid resolution; typically its IDR or SPS
             // packet; there may be packet preceeding this packet, IDR's
             // resolution will be applied to them.
-            if (buffer_[start_index].data.width() > 0 &&
-                buffer_[start_index].data.height() > 0) {
-              idr_width = buffer_[start_index].data.width();
-              idr_height = buffer_[start_index].data.height();
+            if (buffer_[start_index].packet->width() > 0 &&
+                buffer_[start_index].packet->height() > 0) {
+              idr_width = buffer_[start_index].packet->width();
+              idr_height = buffer_[start_index].packet->height();
             }
           }
         }
@@ -344,8 +340,8 @@
         // the PacketBuffer to hand out incomplete frames.
         // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=7106
         if (is_h264 &&
-            (!buffer_[start_index].used ||
-             buffer_[start_index].data.timestamp != frame_timestamp)) {
+            (!buffer_[start_index].used() ||
+             buffer_[start_index].packet->timestamp != frame_timestamp)) {
           break;
         }
 
@@ -369,23 +365,27 @@
         // determines if the RtpFrameObject is a key frame or delta frame.
         const size_t first_packet_index = start_seq_num % buffer_.size();
         if (is_h264_keyframe) {
-          buffer_[first_packet_index].data.video_header.frame_type =
+          buffer_[first_packet_index].packet->video_header.frame_type =
               VideoFrameType::kVideoFrameKey;
           if (idr_width > 0 && idr_height > 0) {
             // IDR frame was finalized and we have the correct resolution for
             // IDR; update first packet to have same resolution as IDR.
-            buffer_[first_packet_index].data.video_header.width = idr_width;
-            buffer_[first_packet_index].data.video_header.height = idr_height;
+            buffer_[first_packet_index].packet->video_header.width = idr_width;
+            buffer_[first_packet_index].packet->video_header.height =
+                idr_height;
           }
         } else {
-          buffer_[first_packet_index].data.video_header.frame_type =
+          buffer_[first_packet_index].packet->video_header.frame_type =
               VideoFrameType::kVideoFrameDelta;
         }
 
         // With IPPP, if this is not a keyframe, make sure there are no gaps
         // in the packet sequence numbers up until this point.
         const uint8_t h264tid =
-            buffer_[start_index].data.video_header.frame_marking.temporal_id;
+            buffer_[start_index].used()
+                ? buffer_[start_index]
+                      .packet->video_header.frame_marking.temporal_id
+                : kNoTemporalIdx;
         if (h264tid == kNoTemporalIdx && !is_h264_keyframe &&
             missing_packets_.upper_bound(start_seq_num) !=
                 missing_packets_.begin()) {
@@ -480,9 +480,9 @@
 
 const PacketBuffer::Packet& PacketBuffer::GetPacket(uint16_t seq_num) const {
   const StoredPacket& entry = buffer_[seq_num % buffer_.size()];
-  RTC_DCHECK(entry.used);
+  RTC_DCHECK(entry.used());
   RTC_DCHECK_EQ(seq_num, entry.seq_num());
-  return entry.data;
+  return *entry.packet;
 }
 
 void PacketBuffer::UpdateMissingPackets(uint16_t seq_num) {