Reland "Batch assign RTP seq# for all packets of a frame."
This is a reland of 5cc99570620890edc3989b2cae1d1ee0669a021c Original change's description: > Batch assign RTP seq# for all packets of a frame. > > This avoids a potential race where other call sites could assign > sequence numbers while the video frame is mid packetization - resulting > in a non-contiguous video sequence. > > Avoiding the tight lock-unlock within the loop also couldn't hurt from > a performance standpoint. > > Bug: webrtc:12448 > Change-Id: I6cc31c7743d2ca75caeaeffb98651a480dbe08e2 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/207867 > Commit-Queue: Erik Språng <sprang@webrtc.org> > Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#33291} Bug: webrtc:12448 Change-Id: I7c5a5e00a5e08330ff24b58af9f090c327eeeaa2 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/208221 Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Commit-Queue: Erik Språng <sprang@webrtc.org> Cr-Commit-Position: refs/heads/master@{#33296}
This commit is contained in:
parent
9915db3453
commit
0f71871cad
@ -47,6 +47,9 @@ constexpr uint32_t kTimestampTicksPerMs = 90;
|
|||||||
// Min size needed to get payload padding from packet history.
|
// Min size needed to get payload padding from packet history.
|
||||||
constexpr int kMinPayloadPaddingBytes = 50;
|
constexpr int kMinPayloadPaddingBytes = 50;
|
||||||
|
|
||||||
|
// RED header if first byte of payload.
|
||||||
|
constexpr size_t kRedForFecHeaderLength = 1;
|
||||||
|
|
||||||
template <typename Extension>
|
template <typename Extension>
|
||||||
constexpr RtpExtensionSize CreateExtensionSize() {
|
constexpr RtpExtensionSize CreateExtensionSize() {
|
||||||
return {Extension::kId, Extension::kValueSizeBytes};
|
return {Extension::kId, Extension::kValueSizeBytes};
|
||||||
@ -611,16 +614,40 @@ bool RTPSender::AssignSequenceNumber(RtpPacketToSend* packet) {
|
|||||||
RTC_DCHECK(packet->Ssrc() == ssrc_);
|
RTC_DCHECK(packet->Ssrc() == ssrc_);
|
||||||
packet->SetSequenceNumber(sequence_number_++);
|
packet->SetSequenceNumber(sequence_number_++);
|
||||||
|
|
||||||
|
UpdateLastPacketState(*packet);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RTPSender::AssignSequenceNumbersAndStoreLastPacketState(
|
||||||
|
rtc::ArrayView<std::unique_ptr<RtpPacketToSend>> packets) {
|
||||||
|
RTC_DCHECK(!packets.empty());
|
||||||
|
MutexLock lock(&send_mutex_);
|
||||||
|
if (!sending_media_)
|
||||||
|
return false;
|
||||||
|
for (auto& packet : packets) {
|
||||||
|
RTC_DCHECK_EQ(packet->Ssrc(), ssrc_);
|
||||||
|
packet->SetSequenceNumber(sequence_number_++);
|
||||||
|
}
|
||||||
|
UpdateLastPacketState(**packets.rbegin());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RTPSender::UpdateLastPacketState(const RtpPacketToSend& packet) {
|
||||||
// Remember marker bit to determine if padding can be inserted with
|
// Remember marker bit to determine if padding can be inserted with
|
||||||
// sequence number following |packet|.
|
// sequence number following |packet|.
|
||||||
last_packet_marker_bit_ = packet->Marker();
|
last_packet_marker_bit_ = packet.Marker();
|
||||||
// Remember payload type to use in the padding packet if rtx is disabled.
|
// Remember media payload type to use in the padding packet if rtx is
|
||||||
last_payload_type_ = packet->PayloadType();
|
// disabled.
|
||||||
|
if (packet.is_red()) {
|
||||||
|
RTC_DCHECK_GE(packet.payload_size(), kRedForFecHeaderLength);
|
||||||
|
last_payload_type_ = packet.PayloadBuffer()[0];
|
||||||
|
} else {
|
||||||
|
last_payload_type_ = packet.PayloadType();
|
||||||
|
}
|
||||||
// Save timestamps to generate timestamp field and extensions for the padding.
|
// Save timestamps to generate timestamp field and extensions for the padding.
|
||||||
last_rtp_timestamp_ = packet->Timestamp();
|
last_rtp_timestamp_ = packet.Timestamp();
|
||||||
last_timestamp_time_ms_ = clock_->TimeInMilliseconds();
|
last_timestamp_time_ms_ = clock_->TimeInMilliseconds();
|
||||||
capture_time_ms_ = packet->capture_time_ms();
|
capture_time_ms_ = packet.capture_time_ms();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RTPSender::SetSendingMediaStatus(bool enabled) {
|
void RTPSender::SetSendingMediaStatus(bool enabled) {
|
||||||
|
|||||||
@ -137,6 +137,11 @@ class RTPSender {
|
|||||||
// Return false if sending was turned off.
|
// Return false if sending was turned off.
|
||||||
bool AssignSequenceNumber(RtpPacketToSend* packet)
|
bool AssignSequenceNumber(RtpPacketToSend* packet)
|
||||||
RTC_LOCKS_EXCLUDED(send_mutex_);
|
RTC_LOCKS_EXCLUDED(send_mutex_);
|
||||||
|
// Same as AssignSequenceNumber(), but applies sequence numbers atomically to
|
||||||
|
// a batch of packets.
|
||||||
|
bool AssignSequenceNumbersAndStoreLastPacketState(
|
||||||
|
rtc::ArrayView<std::unique_ptr<RtpPacketToSend>> packets)
|
||||||
|
RTC_LOCKS_EXCLUDED(send_mutex_);
|
||||||
// Maximum header overhead per fec/padding packet.
|
// Maximum header overhead per fec/padding packet.
|
||||||
size_t FecOrPaddingPacketMaxRtpHeaderLength() const
|
size_t FecOrPaddingPacketMaxRtpHeaderLength() const
|
||||||
RTC_LOCKS_EXCLUDED(send_mutex_);
|
RTC_LOCKS_EXCLUDED(send_mutex_);
|
||||||
@ -179,6 +184,9 @@ class RTPSender {
|
|||||||
|
|
||||||
void UpdateHeaderSizes() RTC_EXCLUSIVE_LOCKS_REQUIRED(send_mutex_);
|
void UpdateHeaderSizes() RTC_EXCLUSIVE_LOCKS_REQUIRED(send_mutex_);
|
||||||
|
|
||||||
|
void UpdateLastPacketState(const RtpPacketToSend& packet)
|
||||||
|
RTC_EXCLUSIVE_LOCKS_REQUIRED(send_mutex_);
|
||||||
|
|
||||||
Clock* const clock_;
|
Clock* const clock_;
|
||||||
Random random_ RTC_GUARDED_BY(send_mutex_);
|
Random random_ RTC_GUARDED_BY(send_mutex_);
|
||||||
|
|
||||||
|
|||||||
@ -648,8 +648,6 @@ bool RTPSenderVideo::SendVideo(
|
|||||||
if (!packetizer->NextPacket(packet.get()))
|
if (!packetizer->NextPacket(packet.get()))
|
||||||
return false;
|
return false;
|
||||||
RTC_DCHECK_LE(packet->payload_size(), expected_payload_capacity);
|
RTC_DCHECK_LE(packet->payload_size(), expected_payload_capacity);
|
||||||
if (!rtp_sender_->AssignSequenceNumber(packet.get()))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
packet->set_allow_retransmission(allow_retransmission);
|
packet->set_allow_retransmission(allow_retransmission);
|
||||||
packet->set_is_key_frame(video_header.frame_type ==
|
packet->set_is_key_frame(video_header.frame_type ==
|
||||||
@ -670,7 +668,7 @@ bool RTPSenderVideo::SendVideo(
|
|||||||
red_packet->SetPayloadType(*red_payload_type_);
|
red_packet->SetPayloadType(*red_payload_type_);
|
||||||
red_packet->set_is_red(true);
|
red_packet->set_is_red(true);
|
||||||
|
|
||||||
// Send |red_packet| instead of |packet| for allocated sequence number.
|
// Append |red_packet| instead of |packet| to output.
|
||||||
red_packet->set_packet_type(RtpPacketMediaType::kVideo);
|
red_packet->set_packet_type(RtpPacketMediaType::kVideo);
|
||||||
red_packet->set_allow_retransmission(packet->allow_retransmission());
|
red_packet->set_allow_retransmission(packet->allow_retransmission());
|
||||||
rtp_packets.emplace_back(std::move(red_packet));
|
rtp_packets.emplace_back(std::move(red_packet));
|
||||||
@ -691,6 +689,11 @@ bool RTPSenderVideo::SendVideo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!rtp_sender_->AssignSequenceNumbersAndStoreLastPacketState(rtp_packets)) {
|
||||||
|
// Media not being sent.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
LogAndSendToNetwork(std::move(rtp_packets), payload.size());
|
LogAndSendToNetwork(std::move(rtp_packets), payload.size());
|
||||||
|
|
||||||
// Update details about the last sent frame.
|
// Update details about the last sent frame.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user