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

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: Add unit tests, fix test issues, address comments Created 4 years, 6 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 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 bool RTPSender::IsRtpHeaderExtensionRegistered(RTPExtensionType type) { 282 bool RTPSender::IsRtpHeaderExtensionRegistered(RTPExtensionType type) {
282 rtc::CritScope lock(&send_critsect_); 283 rtc::CritScope lock(&send_critsect_);
283 return rtp_header_extension_map_.IsRegistered(type); 284 return rtp_header_extension_map_.IsRegistered(type);
284 } 285 }
285 286
286 int32_t RTPSender::DeregisterRtpHeaderExtension(RTPExtensionType type) { 287 int32_t RTPSender::DeregisterRtpHeaderExtension(RTPExtensionType type) {
287 rtc::CritScope lock(&send_critsect_); 288 rtc::CritScope lock(&send_critsect_);
288 return rtp_header_extension_map_.Deregister(type); 289 return rtp_header_extension_map_.Deregister(type);
289 } 290 }
290 291
291 size_t RTPSender::RtpHeaderExtensionTotalLength() const { 292 size_t RTPSender::RtpHeaderExtensionMaxLength() const {
292 rtc::CritScope lock(&send_critsect_); 293 rtc::CritScope lock(&send_critsect_);
293 return rtp_header_extension_map_.GetTotalLengthInBytes(); 294 return rtp_header_extension_map_.GetTotalLengthInBytes();
294 } 295 }
295 296
296 int32_t RTPSender::RegisterPayload( 297 int32_t RTPSender::RegisterPayload(
297 const char payload_name[RTP_PAYLOAD_NAME_SIZE], 298 const char payload_name[RTP_PAYLOAD_NAME_SIZE],
298 int8_t payload_number, 299 int8_t payload_number,
299 uint32_t frequency, 300 uint32_t frequency,
300 size_t channels, 301 size_t channels,
301 uint32_t rate) { 302 uint32_t rate) {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 max_payload_length_ = max_payload_length; 380 max_payload_length_ = max_payload_length;
380 } 381 }
381 382
382 size_t RTPSender::MaxDataPayloadLength() const { 383 size_t RTPSender::MaxDataPayloadLength() const {
383 int rtx; 384 int rtx;
384 { 385 {
385 rtc::CritScope lock(&send_critsect_); 386 rtc::CritScope lock(&send_critsect_);
386 rtx = rtx_; 387 rtx = rtx_;
387 } 388 }
388 if (audio_configured_) { 389 if (audio_configured_) {
389 return max_payload_length_ - RTPHeaderLength(); 390 return max_payload_length_ - RtpHeaderMaxLength();
390 } else { 391 } else {
391 return max_payload_length_ - RTPHeaderLength() // RTP overhead. 392 return max_payload_length_ - RtpHeaderMaxLength() // RTP overhead.
392 - video_->FECPacketOverhead() // FEC/ULP/RED overhead. 393 - video_->FECPacketOverhead() // FEC/ULP/RED overhead.
393 - ((rtx) ? 2 : 0); // RTX overhead. 394 - ((rtx) ? 2 : 0); // RTX overhead.
394 } 395 }
395 } 396 }
396 397
397 size_t RTPSender::MaxPayloadLength() const { 398 size_t RTPSender::MaxPayloadLength() const {
398 return max_payload_length_; 399 return max_payload_length_;
399 } 400 }
400 401
401 void RTPSender::SetRtxStatus(int mode) { 402 void RTPSender::SetRtxStatus(int mode) {
402 rtc::CritScope lock(&send_critsect_); 403 rtc::CritScope lock(&send_critsect_);
403 rtx_ = mode; 404 rtx_ = mode;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 485
485 int32_t RTPSender::SendOutgoingData(FrameType frame_type, 486 int32_t RTPSender::SendOutgoingData(FrameType frame_type,
486 int8_t payload_type, 487 int8_t payload_type,
487 uint32_t capture_timestamp, 488 uint32_t capture_timestamp,
488 int64_t capture_time_ms, 489 int64_t capture_time_ms,
489 const uint8_t* payload_data, 490 const uint8_t* payload_data,
490 size_t payload_size, 491 size_t payload_size,
491 const RTPFragmentationHeader* fragmentation, 492 const RTPFragmentationHeader* fragmentation,
492 const RTPVideoHeader* rtp_hdr) { 493 const RTPVideoHeader* rtp_hdr) {
493 uint32_t ssrc; 494 uint32_t ssrc;
495 uint16_t sequence_number;
494 { 496 {
495 // Drop this packet if we're not sending media packets. 497 // Drop this packet if we're not sending media packets.
496 rtc::CritScope lock(&send_critsect_); 498 rtc::CritScope lock(&send_critsect_);
497 ssrc = ssrc_; 499 ssrc = ssrc_;
500 sequence_number = sequence_number_;
498 if (!sending_media_) { 501 if (!sending_media_) {
499 return 0; 502 return 0;
500 } 503 }
501 } 504 }
502 RtpVideoCodecTypes video_type = kRtpVideoGeneric; 505 RtpVideoCodecTypes video_type = kRtpVideoGeneric;
503 if (CheckPayloadType(payload_type, &video_type) != 0) { 506 if (CheckPayloadType(payload_type, &video_type) != 0) {
504 LOG(LS_ERROR) << "Don't send data with unknown payload type: " 507 LOG(LS_ERROR) << "Don't send data with unknown payload type: "
505 << static_cast<int>(payload_type) << "."; 508 << static_cast<int>(payload_type) << ".";
506 return -1; 509 return -1;
507 } 510 }
508 511
509 int32_t ret_val; 512 int32_t ret_val;
510 if (audio_configured_) { 513 if (audio_configured_) {
511 TRACE_EVENT_ASYNC_STEP1("webrtc", "Audio", capture_timestamp, 514 TRACE_EVENT_ASYNC_STEP1("webrtc", "Audio", capture_timestamp,
512 "Send", "type", FrameTypeToString(frame_type)); 515 "Send", "type", FrameTypeToString(frame_type));
513 assert(frame_type == kAudioFrameSpeech || frame_type == kAudioFrameCN || 516 assert(frame_type == kAudioFrameSpeech || frame_type == kAudioFrameCN ||
514 frame_type == kEmptyFrame); 517 frame_type == kEmptyFrame);
515 518
516 ret_val = audio_->SendAudio(frame_type, payload_type, capture_timestamp, 519 ret_val = audio_->SendAudio(frame_type, payload_type, capture_timestamp,
517 payload_data, payload_size, fragmentation); 520 payload_data, payload_size, fragmentation);
518 } else { 521 } else {
519 TRACE_EVENT_ASYNC_STEP1("webrtc", "Video", capture_time_ms, 522 TRACE_EVENT_ASYNC_STEP1("webrtc", "Video", capture_time_ms,
520 "Send", "type", FrameTypeToString(frame_type)); 523 "Send", "type", FrameTypeToString(frame_type));
521 assert(frame_type != kAudioFrameSpeech && frame_type != kAudioFrameCN); 524 assert(frame_type != kAudioFrameSpeech && frame_type != kAudioFrameCN);
522 525
523 if (frame_type == kEmptyFrame) 526 if (frame_type == kEmptyFrame)
524 return 0; 527 return 0;
525 528
526 ret_val = 529 if (rtp_hdr) {
527 video_->SendVideo(video_type, frame_type, payload_type, 530 playout_delay_oracle_.UpdateRequest(ssrc, rtp_hdr->playout_delay,
528 capture_timestamp, capture_time_ms, payload_data, 531 sequence_number);
529 payload_size, fragmentation, rtp_hdr); 532 }
533
534 ret_val = video_->SendVideo(
535 video_type, frame_type, payload_type, capture_timestamp,
536 capture_time_ms, payload_data, payload_size, fragmentation, rtp_hdr);
530 } 537 }
531 538
532 rtc::CritScope cs(&statistics_crit_); 539 rtc::CritScope cs(&statistics_crit_);
533 // Note: This is currently only counting for video. 540 // Note: This is currently only counting for video.
534 if (frame_type == kVideoFrameKey) { 541 if (frame_type == kVideoFrameKey) {
535 ++frame_counts_.key_frames; 542 ++frame_counts_.key_frames;
536 } else if (frame_type == kVideoFrameDelta) { 543 } else if (frame_type == kVideoFrameDelta) {
537 ++frame_counts_.delta_frames; 544 ++frame_counts_.delta_frames;
538 } 545 }
539 if (frame_count_observer_) { 546 if (frame_count_observer_) {
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
814 if (bytes_re_sent > target_bytes) { 821 if (bytes_re_sent > target_bytes) {
815 break; // Ignore the rest of the packets in the list. 822 break; // Ignore the rest of the packets in the list.
816 } 823 }
817 } 824 }
818 } 825 }
819 if (bytes_re_sent > 0) { 826 if (bytes_re_sent > 0) {
820 UpdateNACKBitRate(bytes_re_sent, now); 827 UpdateNACKBitRate(bytes_re_sent, now);
821 } 828 }
822 } 829 }
823 830
831 void RTPSender::OnReceivedRtcpReceiverReport(
832 const ReportBlockList& report_blocks) {
833 playout_delay_oracle_.OnReceivedRtcpReceiverReport(report_blocks);
834 }
835
824 bool RTPSender::ProcessNACKBitRate(uint32_t now) { 836 bool RTPSender::ProcessNACKBitRate(uint32_t now) {
825 uint32_t num = 0; 837 uint32_t num = 0;
826 size_t byte_count = 0; 838 size_t byte_count = 0;
827 const uint32_t kAvgIntervalMs = 1000; 839 const uint32_t kAvgIntervalMs = 1000;
828 uint32_t target_bitrate = GetTargetBitrate(); 840 uint32_t target_bitrate = GetTargetBitrate();
829 841
830 rtc::CritScope lock(&send_critsect_); 842 rtc::CritScope lock(&send_critsect_);
831 843
832 if (target_bitrate == 0) { 844 if (target_bitrate == 0) {
833 return true; 845 return true;
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
1132 void RTPSender::ProcessBitrate() { 1144 void RTPSender::ProcessBitrate() {
1133 rtc::CritScope lock(&send_critsect_); 1145 rtc::CritScope lock(&send_critsect_);
1134 total_bitrate_sent_.Process(); 1146 total_bitrate_sent_.Process();
1135 nack_bitrate_.Process(); 1147 nack_bitrate_.Process();
1136 if (audio_configured_) { 1148 if (audio_configured_) {
1137 return; 1149 return;
1138 } 1150 }
1139 video_->ProcessBitrate(); 1151 video_->ProcessBitrate();
1140 } 1152 }
1141 1153
1142 size_t RTPSender::RTPHeaderLength() const { 1154 size_t RTPSender::RtpHeaderCurrentLength() const {
1143 rtc::CritScope lock(&send_critsect_); 1155 rtc::CritScope lock(&send_critsect_);
1144 size_t rtp_header_length = kRtpHeaderLength; 1156 size_t rtp_header_length = kRtpHeaderLength;
1145 rtp_header_length += sizeof(uint32_t) * csrcs_.size(); 1157 rtp_header_length += sizeof(uint32_t) * csrcs_.size();
1146 rtp_header_length += RtpHeaderExtensionTotalLength(); 1158 rtp_header_length += RtpHeaderExtensionCurrentLength();
1147 return rtp_header_length; 1159 return rtp_header_length;
1148 } 1160 }
1149 1161
1162 size_t RTPSender::RtpHeaderMaxLength() const {
1163 rtc::CritScope lock(&send_critsect_);
1164 size_t rtp_header_length = kRtpHeaderLength;
1165 rtp_header_length += sizeof(uint32_t) * csrcs_.size();
1166 rtp_header_length += RtpHeaderExtensionMaxLength();
1167 return rtp_header_length;
1168 }
1169
1150 uint16_t RTPSender::AllocateSequenceNumber(uint16_t packets_to_send) { 1170 uint16_t RTPSender::AllocateSequenceNumber(uint16_t packets_to_send) {
1151 rtc::CritScope lock(&send_critsect_); 1171 rtc::CritScope lock(&send_critsect_);
1152 uint16_t first_allocated_sequence_number = sequence_number_; 1172 uint16_t first_allocated_sequence_number = sequence_number_;
1153 sequence_number_ += packets_to_send; 1173 sequence_number_ += packets_to_send;
1154 return first_allocated_sequence_number; 1174 return first_allocated_sequence_number;
1155 } 1175 }
1156 1176
1157 void RTPSender::GetDataCounters(StreamDataCounters* rtp_stats, 1177 void RTPSender::GetDataCounters(StreamDataCounters* rtp_stats,
1158 StreamDataCounters* rtx_stats) const { 1178 StreamDataCounters* rtx_stats) const {
1159 rtc::CritScope lock(&statistics_crit_); 1179 rtc::CritScope lock(&statistics_crit_);
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1263 case kRtpExtensionAbsoluteSendTime: 1283 case kRtpExtensionAbsoluteSendTime:
1264 block_length = BuildAbsoluteSendTimeExtension(extension_data); 1284 block_length = BuildAbsoluteSendTimeExtension(extension_data);
1265 break; 1285 break;
1266 case kRtpExtensionVideoRotation: 1286 case kRtpExtensionVideoRotation:
1267 block_length = BuildVideoRotationExtension(extension_data); 1287 block_length = BuildVideoRotationExtension(extension_data);
1268 break; 1288 break;
1269 case kRtpExtensionTransportSequenceNumber: 1289 case kRtpExtensionTransportSequenceNumber:
1270 block_length = BuildTransportSequenceNumberExtension( 1290 block_length = BuildTransportSequenceNumberExtension(
1271 extension_data, transport_sequence_number_); 1291 extension_data, transport_sequence_number_);
1272 break; 1292 break;
1293 case kRtpExtensionPlayoutDelay:
1294 if (playout_delay_oracle_.send_playout_delay()) {
1295 block_length = BuildPlayoutDelayExtension(
1296 extension_data, playout_delay_oracle_.min_playout_delay_ms(),
1297 playout_delay_oracle_.max_playout_delay_ms());
1298 }
1299 break;
1273 default: 1300 default:
1274 assert(false); 1301 assert(false);
1275 } 1302 }
1276 total_block_length += block_length; 1303 total_block_length += block_length;
1277 type = rtp_header_extension_map_.Next(type); 1304 type = rtp_header_extension_map_.Next(type);
1278 } 1305 }
1279 if (total_block_length == 0) { 1306 if (total_block_length == 0) {
1280 // No extension added. 1307 // No extension added.
1281 return 0; 1308 return 0;
1282 } 1309 }
1283 // Add padding elements until we've filled a 32 bit block. 1310 // Add padding elements until we've filled a 32 bit block.
1284 size_t padding_bytes = 1311 size_t padding_bytes =
1285 RtpUtility::Word32Align(total_block_length) - total_block_length; 1312 RtpUtility::Word32Align(total_block_length) - total_block_length;
1286 if (padding_bytes > 0) { 1313 if (padding_bytes > 0) {
1287 memset(&data_buffer[kHeaderLength + total_block_length], 0, padding_bytes); 1314 memset(&data_buffer[kHeaderLength + total_block_length], 0, padding_bytes);
1288 total_block_length += padding_bytes; 1315 total_block_length += padding_bytes;
1289 } 1316 }
1290 // Set header length (in number of Word32, header excluded). 1317 // Set header length (in number of Word32, header excluded).
1291 ByteWriter<uint16_t>::WriteBigEndian(data_buffer + kPosLength, 1318 ByteWriter<uint16_t>::WriteBigEndian(data_buffer + kPosLength,
1292 total_block_length / 4); 1319 total_block_length / 4);
1293 // Total added length. 1320 // Total added length.
1294 return kHeaderLength + total_block_length; 1321 return kHeaderLength + total_block_length;
1295 } 1322 }
1296 1323
1324 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
1325 if (rtp_header_extension_map_.Size() <= 0)
1326 return 0;
1327
1328 int header_length = 0;
1329 uint8_t id;
1330
1331 RTPExtensionType type = rtp_header_extension_map_.First();
1332 while (type != kRtpExtensionNone) {
1333 switch (type) {
1334 case kRtpExtensionTransmissionTimeOffset:
1335 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
1336 &id) == 0) {
1337 header_length += kTransmissionTimeOffsetLength;
1338 }
1339 break;
1340 case kRtpExtensionAudioLevel:
1341 if (rtp_header_extension_map_.GetId(kRtpExtensionAudioLevel, &id) ==
1342 0) {
1343 header_length += kAudioLevelLength;
1344 }
1345 break;
1346 case kRtpExtensionAbsoluteSendTime:
1347 if (rtp_header_extension_map_.GetId(kRtpExtensionAbsoluteSendTime,
1348 &id) == 0) {
1349 header_length += kAbsoluteSendTimeLength;
1350 }
1351 break;
1352 case kRtpExtensionVideoRotation:
1353 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
1354 0) {
1355 header_length += kVideoRotationLength;
1356 }
1357 break;
1358 case kRtpExtensionTransportSequenceNumber:
1359 if (rtp_header_extension_map_.GetId(
1360 kRtpExtensionTransportSequenceNumber, &id) == 0) {
1361 header_length += kTransportSequenceNumberLength;
1362 }
1363 break;
1364 case kRtpExtensionPlayoutDelay:
1365 if (playout_delay_oracle_.send_playout_delay()) {
1366 if (rtp_header_extension_map_.GetId(kRtpExtensionPlayoutDelay, &id) ==
1367 0) {
1368 header_length += kPlayoutDelayLength;
1369 }
1370 }
1371 break;
1372 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
1373 assert(false);
1374 }
1375 type = rtp_header_extension_map_.Next(type);
1376 }
1377 if (header_length == 0)
1378 return 0;
1379 // Add padding to fill a 32 bit block.
1380 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
1381 if (padding_bytes > 0)
1382 header_length += padding_bytes;
1383
1384 return header_length + kRtpOneByteHeaderLength;
1385 }
1386
1297 uint8_t RTPSender::BuildTransmissionTimeOffsetExtension( 1387 uint8_t RTPSender::BuildTransmissionTimeOffsetExtension(
1298 uint8_t* data_buffer) const { 1388 uint8_t* data_buffer) const {
1299 // From RFC 5450: Transmission Time Offsets in RTP Streams. 1389 // From RFC 5450: Transmission Time Offsets in RTP Streams.
1300 // 1390 //
1301 // The transmission time is signaled to the receiver in-band using the 1391 // The transmission time is signaled to the receiver in-band using the
1302 // general mechanism for RTP header extensions [RFC5285]. The payload 1392 // general mechanism for RTP header extensions [RFC5285]. The payload
1303 // of this extension (the transmitted value) is a 24-bit signed integer. 1393 // of this extension (the transmitted value) is a 24-bit signed integer.
1304 // When added to the RTP timestamp of the packet, it represents the 1394 // When added to the RTP timestamp of the packet, it represents the
1305 // "effective" RTP transmission time of the packet, on the RTP 1395 // "effective" RTP transmission time of the packet, on the RTP
1306 // timescale. 1396 // timescale.
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1438 } 1528 }
1439 size_t pos = 0; 1529 size_t pos = 0;
1440 const uint8_t len = 1; 1530 const uint8_t len = 1;
1441 data_buffer[pos++] = (id << 4) + len; 1531 data_buffer[pos++] = (id << 4) + len;
1442 ByteWriter<uint16_t>::WriteBigEndian(data_buffer + pos, sequence_number); 1532 ByteWriter<uint16_t>::WriteBigEndian(data_buffer + pos, sequence_number);
1443 pos += 2; 1533 pos += 2;
1444 assert(pos == kTransportSequenceNumberLength); 1534 assert(pos == kTransportSequenceNumberLength);
1445 return kTransportSequenceNumberLength; 1535 return kTransportSequenceNumberLength;
1446 } 1536 }
1447 1537
1538 uint8_t RTPSender::BuildPlayoutDelayExtension(
1539 uint8_t* data_buffer,
1540 uint16_t min_playout_delay_ms,
1541 uint16_t max_playout_delay_ms) const {
1542 RTC_DCHECK_LE(min_playout_delay_ms, kPlayoutDelayMaxMs);
1543 RTC_DCHECK_LE(max_playout_delay_ms, kPlayoutDelayMaxMs);
1544 RTC_DCHECK_LE(min_playout_delay_ms, max_playout_delay_ms);
1545 // 0 1 2 3
1546 // 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
1547 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1548 // | ID | len=2 | MIN delay | MAX delay |
1549 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1550 uint8_t id;
1551 if (rtp_header_extension_map_.GetId(kRtpExtensionPlayoutDelay, &id) != 0) {
1552 // Not registered.
1553 return 0;
1554 }
1555 size_t pos = 0;
1556 const uint8_t len = 2;
1557 // Convert MS to value to be sent on extension header.
1558 uint16_t min_playout = min_playout_delay_ms / kPlayoutDelayGranularityMs;
1559 uint16_t max_playout = max_playout_delay_ms / kPlayoutDelayGranularityMs;
1560
1561 data_buffer[pos++] = (id << 4) + len;
1562 data_buffer[pos++] = min_playout >> 4;
1563 data_buffer[pos++] = ((min_playout & 0xf) << 4) | (max_playout >> 8);
1564 data_buffer[pos++] = max_playout & 0xff;
1565 assert(pos == kPlayoutDelayLength);
1566 return kPlayoutDelayLength;
1567 }
1568
1448 bool RTPSender::FindHeaderExtensionPosition(RTPExtensionType type, 1569 bool RTPSender::FindHeaderExtensionPosition(RTPExtensionType type,
1449 const uint8_t* rtp_packet, 1570 const uint8_t* rtp_packet,
1450 size_t rtp_packet_length, 1571 size_t rtp_packet_length,
1451 const RTPHeader& rtp_header, 1572 const RTPHeader& rtp_header,
1452 size_t* position) const { 1573 size_t* position) const {
1453 // Get length until start of header extension block. 1574 // Get length until start of header extension block.
1454 int extension_block_pos = 1575 int extension_block_pos =
1455 rtp_header_extension_map_.GetLengthUntilBlockStartInBytes(type); 1576 rtp_header_extension_map_.GetLengthUntilBlockStartInBytes(type);
1456 if (extension_block_pos < 0) { 1577 if (extension_block_pos < 0) {
1457 LOG(LS_WARNING) << "Failed to find extension position for " << type 1578 LOG(LS_WARNING) << "Failed to find extension position for " << type
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
1911 rtc::CritScope lock(&send_critsect_); 2032 rtc::CritScope lock(&send_critsect_);
1912 2033
1913 RtpState state; 2034 RtpState state;
1914 state.sequence_number = sequence_number_rtx_; 2035 state.sequence_number = sequence_number_rtx_;
1915 state.start_timestamp = start_timestamp_; 2036 state.start_timestamp = start_timestamp_;
1916 2037
1917 return state; 2038 return state;
1918 } 2039 }
1919 2040
1920 } // namespace webrtc 2041 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698