Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(581)

Unified Diff: webrtc/modules/rtp_rtcp/source/rtp_sender.cc

Issue 1739273002: [Draft] RtpPacket sketched. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: rebase to use landed version of rtp::Packet Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/modules/rtp_rtcp/source/rtp_sender.h ('k') | webrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/modules/rtp_rtcp/source/rtp_sender.cc
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
index f7b72b875c785358d42179f333ff2173075c0e99..500353f50497c8f2b6606017dbd1e7dfd110277e 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
@@ -21,6 +21,7 @@
#include "webrtc/call/rtc_event_log.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_cvo.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
+#include "webrtc/modules/rtp_rtcp/source/rtp_packet_to_send.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_sender_audio.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_sender_video.h"
#include "webrtc/modules/rtp_rtcp/source/time_util.h"
@@ -31,7 +32,6 @@ namespace webrtc {
// Max in the RFC 3550 is 255 bytes, we limit it to be modulus 32 for SRTP.
static const size_t kMaxPaddingLength = 224;
static const int kSendSideDelayWindowMs = 1000;
-static const uint32_t kAbsSendTimeFraction = 18;
namespace {
@@ -49,17 +49,6 @@ const char* FrameTypeToString(FrameType frame_type) {
}
return "";
}
-
-// TODO(holmer): Merge this with the implementation in
-// remote_bitrate_estimator_abs_send_time.cc.
-uint32_t ConvertMsTo24Bits(int64_t time_ms) {
- uint32_t time_24_bits =
- static_cast<uint32_t>(
- ((static_cast<uint64_t>(time_ms) << kAbsSendTimeFraction) + 500) /
- 1000) &
- 0x00FFFFFF;
- return time_24_bits;
-}
} // namespace
RTPSender::BitrateAggregator::BitrateAggregator(
@@ -115,10 +104,6 @@ RTPSender::RTPSender(
SendSideDelayObserver* send_side_delay_observer,
RtcEventLog* event_log)
: clock_(clock),
- // TODO(holmer): Remove this conversion when we remove the use of
- // TickTime.
- clock_delta_ms_(clock_->TimeInMilliseconds() -
- TickTime::MillisecondTimestamp()),
random_(clock_->TimeInMicroseconds()),
bitrates_(bitrate_callback),
total_bitrate_sent_(clock, bitrates_.total_bitrate_observer()),
@@ -180,6 +165,8 @@ RTPSender::RTPSender(
// Random start, 16 bits. Can't be 0.
sequence_number_rtx_ = random_.Rand(1, kMaxInitRtpSeqNumber);
sequence_number_ = random_.Rand(1, kMaxInitRtpSeqNumber);
+ encoder_thread_.DetachFromThread();
+ network_thread_.DetachFromThread();
}
RTPSender::~RTPSender() {
@@ -187,6 +174,7 @@ RTPSender::~RTPSender() {
// deleted on the same thread. At the moment this isn't possible due to
// voe::ChannelOwner in voice engine. To reproduce, run:
// voe_auto_test --automated --gtest_filter=*MixManyChannelsForStressOpus
+ // RTC_DCHECK(configuration_thread_.CalledOnValidThread());
// TODO(tommi,holmer): We don't grab locks in the dtor before accessing member
// variables but we grab them in all other methods. (what's the design?)
@@ -270,7 +258,29 @@ int32_t RTPSender::SetTransportSequenceNumber(uint16_t sequence_number) {
int32_t RTPSender::RegisterRtpHeaderExtension(RTPExtensionType type,
uint8_t id) {
+ RTC_DCHECK(configuration_thread_.CalledOnValidThread());
rtc::CritScope lock(&send_critsect_);
+ // Register in rtp_manager_
+ switch (type) {
+ case kRtpExtensionNone:
+ RTC_NOTREACHED();
+ case kRtpExtensionVideoRotation:
+ rtp_manager_.Register<VideoOrientation>(id);
+ break;
+ case kRtpExtensionTransmissionTimeOffset:
+ rtp_manager_.Register<TransmissionOffset>(id);
+ break;
+ case kRtpExtensionAudioLevel:
+ rtp_manager_.Register<AudioLevel>(id);
+ break;
+ case kRtpExtensionAbsoluteSendTime:
+ rtp_manager_.Register<AbsoluteSendTime>(id);
+ break;
+ case kRtpExtensionTransportSequenceNumber:
+ rtp_manager_.Register<TransportSequenceNumber>(id);
+ break;
+ }
+ // Register in older rtp_extension_header_map_
if (type == kRtpExtensionVideoRotation) {
cvo_mode_ = kCVOInactive;
return rtp_header_extension_map_.RegisterInactive(type, id);
@@ -279,11 +289,13 @@ int32_t RTPSender::RegisterRtpHeaderExtension(RTPExtensionType type,
}
bool RTPSender::IsRtpHeaderExtensionRegistered(RTPExtensionType type) {
+ RTC_DCHECK(network_thread_.CalledOnValidThread());
rtc::CritScope lock(&send_critsect_);
return rtp_header_extension_map_.IsRegistered(type);
}
int32_t RTPSender::DeregisterRtpHeaderExtension(RTPExtensionType type) {
+ RTC_DCHECK(configuration_thread_.CalledOnValidThread());
rtc::CritScope lock(&send_critsect_);
return rtp_header_extension_map_.Deregister(type);
}
@@ -293,12 +305,41 @@ size_t RTPSender::RtpHeaderExtensionTotalLength() const {
return rtp_header_extension_map_.GetTotalLengthInBytes();
}
+std::unique_ptr<RtpPacketToSend> RTPSender::CreatePacket() const {
+ RtpPacketToSend* packet =
+ new RtpPacketToSend(&rtp_manager_, max_payload_length_);
+ packet->set_capture_time_ms(clock_->TimeInMilliseconds());
+ return std::unique_ptr<RtpPacketToSend>(packet);
+}
+
+void RTPSender::BuildRtpHeader(RtpPacketToSend* packet,
+ uint32_t capture_timestamp,
+ bool reserve_extensions) {
+ rtc::CritScope lock(&send_critsect_);
+
+ timestamp_ = start_timestamp_ + capture_timestamp;
+ last_timestamp_time_ms_ = clock_->TimeInMilliseconds();
+
+ packet->SetSsrc(ssrc_);
+ packet->SetSequenceNumber(sequence_number_++);
+ packet->SetTimestamp(timestamp_);
+ if (reserve_extensions) {
+ packet->SetCsrcs(csrcs_);
+ // If extension wasn't registered, it will not be reserved.
+ // Reserve only those extensions RTPSender set values itself.
+ packet->ReserveExtension<TransmissionOffset>();
+ packet->ReserveExtension<AbsoluteSendTime>();
+ packet->ReserveExtension<TransportSequenceNumber>();
+ }
+}
+
int32_t RTPSender::RegisterPayload(
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
int8_t payload_number,
uint32_t frequency,
size_t channels,
uint32_t rate) {
+ RTC_DCHECK(configuration_thread_.CalledOnValidThread());
RTC_DCHECK_LT(strlen(payload_name), RTP_PAYLOAD_NAME_SIZE);
rtc::CritScope lock(&send_critsect_);
@@ -490,6 +531,7 @@ int32_t RTPSender::SendOutgoingData(FrameType frame_type,
size_t payload_size,
const RTPFragmentationHeader* fragmentation,
const RTPVideoHeader* rtp_hdr) {
+ RTC_DCHECK(encoder_thread_.CalledOnValidThread());
uint32_t ssrc;
{
// Drop this packet if we're not sending media packets.
@@ -544,6 +586,7 @@ int32_t RTPSender::SendOutgoingData(FrameType frame_type,
}
size_t RTPSender::TrySendRedundantPayloads(size_t bytes_to_send) {
+ RTC_DCHECK(network_thread_.CalledOnValidThread());
{
rtc::CritScope lock(&send_critsect_);
if (!sending_media_)
@@ -552,21 +595,15 @@ size_t RTPSender::TrySendRedundantPayloads(size_t bytes_to_send) {
return 0;
}
- uint8_t buffer[IP_PACKET_SIZE];
int bytes_left = static_cast<int>(bytes_to_send);
while (bytes_left > 0) {
- size_t length = bytes_left;
- int64_t capture_time_ms;
- if (!packet_history_.GetBestFittingPacket(buffer, &length,
- &capture_time_ms)) {
+ auto packet = packet_history_.GetBestFittingPacket(bytes_left);
+ if (!packet) {
break;
}
- if (!PrepareAndSendPacket(buffer, length, capture_time_ms, true, false))
+ if (!PrepareAndSendPacket(packet, true, false))
break;
- RtpUtility::RtpHeaderParser rtp_parser(buffer, length);
- RTPHeader rtp_header;
- rtp_parser.Parse(&rtp_header);
- bytes_left -= static_cast<int>(length - rtp_header.headerLength);
+ bytes_left -= static_cast<int>(packet->payload_size());
}
return bytes_to_send - bytes_left;
}
@@ -574,6 +611,7 @@ size_t RTPSender::TrySendRedundantPayloads(size_t bytes_to_send) {
void RTPSender::BuildPaddingPacket(uint8_t* packet,
size_t header_length,
size_t padding_length) {
+ RTC_DCHECK(network_thread_.CalledOnValidThread());
packet[0] |= 0x20; // Set padding bit.
int32_t* data = reinterpret_cast<int32_t*>(&(packet[header_length]));
@@ -597,9 +635,9 @@ size_t RTPSender::SendPadData(size_t bytes,
size_t padding_bytes_in_packet =
std::min(MaxDataPayloadLength(), kMaxPaddingLength);
size_t bytes_sent = 0;
- bool using_transport_seq = rtp_header_extension_map_.IsRegistered(
- kRtpExtensionTransportSequenceNumber) &&
- transport_sequence_number_allocator_;
+ bool using_transport_seq =
+ transport_sequence_number_allocator_ &&
+ rtp_manager_.IsRegistered<TransportSequenceNumber>();
for (; bytes > 0; bytes -= padding_bytes_in_packet) {
if (bytes < padding_bytes_in_packet)
bytes = padding_bytes_in_packet;
@@ -651,109 +689,96 @@ size_t RTPSender::SendPadData(size_t bytes,
over_rtx = true;
}
}
+ RtpPacketToSend padding_packet(&rtp_manager_);
+ padding_packet.SetPayloadType(payload_type);
+ padding_packet.SetSsrc(ssrc);
+ padding_packet.SetTimestamp(timestamp);
+ padding_packet.SetSequenceNumber(sequence_number);
- uint8_t padding_packet[IP_PACKET_SIZE];
- size_t header_length =
- CreateRtpHeader(padding_packet, payload_type, ssrc, false, timestamp,
- sequence_number, std::vector<uint32_t>());
- BuildPaddingPacket(padding_packet, header_length, padding_bytes_in_packet);
- size_t length = padding_bytes_in_packet + header_length;
int64_t now_ms = clock_->TimeInMilliseconds();
-
- RtpUtility::RtpHeaderParser rtp_parser(padding_packet, length);
- RTPHeader rtp_header;
- rtp_parser.Parse(&rtp_header);
-
+ padding_packet.ReserveExtension<TransmissionOffset>();
if (capture_time_ms > 0) {
- UpdateTransmissionTimeOffset(
- padding_packet, length, rtp_header, now_ms - capture_time_ms);
- }
-
- UpdateAbsoluteSendTime(padding_packet, length, rtp_header, now_ms);
-
- PacketOptions options;
- if (using_transport_seq) {
- options.packet_id =
- UpdateTransportSequenceNumber(padding_packet, length, rtp_header);
- }
-
- if (using_transport_seq && transport_feedback_observer_) {
- transport_feedback_observer_->AddPacket(options.packet_id, length, true);
+ int64_t offset_rtp = (now_ms - capture_time_ms) * 90;
+ padding_packet.SetExtension<TransmissionOffset>(offset_rtp);
}
-
- if (!SendPacketToNetwork(padding_packet, length, options))
+ padding_packet.SetExtension<AbsoluteSendTime>(now_ms);
+ padding_packet.ReserveExtension<TransportSequenceNumber>();
+ padding_packet.SetPadding(padding_bytes_in_packet, &random_);
+ if (!SendPacketToNetwork(&padding_packet))
break;
bytes_sent += padding_bytes_in_packet;
- UpdateRtpStats(padding_packet, length, rtp_header, over_rtx, false);
+ UpdateRtpStats(padding_packet, over_rtx, false);
}
return bytes_sent;
}
-void RTPSender::SetStorePacketsStatus(bool enable, uint16_t number_to_store) {
- packet_history_.SetStorePacketsStatus(enable, number_to_store);
-}
-
-bool RTPSender::StorePackets() const {
- return packet_history_.StorePackets();
+void RTPSender::SetStorePacketsSize(uint16_t number_to_store) {
+ packet_history_.SetStoreSize(number_to_store);
}
int32_t RTPSender::ReSendPacket(uint16_t packet_id, int64_t min_resend_time) {
- size_t length = IP_PACKET_SIZE;
- uint8_t data_buffer[IP_PACKET_SIZE];
- int64_t capture_time_ms;
-
- if (!packet_history_.GetPacketAndSetSendTime(packet_id, min_resend_time, true,
- data_buffer, &length,
- &capture_time_ms)) {
- // Packet not found.
+ RTC_DCHECK(network_thread_.CalledOnValidThread());
+ RtpPacketToSend* packet =
+ packet_history_.GetPacket(packet_id, min_resend_time, true);
+ if (!packet)
return 0;
- }
if (paced_sender_) {
- RtpUtility::RtpHeaderParser rtp_parser(data_buffer, length);
- RTPHeader header;
- if (!rtp_parser.Parse(&header)) {
- assert(false);
- return -1;
- }
- // Convert from TickTime to Clock since capture_time_ms is based on
- // TickTime.
- int64_t corrected_capture_tims_ms = capture_time_ms + clock_delta_ms_;
- paced_sender_->InsertPacket(
- RtpPacketSender::kNormalPriority, header.ssrc, header.sequenceNumber,
- corrected_capture_tims_ms, length - header.headerLength, true);
+ paced_sender_->InsertPacket(RtpPacketSender::kNormalPriority,
+ packet->Ssrc(), packet->SequenceNumber(),
+ packet->capture_time_ms(),
+ packet->payload_size(), true);
- return length;
+ return packet->size();
}
int rtx = kRtxOff;
{
rtc::CritScope lock(&send_critsect_);
rtx = rtx_;
}
- if (!PrepareAndSendPacket(data_buffer, length, capture_time_ms,
- (rtx & kRtxRetransmitted) > 0, true)) {
+ if (!PrepareAndSendPacket(packet, (rtx & kRtxRetransmitted) > 0, true)) {
return -1;
}
- return static_cast<int32_t>(length);
+ return static_cast<int32_t>(packet->size());
}
-bool RTPSender::SendPacketToNetwork(const uint8_t* packet,
- size_t size,
- const PacketOptions& options) {
+bool RTPSender::SendPacketToNetwork(RtpPacketToSend* packet) {
+ RTC_DCHECK(network_thread_.CalledOnValidThread());
+ {
+ rtc::CritScope lock(&send_critsect_);
+ last_packet_marker_bit_ = packet->Marker();
+ last_capture_time_ms_sent_ = packet->capture_time_ms();
+ }
+
+ PacketOptions options;
+
+ bool using_transport_seq =
+ transport_sequence_number_allocator_ &&
+ rtp_manager_.IsRegistered<TransportSequenceNumber>();
+ if (using_transport_seq) {
+ options.packet_id = UpdateTransportSequenceNumber(packet);
+
+ if (transport_feedback_observer_) {
+ transport_feedback_observer_->AddPacket(options.packet_id, packet->size(),
+ true);
+ }
+ }
+
int bytes_sent = -1;
if (transport_) {
- bytes_sent = transport_->SendRtp(packet, size, options)
- ? static_cast<int>(size)
- : -1;
+ if (transport_->SendRtp(packet->data(), packet->size(), options)) {
+ bytes_sent = static_cast<int>(packet->size());
+ }
if (event_log_ && bytes_sent > 0) {
- event_log_->LogRtpHeader(kOutgoingPacket, MediaType::ANY, packet, size);
+ event_log_->LogRtpHeader(kOutgoingPacket, MediaType::ANY, packet->data(),
+ packet->size());
}
}
TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
- "RTPSender::SendPacketToNetwork", "size", size, "sent",
- bytes_sent);
+ "RTPSender::SendPacketToNetwork", "size", packet->size(),
+ "sent", bytes_sent);
// TODO(pwestin): Add a separate bitrate for sent bitrate after pacer.
if (bytes_sent <= 0) {
LOG(LS_WARNING) << "Transport failed to send packet";
@@ -870,16 +895,9 @@ void RTPSender::UpdateNACKBitRate(uint32_t bytes, int64_t now) {
bool RTPSender::TimeToSendPacket(uint16_t sequence_number,
int64_t capture_time_ms,
bool retransmission) {
- size_t length = IP_PACKET_SIZE;
- uint8_t data_buffer[IP_PACKET_SIZE];
- int64_t stored_time_ms;
-
- if (!packet_history_.GetPacketAndSetSendTime(sequence_number,
- 0,
- retransmission,
- data_buffer,
- &length,
- &stored_time_ms)) {
+ RTC_DCHECK(network_thread_.CalledOnValidThread());
+ auto packet = packet_history_.GetPacket(sequence_number, 0, retransmission);
+ if (!packet) {
// Packet cannot be found. Allow sending to continue.
return true;
}
@@ -891,72 +909,54 @@ bool RTPSender::TimeToSendPacket(uint16_t sequence_number,
rtc::CritScope lock(&send_critsect_);
rtx = rtx_;
}
- return PrepareAndSendPacket(data_buffer,
- length,
- capture_time_ms,
- retransmission && (rtx & kRtxRetransmitted) > 0,
- retransmission);
+ return PrepareAndSendPacket(
+ packet, retransmission && (rtx & kRtxRetransmitted) > 0, retransmission);
}
-bool RTPSender::PrepareAndSendPacket(uint8_t* buffer,
- size_t length,
- int64_t capture_time_ms,
+bool RTPSender::PrepareAndSendPacket(RtpPacketToSend* packet,
bool send_over_rtx,
bool is_retransmit) {
- uint8_t* buffer_to_send_ptr = buffer;
+ RtpPacketToSend* packet_to_send = packet;
- RtpUtility::RtpHeaderParser rtp_parser(buffer, length);
- RTPHeader rtp_header;
- rtp_parser.Parse(&rtp_header);
- if (!is_retransmit && rtp_header.markerBit) {
+ if (!is_retransmit && packet->Marker()) {
TRACE_EVENT_ASYNC_END0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "PacedSend",
- capture_time_ms);
+ packet->capture_time_ms());
}
- TRACE_EVENT_INSTANT2(
- TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "PrepareAndSendPacket",
- "timestamp", rtp_header.timestamp, "seqnum", rtp_header.sequenceNumber);
+ TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
+ "PrepareAndSendPacket", "timestamp", packet->Timestamp(),
+ "seqnum", packet->SequenceNumber());
- uint8_t data_buffer_rtx[IP_PACKET_SIZE];
+ std::unique_ptr<RtpPacketToSend> packet_rtx;
if (send_over_rtx) {
- BuildRtxPacket(buffer, &length, data_buffer_rtx);
- buffer_to_send_ptr = data_buffer_rtx;
+ packet_rtx = BuildRtxPacket(*packet);
+ packet_to_send = packet_rtx.get();
}
int64_t now_ms = clock_->TimeInMilliseconds();
- int64_t diff_ms = now_ms - capture_time_ms;
- UpdateTransmissionTimeOffset(buffer_to_send_ptr, length, rtp_header,
- diff_ms);
- UpdateAbsoluteSendTime(buffer_to_send_ptr, length, rtp_header, now_ms);
-
- // TODO(sprang): Potentially too much overhead in IsRegistered()?
- bool using_transport_seq = rtp_header_extension_map_.IsRegistered(
- kRtpExtensionTransportSequenceNumber) &&
- transport_sequence_number_allocator_;
-
- PacketOptions options;
- if (using_transport_seq) {
- options.packet_id =
- UpdateTransportSequenceNumber(buffer_to_send_ptr, length, rtp_header);
- }
+ int64_t diff_rtp = (now_ms - packet->capture_time_ms()) * 90;
+ packet_to_send->SetExtension<TransmissionOffset>(diff_rtp);
+ packet_to_send->SetExtension<AbsoluteSendTime>(now_ms);
- if (using_transport_seq && transport_feedback_observer_) {
- transport_feedback_observer_->AddPacket(options.packet_id, length, true);
- }
-
- bool ret = SendPacketToNetwork(buffer_to_send_ptr, length, options);
+ bool ret = SendPacketToNetwork(packet_to_send);
+ // Update original packet even in case of retransmit.
+ packet->set_send_time_ms(clock_->TimeInMilliseconds());
if (ret) {
rtc::CritScope lock(&send_critsect_);
media_has_been_sent_ = true;
}
- UpdateRtpStats(buffer_to_send_ptr, length, rtp_header, send_over_rtx,
- is_retransmit);
+ UpdateRtpStats(*packet_to_send, send_over_rtx, is_retransmit);
return ret;
}
-void RTPSender::UpdateRtpStats(const uint8_t* buffer,
- size_t packet_length,
- const RTPHeader& header,
+void CountPacket(RtpPacketCounter* counter, const RtpPacketToSend& packet) {
+ ++counter->packets;
+ counter->header_bytes += packet.headers_size();
+ counter->padding_bytes += packet.padding_size();
+ counter->payload_bytes += packet.payload_size();
+}
+
+void RTPSender::UpdateRtpStats(const RtpPacketToSend& packet,
bool is_rtx,
bool is_retransmit) {
StreamDataCounters* counters;
@@ -970,26 +970,25 @@ void RTPSender::UpdateRtpStats(const uint8_t* buffer,
counters = &rtp_stats_;
}
- total_bitrate_sent_.Update(packet_length);
+ total_bitrate_sent_.Update(packet.size());
if (counters->first_packet_time_ms == -1) {
counters->first_packet_time_ms = clock_->TimeInMilliseconds();
}
- if (IsFecPacket(buffer, header)) {
- counters->fec.AddPacket(packet_length, header);
+ if (IsFecPacket(packet)) {
+ CountPacket(&counters->fec, packet);
}
if (is_retransmit) {
- counters->retransmitted.AddPacket(packet_length, header);
+ CountPacket(&counters->retransmitted, packet);
}
- counters->transmitted.AddPacket(packet_length, header);
+ CountPacket(&counters->transmitted, packet);
if (rtp_stats_callback_) {
rtp_stats_callback_->DataCountersUpdated(*counters, ssrc);
}
}
-bool RTPSender::IsFecPacket(const uint8_t* buffer,
- const RTPHeader& header) const {
+bool RTPSender::IsFecPacket(const RtpPacketToSend& packet) const {
if (!video_) {
return false;
}
@@ -997,9 +996,8 @@ bool RTPSender::IsFecPacket(const uint8_t* buffer,
uint8_t pt_red;
uint8_t pt_fec;
video_->GenericFECStatus(&fec_enabled, &pt_red, &pt_fec);
- return fec_enabled &&
- header.payloadType == pt_red &&
- buffer[header.headerLength] == pt_fec;
+ return fec_enabled && packet.PayloadType() == pt_red &&
+ packet.payload()[0] == pt_fec;
}
size_t RTPSender::TimeToSendPadding(size_t bytes) {
@@ -1007,22 +1005,19 @@ size_t RTPSender::TimeToSendPadding(size_t bytes) {
return 0;
size_t bytes_sent = TrySendRedundantPayloads(bytes);
if (bytes_sent < bytes)
- bytes_sent += SendPadData(bytes - bytes_sent, false, 0, 0);
+ bytes_sent +=
+ SendPadData(bytes - bytes_sent, false, 0, last_capture_time_ms_sent_);
return bytes_sent;
}
-// TODO(pwestin): send in the RtpHeaderParser to avoid parsing it again.
-int32_t RTPSender::SendToNetwork(uint8_t* buffer,
+int32_t RTPSender::SendToNetwork(std::unique_ptr<RtpPacketToSend> packet_ptr,
size_t payload_length,
- size_t rtp_header_length,
int64_t capture_time_ms,
StorageType storage,
RtpPacketSender::Priority priority) {
- size_t length = payload_length + rtp_header_length;
- RtpUtility::RtpHeaderParser rtp_parser(buffer, length);
-
- RTPHeader rtp_header;
- rtp_parser.Parse(&rtp_header);
+ RTC_DCHECK(packet_ptr);
+ // Real payload_length might be less than PayloadSize() because of RED/FEC.
+ RTC_DCHECK_GE(packet_ptr->payload_size(), payload_length);
int64_t now_ms = clock_->TimeInMilliseconds();
@@ -1030,31 +1025,25 @@ int32_t RTPSender::SendToNetwork(uint8_t* buffer,
// TODO(holmer): This should be changed all over Video Engine so that negative
// time is consider invalid, while 0 is considered a valid time.
if (capture_time_ms > 0) {
- UpdateTransmissionTimeOffset(buffer, length, rtp_header,
- now_ms - capture_time_ms);
+ uint32_t rtp_offset = (now_ms - capture_time_ms) * 90;
+ packet_ptr->SetExtension<TransmissionOffset>(rtp_offset);
}
- UpdateAbsoluteSendTime(buffer, length, rtp_header, now_ms);
+ packet_ptr->SetExtension<AbsoluteSendTime>(now_ms);
+ packet_ptr->set_capture_time_ms(capture_time_ms);
// Used for NACK and to spread out the transmission of packets.
- if (packet_history_.PutRTPPacket(buffer, length, capture_time_ms, storage) !=
- 0) {
- return -1;
- }
+ RtpPacketToSend* packet = packet_history_.PutRtpPacket(&packet_ptr, storage);
if (paced_sender_) {
- // Correct offset between implementations of millisecond time stamps in
- // TickTime and Clock.
- int64_t corrected_time_ms = capture_time_ms + clock_delta_ms_;
- paced_sender_->InsertPacket(priority, rtp_header.ssrc,
- rtp_header.sequenceNumber, corrected_time_ms,
+ paced_sender_->InsertPacket(priority, packet->Ssrc(),
+ packet->SequenceNumber(), capture_time_ms,
payload_length, false);
- if (last_capture_time_ms_sent_ == 0 ||
- corrected_time_ms > last_capture_time_ms_sent_) {
- last_capture_time_ms_sent_ = corrected_time_ms;
+ if (capture_time_ms > last_capture_time_ms_sent_) {
+ last_capture_time_ms_sent_ = capture_time_ms;
TRACE_EVENT_ASYNC_BEGIN1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
- "PacedSend", corrected_time_ms,
- "capture_time_ms", corrected_time_ms);
+ "PacedSend", capture_time_ms, "capture_time_ms",
+ capture_time_ms);
}
return 0;
}
@@ -1062,26 +1051,11 @@ int32_t RTPSender::SendToNetwork(uint8_t* buffer,
UpdateDelayStatistics(capture_time_ms, now_ms);
}
- // TODO(sprang): Potentially too much overhead in IsRegistered()?
- bool using_transport_seq = rtp_header_extension_map_.IsRegistered(
- kRtpExtensionTransportSequenceNumber) &&
- transport_sequence_number_allocator_;
-
- PacketOptions options;
- if (using_transport_seq) {
- options.packet_id =
- UpdateTransportSequenceNumber(buffer, length, rtp_header);
- if (transport_feedback_observer_) {
- transport_feedback_observer_->AddPacket(options.packet_id, length, true);
- }
- }
-
- bool sent = SendPacketToNetwork(buffer, length, options);
-
+ bool sent = SendPacketToNetwork(packet);
// Mark the packet as sent in the history even if send failed. Dropping a
// packet here should be treated as any other packet drop so we should be
// ready for a retransmission.
- packet_history_.SetSent(rtp_header.sequenceNumber);
+ packet->set_send_time_ms(clock_->TimeInMilliseconds());
if (!sent)
return -1;
@@ -1090,7 +1064,7 @@ int32_t RTPSender::SendToNetwork(uint8_t* buffer,
rtc::CritScope lock(&send_critsect_);
media_has_been_sent_ = true;
}
- UpdateRtpStats(buffer, length, rtp_header, false, false);
+ UpdateRtpStats(*packet, false, false);
return 0;
}
@@ -1583,56 +1557,12 @@ bool RTPSender::UpdateVideoRotation(uint8_t* rtp_packet,
return true;
}
-void RTPSender::UpdateAbsoluteSendTime(uint8_t* rtp_packet,
- size_t rtp_packet_length,
- const RTPHeader& rtp_header,
- int64_t now_ms) const {
- size_t offset;
- rtc::CritScope lock(&send_critsect_);
-
- switch (VerifyExtension(kRtpExtensionAbsoluteSendTime, rtp_packet,
- rtp_packet_length, rtp_header,
- kAbsoluteSendTimeLength, &offset)) {
- case ExtensionStatus::kNotRegistered:
- return;
- case ExtensionStatus::kError:
- LOG(LS_WARNING) << "Failed to update absolute send time";
- return;
- case ExtensionStatus::kOk:
- break;
- default:
- RTC_NOTREACHED();
- }
-
- // Update absolute send time field (convert ms to 24-bit unsigned with 18 bit
- // fractional part).
- ByteWriter<uint32_t, 3>::WriteBigEndian(rtp_packet + offset + 1,
- ConvertMsTo24Bits(now_ms));
-}
-
uint16_t RTPSender::UpdateTransportSequenceNumber(
- uint8_t* rtp_packet,
- size_t rtp_packet_length,
- const RTPHeader& rtp_header) const {
- size_t offset;
+ RtpPacketToSend* packet) const {
rtc::CritScope lock(&send_critsect_);
- switch (VerifyExtension(kRtpExtensionTransportSequenceNumber, rtp_packet,
- rtp_packet_length, rtp_header,
- kTransportSequenceNumberLength, &offset)) {
- case ExtensionStatus::kNotRegistered:
- return 0;
- case ExtensionStatus::kError:
- LOG(LS_WARNING) << "Failed to update transport sequence number";
- return 0;
- case ExtensionStatus::kOk:
- break;
- default:
- RTC_NOTREACHED();
- }
-
uint16_t seq = transport_sequence_number_allocator_->AllocateSequenceNumber();
- BuildTransportSequenceNumberExtension(rtp_packet + offset, seq);
+ RTC_CHECK(packet->SetExtension<TransportSequenceNumber>(seq));
return seq;
}
@@ -1808,49 +1738,35 @@ int32_t RTPSender::SetFecParameters(
return 0;
}
-void RTPSender::BuildRtxPacket(uint8_t* buffer, size_t* length,
- uint8_t* buffer_rtx) {
- rtc::CritScope lock(&send_critsect_);
- uint8_t* data_buffer_rtx = buffer_rtx;
- // Add RTX header.
- RtpUtility::RtpHeaderParser rtp_parser(
- reinterpret_cast<const uint8_t*>(buffer), *length);
-
- RTPHeader rtp_header;
- rtp_parser.Parse(&rtp_header);
-
- // Add original RTP header.
- memcpy(data_buffer_rtx, buffer, rtp_header.headerLength);
-
- // Replace payload type, if a specific type is set for RTX.
- auto kv = rtx_payload_type_map_.find(rtp_header.payloadType);
- // Use rtx mapping associated with media codec if we can't find one, assuming
- // it's red.
- // TODO(holmer): Remove once old Chrome versions don't rely on this.
- if (kv == rtx_payload_type_map_.end())
- kv = rtx_payload_type_map_.find(payload_type_);
- if (kv != rtx_payload_type_map_.end())
- data_buffer_rtx[1] = kv->second;
- if (rtp_header.markerBit)
- data_buffer_rtx[1] |= kRtpMarkerBitMask;
-
- // Replace sequence number.
- uint8_t* ptr = data_buffer_rtx + 2;
- ByteWriter<uint16_t>::WriteBigEndian(ptr, sequence_number_rtx_++);
-
- // Replace SSRC.
- ptr += 6;
- ByteWriter<uint32_t>::WriteBigEndian(ptr, ssrc_rtx_);
+std::unique_ptr<RtpPacketToSend> RTPSender::BuildRtxPacket(
+ const RtpPacketToSend& packet) {
+ std::unique_ptr<RtpPacketToSend> packet_rtx = CreatePacket();
+ // Copy original RTP header.
+ packet_rtx->CopyHeader(packet);
+ {
+ rtc::CritScope lock(&send_critsect_);
+ // Replace payload type, if a specific type is set for RTX.
+ auto kv = rtx_payload_type_map_.find(packet.PayloadType());
+ // Use rtx mapping associated with media codec if we can't find one,
+ // assuming
+ // it's red.
+ // TODO(holmer): Remove once old Chrome versions don't rely on this.
+ if (kv == rtx_payload_type_map_.end())
+ kv = rtx_payload_type_map_.find(payload_type_);
+ if (kv != rtx_payload_type_map_.end())
+ packet_rtx->SetPayloadType(kv->second);
+
+ // Replace sequence number.
+ packet_rtx->SetSequenceNumber(sequence_number_rtx_++);
+ packet_rtx->SetSsrc(ssrc_rtx_);
+ }
+ uint8_t* data = packet_rtx->AllocatePayload(packet.payload_size() + 2);
// Add OSN (original sequence number).
- ptr = data_buffer_rtx + rtp_header.headerLength;
- ByteWriter<uint16_t>::WriteBigEndian(ptr, rtp_header.sequenceNumber);
- ptr += 2;
-
+ ByteWriter<uint16_t>::WriteBigEndian(data, packet.SequenceNumber());
// Add original payload data.
- memcpy(ptr, buffer + rtp_header.headerLength,
- *length - rtp_header.headerLength);
- *length += 2;
+ memcpy(&data[2], packet.payload(), packet.payload_size());
+ return packet_rtx;
}
void RTPSender::RegisterRtpStatisticsCallback(
« no previous file with comments | « webrtc/modules/rtp_rtcp/source/rtp_sender.h ('k') | webrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698