Cleanup RtpPacketizerH264 constructor

Merge SetPayloadData into constructor.
Add TODO to support first_packet_reduction_len

Bug: webrtc:9680
Change-Id: I65e771848e0ffe8968cd084840e77afc0152caeb
Reviewed-on: https://webrtc-review.googlesource.com/99505
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24702}
diff --git a/modules/rtp_rtcp/source/rtp_format.cc b/modules/rtp_rtcp/source/rtp_format.cc
index a84ebd8..13ec0af 100644
--- a/modules/rtp_rtcp/source/rtp_format.cc
+++ b/modules/rtp_rtcp/source/rtp_format.cc
@@ -31,13 +31,11 @@
     const RTPFragmentationHeader* fragmentation) {
   switch (type) {
     case kVideoCodecH264: {
+      RTC_CHECK(fragmentation);
       const auto& h264 =
           absl::get<RTPVideoHeaderH264>(rtp_video_header.video_type_header);
-      auto packetizer = absl::make_unique<RtpPacketizerH264>(
-          limits.max_payload_len, limits.last_packet_reduction_len,
-          h264.packetization_mode);
-      packetizer->SetPayloadData(payload.data(), payload.size(), fragmentation);
-      return std::move(packetizer);
+      return absl::make_unique<RtpPacketizerH264>(
+          payload, limits, h264.packetization_mode, *fragmentation);
     }
     case kVideoCodecVP8: {
       const auto& vp8 =
diff --git a/modules/rtp_rtcp/source/rtp_format_h264.cc b/modules/rtp_rtcp/source/rtp_format_h264.cc
index 373cce9..0422595 100644
--- a/modules/rtp_rtcp/source/rtp_format_h264.cc
+++ b/modules/rtp_rtcp/source/rtp_format_h264.cc
@@ -79,39 +79,24 @@
 
 }  // namespace
 
-RtpPacketizerH264::RtpPacketizerH264(size_t max_payload_len,
-                                     size_t last_packet_reduction_len,
-                                     H264PacketizationMode packetization_mode)
-    : max_payload_len_(max_payload_len),
-      last_packet_reduction_len_(last_packet_reduction_len),
-      num_packets_left_(0),
-      packetization_mode_(packetization_mode) {
+RtpPacketizerH264::RtpPacketizerH264(
+    rtc::ArrayView<const uint8_t> payload,
+    PayloadSizeLimits limits,
+    H264PacketizationMode packetization_mode,
+    const RTPFragmentationHeader& fragmentation)
+    : max_payload_len_(limits.max_payload_len),
+      // TODO(bugs.webrtc.org/9680): Do not ignore first_packet_reduction_len.
+      last_packet_reduction_len_(limits.last_packet_reduction_len),
+      num_packets_left_(0) {
   // Guard against uninitialized memory in packetization_mode.
   RTC_CHECK(packetization_mode == H264PacketizationMode::NonInterleaved ||
             packetization_mode == H264PacketizationMode::SingleNalUnit);
-  RTC_CHECK_GT(max_payload_len, last_packet_reduction_len);
-}
+  RTC_CHECK_GT(limits.max_payload_len, limits.last_packet_reduction_len);
 
-RtpPacketizerH264::~RtpPacketizerH264() {}
-
-RtpPacketizerH264::Fragment::~Fragment() = default;
-
-RtpPacketizerH264::Fragment::Fragment(const uint8_t* buffer, size_t length)
-    : buffer(buffer), length(length) {}
-RtpPacketizerH264::Fragment::Fragment(const Fragment& fragment)
-    : buffer(fragment.buffer), length(fragment.length) {}
-
-size_t RtpPacketizerH264::SetPayloadData(
-    const uint8_t* payload_data,
-    size_t payload_size,
-    const RTPFragmentationHeader* fragmentation) {
-  RTC_DCHECK(packets_.empty());
-  RTC_DCHECK(input_fragments_.empty());
-  RTC_DCHECK(fragmentation);
-  for (int i = 0; i < fragmentation->fragmentationVectorSize; ++i) {
+  for (int i = 0; i < fragmentation.fragmentationVectorSize; ++i) {
     const uint8_t* buffer =
-        &payload_data[fragmentation->fragmentationOffset[i]];
-    size_t length = fragmentation->fragmentationLength[i];
+        payload.data() + fragmentation.fragmentationOffset[i];
+    size_t length = fragmentation.fragmentationLength[i];
 
     bool updated_sps = false;
     H264::NaluType nalu_type = H264::ParseNaluType(buffer[0]);
@@ -169,7 +154,7 @@
     if (!updated_sps)
       input_fragments_.push_back(Fragment(buffer, length));
   }
-  if (!GeneratePackets()) {
+  if (!GeneratePackets(packetization_mode)) {
     // If failed to generate all the packets, discard already generated
     // packets in case the caller would ignore return value and still try to
     // call NextPacket().
@@ -177,18 +162,26 @@
     while (!packets_.empty()) {
       packets_.pop();
     }
-    return 0;
   }
-  return num_packets_left_;
 }
 
+RtpPacketizerH264::~RtpPacketizerH264() = default;
+
+RtpPacketizerH264::Fragment::~Fragment() = default;
+
+RtpPacketizerH264::Fragment::Fragment(const uint8_t* buffer, size_t length)
+    : buffer(buffer), length(length) {}
+RtpPacketizerH264::Fragment::Fragment(const Fragment& fragment)
+    : buffer(fragment.buffer), length(fragment.length) {}
+
 size_t RtpPacketizerH264::NumPackets() const {
   return num_packets_left_;
 }
 
-bool RtpPacketizerH264::GeneratePackets() {
+bool RtpPacketizerH264::GeneratePackets(
+    H264PacketizationMode packetization_mode) {
   for (size_t i = 0; i < input_fragments_.size();) {
-    switch (packetization_mode_) {
+    switch (packetization_mode) {
       case H264PacketizationMode::SingleNalUnit:
         if (!PacketizeSingleNalu(i))
           return false;
@@ -340,11 +333,9 @@
     packets_.pop();
     input_fragments_.pop_front();
   } else if (packet.aggregated) {
-    RTC_CHECK(H264PacketizationMode::NonInterleaved == packetization_mode_);
     bool is_last_packet = num_packets_left_ == 1;
     NextAggregatePacket(rtp_packet, is_last_packet);
   } else {
-    RTC_CHECK(H264PacketizationMode::NonInterleaved == packetization_mode_);
     NextFragmentPacket(rtp_packet);
   }
   RTC_DCHECK_LE(rtp_packet->payload_size(), max_payload_len_);
diff --git a/modules/rtp_rtcp/source/rtp_format_h264.h b/modules/rtp_rtcp/source/rtp_format_h264.h
index 1f6702a..57d9926 100644
--- a/modules/rtp_rtcp/source/rtp_format_h264.h
+++ b/modules/rtp_rtcp/source/rtp_format_h264.h
@@ -26,16 +26,13 @@
  public:
   // Initialize with payload from encoder.
   // The payload_data must be exactly one encoded H264 frame.
-  RtpPacketizerH264(size_t max_payload_len,
-                    size_t last_packet_reduction_len,
-                    H264PacketizationMode packetization_mode);
+  RtpPacketizerH264(rtc::ArrayView<const uint8_t> payload,
+                    PayloadSizeLimits limits,
+                    H264PacketizationMode packetization_mode,
+                    const RTPFragmentationHeader& fragmentation);
 
   ~RtpPacketizerH264() override;
 
-  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 H264 payload header.
@@ -80,7 +77,7 @@
     uint8_t header;
   };
 
-  bool GeneratePackets();
+  bool GeneratePackets(H264PacketizationMode packetization_mode);
   void PacketizeFuA(size_t fragment_index);
   size_t PacketizeStapA(size_t fragment_index);
   bool PacketizeSingleNalu(size_t fragment_index);
@@ -90,7 +87,6 @@
   const size_t max_payload_len_;
   const size_t last_packet_reduction_len_;
   size_t num_packets_left_;
-  const H264PacketizationMode packetization_mode_;
   std::deque<Fragment> input_fragments_;
   std::queue<PacketUnit> packets_;
 
diff --git a/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc b/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc
index 0183a6a..c90dbba 100644
--- a/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc
@@ -33,8 +33,9 @@
 };
 
 constexpr RtpPacketToSend::ExtensionManager* kNoExtensions = nullptr;
-const size_t kMaxPayloadSize = 1200;
-const size_t kLengthFieldLength = 2;
+constexpr size_t kMaxPayloadSize = 1200;
+constexpr size_t kLengthFieldLength = 2;
+constexpr RtpPacketizer::PayloadSizeLimits kNoLimits;
 
 enum Nalu {
   kSlice = 1,
@@ -68,19 +69,11 @@
       kNalHeaderSize + frameSize - payloadOffset;
 }
 
-std::unique_ptr<RtpPacketizerH264> CreateH264Packetizer(
-    H264PacketizationMode mode,
-    size_t max_payload_size,
-    size_t last_packet_reduction) {
-  return absl::make_unique<RtpPacketizerH264>(max_payload_size,
-                                              last_packet_reduction, mode);
-}
-
 void VerifyFua(size_t fua_index,
                const uint8_t* expected_payload,
                int offset,
                rtc::ArrayView<const uint8_t> packet,
-               const std::vector<size_t>& expected_sizes) {
+               rtc::ArrayView<const size_t> expected_sizes) {
   ASSERT_EQ(expected_sizes[fua_index] + kFuAHeaderSize, packet.size())
       << "FUA index: " << fua_index;
   const uint8_t kFuIndicator = 0x1C;  // F=0, NRI=0, Type=28.
@@ -105,34 +98,34 @@
 void TestFua(size_t frame_size,
              size_t max_payload_size,
              size_t last_packet_reduction,
-             const std::vector<size_t>& expected_sizes) {
-  std::unique_ptr<uint8_t[]> frame;
-  frame.reset(new uint8_t[frame_size]);
+             rtc::ArrayView<const size_t> expected_sizes) {
+  std::vector<uint8_t> frame(frame_size);
   frame[0] = 0x05;  // F=0, NRI=0, Type=5.
   for (size_t i = 0; i < frame_size - kNalHeaderSize; ++i) {
     frame[i + kNalHeaderSize] = i;
   }
+  RtpPacketizer::PayloadSizeLimits limits;
+  limits.max_payload_len = max_payload_size;
+  limits.last_packet_reduction_len = last_packet_reduction;
   RTPFragmentationHeader fragmentation;
   fragmentation.VerifyAndAllocateFragmentationHeader(1);
   fragmentation.fragmentationOffset[0] = 0;
   fragmentation.fragmentationLength[0] = frame_size;
-  std::unique_ptr<RtpPacketizerH264> packetizer(
-      CreateH264Packetizer(H264PacketizationMode::NonInterleaved,
-                           max_payload_size, last_packet_reduction));
-  EXPECT_EQ(
-      expected_sizes.size(),
-      packetizer->SetPayloadData(frame.get(), frame_size, &fragmentation));
+
+  RtpPacketizerH264 packetizer(
+      frame, limits, H264PacketizationMode::NonInterleaved, fragmentation);
+  EXPECT_EQ(packetizer.NumPackets(), expected_sizes.size());
 
   RtpPacketToSend packet(kNoExtensions);
   ASSERT_LE(max_payload_size, packet.FreeCapacity());
   size_t offset = kNalHeaderSize;
   for (size_t i = 0; i < expected_sizes.size(); ++i) {
-    ASSERT_TRUE(packetizer->NextPacket(&packet));
-    VerifyFua(i, frame.get(), offset, packet.payload(), expected_sizes);
+    ASSERT_TRUE(packetizer.NextPacket(&packet));
+    VerifyFua(i, frame.data(), offset, packet.payload(), expected_sizes);
     offset += expected_sizes[i];
   }
 
-  EXPECT_FALSE(packetizer->NextPacket(&packet));
+  EXPECT_FALSE(packetizer.NextPacket(&packet));
 }
 
 size_t GetExpectedNaluOffset(const RTPFragmentationHeader& fragmentation,
@@ -189,21 +182,22 @@
   fragmentation.VerifyAndAllocateFragmentationHeader(1);
   fragmentation.fragmentationOffset[0] = 0;
   fragmentation.fragmentationLength[0] = sizeof(frame);
-  std::unique_ptr<RtpPacketizerH264> packetizer(
-      CreateH264Packetizer(GetParam(), kMaxPayloadSize, 0));
-  ASSERT_EQ(1u,
-            packetizer->SetPayloadData(frame, sizeof(frame), &fragmentation));
+
+  RtpPacketizerH264 packetizer(frame, kNoLimits, GetParam(), fragmentation);
+  ASSERT_EQ(packetizer.NumPackets(), 1u);
+
   RtpPacketToSend packet(kNoExtensions);
-  ASSERT_LE(kMaxPayloadSize, packet.FreeCapacity());
-  ASSERT_TRUE(packetizer->NextPacket(&packet));
+  ASSERT_TRUE(packetizer.NextPacket(&packet));
   EXPECT_EQ(2u, packet.payload_size());
   VerifySingleNaluPayload(fragmentation, 0, frame, packet.payload());
-  EXPECT_FALSE(packetizer->NextPacket(&packet));
+  EXPECT_FALSE(packetizer.NextPacket(&packet));
 }
 
 TEST_P(RtpPacketizerH264ModeTest, TestSingleNaluTwoPackets) {
+  RtpPacketizer::PayloadSizeLimits limits;
+  limits.max_payload_len = kMaxPayloadSize;
   const size_t kFrameSize = kMaxPayloadSize + 100;
-  uint8_t frame[kFrameSize] = {0};
+  uint8_t frame[kFrameSize];
   for (size_t i = 0; i < kFrameSize; ++i)
     frame[i] = i;
   RTPFragmentationHeader fragmentation;
@@ -216,20 +210,19 @@
   frame[fragmentation.fragmentationOffset[0]] = 0x01;
   frame[fragmentation.fragmentationOffset[1]] = 0x01;
 
-  std::unique_ptr<RtpPacketizerH264> packetizer(
-      CreateH264Packetizer(GetParam(), kMaxPayloadSize, 0));
-  ASSERT_EQ(2u, packetizer->SetPayloadData(frame, kFrameSize, &fragmentation));
+  RtpPacketizerH264 packetizer(frame, limits, GetParam(), fragmentation);
+  ASSERT_EQ(packetizer.NumPackets(), 2u);
 
   RtpPacketToSend packet(kNoExtensions);
-  ASSERT_TRUE(packetizer->NextPacket(&packet));
+  ASSERT_TRUE(packetizer.NextPacket(&packet));
   ASSERT_EQ(fragmentation.fragmentationOffset[1], packet.payload_size());
   VerifySingleNaluPayload(fragmentation, 0, frame, packet.payload());
 
-  ASSERT_TRUE(packetizer->NextPacket(&packet));
+  ASSERT_TRUE(packetizer.NextPacket(&packet));
   ASSERT_EQ(fragmentation.fragmentationLength[1], packet.payload_size());
   VerifySingleNaluPayload(fragmentation, 1, frame, packet.payload());
 
-  EXPECT_FALSE(packetizer->NextPacket(&packet));
+  EXPECT_FALSE(packetizer.NextPacket(&packet));
 }
 
 INSTANTIATE_TEST_CASE_P(
@@ -239,6 +232,8 @@
                       H264PacketizationMode::NonInterleaved));
 
 TEST(RtpPacketizerH264Test, TestStapA) {
+  RtpPacketizer::PayloadSizeLimits limits;
+  limits.max_payload_len = kMaxPayloadSize;
   const size_t kFrameSize =
       kMaxPayloadSize - 3 * kLengthFieldLength - kNalHeaderSize;
   uint8_t frame[kFrameSize] = {0x07, 0xFF,  // F=0, NRI=0, Type=7 (SPS).
@@ -249,13 +244,14 @@
     frame[i + kPayloadOffset] = i;
   RTPFragmentationHeader fragmentation;
   CreateThreeFragments(&fragmentation, kFrameSize, kPayloadOffset);
-  std::unique_ptr<RtpPacketizerH264> packetizer(CreateH264Packetizer(
-      H264PacketizationMode::NonInterleaved, kMaxPayloadSize, 0));
-  ASSERT_EQ(1u, packetizer->SetPayloadData(frame, kFrameSize, &fragmentation));
+
+  RtpPacketizerH264 packetizer(
+      frame, limits, H264PacketizationMode::NonInterleaved, fragmentation);
+  ASSERT_EQ(packetizer.NumPackets(), 1u);
 
   RtpPacketToSend packet(kNoExtensions);
   ASSERT_LE(kMaxPayloadSize, packet.FreeCapacity());
-  ASSERT_TRUE(packetizer->NextPacket(&packet));
+  ASSERT_TRUE(packetizer.NextPacket(&packet));
   size_t expected_packet_size =
       kNalHeaderSize + 3 * kLengthFieldLength + kFrameSize;
   ASSERT_EQ(expected_packet_size, packet.payload_size());
@@ -263,12 +259,14 @@
   for (size_t i = 0; i < fragmentation.fragmentationVectorSize; ++i)
     VerifyStapAPayload(fragmentation, 0, i, frame, packet.payload());
 
-  EXPECT_FALSE(packetizer->NextPacket(&packet));
+  EXPECT_FALSE(packetizer.NextPacket(&packet));
 }
 
 TEST(RtpPacketizerH264Test, TestStapARespectsPacketReduction) {
-  const size_t kLastPacketReduction = 100;
-  const size_t kFrameSize = kMaxPayloadSize - 1 - kLastPacketReduction;
+  RtpPacketizer::PayloadSizeLimits limits;
+  limits.max_payload_len = kMaxPayloadSize;
+  limits.last_packet_reduction_len = 100;
+  const size_t kFrameSize = kMaxPayloadSize - 1 - 100;
   uint8_t frame[kFrameSize] = {0x07, 0xFF,  // F=0, NRI=0, Type=7.
                                0x08, 0xFF,  // F=0, NRI=0, Type=8.
                                0x05};       // F=0, NRI=0, Type=5.
@@ -284,14 +282,14 @@
   fragmentation.fragmentationOffset[2] = 4;
   fragmentation.fragmentationLength[2] =
       kNalHeaderSize + kFrameSize - kPayloadOffset;
-  std::unique_ptr<RtpPacketizerH264> packetizer(
-      CreateH264Packetizer(H264PacketizationMode::NonInterleaved,
-                           kMaxPayloadSize, kLastPacketReduction));
-  ASSERT_EQ(2u, packetizer->SetPayloadData(frame, kFrameSize, &fragmentation));
+
+  RtpPacketizerH264 packetizer(
+      frame, limits, H264PacketizationMode::NonInterleaved, fragmentation);
+  ASSERT_EQ(packetizer.NumPackets(), 2u);
 
   RtpPacketToSend packet(kNoExtensions);
   ASSERT_LE(kMaxPayloadSize, packet.FreeCapacity());
-  ASSERT_TRUE(packetizer->NextPacket(&packet));
+  ASSERT_TRUE(packetizer.NextPacket(&packet));
   size_t expected_packet_size = kNalHeaderSize;
   for (size_t i = 0; i < 2; ++i) {
     expected_packet_size +=
@@ -301,16 +299,18 @@
   for (size_t i = 0; i < 2; ++i)
     VerifyStapAPayload(fragmentation, 0, i, frame, packet.payload());
 
-  ASSERT_TRUE(packetizer->NextPacket(&packet));
+  ASSERT_TRUE(packetizer.NextPacket(&packet));
   expected_packet_size = fragmentation.fragmentationLength[2];
   ASSERT_EQ(expected_packet_size, packet.payload_size());
   VerifySingleNaluPayload(fragmentation, 2, frame, packet.payload());
 
-  EXPECT_FALSE(packetizer->NextPacket(&packet));
+  EXPECT_FALSE(packetizer.NextPacket(&packet));
 }
 
 TEST(RtpPacketizerH264Test, TestSingleNalUnitModeHasNoStapA) {
   // This is the same setup as for the TestStapA test.
+  RtpPacketizer::PayloadSizeLimits limits;
+  limits.max_payload_len = kMaxPayloadSize;
   const size_t kFrameSize =
       kMaxPayloadSize - 3 * kLengthFieldLength - kNalHeaderSize;
   uint8_t frame[kFrameSize] = {0x07, 0xFF,  // F=0, NRI=0, Type=7 (SPS).
@@ -321,19 +321,22 @@
     frame[i + kPayloadOffset] = i;
   RTPFragmentationHeader fragmentation;
   CreateThreeFragments(&fragmentation, kFrameSize, kPayloadOffset);
-  std::unique_ptr<RtpPacketizerH264> packetizer(CreateH264Packetizer(
-      H264PacketizationMode::SingleNalUnit, kMaxPayloadSize, 0));
-  packetizer->SetPayloadData(frame, kFrameSize, &fragmentation);
+
+  RtpPacketizerH264 packetizer(
+      frame, limits, H264PacketizationMode::SingleNalUnit, fragmentation);
+  EXPECT_EQ(packetizer.NumPackets(), 3u);
 
   RtpPacketToSend packet(kNoExtensions);
   // The three fragments should be returned as three packets.
-  ASSERT_TRUE(packetizer->NextPacket(&packet));
-  ASSERT_TRUE(packetizer->NextPacket(&packet));
-  ASSERT_TRUE(packetizer->NextPacket(&packet));
-  EXPECT_FALSE(packetizer->NextPacket(&packet));
+  ASSERT_TRUE(packetizer.NextPacket(&packet));
+  ASSERT_TRUE(packetizer.NextPacket(&packet));
+  ASSERT_TRUE(packetizer.NextPacket(&packet));
+  EXPECT_FALSE(packetizer.NextPacket(&packet));
 }
 
 TEST(RtpPacketizerH264Test, TestTooSmallForStapAHeaders) {
+  RtpPacketizer::PayloadSizeLimits limits;
+  limits.max_payload_len = kMaxPayloadSize;
   const size_t kFrameSize = kMaxPayloadSize - 1;
   uint8_t frame[kFrameSize] = {0x07, 0xFF,  // F=0, NRI=0, Type=7.
                                0x08, 0xFF,  // F=0, NRI=0, Type=8.
@@ -350,13 +353,13 @@
   fragmentation.fragmentationOffset[2] = 4;
   fragmentation.fragmentationLength[2] =
       kNalHeaderSize + kFrameSize - kPayloadOffset;
-  std::unique_ptr<RtpPacketizerH264> packetizer(CreateH264Packetizer(
-      H264PacketizationMode::NonInterleaved, kMaxPayloadSize, 0));
-  ASSERT_EQ(2u, packetizer->SetPayloadData(frame, kFrameSize, &fragmentation));
+  RtpPacketizerH264 packetizer(
+      frame, limits, H264PacketizationMode::NonInterleaved, fragmentation);
+  ASSERT_EQ(packetizer.NumPackets(), 2u);
 
   RtpPacketToSend packet(kNoExtensions);
   ASSERT_LE(kMaxPayloadSize, packet.FreeCapacity());
-  ASSERT_TRUE(packetizer->NextPacket(&packet));
+  ASSERT_TRUE(packetizer.NextPacket(&packet));
   size_t expected_packet_size = kNalHeaderSize;
   for (size_t i = 0; i < 2; ++i) {
     expected_packet_size +=
@@ -366,15 +369,17 @@
   for (size_t i = 0; i < 2; ++i)
     VerifyStapAPayload(fragmentation, 0, i, frame, packet.payload());
 
-  ASSERT_TRUE(packetizer->NextPacket(&packet));
+  ASSERT_TRUE(packetizer.NextPacket(&packet));
   expected_packet_size = fragmentation.fragmentationLength[2];
   ASSERT_EQ(expected_packet_size, packet.payload_size());
   VerifySingleNaluPayload(fragmentation, 2, frame, packet.payload());
 
-  EXPECT_FALSE(packetizer->NextPacket(&packet));
+  EXPECT_FALSE(packetizer.NextPacket(&packet));
 }
 
 TEST(RtpPacketizerH264Test, TestMixedStapA_FUA) {
+  RtpPacketizer::PayloadSizeLimits limits;
+  limits.max_payload_len = kMaxPayloadSize;
   const size_t kFuaNaluSize = 2 * (kMaxPayloadSize - 100);
   const size_t kStapANaluSize = 100;
   RTPFragmentationHeader fragmentation;
@@ -395,9 +400,9 @@
       frame[nalu_offset + j] = i + j;
     }
   }
-  std::unique_ptr<RtpPacketizerH264> packetizer(CreateH264Packetizer(
-      H264PacketizationMode::NonInterleaved, kMaxPayloadSize, 0));
-  ASSERT_EQ(3u, packetizer->SetPayloadData(frame, kFrameSize, &fragmentation));
+  RtpPacketizerH264 packetizer(
+      frame, limits, H264PacketizationMode::NonInterleaved, fragmentation);
+  ASSERT_EQ(packetizer.NumPackets(), 3u);
 
   // First expecting two FU-A packets.
   std::vector<size_t> fua_sizes;
@@ -407,56 +412,40 @@
   ASSERT_LE(kMaxPayloadSize, packet.FreeCapacity());
   int fua_offset = kNalHeaderSize;
   for (size_t i = 0; i < 2; ++i) {
-    ASSERT_TRUE(packetizer->NextPacket(&packet));
+    ASSERT_TRUE(packetizer.NextPacket(&packet));
     VerifyFua(i, frame, fua_offset, packet.payload(), fua_sizes);
     fua_offset += fua_sizes[i];
   }
   // Then expecting one STAP-A packet with two nal units.
-  ASSERT_TRUE(packetizer->NextPacket(&packet));
+  ASSERT_TRUE(packetizer.NextPacket(&packet));
   size_t expected_packet_size =
       kNalHeaderSize + 2 * kLengthFieldLength + 2 * kStapANaluSize;
   ASSERT_EQ(expected_packet_size, packet.payload_size());
   for (size_t i = 1; i < fragmentation.fragmentationVectorSize; ++i)
     VerifyStapAPayload(fragmentation, 1, i, frame, packet.payload());
 
-  EXPECT_FALSE(packetizer->NextPacket(&packet));
+  EXPECT_FALSE(packetizer.NextPacket(&packet));
 }
 
 TEST(RtpPacketizerH264Test, TestFUAOddSize) {
   const size_t kExpectedPayloadSizes[2] = {600, 600};
-  TestFua(
-      kMaxPayloadSize + 1, kMaxPayloadSize, 0,
-      std::vector<size_t>(kExpectedPayloadSizes,
-                          kExpectedPayloadSizes +
-                              sizeof(kExpectedPayloadSizes) / sizeof(size_t)));
+  TestFua(kMaxPayloadSize + 1, kMaxPayloadSize, 0, kExpectedPayloadSizes);
 }
 
 TEST(RtpPacketizerH264Test, TestFUAWithLastPacketReduction) {
   const size_t kExpectedPayloadSizes[2] = {601, 597};
-  TestFua(
-      kMaxPayloadSize - 1, kMaxPayloadSize, 4,
-      std::vector<size_t>(kExpectedPayloadSizes,
-                          kExpectedPayloadSizes +
-                              sizeof(kExpectedPayloadSizes) / sizeof(size_t)));
+  TestFua(kMaxPayloadSize - 1, kMaxPayloadSize, 4, kExpectedPayloadSizes);
 }
 
 TEST(RtpPacketizerH264Test, TestFUAEvenSize) {
   const size_t kExpectedPayloadSizes[2] = {600, 601};
-  TestFua(
-      kMaxPayloadSize + 2, kMaxPayloadSize, 0,
-      std::vector<size_t>(kExpectedPayloadSizes,
-                          kExpectedPayloadSizes +
-                              sizeof(kExpectedPayloadSizes) / sizeof(size_t)));
+  TestFua(kMaxPayloadSize + 2, kMaxPayloadSize, 0, kExpectedPayloadSizes);
 }
 
 TEST(RtpPacketizerH264Test, TestFUARounding) {
   const size_t kExpectedPayloadSizes[8] = {1265, 1265, 1265, 1265,
                                            1265, 1266, 1266, 1266};
-  TestFua(
-      10124, 1448, 0,
-      std::vector<size_t>(kExpectedPayloadSizes,
-                          kExpectedPayloadSizes +
-                              sizeof(kExpectedPayloadSizes) / sizeof(size_t)));
+  TestFua(10124, 1448, 0, kExpectedPayloadSizes);
 }
 
 TEST(RtpPacketizerH264Test, TestFUABig) {
@@ -464,15 +453,13 @@
                                             1198, 1198, 1198, 1198, 1198};
   // Generate 10 full sized packets, leave room for FU-A headers minus the NALU
   // header.
-  TestFua(
-      10 * (kMaxPayloadSize - kFuAHeaderSize) + kNalHeaderSize, kMaxPayloadSize,
-      0,
-      std::vector<size_t>(kExpectedPayloadSizes,
-                          kExpectedPayloadSizes +
-                              sizeof(kExpectedPayloadSizes) / sizeof(size_t)));
+  TestFua(10 * (kMaxPayloadSize - kFuAHeaderSize) + kNalHeaderSize,
+          kMaxPayloadSize, 0, kExpectedPayloadSizes);
 }
 
 TEST(RtpPacketizerH264Test, SendOverlongDataInPacketizationMode0) {
+  RtpPacketizer::PayloadSizeLimits limits;
+  limits.max_payload_len = kMaxPayloadSize;
   const size_t kFrameSize = kMaxPayloadSize + 1;
   uint8_t frame[kFrameSize] = {0};
   for (size_t i = 0; i < kFrameSize; ++i)
@@ -484,9 +471,9 @@
   // Set NAL headers.
   frame[fragmentation.fragmentationOffset[0]] = 0x01;
 
-  std::unique_ptr<RtpPacketizerH264> packetizer(CreateH264Packetizer(
-      H264PacketizationMode::SingleNalUnit, kMaxPayloadSize, 0));
-  EXPECT_EQ(0u, packetizer->SetPayloadData(frame, kFrameSize, &fragmentation));
+  RtpPacketizerH264 packetizer(
+      frame, limits, H264PacketizationMode::SingleNalUnit, fragmentation);
+  EXPECT_EQ(packetizer.NumPackets(), 0u);
 }
 
 namespace {
@@ -522,31 +509,29 @@
  protected:
   rtc::Buffer in_buffer_;
   RTPFragmentationHeader fragmentation_header_;
-  std::unique_ptr<RtpPacketizerH264> packetizer_;
 };
 
 TEST_F(RtpPacketizerH264TestSpsRewriting, FuASps) {
   const size_t kHeaderOverhead = kFuAHeaderSize + 1;
 
   // Set size to fragment SPS into two FU-A packets.
-  packetizer_ =
-      CreateH264Packetizer(H264PacketizationMode::NonInterleaved,
-                           sizeof(kOriginalSps) - 2 + kHeaderOverhead, 0);
-
-  packetizer_->SetPayloadData(in_buffer_.data(), in_buffer_.size(),
-                              &fragmentation_header_);
+  RtpPacketizer::PayloadSizeLimits limits;
+  limits.max_payload_len = sizeof(kOriginalSps) - 2 + kHeaderOverhead;
+  RtpPacketizerH264 packetizer(in_buffer_, limits,
+                               H264PacketizationMode::NonInterleaved,
+                               fragmentation_header_);
 
   RtpPacketToSend packet(kNoExtensions);
   ASSERT_LE(sizeof(kOriginalSps) + kHeaderOverhead, packet.FreeCapacity());
 
-  EXPECT_TRUE(packetizer_->NextPacket(&packet));
+  EXPECT_TRUE(packetizer.NextPacket(&packet));
   size_t offset = H264::kNaluTypeSize;
   size_t length = packet.payload_size() - kFuAHeaderSize;
   EXPECT_THAT(packet.payload().subview(kFuAHeaderSize),
               ElementsAreArray(&kRewrittenSps[offset], length));
   offset += length;
 
-  EXPECT_TRUE(packetizer_->NextPacket(&packet));
+  EXPECT_TRUE(packetizer.NextPacket(&packet));
   length = packet.payload_size() - kFuAHeaderSize;
   EXPECT_THAT(packet.payload().subview(kFuAHeaderSize),
               ElementsAreArray(&kRewrittenSps[offset], length));
@@ -562,16 +547,17 @@
                                     sizeof(kIdrTwo) + (kLengthFieldLength * 3);
 
   // Set size to include SPS and the rest of the packets in a Stap-A package.
-  packetizer_ = CreateH264Packetizer(H264PacketizationMode::NonInterleaved,
-                                     kExpectedTotalSize + kHeaderOverhead, 0);
+  RtpPacketizer::PayloadSizeLimits limits;
+  limits.max_payload_len = kExpectedTotalSize + kHeaderOverhead;
 
-  packetizer_->SetPayloadData(in_buffer_.data(), in_buffer_.size(),
-                              &fragmentation_header_);
+  RtpPacketizerH264 packetizer(in_buffer_, limits,
+                               H264PacketizationMode::NonInterleaved,
+                               fragmentation_header_);
 
   RtpPacketToSend packet(kNoExtensions);
   ASSERT_LE(kExpectedTotalSize + kHeaderOverhead, packet.FreeCapacity());
 
-  EXPECT_TRUE(packetizer_->NextPacket(&packet));
+  EXPECT_TRUE(packetizer.NextPacket(&packet));
   EXPECT_EQ(kExpectedTotalSize, packet.payload_size());
   EXPECT_THAT(packet.payload().subview(H264::kNaluTypeSize + kLengthFieldLength,
                                        sizeof(kRewrittenSps)),