Calculate max payload size for an rtp packet to fit full video frame
instead of sometimes incorrectly guessing it
Bug: webrtc:9868
Change-Id: I8b15ecca4c660d83ea129dc9df6ec174ad83b4c6
Reviewed-on: https://webrtc-review.googlesource.com/c/106281
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25213}
diff --git a/modules/rtp_rtcp/source/rtp_sender_video.cc b/modules/rtp_rtcp/source/rtp_sender_video.cc
index 2bcaea7..cb0415c 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_video.cc
@@ -387,33 +387,37 @@
int packet_capacity = rtp_sender_->MaxRtpPacketSize() - fec_packet_overhead -
(rtp_sender_->RtxStatus() ? kRtxHeaderSize : 0);
- auto create_packet = [&] {
- std::unique_ptr<RtpPacketToSend> rtp_packet = rtp_sender_->AllocatePacket();
- RTC_DCHECK_LE(packet_capacity, rtp_packet->capacity());
+ std::unique_ptr<RtpPacketToSend> single_packet =
+ rtp_sender_->AllocatePacket();
+ RTC_DCHECK_LE(packet_capacity, single_packet->capacity());
+ single_packet->SetPayloadType(payload_type);
+ single_packet->SetTimestamp(rtp_timestamp);
+ single_packet->set_capture_time_ms(capture_time_ms);
- rtp_packet->SetPayloadType(payload_type);
- rtp_packet->SetTimestamp(rtp_timestamp);
- rtp_packet->set_capture_time_ms(capture_time_ms);
- return rtp_packet;
- };
-
- auto first_packet = create_packet();
- auto middle_packet = absl::make_unique<RtpPacketToSend>(*first_packet);
- auto last_packet = absl::make_unique<RtpPacketToSend>(*first_packet);
+ auto first_packet = absl::make_unique<RtpPacketToSend>(*single_packet);
+ auto middle_packet = absl::make_unique<RtpPacketToSend>(*single_packet);
+ auto last_packet = absl::make_unique<RtpPacketToSend>(*single_packet);
// Simplest way to estimate how much extensions would occupy is to set them.
AddRtpHeaderExtensions(*video_header, frame_type, set_video_rotation,
+ /*first=*/true, /*last=*/true, single_packet.get());
+ AddRtpHeaderExtensions(*video_header, frame_type, set_video_rotation,
/*first=*/true, /*last=*/false, first_packet.get());
AddRtpHeaderExtensions(*video_header, frame_type, set_video_rotation,
/*first=*/false, /*last=*/false, middle_packet.get());
AddRtpHeaderExtensions(*video_header, frame_type, set_video_rotation,
/*first=*/false, /*last=*/true, last_packet.get());
+ RTC_DCHECK_GT(packet_capacity, single_packet->headers_size());
RTC_DCHECK_GT(packet_capacity, first_packet->headers_size());
RTC_DCHECK_GT(packet_capacity, middle_packet->headers_size());
RTC_DCHECK_GT(packet_capacity, last_packet->headers_size());
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = packet_capacity - middle_packet->headers_size();
+ RTC_DCHECK_GE(single_packet->headers_size(), middle_packet->headers_size());
+ limits.single_packet_reduction_len =
+ single_packet->headers_size() - middle_packet->headers_size();
+
RTC_DCHECK_GE(first_packet->headers_size(), middle_packet->headers_size());
limits.first_packet_reduction_len =
first_packet->headers_size() - middle_packet->headers_size();
@@ -422,16 +426,6 @@
limits.last_packet_reduction_len =
last_packet->headers_size() - middle_packet->headers_size();
- // TODO(bugs.webrtc.org/9868, bugs.webrtc.org/7990): Calculate correctly:
- // Single packet might need more space for extensions than sum of first and
- // last packet reductions when two byte header extension is used. It also may
- // need more even for one-byte header extension because of padding.
- // e.g. if middle_packet uses 5 bytes for extensions, it is padded to 8.
- // if first_packet and last_packet use 2 bytes for extensions each, reduction
- // would be 0 for both of them, but single packet would need 4 extra bytes.
- limits.single_packet_reduction_len =
- limits.first_packet_reduction_len + limits.last_packet_reduction_len;
-
RTPVideoHeader minimized_video_header;
const RTPVideoHeader* packetize_video_header = video_header;
if (first_packet->HasExtension<RtpGenericFrameDescriptorExtension>() &&
@@ -457,10 +451,7 @@
int expected_payload_capacity;
// Choose right packet template:
if (num_packets == 1) {
- // No prepared template, create a new packet.
- packet = create_packet();
- AddRtpHeaderExtensions(*video_header, frame_type, set_video_rotation,
- /*first=*/true, /*last=*/true, packet.get());
+ packet = std::move(single_packet);
expected_payload_capacity =
limits.max_payload_len - limits.single_packet_reduction_len;
} else if (i == 0) {