| OLD | NEW |
| 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 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 uint32_t buffer_size) | 83 uint32_t buffer_size) |
| 84 : feedback_state(feedback_state), | 84 : feedback_state(feedback_state), |
| 85 nack_size(nack_size), | 85 nack_size(nack_size), |
| 86 nack_list(nack_list), | 86 nack_list(nack_list), |
| 87 repeat(repeat), | 87 repeat(repeat), |
| 88 picture_id(picture_id), | 88 picture_id(picture_id), |
| 89 buffer(buffer), | 89 buffer(buffer), |
| 90 buffer_size(buffer_size), | 90 buffer_size(buffer_size), |
| 91 ntp_sec(0), | 91 ntp_sec(0), |
| 92 ntp_frac(0), | 92 ntp_frac(0), |
| 93 jitter_transmission_offset(0), | |
| 94 position(0) {} | 93 position(0) {} |
| 95 | 94 |
| 96 uint8_t* AllocateData(uint32_t bytes) { | 95 uint8_t* AllocateData(uint32_t bytes) { |
| 97 DCHECK_LE(position + bytes, buffer_size); | 96 DCHECK_LE(position + bytes, buffer_size); |
| 98 uint8_t* ptr = &buffer[position]; | 97 uint8_t* ptr = &buffer[position]; |
| 99 position += bytes; | 98 position += bytes; |
| 100 return ptr; | 99 return ptr; |
| 101 } | 100 } |
| 102 | 101 |
| 103 const FeedbackState& feedback_state; | 102 const FeedbackState& feedback_state; |
| 104 int32_t nack_size; | 103 int32_t nack_size; |
| 105 const uint16_t* nack_list; | 104 const uint16_t* nack_list; |
| 106 bool repeat; | 105 bool repeat; |
| 107 uint64_t picture_id; | 106 uint64_t picture_id; |
| 108 uint8_t* buffer; | 107 uint8_t* buffer; |
| 109 uint32_t buffer_size; | 108 uint32_t buffer_size; |
| 110 uint32_t ntp_sec; | 109 uint32_t ntp_sec; |
| 111 uint32_t ntp_frac; | 110 uint32_t ntp_frac; |
| 112 uint32_t jitter_transmission_offset; | |
| 113 uint32_t position; | 111 uint32_t position; |
| 114 }; | 112 }; |
| 115 | 113 |
| 116 // TODO(sprang): Once all builders use RtcpPacket, call SendToNetwork() here. | 114 // TODO(sprang): Once all builders use RtcpPacket, call SendToNetwork() here. |
| 117 class RTCPSender::PacketBuiltCallback | 115 class RTCPSender::PacketBuiltCallback |
| 118 : public rtcp::RtcpPacket::PacketReadyCallback { | 116 : public rtcp::RtcpPacket::PacketReadyCallback { |
| 119 public: | 117 public: |
| 120 PacketBuiltCallback(RtcpContext* context) : context_(context) {} | 118 PacketBuiltCallback(RtcpContext* context) : context_(context) {} |
| 121 virtual ~PacketBuiltCallback() {} | 119 virtual ~PacketBuiltCallback() {} |
| 122 void OnPacketReady(uint8_t* data, size_t length) override { | 120 void OnPacketReady(uint8_t* data, size_t length) override { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 139 method_(kRtcpOff), | 137 method_(kRtcpOff), |
| 140 critical_section_transport_( | 138 critical_section_transport_( |
| 141 CriticalSectionWrapper::CreateCriticalSection()), | 139 CriticalSectionWrapper::CreateCriticalSection()), |
| 142 cbTransport_(nullptr), | 140 cbTransport_(nullptr), |
| 143 | 141 |
| 144 critical_section_rtcp_sender_( | 142 critical_section_rtcp_sender_( |
| 145 CriticalSectionWrapper::CreateCriticalSection()), | 143 CriticalSectionWrapper::CreateCriticalSection()), |
| 146 using_nack_(false), | 144 using_nack_(false), |
| 147 sending_(false), | 145 sending_(false), |
| 148 remb_enabled_(false), | 146 remb_enabled_(false), |
| 149 extended_jitter_report_enabled_(false), | |
| 150 next_time_to_send_rtcp_(0), | 147 next_time_to_send_rtcp_(0), |
| 151 start_timestamp_(0), | 148 start_timestamp_(0), |
| 152 last_rtp_timestamp_(0), | 149 last_rtp_timestamp_(0), |
| 153 last_frame_capture_time_ms_(-1), | 150 last_frame_capture_time_ms_(-1), |
| 154 ssrc_(0), | 151 ssrc_(0), |
| 155 remote_ssrc_(0), | 152 remote_ssrc_(0), |
| 156 receive_statistics_(receive_statistics), | 153 receive_statistics_(receive_statistics), |
| 157 | 154 |
| 158 sequence_number_fir_(0), | 155 sequence_number_fir_(0), |
| 159 | 156 |
| 160 remb_bitrate_(0), | 157 remb_bitrate_(0), |
| 161 | 158 |
| 162 tmmbr_help_(), | 159 tmmbr_help_(), |
| 163 tmmbr_send_(0), | 160 tmmbr_send_(0), |
| 164 packet_oh_send_(0), | 161 packet_oh_send_(0), |
| 165 | 162 |
| 166 app_sub_type_(0), | 163 app_sub_type_(0), |
| 167 app_name_(0), | 164 app_name_(0), |
| 168 app_data_(nullptr), | 165 app_data_(nullptr), |
| 169 app_length_(0), | 166 app_length_(0), |
| 170 | 167 |
| 171 xr_send_receiver_reference_time_enabled_(false), | 168 xr_send_receiver_reference_time_enabled_(false), |
| 172 packet_type_counter_observer_(packet_type_counter_observer) { | 169 packet_type_counter_observer_(packet_type_counter_observer) { |
| 173 memset(last_send_report_, 0, sizeof(last_send_report_)); | 170 memset(last_send_report_, 0, sizeof(last_send_report_)); |
| 174 memset(last_rtcp_time_, 0, sizeof(last_rtcp_time_)); | 171 memset(last_rtcp_time_, 0, sizeof(last_rtcp_time_)); |
| 175 | 172 |
| 176 builders_[kRtcpSr] = &RTCPSender::BuildSR; | 173 builders_[kRtcpSr] = &RTCPSender::BuildSR; |
| 177 builders_[kRtcpRr] = &RTCPSender::BuildRR; | 174 builders_[kRtcpRr] = &RTCPSender::BuildRR; |
| 178 builders_[kRtcpSdes] = &RTCPSender::BuildSDES; | 175 builders_[kRtcpSdes] = &RTCPSender::BuildSDES; |
| 179 builders_[kRtcpTransmissionTimeOffset] = | |
| 180 &RTCPSender::BuildExtendedJitterReport; | |
| 181 builders_[kRtcpPli] = &RTCPSender::BuildPLI; | 176 builders_[kRtcpPli] = &RTCPSender::BuildPLI; |
| 182 builders_[kRtcpFir] = &RTCPSender::BuildFIR; | 177 builders_[kRtcpFir] = &RTCPSender::BuildFIR; |
| 183 builders_[kRtcpSli] = &RTCPSender::BuildSLI; | 178 builders_[kRtcpSli] = &RTCPSender::BuildSLI; |
| 184 builders_[kRtcpRpsi] = &RTCPSender::BuildRPSI; | 179 builders_[kRtcpRpsi] = &RTCPSender::BuildRPSI; |
| 185 builders_[kRtcpRemb] = &RTCPSender::BuildREMB; | 180 builders_[kRtcpRemb] = &RTCPSender::BuildREMB; |
| 186 builders_[kRtcpBye] = &RTCPSender::BuildBYE; | 181 builders_[kRtcpBye] = &RTCPSender::BuildBYE; |
| 187 builders_[kRtcpApp] = &RTCPSender::BuildAPP; | 182 builders_[kRtcpApp] = &RTCPSender::BuildAPP; |
| 188 builders_[kRtcpTmmbr] = &RTCPSender::BuildTMMBR; | 183 builders_[kRtcpTmmbr] = &RTCPSender::BuildTMMBR; |
| 189 builders_[kRtcpTmmbn] = &RTCPSender::BuildTMMBN; | 184 builders_[kRtcpTmmbn] = &RTCPSender::BuildTMMBN; |
| 190 builders_[kRtcpNack] = &RTCPSender::BuildNACK; | 185 builders_[kRtcpNack] = &RTCPSender::BuildNACK; |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 | 268 |
| 274 void RTCPSender::SetTMMBRStatus(bool enable) { | 269 void RTCPSender::SetTMMBRStatus(bool enable) { |
| 275 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); | 270 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); |
| 276 if (enable) { | 271 if (enable) { |
| 277 SetFlag(RTCPPacketType::kRtcpTmmbr, false); | 272 SetFlag(RTCPPacketType::kRtcpTmmbr, false); |
| 278 } else { | 273 } else { |
| 279 ConsumeFlag(RTCPPacketType::kRtcpTmmbr, true); | 274 ConsumeFlag(RTCPPacketType::kRtcpTmmbr, true); |
| 280 } | 275 } |
| 281 } | 276 } |
| 282 | 277 |
| 283 bool RTCPSender::IJ() const { | |
| 284 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); | |
| 285 return extended_jitter_report_enabled_; | |
| 286 } | |
| 287 | |
| 288 void RTCPSender::SetIJStatus(bool enable) { | |
| 289 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); | |
| 290 extended_jitter_report_enabled_ = enable; | |
| 291 } | |
| 292 | |
| 293 void RTCPSender::SetStartTimestamp(uint32_t start_timestamp) { | 278 void RTCPSender::SetStartTimestamp(uint32_t start_timestamp) { |
| 294 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); | 279 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); |
| 295 start_timestamp_ = start_timestamp; | 280 start_timestamp_ = start_timestamp; |
| 296 } | 281 } |
| 297 | 282 |
| 298 void RTCPSender::SetLastRtpTime(uint32_t rtp_timestamp, | 283 void RTCPSender::SetLastRtpTime(uint32_t rtp_timestamp, |
| 299 int64_t capture_time_ms) { | 284 int64_t capture_time_ms) { |
| 300 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); | 285 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); |
| 301 last_rtp_timestamp_ = rtp_timestamp; | 286 last_rtp_timestamp_ = rtp_timestamp; |
| 302 if (capture_time_ms < 0) { | 287 if (capture_time_ms < 0) { |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 ctx->buffer_size - ctx->position, | 541 ctx->buffer_size - ctx->position, |
| 557 &callback)) { | 542 &callback)) { |
| 558 return BuildResult::kTruncated; | 543 return BuildResult::kTruncated; |
| 559 } | 544 } |
| 560 | 545 |
| 561 report_blocks_.clear(); | 546 report_blocks_.clear(); |
| 562 | 547 |
| 563 return BuildResult::kSuccess; | 548 return BuildResult::kSuccess; |
| 564 } | 549 } |
| 565 | 550 |
| 566 // From RFC 5450: Transmission Time Offsets in RTP Streams. | |
| 567 // 0 1 2 3 | |
| 568 // 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 | |
| 569 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 570 // hdr |V=2|P| RC | PT=IJ=195 | length | | |
| 571 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 572 // | inter-arrival jitter | | |
| 573 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 574 // . . | |
| 575 // . . | |
| 576 // . . | |
| 577 // | inter-arrival jitter | | |
| 578 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 579 // | |
| 580 // If present, this RTCP packet must be placed after a receiver report | |
| 581 // (inside a compound RTCP packet), and MUST have the same value for RC | |
| 582 // (reception report count) as the receiver report. | |
| 583 | |
| 584 RTCPSender::BuildResult RTCPSender::BuildExtendedJitterReport( | |
| 585 RtcpContext* ctx) { | |
| 586 // sanity | |
| 587 if (ctx->position + 8 >= IP_PACKET_SIZE) | |
| 588 return BuildResult::kTruncated; | |
| 589 | |
| 590 // add picture loss indicator | |
| 591 uint8_t RC = 1; | |
| 592 *ctx->AllocateData(1) = 0x80 + RC; | |
| 593 *ctx->AllocateData(1) = 195; | |
| 594 | |
| 595 // Used fixed length of 2 | |
| 596 *ctx->AllocateData(1) = 0; | |
| 597 *ctx->AllocateData(1) = 1; | |
| 598 | |
| 599 // Add inter-arrival jitter | |
| 600 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), | |
| 601 ctx->jitter_transmission_offset); | |
| 602 return BuildResult::kSuccess; | |
| 603 } | |
| 604 | |
| 605 RTCPSender::BuildResult RTCPSender::BuildPLI(RtcpContext* ctx) { | 551 RTCPSender::BuildResult RTCPSender::BuildPLI(RtcpContext* ctx) { |
| 606 // sanity | 552 // sanity |
| 607 if (ctx->position + 12 >= IP_PACKET_SIZE) | 553 if (ctx->position + 12 >= IP_PACKET_SIZE) |
| 608 return BuildResult::kTruncated; | 554 return BuildResult::kTruncated; |
| 609 | 555 |
| 610 // add picture loss indicator | 556 // add picture loss indicator |
| 611 uint8_t FMT = 1; | 557 uint8_t FMT = 1; |
| 612 *ctx->AllocateData(1) = 0x80 + FMT; | 558 *ctx->AllocateData(1) = 0x80 + FMT; |
| 613 *ctx->AllocateData(1) = 206; | 559 *ctx->AllocateData(1) = 206; |
| 614 | 560 |
| (...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1379 StatisticianMap statisticians = | 1325 StatisticianMap statisticians = |
| 1380 receive_statistics_->GetActiveStatisticians(); | 1326 receive_statistics_->GetActiveStatisticians(); |
| 1381 if (!statisticians.empty()) { | 1327 if (!statisticians.empty()) { |
| 1382 for (auto it = statisticians.begin(); it != statisticians.end(); ++it) { | 1328 for (auto it = statisticians.begin(); it != statisticians.end(); ++it) { |
| 1383 RTCPReportBlock report_block; | 1329 RTCPReportBlock report_block; |
| 1384 if (PrepareReport(feedback_state, it->first, it->second, | 1330 if (PrepareReport(feedback_state, it->first, it->second, |
| 1385 &report_block)) { | 1331 &report_block)) { |
| 1386 AddReportBlock(report_block); | 1332 AddReportBlock(report_block); |
| 1387 } | 1333 } |
| 1388 } | 1334 } |
| 1389 if (extended_jitter_report_enabled_) | |
| 1390 SetFlag(kRtcpTransmissionTimeOffset, true); | |
| 1391 } | 1335 } |
| 1392 } | 1336 } |
| 1393 | 1337 |
| 1394 auto it = report_flags_.begin(); | 1338 auto it = report_flags_.begin(); |
| 1395 while (it != report_flags_.end()) { | 1339 while (it != report_flags_.end()) { |
| 1396 auto builder = builders_.find(it->type); | 1340 auto builder = builders_.find(it->type); |
| 1397 DCHECK(builder != builders_.end()); | 1341 DCHECK(builder != builders_.end()); |
| 1398 if (it->is_volatile) { | 1342 if (it->is_volatile) { |
| 1399 report_flags_.erase(it++); | 1343 report_flags_.erase(it++); |
| 1400 } else { | 1344 } else { |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1558 | 1502 |
| 1559 bool RTCPSender::AllVolatileFlagsConsumed() const { | 1503 bool RTCPSender::AllVolatileFlagsConsumed() const { |
| 1560 for (const ReportFlag& flag : report_flags_) { | 1504 for (const ReportFlag& flag : report_flags_) { |
| 1561 if (flag.is_volatile) | 1505 if (flag.is_volatile) |
| 1562 return false; | 1506 return false; |
| 1563 } | 1507 } |
| 1564 return true; | 1508 return true; |
| 1565 } | 1509 } |
| 1566 | 1510 |
| 1567 } // namespace webrtc | 1511 } // namespace webrtc |
| OLD | NEW |