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

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

Issue 2007743003: Add sender controlled playout delay limits (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@cleanup_rtp_hdr_extensions
Patch Set: Add unit tests, fix test issues, address comments Created 4 years, 7 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
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 cda776bf22b2cdcef3510233fe94acda11286aa4..9635e92bb85061b00a6f23d97b3a83240e915d27 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
@@ -22,6 +22,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/playout_delay_oracle.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"
@@ -288,7 +289,7 @@ int32_t RTPSender::DeregisterRtpHeaderExtension(RTPExtensionType type) {
return rtp_header_extension_map_.Deregister(type);
}
-size_t RTPSender::RtpHeaderExtensionTotalLength() const {
+size_t RTPSender::RtpHeaderExtensionMaxLength() const {
rtc::CritScope lock(&send_critsect_);
return rtp_header_extension_map_.GetTotalLengthInBytes();
}
@@ -386,11 +387,11 @@ size_t RTPSender::MaxDataPayloadLength() const {
rtx = rtx_;
}
if (audio_configured_) {
- return max_payload_length_ - RTPHeaderLength();
+ return max_payload_length_ - RtpHeaderMaxLength();
} else {
- return max_payload_length_ - RTPHeaderLength() // RTP overhead.
- - video_->FECPacketOverhead() // FEC/ULP/RED overhead.
- - ((rtx) ? 2 : 0); // RTX overhead.
+ return max_payload_length_ - RtpHeaderMaxLength() // RTP overhead.
+ - video_->FECPacketOverhead() // FEC/ULP/RED overhead.
+ - ((rtx) ? 2 : 0); // RTX overhead.
}
}
@@ -491,10 +492,12 @@ int32_t RTPSender::SendOutgoingData(FrameType frame_type,
const RTPFragmentationHeader* fragmentation,
const RTPVideoHeader* rtp_hdr) {
uint32_t ssrc;
+ uint16_t sequence_number;
{
// Drop this packet if we're not sending media packets.
rtc::CritScope lock(&send_critsect_);
ssrc = ssrc_;
+ sequence_number = sequence_number_;
if (!sending_media_) {
return 0;
}
@@ -523,10 +526,14 @@ int32_t RTPSender::SendOutgoingData(FrameType frame_type,
if (frame_type == kEmptyFrame)
return 0;
- ret_val =
- video_->SendVideo(video_type, frame_type, payload_type,
- capture_timestamp, capture_time_ms, payload_data,
- payload_size, fragmentation, rtp_hdr);
+ if (rtp_hdr) {
+ playout_delay_oracle_.UpdateRequest(ssrc, rtp_hdr->playout_delay,
+ sequence_number);
+ }
+
+ ret_val = video_->SendVideo(
+ video_type, frame_type, payload_type, capture_timestamp,
+ capture_time_ms, payload_data, payload_size, fragmentation, rtp_hdr);
}
rtc::CritScope cs(&statistics_crit_);
@@ -821,6 +828,11 @@ void RTPSender::OnReceivedNACK(const std::list<uint16_t>& nack_sequence_numbers,
}
}
+void RTPSender::OnReceivedRtcpReceiverReport(
+ const ReportBlockList& report_blocks) {
+ playout_delay_oracle_.OnReceivedRtcpReceiverReport(report_blocks);
+}
+
bool RTPSender::ProcessNACKBitRate(uint32_t now) {
uint32_t num = 0;
size_t byte_count = 0;
@@ -1139,11 +1151,19 @@ void RTPSender::ProcessBitrate() {
video_->ProcessBitrate();
}
-size_t RTPSender::RTPHeaderLength() const {
+size_t RTPSender::RtpHeaderCurrentLength() const {
rtc::CritScope lock(&send_critsect_);
size_t rtp_header_length = kRtpHeaderLength;
rtp_header_length += sizeof(uint32_t) * csrcs_.size();
- rtp_header_length += RtpHeaderExtensionTotalLength();
+ rtp_header_length += RtpHeaderExtensionCurrentLength();
+ return rtp_header_length;
+}
+
+size_t RTPSender::RtpHeaderMaxLength() const {
+ rtc::CritScope lock(&send_critsect_);
+ size_t rtp_header_length = kRtpHeaderLength;
+ rtp_header_length += sizeof(uint32_t) * csrcs_.size();
+ rtp_header_length += RtpHeaderExtensionMaxLength();
return rtp_header_length;
}
@@ -1270,6 +1290,13 @@ uint16_t RTPSender::BuildRTPHeaderExtension(uint8_t* data_buffer,
block_length = BuildTransportSequenceNumberExtension(
extension_data, transport_sequence_number_);
break;
+ case kRtpExtensionPlayoutDelay:
+ if (playout_delay_oracle_.send_playout_delay()) {
+ block_length = BuildPlayoutDelayExtension(
+ extension_data, playout_delay_oracle_.min_playout_delay_ms(),
+ playout_delay_oracle_.max_playout_delay_ms());
+ }
+ break;
default:
assert(false);
}
@@ -1294,6 +1321,69 @@ uint16_t RTPSender::BuildRTPHeaderExtension(uint8_t* data_buffer,
return kHeaderLength + total_block_length;
}
+size_t RTPSender::RtpHeaderExtensionCurrentLength() const {
danilchap 2016/06/02 12:12:34 this function sums size of all extensions, includi
Irfan 2016/06/02 18:15:53 I did not realize TotalLength was already taking i
+ if (rtp_header_extension_map_.Size() <= 0)
+ return 0;
+
+ int header_length = 0;
+ uint8_t id;
+
+ RTPExtensionType type = rtp_header_extension_map_.First();
+ while (type != kRtpExtensionNone) {
+ switch (type) {
+ case kRtpExtensionTransmissionTimeOffset:
+ if (rtp_header_extension_map_.GetId(kRtpExtensionTransmissionTimeOffset,
Stefan 2016/06/02 08:07:09 Would have been nice with a method which simply ch
danilchap 2016/06/02 12:12:34 rtp_header_extension_map_ has method IsRegistered
Irfan 2016/06/02 18:15:53 This is now removed in favour of just treating pla
+ &id) == 0) {
+ header_length += kTransmissionTimeOffsetLength;
+ }
+ break;
+ case kRtpExtensionAudioLevel:
+ if (rtp_header_extension_map_.GetId(kRtpExtensionAudioLevel, &id) ==
+ 0) {
+ header_length += kAudioLevelLength;
+ }
+ break;
+ case kRtpExtensionAbsoluteSendTime:
+ if (rtp_header_extension_map_.GetId(kRtpExtensionAbsoluteSendTime,
+ &id) == 0) {
+ header_length += kAbsoluteSendTimeLength;
+ }
+ break;
+ case kRtpExtensionVideoRotation:
+ if (rtp_header_extension_map_.GetId(kRtpExtensionVideoRotation, &id) ==
danilchap 2016/06/02 12:12:34 this means video rotation extension would be count
Irfan 2016/06/02 18:15:53 see above
+ 0) {
+ header_length += kVideoRotationLength;
+ }
+ break;
+ case kRtpExtensionTransportSequenceNumber:
+ if (rtp_header_extension_map_.GetId(
+ kRtpExtensionTransportSequenceNumber, &id) == 0) {
+ header_length += kTransportSequenceNumberLength;
+ }
+ break;
+ case kRtpExtensionPlayoutDelay:
+ if (playout_delay_oracle_.send_playout_delay()) {
+ if (rtp_header_extension_map_.GetId(kRtpExtensionPlayoutDelay, &id) ==
+ 0) {
+ header_length += kPlayoutDelayLength;
+ }
+ }
+ break;
+ default:
danilchap 2016/06/02 12:12:34 do not use default, this way compiler would warn w
Irfan 2016/06/02 18:15:52 removed
+ assert(false);
+ }
+ type = rtp_header_extension_map_.Next(type);
+ }
+ if (header_length == 0)
+ return 0;
+ // Add padding to fill a 32 bit block.
+ size_t padding_bytes = RtpUtility::Word32Align(header_length) - header_length;
danilchap 2016/06/02 12:12:34 this three lines could be replaced with header_len
Irfan 2016/06/02 18:15:53 removed
+ if (padding_bytes > 0)
+ header_length += padding_bytes;
+
+ return header_length + kRtpOneByteHeaderLength;
+}
+
uint8_t RTPSender::BuildTransmissionTimeOffsetExtension(
uint8_t* data_buffer) const {
// From RFC 5450: Transmission Time Offsets in RTP Streams.
@@ -1445,6 +1535,37 @@ uint8_t RTPSender::BuildTransportSequenceNumberExtension(
return kTransportSequenceNumberLength;
}
+uint8_t RTPSender::BuildPlayoutDelayExtension(
+ uint8_t* data_buffer,
+ uint16_t min_playout_delay_ms,
+ uint16_t max_playout_delay_ms) const {
+ RTC_DCHECK_LE(min_playout_delay_ms, kPlayoutDelayMaxMs);
+ RTC_DCHECK_LE(max_playout_delay_ms, kPlayoutDelayMaxMs);
+ RTC_DCHECK_LE(min_playout_delay_ms, max_playout_delay_ms);
+ // 0 1 2 3
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | ID | len=2 | MIN delay | MAX delay |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ uint8_t id;
+ if (rtp_header_extension_map_.GetId(kRtpExtensionPlayoutDelay, &id) != 0) {
+ // Not registered.
+ return 0;
+ }
+ size_t pos = 0;
+ const uint8_t len = 2;
+ // Convert MS to value to be sent on extension header.
+ uint16_t min_playout = min_playout_delay_ms / kPlayoutDelayGranularityMs;
+ uint16_t max_playout = max_playout_delay_ms / kPlayoutDelayGranularityMs;
+
+ data_buffer[pos++] = (id << 4) + len;
+ data_buffer[pos++] = min_playout >> 4;
+ data_buffer[pos++] = ((min_playout & 0xf) << 4) | (max_playout >> 8);
+ data_buffer[pos++] = max_playout & 0xff;
+ assert(pos == kPlayoutDelayLength);
+ return kPlayoutDelayLength;
+}
+
bool RTPSender::FindHeaderExtensionPosition(RTPExtensionType type,
const uint8_t* rtp_packet,
size_t rtp_packet_length,

Powered by Google App Engine
This is Rietveld 408576698