| 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 if (report_blocks_.size() >= RTCP_MAX_REPORT_BLOCKS) { |
| 470 std::map<uint32_t, RTCPReportBlock*>* 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."; | 482 LOG(LS_WARNING) << "Too many report blocks."; |
| 476 return -1; | 483 return -1; |
| 477 } | 484 } |
| 478 std::map<uint32_t, RTCPReportBlock*>::iterator it = | 485 rtcp::ReportBlock* block = &report_blocks_[report_block.remoteSSRC]; |
| 479 report_blocks->find(SSRC); | 486 block->To(report_block.remoteSSRC); |
| 480 if (it != report_blocks->end()) { | 487 block->WithFractionLost(report_block.fractionLost); |
| 481 delete it->second; | 488 block->WithCumulativeLost(report_block.cumulativeLost); |
| 482 report_blocks->erase(it); | 489 block->WithExtHighestSeqNum(report_block.extendedHighSeqNum); |
| 483 } | 490 block->WithJitter(report_block.jitter); |
| 484 RTCPReportBlock* copyReportBlock = new RTCPReportBlock(); | 491 block->WithLastSr(report_block.lastSR); |
| 485 memcpy(copyReportBlock, reportBlock, sizeof(RTCPReportBlock)); | 492 block->WithDelayLastSr(report_block.delaySinceLastSR); |
| 486 (*report_blocks)[SSRC] = copyReportBlock; | 493 |
| 487 return 0; | 494 return 0; |
| 488 } | 495 } |
| 489 | 496 |
| 490 RTCPSender::BuildResult RTCPSender::BuildSR(RtcpContext* ctx) { | 497 RTCPSender::BuildResult RTCPSender::BuildSR(RtcpContext* ctx) { |
| 491 // sanity | |
| 492 if (ctx->position + 52 >= IP_PACKET_SIZE) { | |
| 493 LOG(LS_WARNING) << "Failed to build Sender Report."; | |
| 494 return BuildResult::kTruncated; | |
| 495 } | |
| 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 for (int i = (RTCP_NUMBER_OF_SR - 2); i >= 0; i--) { | 498 for (int i = (RTCP_NUMBER_OF_SR - 2); i >= 0; i--) { |
| 505 // shift old | 499 // shift old |
| 506 last_send_report_[i + 1] = last_send_report_[i]; | 500 last_send_report_[i + 1] = last_send_report_[i]; |
| 507 last_rtcp_time_[i + 1] = last_rtcp_time_[i]; | 501 last_rtcp_time_[i + 1] = last_rtcp_time_[i]; |
| 508 } | 502 } |
| 509 | 503 |
| 510 last_rtcp_time_[0] = Clock::NtpToMs(ctx->ntp_sec, ctx->ntp_frac); | 504 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); | 505 last_send_report_[0] = (ctx->ntp_sec << 16) + (ctx->ntp_frac >> 16); |
| 512 | 506 |
| 513 // The timestamp of this RTCP packet should be estimated as the timestamp of | 507 // 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 | 508 // 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 | 509 // timestamp as the last frame's timestamp + the time since the last frame |
| 516 // was captured. | 510 // was captured. |
| 517 RTPtime = start_timestamp_ + last_rtp_timestamp_ + | 511 uint32_t rtp_timestamp = |
| 518 (clock_->TimeInMilliseconds() - last_frame_capture_time_ms_) * | 512 start_timestamp_ + last_rtp_timestamp_ + |
| 519 (ctx->feedback_state.frequency_hz / 1000); | 513 (clock_->TimeInMilliseconds() - last_frame_capture_time_ms_) * |
| 514 (ctx->feedback_state.frequency_hz / 1000); |
| 520 | 515 |
| 521 // Add sender data | 516 rtcp::SenderReport report; |
| 522 // Save for our length field | 517 report.From(ssrc_); |
| 523 ctx->AllocateData(2); | 518 report.WithNtpSec(ctx->ntp_sec); |
| 519 report.WithNtpFrac(ctx->ntp_frac); |
| 520 report.WithRtpTimestamp(rtp_timestamp); |
| 521 report.WithPacketCount(ctx->feedback_state.packets_sent); |
| 522 report.WithOctetCount(ctx->feedback_state.media_bytes_sent); |
| 524 | 523 |
| 525 // Add our own SSRC | 524 for (auto it : report_blocks_) |
| 526 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ssrc_); | 525 report.WithReportBlock(it.second); |
| 527 // NTP | |
| 528 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ctx->ntp_sec); | |
| 529 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ctx->ntp_frac); | |
| 530 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), RTPtime); | |
| 531 | 526 |
| 532 // sender's packet count | 527 PacketBuiltCallback callback(ctx); |
| 533 ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), | 528 if (!report.BuildExternalBuffer(&ctx->buffer[ctx->position], |
| 534 ctx->feedback_state.packets_sent); | 529 ctx->buffer_size - ctx->position, |
| 535 | 530 &callback)) { |
| 536 // sender's octet count | 531 return BuildResult::kTruncated; |
| 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 } | 532 } |
| 552 | 533 |
| 553 ctx->buffer[posNumberOfReportBlocks] += numberOfReportBlocks; | 534 report_blocks_.clear(); |
| 554 | |
| 555 uint16_t len = static_cast<uint16_t>((ctx->position / 4) - 1); | |
| 556 ByteWriter<uint16_t>::WriteBigEndian(&ctx->buffer[2], len); | |
| 557 | |
| 558 return BuildResult::kSuccess; | 535 return BuildResult::kSuccess; |
| 559 } | 536 } |
| 560 | 537 |
| 561 RTCPSender::BuildResult RTCPSender::BuildSDEC(RtcpContext* ctx) { | 538 RTCPSender::BuildResult RTCPSender::BuildSDEC(RtcpContext* ctx) { |
| 562 size_t lengthCname = strlen(cname_); | 539 size_t lengthCname = strlen(cname_); |
| 563 assert(lengthCname < RTCP_CNAME_SIZE); | 540 assert(lengthCname < RTCP_CNAME_SIZE); |
| 564 | 541 |
| 565 // sanity | 542 // sanity |
| 566 if (ctx->position + 12 + lengthCname >= IP_PACKET_SIZE) { | 543 if (ctx->position + 12 + lengthCname >= IP_PACKET_SIZE) { |
| 567 LOG(LS_WARNING) << "Failed to build SDEC."; | 544 LOG(LS_WARNING) << "Failed to build SDEC."; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 629 SDESLength += padding; | 606 SDESLength += padding; |
| 630 } | 607 } |
| 631 // in 32-bit words minus one and we don't count the header | 608 // in 32-bit words minus one and we don't count the header |
| 632 uint16_t buffer_length = (SDESLength / 4) - 1; | 609 uint16_t buffer_length = (SDESLength / 4) - 1; |
| 633 ByteWriter<uint16_t>::WriteBigEndian(&ctx->buffer[SDESLengthPos], | 610 ByteWriter<uint16_t>::WriteBigEndian(&ctx->buffer[SDESLengthPos], |
| 634 buffer_length); | 611 buffer_length); |
| 635 return BuildResult::kSuccess; | 612 return BuildResult::kSuccess; |
| 636 } | 613 } |
| 637 | 614 |
| 638 RTCPSender::BuildResult RTCPSender::BuildRR(RtcpContext* ctx) { | 615 RTCPSender::BuildResult RTCPSender::BuildRR(RtcpContext* ctx) { |
| 639 // sanity one block | 616 rtcp::ReceiverReport report; |
| 640 if (ctx->position + 32 >= IP_PACKET_SIZE) | 617 report.From(ssrc_); |
| 618 for (auto it : report_blocks_) |
| 619 report.WithReportBlock(it.second); |
| 620 |
| 621 PacketBuiltCallback callback(ctx); |
| 622 if (!report.BuildExternalBuffer(&ctx->buffer[ctx->position], |
| 623 ctx->buffer_size - ctx->position, |
| 624 &callback)) { |
| 641 return BuildResult::kTruncated; | 625 return BuildResult::kTruncated; |
| 642 | |
| 643 uint32_t posNumberOfReportBlocks = ctx->position; | |
| 644 | |
| 645 *ctx->AllocateData(1) = 0x80; | |
| 646 *ctx->AllocateData(1) = 201; | |
| 647 | |
| 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 } | 626 } |
| 667 | 627 |
| 668 ctx->buffer[posNumberOfReportBlocks] += numberOfReportBlocks; | 628 report_blocks_.clear(); |
| 669 | |
| 670 uint16_t len = uint16_t((ctx->position) / 4 - 1); | |
| 671 ByteWriter<uint16_t>::WriteBigEndian(&ctx->buffer[len_pos], len); | |
| 672 | 629 |
| 673 return BuildResult::kSuccess; | 630 return BuildResult::kSuccess; |
| 674 } | 631 } |
| 675 | 632 |
| 676 // From RFC 5450: Transmission Time Offsets in RTP Streams. | 633 // From RFC 5450: Transmission Time Offsets in RTP Streams. |
| 677 // 0 1 2 3 | 634 // 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 | 635 // 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 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 636 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 680 // hdr |V=2|P| RC | PT=IJ=195 | length | | 637 // hdr |V=2|P| RC | PT=IJ=195 | length | |
| 681 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 638 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| (...skipping 802 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1484 minIntervalMs = RTCP_INTERVAL_VIDEO_MS; | 1441 minIntervalMs = RTCP_INTERVAL_VIDEO_MS; |
| 1485 timeToNext = (minIntervalMs / 2) + (minIntervalMs * random / 1000); | 1442 timeToNext = (minIntervalMs / 2) + (minIntervalMs * random / 1000); |
| 1486 } | 1443 } |
| 1487 next_time_to_send_rtcp_ = clock_->TimeInMilliseconds() + timeToNext; | 1444 next_time_to_send_rtcp_ = clock_->TimeInMilliseconds() + timeToNext; |
| 1488 | 1445 |
| 1489 StatisticianMap statisticians = | 1446 StatisticianMap statisticians = |
| 1490 receive_statistics_->GetActiveStatisticians(); | 1447 receive_statistics_->GetActiveStatisticians(); |
| 1491 if (!statisticians.empty()) { | 1448 if (!statisticians.empty()) { |
| 1492 for (auto it = statisticians.begin(); it != statisticians.end(); ++it) { | 1449 for (auto it = statisticians.begin(); it != statisticians.end(); ++it) { |
| 1493 RTCPReportBlock report_block; | 1450 RTCPReportBlock report_block; |
| 1494 if (PrepareReport(feedback_state, it->second, &report_block, | 1451 if (PrepareReport(feedback_state, it->first, it->second, |
| 1495 &context.ntp_sec, &context.ntp_frac)) { | 1452 &report_block)) { |
| 1496 AddReportBlock(it->first, &internal_report_blocks_, &report_block); | 1453 AddReportBlock(report_block); |
| 1497 } | 1454 } |
| 1498 } | 1455 } |
| 1499 if (extended_jitter_report_enabled_) | 1456 if (extended_jitter_report_enabled_) |
| 1500 SetFlag(kRtcpTransmissionTimeOffset, true); | 1457 SetFlag(kRtcpTransmissionTimeOffset, true); |
| 1501 } | 1458 } |
| 1502 } | 1459 } |
| 1503 | 1460 |
| 1504 auto it = report_flags_.begin(); | 1461 auto it = report_flags_.begin(); |
| 1505 while (it != report_flags_.end()) { | 1462 while (it != report_flags_.end()) { |
| 1506 auto builder = builders_.find(it->type); | 1463 auto builder = builders_.find(it->type); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1532 packet_type_counter_observer_->RtcpPacketTypesCounterUpdated( | 1489 packet_type_counter_observer_->RtcpPacketTypesCounterUpdated( |
| 1533 remote_ssrc_, packet_type_counter_); | 1490 remote_ssrc_, packet_type_counter_); |
| 1534 } | 1491 } |
| 1535 | 1492 |
| 1536 DCHECK(AllVolatileFlagsConsumed()); | 1493 DCHECK(AllVolatileFlagsConsumed()); |
| 1537 | 1494 |
| 1538 return context.position; | 1495 return context.position; |
| 1539 } | 1496 } |
| 1540 | 1497 |
| 1541 bool RTCPSender::PrepareReport(const FeedbackState& feedback_state, | 1498 bool RTCPSender::PrepareReport(const FeedbackState& feedback_state, |
| 1499 uint32_t ssrc, |
| 1542 StreamStatistician* statistician, | 1500 StreamStatistician* statistician, |
| 1543 RTCPReportBlock* report_block, | 1501 RTCPReportBlock* report_block) { |
| 1544 uint32_t* ntp_secs, uint32_t* ntp_frac) { | |
| 1545 // Do we have receive statistics to send? | 1502 // Do we have receive statistics to send? |
| 1546 RtcpStatistics stats; | 1503 RtcpStatistics stats; |
| 1547 if (!statistician->GetStatistics(&stats, true)) | 1504 if (!statistician->GetStatistics(&stats, true)) |
| 1548 return false; | 1505 return false; |
| 1549 report_block->fractionLost = stats.fraction_lost; | 1506 report_block->fractionLost = stats.fraction_lost; |
| 1550 report_block->cumulativeLost = stats.cumulative_lost; | 1507 report_block->cumulativeLost = stats.cumulative_lost; |
| 1551 report_block->extendedHighSeqNum = | 1508 report_block->extendedHighSeqNum = |
| 1552 stats.extended_max_sequence_number; | 1509 stats.extended_max_sequence_number; |
| 1553 report_block->jitter = stats.jitter; | 1510 report_block->jitter = stats.jitter; |
| 1511 report_block->remoteSSRC = ssrc; |
| 1554 | 1512 |
| 1555 // get our NTP as late as possible to avoid a race | 1513 // TODO(sprang): Do we really need separate time stamps for each report? |
| 1556 clock_->CurrentNtp(*ntp_secs, *ntp_frac); | 1514 // Get our NTP as late as possible to avoid a race. |
| 1515 uint32_t ntp_secs; |
| 1516 uint32_t ntp_frac; |
| 1517 clock_->CurrentNtp(ntp_secs, ntp_frac); |
| 1557 | 1518 |
| 1558 // Delay since last received report | 1519 // Delay since last received report. |
| 1559 uint32_t delaySinceLastReceivedSR = 0; | 1520 uint32_t delaySinceLastReceivedSR = 0; |
| 1560 if ((feedback_state.last_rr_ntp_secs != 0) || | 1521 if ((feedback_state.last_rr_ntp_secs != 0) || |
| 1561 (feedback_state.last_rr_ntp_frac != 0)) { | 1522 (feedback_state.last_rr_ntp_frac != 0)) { |
| 1562 // get the 16 lowest bits of seconds and the 16 higest bits of fractions | 1523 // Get the 16 lowest bits of seconds and the 16 highest bits of fractions. |
| 1563 uint32_t now = *ntp_secs & 0x0000FFFF; | 1524 uint32_t now = ntp_secs & 0x0000FFFF; |
| 1564 now <<= 16; | 1525 now <<= 16; |
| 1565 now += (*ntp_frac & 0xffff0000) >> 16; | 1526 now += (ntp_frac & 0xffff0000) >> 16; |
| 1566 | 1527 |
| 1567 uint32_t receiveTime = feedback_state.last_rr_ntp_secs & 0x0000FFFF; | 1528 uint32_t receiveTime = feedback_state.last_rr_ntp_secs & 0x0000FFFF; |
| 1568 receiveTime <<= 16; | 1529 receiveTime <<= 16; |
| 1569 receiveTime += (feedback_state.last_rr_ntp_frac & 0xffff0000) >> 16; | 1530 receiveTime += (feedback_state.last_rr_ntp_frac & 0xffff0000) >> 16; |
| 1570 | 1531 |
| 1571 delaySinceLastReceivedSR = now-receiveTime; | 1532 delaySinceLastReceivedSR = now-receiveTime; |
| 1572 } | 1533 } |
| 1573 report_block->delaySinceLastSR = delaySinceLastReceivedSR; | 1534 report_block->delaySinceLastSR = delaySinceLastReceivedSR; |
| 1574 report_block->lastSR = feedback_state.remote_sr; | 1535 report_block->lastSR = feedback_state.remote_sr; |
| 1575 return true; | 1536 return true; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1620 void RTCPSender::SendRtcpXrReceiverReferenceTime(bool enable) { | 1581 void RTCPSender::SendRtcpXrReceiverReferenceTime(bool enable) { |
| 1621 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); | 1582 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); |
| 1622 xr_send_receiver_reference_time_enabled_ = enable; | 1583 xr_send_receiver_reference_time_enabled_ = enable; |
| 1623 } | 1584 } |
| 1624 | 1585 |
| 1625 bool RTCPSender::RtcpXrReceiverReferenceTime() const { | 1586 bool RTCPSender::RtcpXrReceiverReferenceTime() const { |
| 1626 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); | 1587 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); |
| 1627 return xr_send_receiver_reference_time_enabled_; | 1588 return xr_send_receiver_reference_time_enabled_; |
| 1628 } | 1589 } |
| 1629 | 1590 |
| 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 | 1591 // no callbacks allowed inside this function |
| 1684 int32_t RTCPSender::SetTMMBN(const TMMBRSet* boundingSet, | 1592 int32_t RTCPSender::SetTMMBN(const TMMBRSet* boundingSet, |
| 1685 uint32_t maxBitrateKbit) { | 1593 uint32_t maxBitrateKbit) { |
| 1686 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); | 1594 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); |
| 1687 | 1595 |
| 1688 if (0 == tmmbr_help_.SetTMMBRBoundingSetToSend(boundingSet, maxBitrateKbit)) { | 1596 if (0 == tmmbr_help_.SetTMMBRBoundingSetToSend(boundingSet, maxBitrateKbit)) { |
| 1689 SetFlag(kRtcpTmmbn, true); | 1597 SetFlag(kRtcpTmmbn, true); |
| 1690 return 0; | 1598 return 0; |
| 1691 } | 1599 } |
| 1692 return -1; | 1600 return -1; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1717 | 1625 |
| 1718 bool RTCPSender::AllVolatileFlagsConsumed() const { | 1626 bool RTCPSender::AllVolatileFlagsConsumed() const { |
| 1719 for (const ReportFlag& flag : report_flags_) { | 1627 for (const ReportFlag& flag : report_flags_) { |
| 1720 if (flag.is_volatile) | 1628 if (flag.is_volatile) |
| 1721 return false; | 1629 return false; |
| 1722 } | 1630 } |
| 1723 return true; | 1631 return true; |
| 1724 } | 1632 } |
| 1725 | 1633 |
| 1726 } // namespace webrtc | 1634 } // namespace webrtc |
| OLD | NEW |