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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
106 bool repeat; | 106 bool repeat; |
107 uint64_t picture_id; | 107 uint64_t picture_id; |
108 uint8_t* buffer; | 108 uint8_t* buffer; |
109 uint32_t buffer_size; | 109 uint32_t buffer_size; |
110 uint32_t ntp_sec; | 110 uint32_t ntp_sec; |
111 uint32_t ntp_frac; | 111 uint32_t ntp_frac; |
112 uint32_t jitter_transmission_offset; | 112 uint32_t jitter_transmission_offset; |
113 uint32_t position; | 113 uint32_t position; |
114 }; | 114 }; |
115 | 115 |
116 // TODO(sprang): Once all builders use RtcpPacket, call SendToNetwork() here. | |
117 class RTCPSender::PacketBuiltCallback | |
118 : public rtcp::RtcpPacket::PacketReadyCallback { | |
119 public: | |
120 PacketBuiltCallback(RtcpContext* context) : context_(context) {} | |
121 virtual ~PacketBuiltCallback() {} | |
122 void OnPacketReady(uint8_t* data, size_t length) override { | |
123 context_->position += length; | |
124 } | |
125 | |
126 private: | |
127 RtcpContext* const context_; | |
128 }; | |
129 | |
116 RTCPSender::RTCPSender( | 130 RTCPSender::RTCPSender( |
117 int32_t id, | 131 int32_t id, |
118 bool audio, | 132 bool audio, |
119 Clock* clock, | 133 Clock* clock, |
120 ReceiveStatistics* receive_statistics, | 134 ReceiveStatistics* receive_statistics, |
121 RtcpPacketTypeCounterObserver* packet_type_counter_observer) | 135 RtcpPacketTypeCounterObserver* packet_type_counter_observer) |
122 : id_(id), | 136 : id_(id), |
123 audio_(audio), | 137 audio_(audio), |
124 clock_(clock), | 138 clock_(clock), |
125 method_(kRtcpOff), | 139 method_(kRtcpOff), |
(...skipping 17 matching lines...) Expand all Loading... | |
143 | 157 |
144 sequence_number_fir_(0), | 158 sequence_number_fir_(0), |
145 | 159 |
146 remb_bitrate_(0), | 160 remb_bitrate_(0), |
147 | 161 |
148 tmmbr_help_(), | 162 tmmbr_help_(), |
149 tmmbr_send_(0), | 163 tmmbr_send_(0), |
150 packet_oh_send_(0), | 164 packet_oh_send_(0), |
151 | 165 |
152 app_sub_type_(0), | 166 app_sub_type_(0), |
167 app_name_(0), | |
153 app_data_(nullptr), | 168 app_data_(nullptr), |
154 app_length_(0), | 169 app_length_(0), |
155 | 170 |
156 xr_send_receiver_reference_time_enabled_(false), | 171 xr_send_receiver_reference_time_enabled_(false), |
157 packet_type_counter_observer_(packet_type_counter_observer) { | 172 packet_type_counter_observer_(packet_type_counter_observer) { |
158 memset(cname_, 0, sizeof(cname_)); | 173 memset(cname_, 0, sizeof(cname_)); |
159 memset(last_send_report_, 0, sizeof(last_send_report_)); | 174 memset(last_send_report_, 0, sizeof(last_send_report_)); |
160 memset(last_rtcp_time_, 0, sizeof(last_rtcp_time_)); | 175 memset(last_rtcp_time_, 0, sizeof(last_rtcp_time_)); |
161 | 176 |
162 builders_[kRtcpSr] = &RTCPSender::BuildSR; | 177 builders_[kRtcpSr] = &RTCPSender::BuildSR; |
(...skipping 11 matching lines...) Expand all Loading... | |
174 builders_[kRtcpTmmbr] = &RTCPSender::BuildTMMBR; | 189 builders_[kRtcpTmmbr] = &RTCPSender::BuildTMMBR; |
175 builders_[kRtcpTmmbn] = &RTCPSender::BuildTMMBN; | 190 builders_[kRtcpTmmbn] = &RTCPSender::BuildTMMBN; |
176 builders_[kRtcpNack] = &RTCPSender::BuildNACK; | 191 builders_[kRtcpNack] = &RTCPSender::BuildNACK; |
177 builders_[kRtcpXrVoipMetric] = &RTCPSender::BuildVoIPMetric; | 192 builders_[kRtcpXrVoipMetric] = &RTCPSender::BuildVoIPMetric; |
178 builders_[kRtcpXrReceiverReferenceTime] = | 193 builders_[kRtcpXrReceiverReferenceTime] = |
179 &RTCPSender::BuildReceiverReferenceTime; | 194 &RTCPSender::BuildReceiverReferenceTime; |
180 builders_[kRtcpXrDlrrReportBlock] = &RTCPSender::BuildDlrr; | 195 builders_[kRtcpXrDlrrReportBlock] = &RTCPSender::BuildDlrr; |
181 } | 196 } |
182 | 197 |
183 RTCPSender::~RTCPSender() { | 198 RTCPSender::~RTCPSender() { |
184 for (auto it : internal_report_blocks_) | |
185 delete it.second; | |
186 | |
187 for (auto it : csrc_cnames_) | 199 for (auto it : csrc_cnames_) |
188 delete it.second; | 200 delete it.second; |
189 } | 201 } |
190 | 202 |
191 int32_t RTCPSender::RegisterSendTransport(Transport* outgoingTransport) { | 203 int32_t RTCPSender::RegisterSendTransport(Transport* outgoingTransport) { |
192 CriticalSectionScoped lock(critical_section_transport_.get()); | 204 CriticalSectionScoped lock(critical_section_transport_.get()); |
193 cbTransport_ = outgoingTransport; | 205 cbTransport_ = outgoingTransport; |
194 return 0; | 206 return 0; |
195 } | 207 } |
196 | 208 |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
458 return false; | 470 return false; |
459 } | 471 } |
460 std::map<uint32_t, int64_t>::const_iterator it = last_xr_rr_.find(mid_ntp); | 472 std::map<uint32_t, int64_t>::const_iterator it = last_xr_rr_.find(mid_ntp); |
461 if (it == last_xr_rr_.end()) { | 473 if (it == last_xr_rr_.end()) { |
462 return false; | 474 return false; |
463 } | 475 } |
464 *time_ms = it->second; | 476 *time_ms = it->second; |
465 return true; | 477 return true; |
466 } | 478 } |
467 | 479 |
468 int32_t RTCPSender::AddReportBlock( | 480 int32_t RTCPSender::AddReportBlock(const RTCPReportBlock& report_block) { |
469 uint32_t SSRC, | 481 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); |
åsapersson
2015/06/12 08:16:24
lock already taken?
sprang_webrtc
2015/06/12 09:04:32
True, removed lock and added thread annotation.
| |
470 std::map<uint32_t, RTCPReportBlock*>* report_blocks, | 482 if (report_blocks_.size() >= RTCP_MAX_REPORT_BLOCKS) { |
471 const RTCPReportBlock* reportBlock) { | |
472 assert(reportBlock); | |
473 | |
474 if (report_blocks->size() >= RTCP_MAX_REPORT_BLOCKS) { | |
475 LOG(LS_WARNING) << "Too many report blocks."; | 483 LOG(LS_WARNING) << "Too many report blocks."; |
476 return -1; | 484 return -1; |
477 } | 485 } |
478 std::map<uint32_t, RTCPReportBlock*>::iterator it = | 486 rtcp::ReportBlock* block = &report_blocks_[report_block.remoteSSRC]; |
479 report_blocks->find(SSRC); | 487 block->To(report_block.remoteSSRC); |
480 if (it != report_blocks->end()) { | 488 block->WithFractionLost(report_block.fractionLost); |
481 delete it->second; | 489 block->WithCumulativeLost(report_block.cumulativeLost); |
482 report_blocks->erase(it); | 490 block->WithExtHighestSeqNum(report_block.extendedHighSeqNum); |
483 } | 491 block->WithJitter(report_block.jitter); |
484 RTCPReportBlock* copyReportBlock = new RTCPReportBlock(); | 492 block->WithLastSr(report_block.lastSR); |
485 memcpy(copyReportBlock, reportBlock, sizeof(RTCPReportBlock)); | 493 block->WithDelayLastSr(report_block.delaySinceLastSR); |
486 (*report_blocks)[SSRC] = copyReportBlock; | 494 |
487 return 0; | 495 return 0; |
488 } | 496 } |
489 | 497 |
490 RTCPSender::BuildResult RTCPSender::BuildSR(RtcpContext* ctx) { | 498 RTCPSender::BuildResult RTCPSender::BuildSR(RtcpContext* ctx) { |
491 // sanity | 499 // sanity |
åsapersson
2015/06/12 08:16:24
Is this still needed?
sprang_webrtc
2015/06/12 09:04:32
Removed and used the logic from RtcpPacket instead
| |
492 if (ctx->position + 52 >= IP_PACKET_SIZE) { | 500 if (ctx->position + 52 >= IP_PACKET_SIZE) { |
493 LOG(LS_WARNING) << "Failed to build Sender Report."; | 501 LOG(LS_WARNING) << "Failed to build Sender Report."; |
494 return BuildResult::kTruncated; | 502 return BuildResult::kTruncated; |
495 } | 503 } |
496 uint32_t RTPtime; | |
497 | |
498 uint32_t posNumberOfReportBlocks = ctx->position; | |
499 *ctx->AllocateData(1) = 0x80; | |
500 | |
501 // Sender report | |
502 *ctx->AllocateData(1) = 200; | |
503 | 504 |
504 for (int i = (RTCP_NUMBER_OF_SR - 2); i >= 0; i--) { | 505 for (int i = (RTCP_NUMBER_OF_SR - 2); i >= 0; i--) { |
505 // shift old | 506 // shift old |
506 last_send_report_[i + 1] = last_send_report_[i]; | 507 last_send_report_[i + 1] = last_send_report_[i]; |
507 last_rtcp_time_[i + 1] = last_rtcp_time_[i]; | 508 last_rtcp_time_[i + 1] = last_rtcp_time_[i]; |
508 } | 509 } |
509 | 510 |
510 last_rtcp_time_[0] = Clock::NtpToMs(ctx->ntp_sec, ctx->ntp_frac); | 511 last_rtcp_time_[0] = Clock::NtpToMs(ctx->ntp_sec, ctx->ntp_frac); |
511 last_send_report_[0] = (ctx->ntp_sec << 16) + (ctx->ntp_frac >> 16); | 512 last_send_report_[0] = (ctx->ntp_sec << 16) + (ctx->ntp_frac >> 16); |
512 | 513 |
513 // The timestamp of this RTCP packet should be estimated as the timestamp of | 514 // The timestamp of this RTCP packet should be estimated as the timestamp of |
514 // the frame being captured at this moment. We are calculating that | 515 // the frame being captured at this moment. We are calculating that |
515 // timestamp as the last frame's timestamp + the time since the last frame | 516 // timestamp as the last frame's timestamp + the time since the last frame |
516 // was captured. | 517 // was captured. |
517 RTPtime = start_timestamp_ + last_rtp_timestamp_ + | 518 uint32_t rtp_timestamp = |
518 (clock_->TimeInMilliseconds() - last_frame_capture_time_ms_) * | 519 start_timestamp_ + last_rtp_timestamp_ + |
519 (ctx->feedback_state.frequency_hz / 1000); | 520 (clock_->TimeInMilliseconds() - last_frame_capture_time_ms_) * |
521 (ctx->feedback_state.frequency_hz / 1000); | |
520 | 522 |
521 // Add sender data | 523 rtcp::SenderReport report; |
522 // Save for our length field | 524 report.From(ssrc_); |
523 ctx->AllocateData(2); | 525 report.WithNtpSec(ctx->ntp_sec); |
526 report.WithNtpFrac(ctx->ntp_frac); | |
527 report.WithRtpTimestamp(rtp_timestamp); | |
528 report.WithPacketCount(ctx->feedback_state.packets_sent); | |
529 report.WithOctetCount(ctx->feedback_state.media_bytes_sent); | |
524 | 530 |
525 // Add our own SSRC | 531 for (auto it : report_blocks_) { |
526 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ssrc_); | 532 report.WithReportBlock(it.second); |
527 // NTP | 533 } |
528 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ctx->ntp_sec); | 534 report_blocks_.clear(); |
529 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ctx->ntp_frac); | |
530 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), RTPtime); | |
531 | 535 |
532 // sender's packet count | 536 PacketBuiltCallback callback(ctx); |
533 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), | 537 report.BuildExternalBuffer(&ctx->buffer[ctx->position], |
534 ctx->feedback_state.packets_sent); | 538 ctx->buffer_size - ctx->position, &callback); |
535 | |
536 // sender's octet count | |
537 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), | |
538 ctx->feedback_state.media_bytes_sent); | |
539 | |
540 uint8_t numberOfReportBlocks = 0; | |
541 BuildResult result = WriteAllReportBlocksToBuffer(ctx, &numberOfReportBlocks); | |
542 switch (result) { | |
543 case BuildResult::kError: | |
544 case BuildResult::kTruncated: | |
545 case BuildResult::kAborted: | |
546 return result; | |
547 case BuildResult::kSuccess: | |
548 break; | |
549 default: | |
550 abort(); | |
551 } | |
552 | |
553 ctx->buffer[posNumberOfReportBlocks] += numberOfReportBlocks; | |
554 | |
555 uint16_t len = static_cast<uint16_t>((ctx->position / 4) - 1); | |
556 ByteWriter<uint16_t>::WriteBigEndian(&ctx->buffer[2], len); | |
557 | 539 |
558 return BuildResult::kSuccess; | 540 return BuildResult::kSuccess; |
559 } | 541 } |
560 | 542 |
561 RTCPSender::BuildResult RTCPSender::BuildSDEC(RtcpContext* ctx) { | 543 RTCPSender::BuildResult RTCPSender::BuildSDEC(RtcpContext* ctx) { |
562 size_t lengthCname = strlen(cname_); | 544 size_t lengthCname = strlen(cname_); |
563 assert(lengthCname < RTCP_CNAME_SIZE); | 545 assert(lengthCname < RTCP_CNAME_SIZE); |
564 | 546 |
565 // sanity | 547 // sanity |
566 if (ctx->position + 12 + lengthCname >= IP_PACKET_SIZE) { | 548 if (ctx->position + 12 + lengthCname >= IP_PACKET_SIZE) { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
633 ByteWriter<uint16_t>::WriteBigEndian(&ctx->buffer[SDESLengthPos], | 615 ByteWriter<uint16_t>::WriteBigEndian(&ctx->buffer[SDESLengthPos], |
634 buffer_length); | 616 buffer_length); |
635 return BuildResult::kSuccess; | 617 return BuildResult::kSuccess; |
636 } | 618 } |
637 | 619 |
638 RTCPSender::BuildResult RTCPSender::BuildRR(RtcpContext* ctx) { | 620 RTCPSender::BuildResult RTCPSender::BuildRR(RtcpContext* ctx) { |
639 // sanity one block | 621 // sanity one block |
640 if (ctx->position + 32 >= IP_PACKET_SIZE) | 622 if (ctx->position + 32 >= IP_PACKET_SIZE) |
641 return BuildResult::kTruncated; | 623 return BuildResult::kTruncated; |
642 | 624 |
643 uint32_t posNumberOfReportBlocks = ctx->position; | 625 rtcp::ReceiverReport report; |
626 report.From(ssrc_); | |
627 for (auto it : report_blocks_) | |
628 report.WithReportBlock(it.second); | |
629 report_blocks_.clear(); | |
644 | 630 |
645 *ctx->AllocateData(1) = 0x80; | 631 PacketBuiltCallback callback(ctx); |
646 *ctx->AllocateData(1) = 201; | 632 report.BuildExternalBuffer(&ctx->buffer[ctx->position], |
647 | 633 ctx->buffer_size - ctx->position, &callback); |
648 // Save for our length field | |
649 uint32_t len_pos = ctx->position; | |
650 ctx->AllocateData(2); | |
651 | |
652 // Add our own SSRC | |
653 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ssrc_); | |
654 | |
655 uint8_t numberOfReportBlocks = 0; | |
656 BuildResult result = WriteAllReportBlocksToBuffer(ctx, &numberOfReportBlocks); | |
657 switch (result) { | |
658 case BuildResult::kError: | |
659 case BuildResult::kTruncated: | |
660 case BuildResult::kAborted: | |
661 return result; | |
662 case BuildResult::kSuccess: | |
663 break; | |
664 default: | |
665 abort(); | |
666 } | |
667 | |
668 ctx->buffer[posNumberOfReportBlocks] += numberOfReportBlocks; | |
669 | |
670 uint16_t len = uint16_t((ctx->position) / 4 - 1); | |
671 ByteWriter<uint16_t>::WriteBigEndian(&ctx->buffer[len_pos], len); | |
672 | 634 |
673 return BuildResult::kSuccess; | 635 return BuildResult::kSuccess; |
674 } | 636 } |
675 | 637 |
676 // From RFC 5450: Transmission Time Offsets in RTP Streams. | 638 // From RFC 5450: Transmission Time Offsets in RTP Streams. |
677 // 0 1 2 3 | 639 // 0 1 2 3 |
678 // 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 | 640 // 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 |
679 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 641 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
680 // hdr |V=2|P| RC | PT=IJ=195 | length | | 642 // hdr |V=2|P| RC | PT=IJ=195 | length | |
681 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 643 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
(...skipping 804 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1486 } | 1448 } |
1487 next_time_to_send_rtcp_ = clock_->TimeInMilliseconds() + timeToNext; | 1449 next_time_to_send_rtcp_ = clock_->TimeInMilliseconds() + timeToNext; |
1488 | 1450 |
1489 StatisticianMap statisticians = | 1451 StatisticianMap statisticians = |
1490 receive_statistics_->GetActiveStatisticians(); | 1452 receive_statistics_->GetActiveStatisticians(); |
1491 if (!statisticians.empty()) { | 1453 if (!statisticians.empty()) { |
1492 for (auto it = statisticians.begin(); it != statisticians.end(); ++it) { | 1454 for (auto it = statisticians.begin(); it != statisticians.end(); ++it) { |
1493 RTCPReportBlock report_block; | 1455 RTCPReportBlock report_block; |
1494 if (PrepareReport(feedback_state, it->second, &report_block, | 1456 if (PrepareReport(feedback_state, it->second, &report_block, |
1495 &context.ntp_sec, &context.ntp_frac)) { | 1457 &context.ntp_sec, &context.ntp_frac)) { |
1496 AddReportBlock(it->first, &internal_report_blocks_, &report_block); | 1458 report_block.remoteSSRC = it->first; |
åsapersson
2015/06/12 08:16:24
maybe move inside PrepareReport
sprang_webrtc
2015/06/12 09:04:32
Done.
| |
1459 AddReportBlock(report_block); | |
1497 } | 1460 } |
1498 } | 1461 } |
1499 if (extended_jitter_report_enabled_) | 1462 if (extended_jitter_report_enabled_) |
1500 SetFlag(kRtcpTransmissionTimeOffset, true); | 1463 SetFlag(kRtcpTransmissionTimeOffset, true); |
1501 } | 1464 } |
1502 } | 1465 } |
1503 | 1466 |
1504 auto it = report_flags_.begin(); | 1467 auto it = report_flags_.begin(); |
1505 while (it != report_flags_.end()) { | 1468 while (it != report_flags_.end()) { |
1506 auto builder = builders_.find(it->type); | 1469 auto builder = builders_.find(it->type); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1545 // Do we have receive statistics to send? | 1508 // Do we have receive statistics to send? |
1546 RtcpStatistics stats; | 1509 RtcpStatistics stats; |
1547 if (!statistician->GetStatistics(&stats, true)) | 1510 if (!statistician->GetStatistics(&stats, true)) |
1548 return false; | 1511 return false; |
1549 report_block->fractionLost = stats.fraction_lost; | 1512 report_block->fractionLost = stats.fraction_lost; |
1550 report_block->cumulativeLost = stats.cumulative_lost; | 1513 report_block->cumulativeLost = stats.cumulative_lost; |
1551 report_block->extendedHighSeqNum = | 1514 report_block->extendedHighSeqNum = |
1552 stats.extended_max_sequence_number; | 1515 stats.extended_max_sequence_number; |
1553 report_block->jitter = stats.jitter; | 1516 report_block->jitter = stats.jitter; |
1554 | 1517 |
1555 // get our NTP as late as possible to avoid a race | 1518 // get our NTP as late as possible to avoid a race |
åsapersson
2015/06/12 08:16:24
Can ntp_sec and ntp_frac be local variables?
sprang_webrtc
2015/06/12 09:04:32
Done.
| |
1556 clock_->CurrentNtp(*ntp_secs, *ntp_frac); | 1519 clock_->CurrentNtp(*ntp_secs, *ntp_frac); |
1557 | 1520 |
1558 // Delay since last received report | 1521 // Delay since last received report |
1559 uint32_t delaySinceLastReceivedSR = 0; | 1522 uint32_t delaySinceLastReceivedSR = 0; |
1560 if ((feedback_state.last_rr_ntp_secs != 0) || | 1523 if ((feedback_state.last_rr_ntp_secs != 0) || |
1561 (feedback_state.last_rr_ntp_frac != 0)) { | 1524 (feedback_state.last_rr_ntp_frac != 0)) { |
1562 // get the 16 lowest bits of seconds and the 16 higest bits of fractions | 1525 // get the 16 lowest bits of seconds and the 16 higest bits of fractions |
1563 uint32_t now = *ntp_secs & 0x0000FFFF; | 1526 uint32_t now = *ntp_secs & 0x0000FFFF; |
1564 now <<= 16; | 1527 now <<= 16; |
1565 now += (*ntp_frac & 0xffff0000) >> 16; | 1528 now += (*ntp_frac & 0xffff0000) >> 16; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1620 void RTCPSender::SendRtcpXrReceiverReferenceTime(bool enable) { | 1583 void RTCPSender::SendRtcpXrReceiverReferenceTime(bool enable) { |
1621 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); | 1584 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); |
1622 xr_send_receiver_reference_time_enabled_ = enable; | 1585 xr_send_receiver_reference_time_enabled_ = enable; |
1623 } | 1586 } |
1624 | 1587 |
1625 bool RTCPSender::RtcpXrReceiverReferenceTime() const { | 1588 bool RTCPSender::RtcpXrReceiverReferenceTime() const { |
1626 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); | 1589 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); |
1627 return xr_send_receiver_reference_time_enabled_; | 1590 return xr_send_receiver_reference_time_enabled_; |
1628 } | 1591 } |
1629 | 1592 |
1630 // called under critsect critical_section_rtcp_sender_ | |
1631 RTCPSender::BuildResult RTCPSender::WriteAllReportBlocksToBuffer( | |
1632 RtcpContext* ctx, | |
1633 uint8_t* numberOfReportBlocks) { | |
1634 *numberOfReportBlocks = internal_report_blocks_.size(); | |
1635 if ((ctx->position + *numberOfReportBlocks * 24) >= IP_PACKET_SIZE) { | |
1636 LOG(LS_WARNING) << "Can't fit all report blocks."; | |
1637 return BuildResult::kError; | |
1638 } | |
1639 WriteReportBlocksToBuffer(ctx, internal_report_blocks_); | |
1640 while (!internal_report_blocks_.empty()) { | |
1641 delete internal_report_blocks_.begin()->second; | |
1642 internal_report_blocks_.erase(internal_report_blocks_.begin()); | |
1643 } | |
1644 return BuildResult::kSuccess; | |
1645 } | |
1646 | |
1647 void RTCPSender::WriteReportBlocksToBuffer( | |
1648 RtcpContext* ctx, | |
1649 const std::map<uint32_t, RTCPReportBlock*>& report_blocks) { | |
1650 std::map<uint32_t, RTCPReportBlock*>::const_iterator it = | |
1651 report_blocks.begin(); | |
1652 for (; it != report_blocks.end(); it++) { | |
1653 uint32_t remoteSSRC = it->first; | |
1654 RTCPReportBlock* reportBlock = it->second; | |
1655 if (reportBlock) { | |
1656 // Remote SSRC | |
1657 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), remoteSSRC); | |
1658 | |
1659 // fraction lost | |
1660 *ctx->AllocateData(1) = reportBlock->fractionLost; | |
1661 | |
1662 // cumulative loss | |
1663 ByteWriter<uint32_t, 3>::WriteBigEndian(ctx->AllocateData(3), | |
1664 reportBlock->cumulativeLost); | |
1665 | |
1666 // extended highest seq_no, contain the highest sequence number received | |
1667 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), | |
1668 reportBlock->extendedHighSeqNum); | |
1669 | |
1670 // Jitter | |
1671 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), | |
1672 reportBlock->jitter); | |
1673 | |
1674 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), | |
1675 reportBlock->lastSR); | |
1676 | |
1677 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), | |
1678 reportBlock->delaySinceLastSR); | |
1679 } | |
1680 } | |
1681 } | |
1682 | |
1683 // no callbacks allowed inside this function | 1593 // no callbacks allowed inside this function |
1684 int32_t RTCPSender::SetTMMBN(const TMMBRSet* boundingSet, | 1594 int32_t RTCPSender::SetTMMBN(const TMMBRSet* boundingSet, |
1685 uint32_t maxBitrateKbit) { | 1595 uint32_t maxBitrateKbit) { |
1686 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); | 1596 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); |
1687 | 1597 |
1688 if (0 == tmmbr_help_.SetTMMBRBoundingSetToSend(boundingSet, maxBitrateKbit)) { | 1598 if (0 == tmmbr_help_.SetTMMBRBoundingSetToSend(boundingSet, maxBitrateKbit)) { |
1689 SetFlag(kRtcpTmmbn, true); | 1599 SetFlag(kRtcpTmmbn, true); |
1690 return 0; | 1600 return 0; |
1691 } | 1601 } |
1692 return -1; | 1602 return -1; |
(...skipping 24 matching lines...) Expand all Loading... | |
1717 | 1627 |
1718 bool RTCPSender::AllVolatileFlagsConsumed() const { | 1628 bool RTCPSender::AllVolatileFlagsConsumed() const { |
1719 for (const ReportFlag& flag : report_flags_) { | 1629 for (const ReportFlag& flag : report_flags_) { |
1720 if (flag.is_volatile) | 1630 if (flag.is_volatile) |
1721 return false; | 1631 return false; |
1722 } | 1632 } |
1723 return true; | 1633 return true; |
1724 } | 1634 } |
1725 | 1635 |
1726 } // namespace webrtc | 1636 } // namespace webrtc |
OLD | NEW |