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

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: 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..c0dbd03954e3672dd038982937042ba163bf9c96 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"
@@ -523,10 +524,13 @@ 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);
+ playout_delay_oracle_.Update(ssrc, rtp_hdr->min_playout_delay_ms,
+ rtp_hdr->max_playout_delay_ms,
+ sequence_number_);
danilchap 2016/05/24 13:28:24 sequence_number_ here is 16 bit, i.e. wrapped, but
sprang_webrtc 2016/05/24 14:46:08 Or use SequenceNumberUnwrapper from module_common_
Irfan 2016/05/25 09:32:53 good catch. done.
+
+ 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 +825,12 @@ void RTPSender::OnReceivedNACK(const std::list<uint16_t>& nack_sequence_numbers,
}
}
+void RTPSender::OnReceivedRtcpReceiverReport(
+ const ReportBlockList& report_blocks) {
+ rtc::CritScope lock(&send_critsect_);
+ playout_delay_oracle_.OnReceivedRtcpReceiverReport(report_blocks);
+}
+
bool RTPSender::ProcessNACKBitRate(uint32_t now) {
uint32_t num = 0;
size_t byte_count = 0;
@@ -1034,6 +1044,12 @@ int32_t RTPSender::SendToNetwork(uint8_t* buffer,
UpdateAbsoluteSendTime(buffer, length, rtp_header, now_ms);
+ if (playout_delay_oracle_.ShouldIncludePlayoutDelayExtension(rtp_header.ssrc))
+ UpdatePlayoutDelayLimits(
+ buffer, length, rtp_header,
+ playout_delay_oracle_.MinPlayoutDelayMs(rtp_header.ssrc),
+ playout_delay_oracle_.MaxPlayoutDelayMs(rtp_header.ssrc));
+
// Used for NACK and to spread out the transmission of packets.
if (packet_history_.PutRTPPacket(buffer, length, capture_time_ms, storage) !=
0) {
@@ -1191,7 +1207,7 @@ size_t RTPSender::CreateRtpHeader(uint8_t* header,
}
uint16_t len =
- BuildRTPHeaderExtension(header + rtp_header_length, marker_bit);
+ BuildRTPHeaderExtension(ssrc, header + rtp_header_length, marker_bit);
if (len > 0) {
header[0] |= 0x10; // Set extension bit.
rtp_header_length += len;
@@ -1225,7 +1241,8 @@ int32_t RTPSender::BuildRTPheader(uint8_t* data_buffer,
timestamp_, sequence_number, csrcs_);
}
-uint16_t RTPSender::BuildRTPHeaderExtension(uint8_t* data_buffer,
+uint16_t RTPSender::BuildRTPHeaderExtension(uint32_t ssrc,
+ uint8_t* data_buffer,
bool marker_bit) const {
if (rtp_header_extension_map_.Size() <= 0) {
return 0;
@@ -1270,6 +1287,13 @@ uint16_t RTPSender::BuildRTPHeaderExtension(uint8_t* data_buffer,
block_length = BuildTransportSequenceNumberExtension(
extension_data, transport_sequence_number_);
break;
+ case kRtpExtensionPlayoutDelay:
+ if (playout_delay_oracle_.ShouldIncludePlayoutDelayExtension(ssrc)) {
+ block_length = BuildPlayoutDelayExtension(
+ extension_data, playout_delay_oracle_.MinPlayoutDelayMs(ssrc),
+ playout_delay_oracle_.MaxPlayoutDelayMs(ssrc));
+ }
+ break;
default:
assert(false);
}
@@ -1445,6 +1469,36 @@ 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);
+ // 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,
@@ -1638,6 +1692,34 @@ bool RTPSender::UpdateTransportSequenceNumber(
return true;
}
+void RTPSender::UpdatePlayoutDelayLimits(uint8_t* rtp_packet,
+ size_t rtp_packet_length,
+ const RTPHeader& rtp_header,
+ uint16_t min_playout_delay_ms,
+ uint16_t max_playout_delay_ms) const {
+ size_t offset;
+ rtc::CritScope lock(&send_critsect_);
+
+ switch (VerifyExtension(kRtpExtensionPlayoutDelay, rtp_packet,
+ rtp_packet_length, rtp_header, kPlayoutDelayLength,
+ &offset)) {
+ case ExtensionStatus::kNotRegistered:
+ return;
+ case ExtensionStatus::kError:
+ LOG(LS_WARNING) << "Failed to update playout delay limits";
+ return;
+ case ExtensionStatus::kOk:
+ break;
+ default:
+ RTC_NOTREACHED();
+ }
+
+ int length = BuildPlayoutDelayExtension(
+ rtp_packet + offset, min_playout_delay_ms, max_playout_delay_ms);
+ RTC_DCHECK(length == kPlayoutDelayLength);
danilchap 2016/05/24 13:28:24 RTC_DCHECK_EQ
Irfan 2016/05/25 09:32:53 replaced with assert
danilchap 2016/05/25 19:08:48 Acknowledged.
+ return;
+}
+
bool RTPSender::AllocateTransportSequenceNumber(int* packet_id) const {
if (!transport_sequence_number_allocator_)
return false;

Powered by Google App Engine
This is Rietveld 408576698