Cleanup RtpPacketizerGeneric

merge SetPayloadData into constructor.
Reuse payload size split function

Bug: webrtc:9680
Change-Id: If8de22b2fc39c0bdf6d60154ecaaf19e2dccdcc9
Reviewed-on: https://webrtc-review.googlesource.com/97640
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24598}
diff --git a/modules/rtp_rtcp/source/rtp_format.cc b/modules/rtp_rtcp/source/rtp_format.cc
index 030236c..8a6e8f1 100644
--- a/modules/rtp_rtcp/source/rtp_format.cc
+++ b/modules/rtp_rtcp/source/rtp_format.cc
@@ -53,11 +53,8 @@
       return std::move(packetizer);
     }
     default: {
-      auto packetizer = absl::make_unique<RtpPacketizerGeneric>(
-          rtp_video_header, frame_type, limits.max_payload_len,
-          limits.last_packet_reduction_len);
-      packetizer->SetPayloadData(payload.data(), payload.size(), nullptr);
-      return std::move(packetizer);
+      return absl::make_unique<RtpPacketizerGeneric>(
+          payload, limits, rtp_video_header, frame_type);
     }
   }
 }
diff --git a/modules/rtp_rtcp/source/rtp_format_video_generic.cc b/modules/rtp_rtcp/source/rtp_format_video_generic.cc
index 1731237..edd1e3c 100644
--- a/modules/rtp_rtcp/source/rtp_format_video_generic.cc
+++ b/modules/rtp_rtcp/source/rtp_format_video_generic.cc
@@ -21,121 +21,70 @@
 static const size_t kExtendedHeaderLength = 2;
 
 RtpPacketizerGeneric::RtpPacketizerGeneric(
+    rtc::ArrayView<const uint8_t> payload,
+    PayloadSizeLimits limits,
     const RTPVideoHeader& rtp_video_header,
-    FrameType frame_type,
-    size_t max_payload_len,
-    size_t last_packet_reduction_len)
-    : picture_id_(rtp_video_header.generic
-                      ? absl::optional<uint16_t>(
-                            rtp_video_header.generic->frame_id & 0x7FFF)
-                      : absl::nullopt),
-      payload_data_(nullptr),
-      payload_size_(0),
-      max_payload_len_(max_payload_len - kGenericHeaderLength -
-                       (picture_id_.has_value() ? kExtendedHeaderLength : 0)),
-      last_packet_reduction_len_(last_packet_reduction_len),
-      frame_type_(frame_type),
-      num_packets_left_(0),
-      num_larger_packets_(0) {}
+    FrameType frame_type)
+    : remaining_payload_(payload) {
+  BuildHeader(rtp_video_header, frame_type);
 
-RtpPacketizerGeneric::~RtpPacketizerGeneric() {}
-
-size_t RtpPacketizerGeneric::SetPayloadData(
-    const uint8_t* payload_data,
-    size_t payload_size,
-    const RTPFragmentationHeader* fragmentation) {
-  payload_data_ = payload_data;
-  payload_size_ = payload_size;
-
-  // Fragment packets such that they are almost the same size, even accounting
-  // for larger header in the last packet.
-  // Since we are given how much extra space is occupied by the longer header
-  // in the last packet, we can pretend that RTP headers are the same, but
-  // there's last_packet_reduction_len_ virtual payload, to be put at the end of
-  // the last packet.
-  //
-  size_t total_bytes = payload_size_ + last_packet_reduction_len_;
-
-  // Minimum needed number of packets to fit payload and virtual payload in the
-  // last packet.
-  num_packets_left_ = (total_bytes + max_payload_len_ - 1) / max_payload_len_;
-  // Given number of packets, calculate average size rounded down.
-  payload_len_per_packet_ = total_bytes / num_packets_left_;
-  // If we can't divide everything perfectly evenly, we put 1 extra byte in some
-  // last packets: 14 bytes in 4 packets would be split as 3+3+4+4.
-  num_larger_packets_ = total_bytes % num_packets_left_;
-  RTC_DCHECK_LE(payload_len_per_packet_, max_payload_len_);
-
-  generic_header_ = RtpFormatVideoGeneric::kFirstPacketBit;
-  if (frame_type_ == kVideoFrameKey) {
-    generic_header_ |= RtpFormatVideoGeneric::kKeyFrameBit;
-  }
-  if (picture_id_.has_value()) {
-    generic_header_ |= RtpFormatVideoGeneric::kExtendedHeaderBit;
-  }
-
-  return num_packets_left_;
+  limits.max_payload_len -= header_size_;
+  payload_sizes_ = SplitAboutEqually(payload.size(), limits);
+  current_packet_ = payload_sizes_.begin();
 }
 
+RtpPacketizerGeneric::~RtpPacketizerGeneric() = default;
+
 size_t RtpPacketizerGeneric::NumPackets() const {
-  return num_packets_left_;
+  return payload_sizes_.end() - current_packet_;
 }
 
 bool RtpPacketizerGeneric::NextPacket(RtpPacketToSend* packet) {
   RTC_DCHECK(packet);
-  if (num_packets_left_ == 0)
+  if (current_packet_ == payload_sizes_.end())
     return false;
-  // Last larger_packets_ packets are 1 byte larger than previous packets.
-  // Increase per packet payload once needed.
-  if (num_packets_left_ == num_larger_packets_)
-    ++payload_len_per_packet_;
-  size_t next_packet_payload_len = payload_len_per_packet_;
-  if (payload_size_ <= next_packet_payload_len) {
-    // Whole payload fits into this packet.
-    next_packet_payload_len = payload_size_;
-    if (num_packets_left_ == 2) {
-      // This is the penultimate packet. Leave at least 1 payload byte for the
-      // last packet.
-      --next_packet_payload_len;
-      RTC_DCHECK_GT(next_packet_payload_len, 0);
-    }
-  }
-  RTC_DCHECK_LE(next_packet_payload_len, max_payload_len_);
 
-  size_t total_length = next_packet_payload_len + kGenericHeaderLength +
-                        (picture_id_.has_value() ? kExtendedHeaderLength : 0);
-  uint8_t* out_ptr = packet->AllocatePayload(total_length);
+  size_t next_packet_payload_len = *current_packet_;
 
-  // Put generic header in packet.
-  out_ptr[0] = generic_header_;
-  out_ptr += kGenericHeaderLength;
+  uint8_t* out_ptr =
+      packet->AllocatePayload(header_size_ + next_packet_payload_len);
+  RTC_CHECK(out_ptr);
 
-  if (picture_id_.has_value()) {
-    WriteExtendedHeader(out_ptr);
-    out_ptr += kExtendedHeaderLength;
-  }
+  memcpy(out_ptr, header_, header_size_);
+  memcpy(out_ptr + header_size_, remaining_payload_.data(),
+         next_packet_payload_len);
 
   // Remove first-packet bit, following packets are intermediate.
-  generic_header_ &= ~RtpFormatVideoGeneric::kFirstPacketBit;
+  header_[0] &= ~RtpFormatVideoGeneric::kFirstPacketBit;
 
-  // Put payload in packet.
-  memcpy(out_ptr, payload_data_, next_packet_payload_len);
-  payload_data_ += next_packet_payload_len;
-  payload_size_ -= next_packet_payload_len;
-  --num_packets_left_;
+  remaining_payload_ = remaining_payload_.subview(next_packet_payload_len);
+
+  ++current_packet_;
+
   // Packets left to produce and data left to split should end at the same time.
-  RTC_DCHECK_EQ(num_packets_left_ == 0, payload_size_ == 0);
+  RTC_DCHECK_EQ(current_packet_ == payload_sizes_.end(),
+                remaining_payload_.empty());
 
-  packet->SetMarker(payload_size_ == 0);
-
+  packet->SetMarker(remaining_payload_.empty());
   return true;
 }
 
-void RtpPacketizerGeneric::WriteExtendedHeader(uint8_t* out_ptr) {
-  // Store bottom 15 bits of the the sequence number. Only 15 bits are used for
-  // compatibility with other packetizer implemenetations that also use 15 bits.
-  out_ptr[0] = (*picture_id_ >> 8) & 0x7F;
-  out_ptr[1] = *picture_id_ & 0xFF;
+void RtpPacketizerGeneric::BuildHeader(const RTPVideoHeader& rtp_video_header,
+                                       FrameType frame_type) {
+  header_size_ = kGenericHeaderLength;
+  header_[0] = RtpFormatVideoGeneric::kFirstPacketBit;
+  if (frame_type == kVideoFrameKey) {
+    header_[0] |= RtpFormatVideoGeneric::kKeyFrameBit;
+  }
+  if (rtp_video_header.generic.has_value()) {
+    // Store bottom 15 bits of the the picture id. Only 15 bits are used for
+    // compatibility with other packetizer implemenetations.
+    uint16_t picture_id = rtp_video_header.generic->frame_id & 0x7FFF;
+    header_[0] |= RtpFormatVideoGeneric::kExtendedHeaderBit;
+    header_[1] = (picture_id >> 8) & 0x7F;
+    header_[2] = picture_id & 0xFF;
+    header_size_ += kExtendedHeaderLength;
+  }
 }
 
 RtpDepacketizerGeneric::~RtpDepacketizerGeneric() = default;
diff --git a/modules/rtp_rtcp/source/rtp_format_video_generic.h b/modules/rtp_rtcp/source/rtp_format_video_generic.h
index 293b6e9..7d14886 100644
--- a/modules/rtp_rtcp/source/rtp_format_video_generic.h
+++ b/modules/rtp_rtcp/source/rtp_format_video_generic.h
@@ -10,8 +10,9 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VIDEO_GENERIC_H_
 #define MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VIDEO_GENERIC_H_
 
-#include <string>
+#include <vector>
 
+#include "api/array_view.h"
 #include "common_types.h"  // NOLINT(build/include)
 #include "modules/rtp_rtcp/source/rtp_format.h"
 #include "rtc_base/constructormagic.h"
@@ -29,18 +30,13 @@
  public:
   // Initialize with payload from encoder.
   // The payload_data must be exactly one encoded generic frame.
-  RtpPacketizerGeneric(const RTPVideoHeader& rtp_video_header,
-                       FrameType frametype,
-                       size_t max_payload_len,
-                       size_t last_packet_reduction_len);
+  RtpPacketizerGeneric(rtc::ArrayView<const uint8_t> payload,
+                       PayloadSizeLimits limits,
+                       const RTPVideoHeader& rtp_video_header,
+                       FrameType frametype);
 
   ~RtpPacketizerGeneric() override;
 
-  // Returns total number of packets to be generated.
-  size_t SetPayloadData(const uint8_t* payload_data,
-                        size_t payload_size,
-                        const RTPFragmentationHeader* fragmentation);
-
   size_t NumPackets() const override;
 
   // Get the next payload with generic payload header.
@@ -49,20 +45,15 @@
   bool NextPacket(RtpPacketToSend* packet) override;
 
  private:
-  const absl::optional<uint16_t> picture_id_;
-  const uint8_t* payload_data_;
-  size_t payload_size_;
-  const size_t max_payload_len_;
-  const size_t last_packet_reduction_len_;
-  FrameType frame_type_;
-  size_t payload_len_per_packet_;
-  uint8_t generic_header_;
-  // Number of packets yet to be retrieved by NextPacket() call.
-  size_t num_packets_left_;
-  // Number of packets, which will be 1 byte more than the rest.
-  size_t num_larger_packets_;
+  // Fills header_ and header_size_ members.
+  void BuildHeader(const RTPVideoHeader& rtp_video_header,
+                   FrameType frame_type);
 
-  void WriteExtendedHeader(uint8_t* out_ptr);
+  uint8_t header_[3];
+  size_t header_size_;
+  rtc::ArrayView<const uint8_t> remaining_payload_;
+  std::vector<size_t> payload_sizes_;
+  std::vector<size_t>::const_iterator current_packet_;
 
   RTC_DISALLOW_COPY_AND_ASSIGN(RtpPacketizerGeneric);
 };
diff --git a/modules/rtp_rtcp/source/rtp_format_video_generic_unittest.cc b/modules/rtp_rtcp/source/rtp_format_video_generic_unittest.cc
index e77dabf..8cf1ffa 100644
--- a/modules/rtp_rtcp/source/rtp_format_video_generic_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_format_video_generic_unittest.cc
@@ -29,10 +29,9 @@
 using ::testing::ElementsAreArray;
 using ::testing::Le;
 using ::testing::SizeIs;
+using ::testing::Contains;
 
-const size_t kMaxPayloadSize = 1200;
-
-uint8_t kTestPayload[kMaxPayloadSize];
+constexpr RtpPacketizer::PayloadSizeLimits kNoSizeLimits;
 
 std::vector<size_t> NextPacketFillPayloadSizes(
     RtpPacketizerGeneric* packetizer) {
@@ -44,185 +43,100 @@
   return result;
 }
 
-size_t GetEffectivePacketsSizeDifference(std::vector<size_t>* payload_sizes,
-                                         size_t last_packet_reduction_len) {
-  // Account for larger last packet header.
-  payload_sizes->back() += last_packet_reduction_len;
-  auto minmax =
-      std::minmax_element(payload_sizes->begin(), payload_sizes->end());
-  // MAX-MIN
-  size_t difference = *minmax.second - *minmax.first;
-  // Revert temporary changes.
-  payload_sizes->back() -= last_packet_reduction_len;
-  return difference;
+TEST(RtpPacketizerVideoGeneric, RespectsMaxPayloadSize) {
+  const size_t kPayloadSize = 50;
+  const uint8_t kPayload[kPayloadSize] = {};
+
+  RtpPacketizer::PayloadSizeLimits limits;
+  limits.max_payload_len = 6;
+  RtpPacketizerGeneric packetizer(kPayload, limits, RTPVideoHeader(),
+                                  kVideoFrameKey);
+
+  std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
+
+  EXPECT_THAT(payload_sizes, Each(Le(limits.max_payload_len)));
 }
 
-}  // namespace
+TEST(RtpPacketizerVideoGeneric, UsesMaxPayloadSize) {
+  const size_t kPayloadSize = 50;
+  const uint8_t kPayload[kPayloadSize] = {};
 
-TEST(RtpPacketizerVideoGeneric, AllPacketsMayBeEqualAndRespectMaxPayloadSize) {
-  const size_t kMaxPayloadLen = 6;
-  const size_t kLastPacketReductionLen = 2;
+  RtpPacketizer::PayloadSizeLimits limits;
+  limits.max_payload_len = 6;
+  RtpPacketizerGeneric packetizer(kPayload, limits, RTPVideoHeader(),
+                                  kVideoFrameKey);
+
+  std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
+
+  // With kPayloadSize > max_payload_len^2, there should be packets that use
+  // all the payload, otherwise it is possible to use less packets.
+  EXPECT_THAT(payload_sizes, Contains(limits.max_payload_len));
+}
+
+TEST(RtpPacketizerVideoGeneric, WritesExtendedHeaderWhenPictureIdIsSet) {
   const size_t kPayloadSize = 13;
-  RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
-                                  kMaxPayloadLen, kLastPacketReductionLen);
-  size_t num_packets =
-      packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
-  std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
-  EXPECT_THAT(payload_sizes, SizeIs(num_packets));
-
-  EXPECT_THAT(payload_sizes, Each(Le(kMaxPayloadLen)));
-}
-
-TEST(RtpPacketizerVideoGeneric,
-     AllPacketsMayBeEqual_RespectsLastPacketReductionLength) {
-  const size_t kMaxPayloadLen = 6;
-  const size_t kLastPacketReductionLen = 2;
-  const size_t kPayloadSize = 13;
-  RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
-                                  kMaxPayloadLen, kLastPacketReductionLen);
-  size_t num_packets =
-      packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
-  std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
-  EXPECT_THAT(payload_sizes, SizeIs(num_packets));
-
-  EXPECT_LE(payload_sizes.back(), kMaxPayloadLen - kLastPacketReductionLen);
-}
-
-TEST(RtpPacketizerVideoGeneric,
-     AllPacketsMayBeEqual_MakesPacketsAlmostEqualInSize) {
-  const size_t kMaxPayloadLen = 6;
-  const size_t kLastPacketReductionLen = 2;
-  const size_t kPayloadSize = 13;
-  RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
-                                  kMaxPayloadLen, kLastPacketReductionLen);
-  size_t num_packets =
-      packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
-  std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
-  EXPECT_THAT(payload_sizes, SizeIs(num_packets));
-
-  size_t sizes_difference = GetEffectivePacketsSizeDifference(
-      &payload_sizes, kLastPacketReductionLen);
-  EXPECT_LE(sizes_difference, 1u);
-}
-
-TEST(RtpPacketizerVideoGeneric,
-     AllPacketsMayBeEqual_GeneratesMinimumNumberOfPackets) {
-  const size_t kMaxPayloadLen = 6;
-  const size_t kLastPacketReductionLen = 3;
-  const size_t kPayloadSize = 13;
-  // Computed by hand. 3 packets would have capacity 3*(6-1)-3=12 (max length -
-  // generic header lengh for each packet minus last packet reduction).
-  // 4 packets is enough for kPayloadSize.
-  const size_t kMinNumPackets = 4;
-  RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
-                                  kMaxPayloadLen, kLastPacketReductionLen);
-  size_t num_packets =
-      packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
-  std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
-  EXPECT_THAT(payload_sizes, SizeIs(num_packets));
-
-  EXPECT_EQ(num_packets, kMinNumPackets);
-}
-
-TEST(RtpPacketizerVideoGeneric, SomePacketsAreSmaller_RespectsMaxPayloadSize) {
-  const size_t kMaxPayloadLen = 8;
-  const size_t kLastPacketReductionLen = 5;
-  const size_t kPayloadSize = 28;
-  RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
-                                  kMaxPayloadLen, kLastPacketReductionLen);
-  size_t num_packets =
-      packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
-  std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
-  EXPECT_THAT(payload_sizes, SizeIs(num_packets));
-
-  EXPECT_THAT(payload_sizes, Each(Le(kMaxPayloadLen)));
-}
-
-TEST(RtpPacketizerVideoGeneric,
-     SomePacketsAreSmaller_RespectsLastPacketReductionLength) {
-  const size_t kMaxPayloadLen = 8;
-  const size_t kLastPacketReductionLen = 5;
-  const size_t kPayloadSize = 28;
-  RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
-                                  kMaxPayloadLen, kLastPacketReductionLen);
-  size_t num_packets =
-      packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
-  std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
-  EXPECT_THAT(payload_sizes, SizeIs(num_packets));
-
-  EXPECT_LE(payload_sizes.back(), kMaxPayloadLen - kLastPacketReductionLen);
-}
-
-TEST(RtpPacketizerVideoGeneric,
-     SomePacketsAreSmaller_MakesPacketsAlmostEqualInSize) {
-  const size_t kMaxPayloadLen = 8;
-  const size_t kLastPacketReductionLen = 5;
-  const size_t kPayloadSize = 28;
-  RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
-                                  kMaxPayloadLen, kLastPacketReductionLen);
-  size_t num_packets =
-      packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
-  std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
-  EXPECT_THAT(payload_sizes, SizeIs(num_packets));
-
-  size_t sizes_difference = GetEffectivePacketsSizeDifference(
-      &payload_sizes, kLastPacketReductionLen);
-  EXPECT_LE(sizes_difference, 1u);
-}
-
-TEST(RtpPacketizerVideoGeneric,
-     SomePacketsAreSmaller_GeneratesMinimumNumberOfPackets) {
-  const size_t kMaxPayloadLen = 8;
-  const size_t kLastPacketReductionLen = 5;
-  const size_t kPayloadSize = 28;
-  // Computed by hand. 4 packets would have capacity 4*(8-1)-5=23 (max length -
-  // generic header lengh for each packet minus last packet reduction).
-  // 5 packets is enough for kPayloadSize.
-  const size_t kMinNumPackets = 5;
-  RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
-                                  kMaxPayloadLen, kLastPacketReductionLen);
-  size_t num_packets =
-      packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
-  std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
-  EXPECT_THAT(payload_sizes, SizeIs(num_packets));
-
-  EXPECT_EQ(num_packets, kMinNumPackets);
-}
-
-TEST(RtpPacketizerVideoGeneric, HasFrameIdWritesExtendedHeader) {
-  const size_t kMaxPayloadLen = 6;
-  const size_t kLastPacketReductionLen = 2;
-  const size_t kPayloadSize = 13;
+  const uint8_t kPayload[kPayloadSize] = {};
 
   RTPVideoHeader rtp_video_header;
   rtp_video_header.generic.emplace().frame_id = 37;
-  RtpPacketizerGeneric packetizer(rtp_video_header, kVideoFrameKey,
-                                  kMaxPayloadLen, kLastPacketReductionLen);
-  packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
+  RtpPacketizerGeneric packetizer(kPayload, kNoSizeLimits, rtp_video_header,
+                                  kVideoFrameKey);
 
   RtpPacketToSend packet(nullptr);
-  packetizer.NextPacket(&packet);
+  ASSERT_TRUE(packetizer.NextPacket(&packet));
 
   rtc::ArrayView<const uint8_t> payload = packet.payload();
+  EXPECT_EQ(payload.size(), 3 + kPayloadSize);
   EXPECT_TRUE(payload[0] & 0x04);  // Extended header bit is set.
   // Frame id is 37.
   EXPECT_EQ(0u, payload[1]);
   EXPECT_EQ(37u, payload[2]);
 }
 
