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 |