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

Side by Side 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/modules/rtp_rtcp/source/rtp_sender.h" 11 #include "webrtc/modules/rtp_rtcp/source/rtp_sender.h"
12 12
13 #include <stdlib.h> // srand 13 #include <stdlib.h> // srand
14 #include <algorithm> 14 #include <algorithm>
15 #include <utility> 15 #include <utility>
16 16
17 #include "webrtc/base/checks.h" 17 #include "webrtc/base/checks.h"
18 #include "webrtc/base/logging.h" 18 #include "webrtc/base/logging.h"
19 #include "webrtc/base/trace_event.h" 19 #include "webrtc/base/trace_event.h"
20 #include "webrtc/base/timeutils.h" 20 #include "webrtc/base/timeutils.h"
21 #include "webrtc/call.h" 21 #include "webrtc/call.h"
22 #include "webrtc/call/rtc_event_log.h" 22 #include "webrtc/call/rtc_event_log.h"
23 #include "webrtc/modules/rtp_rtcp/include/rtp_cvo.h" 23 #include "webrtc/modules/rtp_rtcp/include/rtp_cvo.h"
24 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" 24 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
25 #include "webrtc/modules/rtp_rtcp/source/playout_delay_oracle.h"
25 #include "webrtc/modules/rtp_rtcp/source/rtp_sender_audio.h" 26 #include "webrtc/modules/rtp_rtcp/source/rtp_sender_audio.h"
26 #include "webrtc/modules/rtp_rtcp/source/rtp_sender_video.h" 27 #include "webrtc/modules/rtp_rtcp/source/rtp_sender_video.h"
27 #include "webrtc/modules/rtp_rtcp/source/time_util.h" 28 #include "webrtc/modules/rtp_rtcp/source/time_util.h"
28 29
29 namespace webrtc { 30 namespace webrtc {
30 31
31 // Max in the RFC 3550 is 255 bytes, we limit it to be modulus 32 for SRTP. 32 // Max in the RFC 3550 is 255 bytes, we limit it to be modulus 32 for SRTP.
32 static const size_t kMaxPaddingLength = 224; 33 static const size_t kMaxPaddingLength = 224;
33 static const int kSendSideDelayWindowMs = 1000; 34 static const int kSendSideDelayWindowMs = 1000;
34 static const uint32_t kAbsSendTimeFraction = 18; 35 static const uint32_t kAbsSendTimeFraction = 18;
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 ret_val = audio_->SendAudio(frame_type, payload_type, capture_timestamp, 517 ret_val = audio_->SendAudio(frame_type, payload_type, capture_timestamp,
517 payload_data, payload_size, fragmentation); 518 payload_data, payload_size, fragmentation);
518 } else { 519 } else {
519 TRACE_EVENT_ASYNC_STEP1("webrtc", "Video", capture_time_ms, 520 TRACE_EVENT_ASYNC_STEP1("webrtc", "Video", capture_time_ms,
520 "Send", "type", FrameTypeToString(frame_type)); 521 "Send", "type", FrameTypeToString(frame_type));
521 assert(frame_type != kAudioFrameSpeech && frame_type != kAudioFrameCN); 522 assert(frame_type != kAudioFrameSpeech && frame_type != kAudioFrameCN);
522 523
523 if (frame_type == kEmptyFrame) 524 if (frame_type == kEmptyFrame)
524 return 0; 525 return 0;
525 526
526 ret_val = 527 playout_delay_oracle_.Update(ssrc, rtp_hdr->min_playout_delay_ms,
527 video_->SendVideo(video_type, frame_type, payload_type, 528 rtp_hdr->max_playout_delay_ms,
528 capture_timestamp, capture_time_ms, payload_data, 529 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.
529 payload_size, fragmentation, rtp_hdr); 530
531 ret_val = video_->SendVideo(
532 video_type, frame_type, payload_type, capture_timestamp,
533 capture_time_ms, payload_data, payload_size, fragmentation, rtp_hdr);
530 } 534 }
531 535
532 rtc::CritScope cs(&statistics_crit_); 536 rtc::CritScope cs(&statistics_crit_);
533 // Note: This is currently only counting for video. 537 // Note: This is currently only counting for video.
534 if (frame_type == kVideoFrameKey) { 538 if (frame_type == kVideoFrameKey) {
535 ++frame_counts_.key_frames; 539 ++frame_counts_.key_frames;
536 } else if (frame_type == kVideoFrameDelta) { 540 } else if (frame_type == kVideoFrameDelta) {
537 ++frame_counts_.delta_frames; 541 ++frame_counts_.delta_frames;
538 } 542 }
539 if (frame_count_observer_) { 543 if (frame_count_observer_) {
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
814 if (bytes_re_sent > target_bytes) { 818 if (bytes_re_sent > target_bytes) {
815 break; // Ignore the rest of the packets in the list. 819 break; // Ignore the rest of the packets in the list.
816 } 820 }
817 } 821 }
818 } 822 }
819 if (bytes_re_sent > 0) { 823 if (bytes_re_sent > 0) {
820 UpdateNACKBitRate(bytes_re_sent, now); 824 UpdateNACKBitRate(bytes_re_sent, now);
821 } 825 }
822 } 826 }
823 827
828 void RTPSender::OnReceivedRtcpReceiverReport(
829 const ReportBlockList& report_blocks) {
830 rtc::CritScope lock(&send_critsect_);
831 playout_delay_oracle_.OnReceivedRtcpReceiverReport(report_blocks);
832 }
833
824 bool RTPSender::ProcessNACKBitRate(uint32_t now) { 834 bool RTPSender::ProcessNACKBitRate(uint32_t now) {
825 uint32_t num = 0; 835 uint32_t num = 0;
826 size_t byte_count = 0; 836 size_t byte_count = 0;
827 const uint32_t kAvgIntervalMs = 1000; 837 const uint32_t kAvgIntervalMs = 1000;
828 uint32_t target_bitrate = GetTargetBitrate(); 838 uint32_t target_bitrate = GetTargetBitrate();
829 839
830 rtc::CritScope lock(&send_critsect_); 840 rtc::CritScope lock(&send_critsect_);
831 841
832 if (target_bitrate == 0) { 842 if (target_bitrate == 0) {
833 return true; 843 return true;
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 // |capture_time_ms| <= 0 is considered invalid. 1037 // |capture_time_ms| <= 0 is considered invalid.
1028 // TODO(holmer): This should be changed all over Video Engine so that negative 1038 // TODO(holmer): This should be changed all over Video Engine so that negative
1029 // time is consider invalid, while 0 is considered a valid time. 1039 // time is consider invalid, while 0 is considered a valid time.
1030 if (capture_time_ms > 0) { 1040 if (capture_time_ms > 0) {
1031 UpdateTransmissionTimeOffset(buffer, length, rtp_header, 1041 UpdateTransmissionTimeOffset(buffer, length, rtp_header,
1032 now_ms - capture_time_ms); 1042 now_ms - capture_time_ms);
1033 } 1043 }
1034 1044
1035 UpdateAbsoluteSendTime(buffer, length, rtp_header, now_ms); 1045 UpdateAbsoluteSendTime(buffer, length, rtp_header, now_ms);
1036 1046
1047 if (playout_delay_oracle_.ShouldIncludePlayoutDelayExtension(rtp_header.ssrc))
1048 UpdatePlayoutDelayLimits(
1049 buffer, length, rtp_header,
1050 playout_delay_oracle_.MinPlayoutDelayMs(rtp_header.ssrc),
1051 playout_delay_oracle_.MaxPlayoutDelayMs(rtp_header.ssrc));
1052
1037 // Used for NACK and to spread out the transmission of packets. 1053 // Used for NACK and to spread out the transmission of packets.
1038 if (packet_history_.PutRTPPacket(buffer, length, capture_time_ms, storage) != 1054 if (packet_history_.PutRTPPacket(buffer, length, capture_time_ms, storage) !=
1039 0) { 1055 0) {
1040 return -1; 1056 return -1;
1041 } 1057 }
1042 1058
1043 if (paced_sender_) { 1059 if (paced_sender_) {
1044 // Correct offset between implementations of millisecond time stamps in 1060 // Correct offset between implementations of millisecond time stamps in
1045 // TickTime and Clock. 1061 // TickTime and Clock.
1046 int64_t corrected_time_ms = capture_time_ms + clock_delta_ms_; 1062 int64_t corrected_time_ms = capture_time_ms + clock_delta_ms_;
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 ByteWriter<uint32_t>::WriteBigEndian(ptr, csrcs[i]); 1200 ByteWriter<uint32_t>::WriteBigEndian(ptr, csrcs[i]);
1185 ptr += 4; 1201 ptr += 4;
1186 } 1202 }
1187 header[0] = (header[0] & 0xf0) | csrcs.size(); 1203 header[0] = (header[0] & 0xf0) | csrcs.size();
1188 1204
1189 // Update length of header. 1205 // Update length of header.
1190 rtp_header_length += sizeof(uint32_t) * csrcs.size(); 1206 rtp_header_length += sizeof(uint32_t) * csrcs.size();
1191 } 1207 }
1192 1208
1193 uint16_t len = 1209 uint16_t len =
1194 BuildRTPHeaderExtension(header + rtp_header_length, marker_bit); 1210 BuildRTPHeaderExtension(ssrc, header + rtp_header_length, marker_bit);
1195 if (len > 0) { 1211 if (len > 0) {
1196 header[0] |= 0x10; // Set extension bit. 1212 header[0] |= 0x10; // Set extension bit.
1197 rtp_header_length += len; 1213 rtp_header_length += len;
1198 } 1214 }
1199 return rtp_header_length; 1215 return rtp_header_length;
1200 } 1216 }
1201 1217
1202 int32_t RTPSender::BuildRTPheader(uint8_t* data_buffer, 1218 int32_t RTPSender::BuildRTPheader(uint8_t* data_buffer,
1203 int8_t payload_type, 1219 int8_t payload_type,
1204 bool marker_bit, 1220 bool marker_bit,
(...skipping 13 matching lines...) Expand all
1218 timestamp_++; 1234 timestamp_++;
1219 } 1235 }
1220 last_timestamp_time_ms_ = clock_->TimeInMilliseconds(); 1236 last_timestamp_time_ms_ = clock_->TimeInMilliseconds();
1221 uint32_t sequence_number = sequence_number_++; 1237 uint32_t sequence_number = sequence_number_++;
1222 capture_time_ms_ = capture_time_ms; 1238 capture_time_ms_ = capture_time_ms;
1223 last_packet_marker_bit_ = marker_bit; 1239 last_packet_marker_bit_ = marker_bit;
1224 return CreateRtpHeader(data_buffer, payload_type, ssrc_, marker_bit, 1240 return CreateRtpHeader(data_buffer, payload_type, ssrc_, marker_bit,
1225 timestamp_, sequence_number, csrcs_); 1241 timestamp_, sequence_number, csrcs_);
1226 } 1242 }
1227 1243
1228 uint16_t RTPSender::BuildRTPHeaderExtension(uint8_t* data_buffer, 1244 uint16_t RTPSender::BuildRTPHeaderExtension(uint32_t ssrc,
1245 uint8_t* data_buffer,
1229 bool marker_bit) const { 1246 bool marker_bit) const {
1230 if (rtp_header_extension_map_.Size() <= 0) { 1247 if (rtp_header_extension_map_.Size() <= 0) {
1231 return 0; 1248 return 0;
1232 } 1249 }
1233 // RTP header extension, RFC 3550. 1250 // RTP header extension, RFC 3550.
1234 // 0 1 2 3 1251 // 0 1 2 3
1235 // 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 1252 // 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
1236 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1253 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1237 // | defined by profile | length | 1254 // | defined by profile | length |
1238 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1255 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
(...skipping 24 matching lines...) Expand all
1263 case kRtpExtensionAbsoluteSendTime: 1280 case kRtpExtensionAbsoluteSendTime:
1264 block_length = BuildAbsoluteSendTimeExtension(extension_data); 1281 block_length = BuildAbsoluteSendTimeExtension(extension_data);
1265 break; 1282 break;
1266 case kRtpExtensionVideoRotation: 1283 case kRtpExtensionVideoRotation:
1267 block_length = BuildVideoRotationExtension(extension_data); 1284 block_length = BuildVideoRotationExtension(extension_data);
1268 break; 1285 break;
1269 case kRtpExtensionTransportSequenceNumber: 1286 case kRtpExtensionTransportSequenceNumber:
1270 block_length = BuildTransportSequenceNumberExtension( 1287 block_length = BuildTransportSequenceNumberExtension(
1271 extension_data, transport_sequence_number_); 1288 extension_data, transport_sequence_number_);
1272 break; 1289 break;
1290 case kRtpExtensionPlayoutDelay:
1291 if (playout_delay_oracle_.ShouldIncludePlayoutDelayExtension(ssrc)) {
1292 block_length = BuildPlayoutDelayExtension(
1293 extension_data, playout_delay_oracle_.MinPlayoutDelayMs(ssrc),
1294 playout_delay_oracle_.MaxPlayoutDelayMs(ssrc));
1295 }
1296 break;
1273 default: 1297 default:
1274 assert(false); 1298 assert(false);
1275 } 1299 }
1276 total_block_length += block_length; 1300 total_block_length += block_length;
1277 type = rtp_header_extension_map_.Next(type); 1301 type = rtp_header_extension_map_.Next(type);
1278 } 1302 }
1279 if (total_block_length == 0) { 1303 if (total_block_length == 0) {
1280 // No extension added. 1304 // No extension added.
1281 return 0; 1305 return 0;
1282 } 1306 }
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1438 } 1462 }
1439 size_t pos = 0; 1463 size_t pos = 0;
1440 const uint8_t len = 1; 1464 const uint8_t len = 1;
1441 data_buffer[pos++] = (id << 4) + len; 1465 data_buffer[pos++] = (id << 4) + len;
1442 ByteWriter<uint16_t>::WriteBigEndian(data_buffer + pos, sequence_number); 1466 ByteWriter<uint16_t>::WriteBigEndian(data_buffer + pos, sequence_number);
1443 pos += 2; 1467 pos += 2;
1444 assert(pos == kTransportSequenceNumberLength); 1468 assert(pos == kTransportSequenceNumberLength);
1445 return kTransportSequenceNumberLength; 1469 return kTransportSequenceNumberLength;
1446 } 1470 }
1447 1471
1472 uint8_t RTPSender::BuildPlayoutDelayExtension(
1473 uint8_t* data_buffer,
1474 uint16_t min_playout_delay_ms,
1475 uint16_t max_playout_delay_ms) const {
1476 RTC_DCHECK_LE(min_playout_delay_ms, kPlayoutDelayMaxMs);
1477 RTC_DCHECK_LE(max_playout_delay_ms, kPlayoutDelayMaxMs);
1478 // 0 1 2 3
1479 // 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
1480 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1481 // | ID | len=2 | MIN delay | MAX delay |
1482 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1483 uint8_t id;
1484 if (rtp_header_extension_map_.GetId(kRtpExtensionPlayoutDelay, &id) != 0) {
1485 // Not registered.
1486 return 0;
1487 }
1488 size_t pos = 0;
1489 const uint8_t len = 2;
1490 // Convert MS to value to be sent on extension header.
1491 uint16_t min_playout = min_playout_delay_ms / kPlayoutDelayGranularityMs;
1492 uint16_t max_playout = max_playout_delay_ms / kPlayoutDelayGranularityMs;
1493
1494 data_buffer[pos++] = (id << 4) + len;
1495 data_buffer[pos++] = min_playout >> 4;
1496 data_buffer[pos++] = ((min_playout & 0xf) << 4) | (max_playout >> 8);
1497 data_buffer[pos++] = max_playout & 0xff;
1498 assert(pos == kPlayoutDelayLength);
1499 return kPlayoutDelayLength;
1500 }
1501
1448 bool RTPSender::FindHeaderExtensionPosition(RTPExtensionType type, 1502 bool RTPSender::FindHeaderExtensionPosition(RTPExtensionType type,
1449 const uint8_t* rtp_packet, 1503 const uint8_t* rtp_packet,
1450 size_t rtp_packet_length, 1504 size_t rtp_packet_length,
1451 const RTPHeader& rtp_header, 1505 const RTPHeader& rtp_header,
1452 size_t* position) const { 1506 size_t* position) const {
1453 // Get length until start of header extension block. 1507 // Get length until start of header extension block.
1454 int extension_block_pos = 1508 int extension_block_pos =
1455 rtp_header_extension_map_.GetLengthUntilBlockStartInBytes(type); 1509 rtp_header_extension_map_.GetLengthUntilBlockStartInBytes(type);
1456 if (extension_block_pos < 0) { 1510 if (extension_block_pos < 0) {
1457 LOG(LS_WARNING) << "Failed to find extension position for " << type 1511 LOG(LS_WARNING) << "Failed to find extension position for " << type
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
1631 case ExtensionStatus::kOk: 1685 case ExtensionStatus::kOk:
1632 break; 1686 break;
1633 default: 1687 default:
1634 RTC_NOTREACHED(); 1688 RTC_NOTREACHED();
1635 } 1689 }
1636 1690
1637 BuildTransportSequenceNumberExtension(rtp_packet + offset, sequence_number); 1691 BuildTransportSequenceNumberExtension(rtp_packet + offset, sequence_number);
1638 return true; 1692 return true;
1639 } 1693 }
1640 1694
1695 void RTPSender::UpdatePlayoutDelayLimits(uint8_t* rtp_packet,
1696 size_t rtp_packet_length,
1697 const RTPHeader& rtp_header,
1698 uint16_t min_playout_delay_ms,
1699 uint16_t max_playout_delay_ms) const {
1700 size_t offset;
1701 rtc::CritScope lock(&send_critsect_);
1702
1703 switch (VerifyExtension(kRtpExtensionPlayoutDelay, rtp_packet,
1704 rtp_packet_length, rtp_header, kPlayoutDelayLength,
1705 &offset)) {
1706 case ExtensionStatus::kNotRegistered:
1707 return;
1708 case ExtensionStatus::kError:
1709 LOG(LS_WARNING) << "Failed to update playout delay limits";
1710 return;
1711 case ExtensionStatus::kOk:
1712 break;
1713 default:
1714 RTC_NOTREACHED();
1715 }
1716
1717 int length = BuildPlayoutDelayExtension(
1718 rtp_packet + offset, min_playout_delay_ms, max_playout_delay_ms);
1719 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.
1720 return;
1721 }
1722
1641 bool RTPSender::AllocateTransportSequenceNumber(int* packet_id) const { 1723 bool RTPSender::AllocateTransportSequenceNumber(int* packet_id) const {
1642 if (!transport_sequence_number_allocator_) 1724 if (!transport_sequence_number_allocator_)
1643 return false; 1725 return false;
1644 1726
1645 *packet_id = transport_sequence_number_allocator_->AllocateSequenceNumber(); 1727 *packet_id = transport_sequence_number_allocator_->AllocateSequenceNumber();
1646 return true; 1728 return true;
1647 } 1729 }
1648 1730
1649 void RTPSender::SetSendingStatus(bool enabled) { 1731 void RTPSender::SetSendingStatus(bool enabled) {
1650 if (enabled) { 1732 if (enabled) {
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
1911 rtc::CritScope lock(&send_critsect_); 1993 rtc::CritScope lock(&send_critsect_);
1912 1994
1913 RtpState state; 1995 RtpState state;
1914 state.sequence_number = sequence_number_rtx_; 1996 state.sequence_number = sequence_number_rtx_;
1915 state.start_timestamp = start_timestamp_; 1997 state.start_timestamp = start_timestamp_;
1916 1998
1917 return state; 1999 return state;
1918 } 2000 }
1919 2001
1920 } // namespace webrtc 2002 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698