+TEST(RtpPacketizerVideoGeneric, RespectsMaxPayloadSizeWithExtendedHeader) {
+  const size_t kPayloadSize = 50;
+  const uint8_t kPayload[kPayloadSize] = {};
+
+  RtpPacketizer::PayloadSizeLimits limits;
+  limits.max_payload_len = 6;
+  RTPVideoHeader rtp_video_header;
+  rtp_video_header.generic.emplace().frame_id = 37;
+  RtpPacketizerGeneric packetizer(kPayload, limits, rtp_video_header,
+                                  kVideoFrameKey);
+
+  std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
+
+  EXPECT_THAT(payload_sizes, Each(Le(limits.max_payload_len)));
+}
+
+TEST(RtpPacketizerVideoGeneric, UsesMaxPayloadSizeWithExtendedHeader) {
+  const size_t kPayloadSize = 50;
+  const uint8_t kPayload[kPayloadSize] = {};
+
+  RtpPacketizer::PayloadSizeLimits limits;
+  limits.max_payload_len = 6;
+  RTPVideoHeader rtp_video_header;
+  rtp_video_header.generic.emplace().frame_id = 37;
+  RtpPacketizerGeneric packetizer(kPayload, limits, rtp_video_header,
+                                  kVideoFrameKey);
+  std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
+
+  // With kPayloadSize > max_payload_len^2, there should be packets that use
+  // all the payload, otherwise it is possible to use less packets.
+  EXPECT_THAT(payload_sizes, Contains(limits.max_payload_len));
+}
+
 TEST(RtpPacketizerVideoGeneric, FrameIdOver15bitsWrapsAround) {
-  const size_t kMaxPayloadLen = 6;
-  const size_t kLastPacketReductionLen = 2;
   const size_t kPayloadSize = 13;
+  const uint8_t kPayload[kPayloadSize] = {};
 
   RTPVideoHeader rtp_video_header;
   rtp_video_header.generic.emplace().frame_id = 0x8137;
-  RtpPacketizerGeneric packetizer(rtp_video_header, kVideoFrameKey,
-                                  kMaxPayloadLen, kLastPacketReductionLen);
-  packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
+  RtpPacketizerGeneric packetizer(kPayload, kNoSizeLimits, rtp_video_header,
+                                  kVideoFrameKey);
 
   RtpPacketToSend packet(nullptr);
-  packetizer.NextPacket(&packet);
+  ASSERT_TRUE(packetizer.NextPacket(&packet));
 
   rtc::ArrayView<const uint8_t> payload = packet.payload();
   EXPECT_TRUE(payload[0] & 0x04);  // Extended header bit is set.
@@ -232,16 +146,14 @@
 }
 
 TEST(RtpPacketizerVideoGeneric, NoFrameIdDoesNotWriteExtendedHeader) {
-  const size_t kMaxPayloadLen = 6;
-  const size_t kLastPacketReductionLen = 2;
   const size_t kPayloadSize = 13;
+  const uint8_t kPayload[kPayloadSize] = {};
 
-  RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
-                                  kMaxPayloadLen, kLastPacketReductionLen);
-  packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
+  RtpPacketizerGeneric packetizer(kPayload, kNoSizeLimits, RTPVideoHeader(),
+                                  kVideoFrameKey);
 
   RtpPacketToSend packet(nullptr);
-  packetizer.NextPacket(&packet);
+  ASSERT_TRUE(packetizer.NextPacket(&packet));
 
   rtc::ArrayView<const uint8_t> payload = packet.payload();
   EXPECT_FALSE(payload[0] & 0x04);
@@ -270,4 +182,5 @@
   EXPECT_EQ(0x1337, parsed_payload.video_header().generic->frame_id);
 }
 
+}  // namespace
 }  // namespace webrtc