1470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 2f6bb77a6f0d250f8c4c2c4dbf059556c00cf8eafpwestin@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 4470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Use of this source code is governed by a BSD-style license 5470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * that can be found in the LICENSE file in the root of the source 6470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * tree. An additional intellectual property rights grant can be found 7470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * in the file PATENTS. All contributing project authors may 8470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * be found in the AUTHORS file in the root of the source tree. 9470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 10470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 11a048d7cb0a5bad5ca49bbcc5273cb4cca28c1710pbos@webrtc.org#include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h" 12470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1312dc1a38ca54a000e4fecfbc6d41138b895c9ca5pbos@webrtc.org#include <assert.h> // assert 149354cc965c04a0c79ea36622043751596a6fd015stefan@webrtc.org#include <string.h> // memcpy 15470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1612dc1a38ca54a000e4fecfbc6d41138b895c9ca5pbos@webrtc.org#include <algorithm> // min 1761be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng#include <limits> // max 18b8b6fbb7a5d2f5a14f7f6f81c253747aa28e4c7fdanilchap#include <utility> 1912dc1a38ca54a000e4fecfbc6d41138b895c9ca5pbos@webrtc.org 2061be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng#include "webrtc/base/checks.h" 21ebc0b4e99365443111857a0c7cfcc8944d8f1b6ePeter Boström#include "webrtc/base/logging.h" 22e4f96501fc5b3e6de0d1ccd262372afcda1f5b4ftommi#include "webrtc/base/trace_event.h" 23a048d7cb0a5bad5ca49bbcc5273cb4cca28c1710pbos@webrtc.org#include "webrtc/common_types.h" 24779c3d16b9623f38a72439bc013102aeb0077a62sprang@webrtc.org#include "webrtc/modules/rtp_rtcp/source/byte_io.h" 250219c9b4bfcbb778137756210eb95f40d936cc66danilchap#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/app.h" 2650c5136cb2ad11eb9ba3df1a1d54d527c8a0dc77danilchap#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/bye.h" 272f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet.h" 28a8890a57a5d03f942924ff61d3c62244f2bdab10danilchap#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/nack.h" 29f8385aded0943c7889d6e9b92f3c0978f3657bb2danilchap#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/pli.h" 3097f7e13c23ddb26543f33bce944d501e58d1dd9bDanil Chapovalov#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report.h" 3192e677a1f8d24dfa0031d307c4a7d8e530cd4eb4danilchap#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sli.h" 32ef3d805f6e50bc488f8e4e9e353068b78c73d17fdanilchap#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn.h" 337e8145f05d5f6921ffca3d62e9c4d1301c1d8bcbdanilchap#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr.h" 34233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" 35e4f96501fc5b3e6de0d1ccd262372afcda1f5b4ftommi#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h" 3698f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/critical_section_wrapper.h" 37741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org 38470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comnamespace webrtc { 3926f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org 4026f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.orgusing RTCPUtility::RTCPCnameInformation; 4126f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org 4261be2a401635eed1d13c169dc104b9ff4a2f477bErik SprångNACKStringBuilder::NACKStringBuilder() 43162abd3562d7b08ab36569800d757b52739b9249danilchap : stream_(""), count_(0), prevNack_(0), consecutive_(false) {} 4479b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com 45f3e4ceee47d747c8868d919c179ecc640b9541f0pbos@webrtc.orgNACKStringBuilder::~NACKStringBuilder() {} 46f3e4ceee47d747c8868d919c179ecc640b9541f0pbos@webrtc.org 47162abd3562d7b08ab36569800d757b52739b9249danilchapvoid NACKStringBuilder::PushNACK(uint16_t nack) { 48242e22b055940be70b1df3031e2363b0d02397b2Erik Språng if (count_ == 0) { 49242e22b055940be70b1df3031e2363b0d02397b2Erik Språng stream_ << nack; 50242e22b055940be70b1df3031e2363b0d02397b2Erik Språng } else if (nack == prevNack_ + 1) { 51242e22b055940be70b1df3031e2363b0d02397b2Erik Språng consecutive_ = true; 5261be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng } else { 53242e22b055940be70b1df3031e2363b0d02397b2Erik Språng if (consecutive_) { 54242e22b055940be70b1df3031e2363b0d02397b2Erik Språng stream_ << "-" << prevNack_; 55242e22b055940be70b1df3031e2363b0d02397b2Erik Språng consecutive_ = false; 5679b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com } 57242e22b055940be70b1df3031e2363b0d02397b2Erik Språng stream_ << "," << nack; 5861be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng } 59242e22b055940be70b1df3031e2363b0d02397b2Erik Språng count_++; 60242e22b055940be70b1df3031e2363b0d02397b2Erik Språng prevNack_ = nack; 6179b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com} 6279b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com 6361be2a401635eed1d13c169dc104b9ff4a2f477bErik Språngstd::string NACKStringBuilder::GetResult() { 64242e22b055940be70b1df3031e2363b0d02397b2Erik Språng if (consecutive_) { 65242e22b055940be70b1df3031e2363b0d02397b2Erik Språng stream_ << "-" << prevNack_; 66242e22b055940be70b1df3031e2363b0d02397b2Erik Språng consecutive_ = false; 6761be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng } 68242e22b055940be70b1df3031e2363b0d02397b2Erik Språng return stream_.str(); 6979b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com} 7079b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com 7159f20bb735562d245357609799578edeed46be32pbos@webrtc.orgRTCPSender::FeedbackState::FeedbackState() 7259f20bb735562d245357609799578edeed46be32pbos@webrtc.org : send_payload_type(0), 7359f20bb735562d245357609799578edeed46be32pbos@webrtc.org frequency_hz(0), 742f4b14e3f31b34a50310357c6c7be86c3bca1537pbos@webrtc.org packets_sent(0), 752f4b14e3f31b34a50310357c6c7be86c3bca1537pbos@webrtc.org media_bytes_sent(0), 7659f20bb735562d245357609799578edeed46be32pbos@webrtc.org send_bitrate(0), 7759f20bb735562d245357609799578edeed46be32pbos@webrtc.org last_rr_ntp_secs(0), 7859f20bb735562d245357609799578edeed46be32pbos@webrtc.org last_rr_ntp_frac(0), 798469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org remote_sr(0), 8061be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng has_last_xr_rr(false), 81162abd3562d7b08ab36569800d757b52739b9249danilchap module(nullptr) {} 8259f20bb735562d245357609799578edeed46be32pbos@webrtc.org 832f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchapclass PacketContainer : public rtcp::CompoundPacket, 84f7c5776d4254e31e51107388a05c66d14108a8afErik Språng public rtcp::RtcpPacket::PacketReadyCallback { 85f7c5776d4254e31e51107388a05c66d14108a8afErik Språng public: 86f7c5776d4254e31e51107388a05c66d14108a8afErik Språng explicit PacketContainer(Transport* transport) 87f7c5776d4254e31e51107388a05c66d14108a8afErik Språng : transport_(transport), bytes_sent_(0) {} 88f7c5776d4254e31e51107388a05c66d14108a8afErik Språng virtual ~PacketContainer() { 89f7c5776d4254e31e51107388a05c66d14108a8afErik Språng for (RtcpPacket* packet : appended_packets_) 90f7c5776d4254e31e51107388a05c66d14108a8afErik Språng delete packet; 91242e22b055940be70b1df3031e2363b0d02397b2Erik Språng } 92242e22b055940be70b1df3031e2363b0d02397b2Erik Språng 93bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng void OnPacketReady(uint8_t* data, size_t length) override { 94f7c5776d4254e31e51107388a05c66d14108a8afErik Språng if (transport_->SendRtcp(data, length)) 95f7c5776d4254e31e51107388a05c66d14108a8afErik Språng bytes_sent_ += length; 96bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng } 97f7c5776d4254e31e51107388a05c66d14108a8afErik Språng 98f7c5776d4254e31e51107388a05c66d14108a8afErik Språng size_t SendPackets() { 992f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap rtcp::CompoundPacket::Build(this); 100f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return bytes_sent_; 10172aa9a6c6e8d05c744496ad8c53273ec49556d28Erik Språng } 102bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng 103bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng private: 104f7c5776d4254e31e51107388a05c66d14108a8afErik Språng Transport* transport_; 105f7c5776d4254e31e51107388a05c66d14108a8afErik Språng size_t bytes_sent_; 106f7c5776d4254e31e51107388a05c66d14108a8afErik Språng}; 107f7c5776d4254e31e51107388a05c66d14108a8afErik Språng 108f7c5776d4254e31e51107388a05c66d14108a8afErik Språngclass RTCPSender::RtcpContext { 109f7c5776d4254e31e51107388a05c66d14108a8afErik Språng public: 110f7c5776d4254e31e51107388a05c66d14108a8afErik Språng RtcpContext(const FeedbackState& feedback_state, 111f7c5776d4254e31e51107388a05c66d14108a8afErik Språng int32_t nack_size, 112f7c5776d4254e31e51107388a05c66d14108a8afErik Språng const uint16_t* nack_list, 113f7c5776d4254e31e51107388a05c66d14108a8afErik Språng bool repeat, 114f7c5776d4254e31e51107388a05c66d14108a8afErik Språng uint64_t picture_id, 115f7c5776d4254e31e51107388a05c66d14108a8afErik Språng uint32_t ntp_sec, 116f7c5776d4254e31e51107388a05c66d14108a8afErik Språng uint32_t ntp_frac, 117f7c5776d4254e31e51107388a05c66d14108a8afErik Språng PacketContainer* container) 118f7c5776d4254e31e51107388a05c66d14108a8afErik Språng : feedback_state_(feedback_state), 119f7c5776d4254e31e51107388a05c66d14108a8afErik Språng nack_size_(nack_size), 120f7c5776d4254e31e51107388a05c66d14108a8afErik Språng nack_list_(nack_list), 121f7c5776d4254e31e51107388a05c66d14108a8afErik Språng repeat_(repeat), 122f7c5776d4254e31e51107388a05c66d14108a8afErik Språng picture_id_(picture_id), 123f7c5776d4254e31e51107388a05c66d14108a8afErik Språng ntp_sec_(ntp_sec), 124f7c5776d4254e31e51107388a05c66d14108a8afErik Språng ntp_frac_(ntp_frac), 125f7c5776d4254e31e51107388a05c66d14108a8afErik Språng container_(container) {} 126f7c5776d4254e31e51107388a05c66d14108a8afErik Språng 127f7c5776d4254e31e51107388a05c66d14108a8afErik Språng virtual ~RtcpContext() {} 128f7c5776d4254e31e51107388a05c66d14108a8afErik Språng 129f7c5776d4254e31e51107388a05c66d14108a8afErik Språng const FeedbackState& feedback_state_; 130f7c5776d4254e31e51107388a05c66d14108a8afErik Språng const int32_t nack_size_; 131f7c5776d4254e31e51107388a05c66d14108a8afErik Språng const uint16_t* nack_list_; 132f7c5776d4254e31e51107388a05c66d14108a8afErik Språng const bool repeat_; 133f7c5776d4254e31e51107388a05c66d14108a8afErik Språng const uint64_t picture_id_; 134f7c5776d4254e31e51107388a05c66d14108a8afErik Språng const uint32_t ntp_sec_; 135f7c5776d4254e31e51107388a05c66d14108a8afErik Språng const uint32_t ntp_frac_; 136f7c5776d4254e31e51107388a05c66d14108a8afErik Språng 137f7c5776d4254e31e51107388a05c66d14108a8afErik Språng PacketContainer* const container_; 138bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng}; 139bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng 1401d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.orgRTCPSender::RTCPSender( 1411d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org bool audio, 1421d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org Clock* clock, 1431d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org ReceiveStatistics* receive_statistics, 14486fd9ed6f9e2a38aa343db8c62764659633231fasprang RtcpPacketTypeCounterObserver* packet_type_counter_observer, 14586fd9ed6f9e2a38aa343db8c62764659633231fasprang Transport* outgoing_transport) 146ac547a653862744d0aae560713f8418ad2852085Peter Boström : audio_(audio), 147242e22b055940be70b1df3031e2363b0d02397b2Erik Språng clock_(clock), 14847a740bc5e36bcaf19385f9d4c0afb0cad070a05danilchap random_(clock_->TimeInMicroseconds()), 149da903eaabbb6c6830efcafc3c2ade1d36f511e43pbos method_(RtcpMode::kOff), 15086fd9ed6f9e2a38aa343db8c62764659633231fasprang transport_(outgoing_transport), 151d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org 152242e22b055940be70b1df3031e2363b0d02397b2Erik Språng critical_section_rtcp_sender_( 153d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org CriticalSectionWrapper::CreateCriticalSection()), 154242e22b055940be70b1df3031e2363b0d02397b2Erik Språng using_nack_(false), 155242e22b055940be70b1df3031e2363b0d02397b2Erik Språng sending_(false), 156242e22b055940be70b1df3031e2363b0d02397b2Erik Språng remb_enabled_(false), 157242e22b055940be70b1df3031e2363b0d02397b2Erik Språng next_time_to_send_rtcp_(0), 158d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org start_timestamp_(0), 159d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org last_rtp_timestamp_(0), 160d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org last_frame_capture_time_ms_(-1), 161242e22b055940be70b1df3031e2363b0d02397b2Erik Språng ssrc_(0), 162242e22b055940be70b1df3031e2363b0d02397b2Erik Språng remote_ssrc_(0), 163d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org receive_statistics_(receive_statistics), 164d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org 165242e22b055940be70b1df3031e2363b0d02397b2Erik Språng sequence_number_fir_(0), 166d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org 167242e22b055940be70b1df3031e2363b0d02397b2Erik Språng remb_bitrate_(0), 168d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org 169242e22b055940be70b1df3031e2363b0d02397b2Erik Språng tmmbr_help_(), 170242e22b055940be70b1df3031e2363b0d02397b2Erik Språng tmmbr_send_(0), 171242e22b055940be70b1df3031e2363b0d02397b2Erik Språng packet_oh_send_(0), 172d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org 173242e22b055940be70b1df3031e2363b0d02397b2Erik Språng app_sub_type_(0), 174bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng app_name_(0), 175242e22b055940be70b1df3031e2363b0d02397b2Erik Språng app_data_(nullptr), 176242e22b055940be70b1df3031e2363b0d02397b2Erik Språng app_length_(0), 177d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org 178242e22b055940be70b1df3031e2363b0d02397b2Erik Språng xr_send_receiver_reference_time_enabled_(false), 1791d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org packet_type_counter_observer_(packet_type_counter_observer) { 180242e22b055940be70b1df3031e2363b0d02397b2Erik Språng memset(last_send_report_, 0, sizeof(last_send_report_)); 181242e22b055940be70b1df3031e2363b0d02397b2Erik Språng memset(last_rtcp_time_, 0, sizeof(last_rtcp_time_)); 18286fd9ed6f9e2a38aa343db8c62764659633231fasprang RTC_DCHECK(transport_ != nullptr); 183242e22b055940be70b1df3031e2363b0d02397b2Erik Språng 184242e22b055940be70b1df3031e2363b0d02397b2Erik Språng builders_[kRtcpSr] = &RTCPSender::BuildSR; 185242e22b055940be70b1df3031e2363b0d02397b2Erik Språng builders_[kRtcpRr] = &RTCPSender::BuildRR; 1860ea42d319e2a18785f5de5fe8d52e0a7a5fd1448Erik Språng builders_[kRtcpSdes] = &RTCPSender::BuildSDES; 187242e22b055940be70b1df3031e2363b0d02397b2Erik Språng builders_[kRtcpPli] = &RTCPSender::BuildPLI; 188242e22b055940be70b1df3031e2363b0d02397b2Erik Språng builders_[kRtcpFir] = &RTCPSender::BuildFIR; 189242e22b055940be70b1df3031e2363b0d02397b2Erik Språng builders_[kRtcpSli] = &RTCPSender::BuildSLI; 190242e22b055940be70b1df3031e2363b0d02397b2Erik Språng builders_[kRtcpRpsi] = &RTCPSender::BuildRPSI; 191242e22b055940be70b1df3031e2363b0d02397b2Erik Språng builders_[kRtcpRemb] = &RTCPSender::BuildREMB; 192242e22b055940be70b1df3031e2363b0d02397b2Erik Språng builders_[kRtcpBye] = &RTCPSender::BuildBYE; 193242e22b055940be70b1df3031e2363b0d02397b2Erik Språng builders_[kRtcpApp] = &RTCPSender::BuildAPP; 194242e22b055940be70b1df3031e2363b0d02397b2Erik Språng builders_[kRtcpTmmbr] = &RTCPSender::BuildTMMBR; 195242e22b055940be70b1df3031e2363b0d02397b2Erik Språng builders_[kRtcpTmmbn] = &RTCPSender::BuildTMMBN; 196242e22b055940be70b1df3031e2363b0d02397b2Erik Språng builders_[kRtcpNack] = &RTCPSender::BuildNACK; 197242e22b055940be70b1df3031e2363b0d02397b2Erik Språng builders_[kRtcpXrVoipMetric] = &RTCPSender::BuildVoIPMetric; 198242e22b055940be70b1df3031e2363b0d02397b2Erik Språng builders_[kRtcpXrReceiverReferenceTime] = 199242e22b055940be70b1df3031e2363b0d02397b2Erik Språng &RTCPSender::BuildReceiverReferenceTime; 200242e22b055940be70b1df3031e2363b0d02397b2Erik Språng builders_[kRtcpXrDlrrReportBlock] = &RTCPSender::BuildDlrr; 201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 203162abd3562d7b08ab36569800d757b52739b9249danilchapRTCPSender::~RTCPSender() {} 204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 205da903eaabbb6c6830efcafc3c2ade1d36f511e43pbosRtcpMode RTCPSender::Status() const { 206242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 207242e22b055940be70b1df3031e2363b0d02397b2Erik Språng return method_; 208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 210da903eaabbb6c6830efcafc3c2ade1d36f511e43pbosvoid RTCPSender::SetRTCPStatus(RtcpMode method) { 211242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 212242e22b055940be70b1df3031e2363b0d02397b2Erik Språng method_ = method; 213d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org 214da903eaabbb6c6830efcafc3c2ade1d36f511e43pbos if (method == RtcpMode::kOff) 215d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org return; 216242e22b055940be70b1df3031e2363b0d02397b2Erik Språng next_time_to_send_rtcp_ = 217242e22b055940be70b1df3031e2363b0d02397b2Erik Språng clock_->TimeInMilliseconds() + 218242e22b055940be70b1df3031e2363b0d02397b2Erik Språng (audio_ ? RTCP_INTERVAL_AUDIO_MS / 2 : RTCP_INTERVAL_VIDEO_MS / 2); 219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 22161be2a401635eed1d13c169dc104b9ff4a2f477bErik Språngbool RTCPSender::Sending() const { 222242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 223242e22b055940be70b1df3031e2363b0d02397b2Erik Språng return sending_; 224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 22661be2a401635eed1d13c169dc104b9ff4a2f477bErik Språngint32_t RTCPSender::SetSendingStatus(const FeedbackState& feedback_state, 22761be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng bool sending) { 22861be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng bool sendRTCPBye = false; 22961be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng { 230242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 23161be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng 232da903eaabbb6c6830efcafc3c2ade1d36f511e43pbos if (method_ != RtcpMode::kOff) { 233242e22b055940be70b1df3031e2363b0d02397b2Erik Språng if (sending == false && sending_ == true) { 23461be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // Trigger RTCP bye 23561be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng sendRTCPBye = true; 23661be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng } 237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 238242e22b055940be70b1df3031e2363b0d02397b2Erik Språng sending_ = sending; 23961be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng } 24061be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng if (sendRTCPBye) 24161be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng return SendRTCP(feedback_state, kRtcpBye); 24261be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng return 0; 243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 24561be2a401635eed1d13c169dc104b9ff4a2f477bErik Språngbool RTCPSender::REMB() const { 246242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 247242e22b055940be70b1df3031e2363b0d02397b2Erik Språng return remb_enabled_; 248741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org} 249741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org 250d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.orgvoid RTCPSender::SetREMBStatus(bool enable) { 251242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 252242e22b055940be70b1df3031e2363b0d02397b2Erik Språng remb_enabled_ = enable; 253741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org} 254741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org 255d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.orgvoid RTCPSender::SetREMBData(uint32_t bitrate, 256d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org const std::vector<uint32_t>& ssrcs) { 257242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 258242e22b055940be70b1df3031e2363b0d02397b2Erik Språng remb_bitrate_ = bitrate; 259d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org remb_ssrcs_ = ssrcs; 2604ef438e2defd6c46404f6b367287364cde66b7fbstefan@webrtc.org 261242e22b055940be70b1df3031e2363b0d02397b2Erik Språng if (remb_enabled_) 262242e22b055940be70b1df3031e2363b0d02397b2Erik Språng SetFlag(kRtcpRemb, false); 263d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org // Send a REMB immediately if we have a new REMB. The frequency of REMBs is 264d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org // throttled by the caller. 265242e22b055940be70b1df3031e2363b0d02397b2Erik Språng next_time_to_send_rtcp_ = clock_->TimeInMilliseconds(); 266741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org} 267741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org 26861be2a401635eed1d13c169dc104b9ff4a2f477bErik Språngbool RTCPSender::TMMBR() const { 269242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 270242e22b055940be70b1df3031e2363b0d02397b2Erik Språng return IsFlagPresent(RTCPPacketType::kRtcpTmmbr); 271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 273d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.orgvoid RTCPSender::SetTMMBRStatus(bool enable) { 274242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 275242e22b055940be70b1df3031e2363b0d02397b2Erik Språng if (enable) { 276242e22b055940be70b1df3031e2363b0d02397b2Erik Språng SetFlag(RTCPPacketType::kRtcpTmmbr, false); 277242e22b055940be70b1df3031e2363b0d02397b2Erik Språng } else { 278242e22b055940be70b1df3031e2363b0d02397b2Erik Språng ConsumeFlag(RTCPPacketType::kRtcpTmmbr, true); 279242e22b055940be70b1df3031e2363b0d02397b2Erik Språng } 280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2827c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.orgvoid RTCPSender::SetStartTimestamp(uint32_t start_timestamp) { 283242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 2847c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org start_timestamp_ = start_timestamp; 2857c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org} 2867c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org 2877c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.orgvoid RTCPSender::SetLastRtpTime(uint32_t rtp_timestamp, 2887c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org int64_t capture_time_ms) { 289242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 2907c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org last_rtp_timestamp_ = rtp_timestamp; 2917c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org if (capture_time_ms < 0) { 2927c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org // We don't currently get a capture time from VoiceEngine. 293242e22b055940be70b1df3031e2363b0d02397b2Erik Språng last_frame_capture_time_ms_ = clock_->TimeInMilliseconds(); 2947c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org } else { 2957c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org last_frame_capture_time_ms_ = capture_time_ms; 2967c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org } 2977c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org} 2987c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org 299d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.orgvoid RTCPSender::SetSSRC(uint32_t ssrc) { 300242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 30161be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng 302242e22b055940be70b1df3031e2363b0d02397b2Erik Språng if (ssrc_ != 0) { 30361be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // not first SetSSRC, probably due to a collision 30461be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // schedule a new RTCP report 30561be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // make sure that we send a RTP packet 306242e22b055940be70b1df3031e2363b0d02397b2Erik Språng next_time_to_send_rtcp_ = clock_->TimeInMilliseconds() + 100; 30761be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng } 308242e22b055940be70b1df3031e2363b0d02397b2Erik Språng ssrc_ = ssrc; 309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 31161be2a401635eed1d13c169dc104b9ff4a2f477bErik Språngvoid RTCPSender::SetRemoteSSRC(uint32_t ssrc) { 312242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 313242e22b055940be70b1df3031e2363b0d02397b2Erik Språng remote_ssrc_ = ssrc; 314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3169ba52f89acd1b9bc88115880dfe2716147bf3b5dPeter Boströmint32_t RTCPSender::SetCNAME(const char* c_name) { 3179ba52f89acd1b9bc88115880dfe2716147bf3b5dPeter Boström if (!c_name) 318a990e122c461e24d19e3249718782e671a811eadtommi@webrtc.org return -1; 319a990e122c461e24d19e3249718782e671a811eadtommi@webrtc.org 32091d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK_LT(strlen(c_name), static_cast<size_t>(RTCP_CNAME_SIZE)); 321242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 3220ea42d319e2a18785f5de5fe8d52e0a7a5fd1448Erik Språng cname_ = c_name; 32326f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org return 0; 324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3260ea42d319e2a18785f5de5fe8d52e0a7a5fd1448Erik Språngint32_t RTCPSender::AddMixedCNAME(uint32_t SSRC, const char* c_name) { 3270ea42d319e2a18785f5de5fe8d52e0a7a5fd1448Erik Språng assert(c_name); 32891d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK_LT(strlen(c_name), static_cast<size_t>(RTCP_CNAME_SIZE)); 329242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 3300ea42d319e2a18785f5de5fe8d52e0a7a5fd1448Erik Språng if (csrc_cnames_.size() >= kRtpCsrcSize) 33126f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org return -1; 3320ea42d319e2a18785f5de5fe8d52e0a7a5fd1448Erik Språng 3330ea42d319e2a18785f5de5fe8d52e0a7a5fd1448Erik Språng csrc_cnames_[SSRC] = c_name; 33426f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org return 0; 33526f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org} 336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 337d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.orgint32_t RTCPSender::RemoveMixedCNAME(uint32_t SSRC) { 338242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 3390ea42d319e2a18785f5de5fe8d52e0a7a5fd1448Erik Språng auto it = csrc_cnames_.find(SSRC); 340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 341242e22b055940be70b1df3031e2363b0d02397b2Erik Språng if (it == csrc_cnames_.end()) 342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 34361be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng 344242e22b055940be70b1df3031e2363b0d02397b2Erik Språng csrc_cnames_.erase(it); 34526f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org return 0; 346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 348d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.orgbool RTCPSender::TimeToSendRTCPReport(bool sendKeyframeBeforeRTP) const { 349162abd3562d7b08ab36569800d757b52739b9249danilchap /* 350162abd3562d7b08ab36569800d757b52739b9249danilchap For audio we use a fix 5 sec interval 351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 352162abd3562d7b08ab36569800d757b52739b9249danilchap For video we use 1 sec interval fo a BW smaller than 360 kbit/s, 353162abd3562d7b08ab36569800d757b52739b9249danilchap technicaly we break the max 5% RTCP BW for video below 10 kbit/s but 354162abd3562d7b08ab36569800d757b52739b9249danilchap that should be extremely rare 355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 357162abd3562d7b08ab36569800d757b52739b9249danilchap From RFC 3550 358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 359162abd3562d7b08ab36569800d757b52739b9249danilchap MAX RTCP BW is 5% if the session BW 360162abd3562d7b08ab36569800d757b52739b9249danilchap A send report is approximately 65 bytes inc CNAME 361162abd3562d7b08ab36569800d757b52739b9249danilchap A receiver report is approximately 28 bytes 362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 363162abd3562d7b08ab36569800d757b52739b9249danilchap The RECOMMENDED value for the reduced minimum in seconds is 360 364162abd3562d7b08ab36569800d757b52739b9249danilchap divided by the session bandwidth in kilobits/second. This minimum 365162abd3562d7b08ab36569800d757b52739b9249danilchap is smaller than 5 seconds for bandwidths greater than 72 kb/s. 366470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 367162abd3562d7b08ab36569800d757b52739b9249danilchap If the participant has not yet sent an RTCP packet (the variable 368162abd3562d7b08ab36569800d757b52739b9249danilchap initial is true), the constant Tmin is set to 2.5 seconds, else it 369162abd3562d7b08ab36569800d757b52739b9249danilchap is set to 5 seconds. 370470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 371162abd3562d7b08ab36569800d757b52739b9249danilchap The interval between RTCP packets is varied randomly over the 372162abd3562d7b08ab36569800d757b52739b9249danilchap range [0.5,1.5] times the calculated interval to avoid unintended 373162abd3562d7b08ab36569800d757b52739b9249danilchap synchronization of all participants 374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 375162abd3562d7b08ab36569800d757b52739b9249danilchap if we send 376162abd3562d7b08ab36569800d757b52739b9249danilchap If the participant is a sender (we_sent true), the constant C is 377162abd3562d7b08ab36569800d757b52739b9249danilchap set to the average RTCP packet size (avg_rtcp_size) divided by 25% 378162abd3562d7b08ab36569800d757b52739b9249danilchap of the RTCP bandwidth (rtcp_bw), and the constant n is set to the 379162abd3562d7b08ab36569800d757b52739b9249danilchap number of senders. 380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 381162abd3562d7b08ab36569800d757b52739b9249danilchap if we receive only 382162abd3562d7b08ab36569800d757b52739b9249danilchap If we_sent is not true, the constant C is set 383162abd3562d7b08ab36569800d757b52739b9249danilchap to the average RTCP packet size divided by 75% of the RTCP 384162abd3562d7b08ab36569800d757b52739b9249danilchap bandwidth. The constant n is set to the number of receivers 385162abd3562d7b08ab36569800d757b52739b9249danilchap (members - senders). If the number of senders is greater than 386162abd3562d7b08ab36569800d757b52739b9249danilchap 25%, senders and receivers are treated together. 387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 388162abd3562d7b08ab36569800d757b52739b9249danilchap reconsideration NOT required for peer-to-peer 389162abd3562d7b08ab36569800d757b52739b9249danilchap "timer reconsideration" is 390162abd3562d7b08ab36569800d757b52739b9249danilchap employed. This algorithm implements a simple back-off mechanism 391162abd3562d7b08ab36569800d757b52739b9249danilchap which causes users to hold back RTCP packet transmission if the 392162abd3562d7b08ab36569800d757b52739b9249danilchap group sizes are increasing. 393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 394162abd3562d7b08ab36569800d757b52739b9249danilchap n = number of members 395162abd3562d7b08ab36569800d757b52739b9249danilchap C = avg_size/(rtcpBW/4) 396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 397162abd3562d7b08ab36569800d757b52739b9249danilchap 3. The deterministic calculated interval Td is set to max(Tmin, n*C). 398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 399162abd3562d7b08ab36569800d757b52739b9249danilchap 4. The calculated interval T is set to a number uniformly distributed 400162abd3562d7b08ab36569800d757b52739b9249danilchap between 0.5 and 1.5 times the deterministic calculated interval. 401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 402162abd3562d7b08ab36569800d757b52739b9249danilchap 5. The resulting value of T is divided by e-3/2=1.21828 to compensate 403162abd3562d7b08ab36569800d757b52739b9249danilchap for the fact that the timer reconsideration algorithm converges to 404162abd3562d7b08ab36569800d757b52739b9249danilchap a value of the RTCP bandwidth below the intended average 405162abd3562d7b08ab36569800d757b52739b9249danilchap */ 406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 407242e22b055940be70b1df3031e2363b0d02397b2Erik Språng int64_t now = clock_->TimeInMilliseconds(); 408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 409242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 411da903eaabbb6c6830efcafc3c2ade1d36f511e43pbos if (method_ == RtcpMode::kOff) 412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return false; 413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 414242e22b055940be70b1df3031e2363b0d02397b2Erik Språng if (!audio_ && sendKeyframeBeforeRTP) { 41561be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // for video key-frames we want to send the RTCP before the large key-frame 41661be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // if we have a 100 ms margin 41761be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng now += RTCP_SEND_BEFORE_KEY_FRAME_MS; 41861be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng } 419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 420242e22b055940be70b1df3031e2363b0d02397b2Erik Språng if (now >= next_time_to_send_rtcp_) { 42161be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng return true; 42261be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng } else if (now < 0x0000ffff && 423242e22b055940be70b1df3031e2363b0d02397b2Erik Språng next_time_to_send_rtcp_ > 0xffff0000) { // 65 sec margin 42461be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // wrap 42561be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng return true; 42661be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng } 42761be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng return false; 428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 43016825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.orgint64_t RTCPSender::SendTimeOfSendReport(uint32_t sendReport) { 431242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 43261be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng 43361be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // This is only saved when we are the sender 434242e22b055940be70b1df3031e2363b0d02397b2Erik Språng if ((last_send_report_[0] == 0) || (sendReport == 0)) { 43561be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng return 0; // will be ignored 43661be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng } else { 43761be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng for (int i = 0; i < RTCP_NUMBER_OF_SR; ++i) { 438242e22b055940be70b1df3031e2363b0d02397b2Erik Språng if (last_send_report_[i] == sendReport) 439242e22b055940be70b1df3031e2363b0d02397b2Erik Språng return last_rtcp_time_[i]; 440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 44161be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng } 44261be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng return 0; 443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4458469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.orgbool RTCPSender::SendTimeOfXrRrReport(uint32_t mid_ntp, 4468469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org int64_t* time_ms) const { 447242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 4488469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org 4498469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org if (last_xr_rr_.empty()) { 4508469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org return false; 4518469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org } 4528469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org std::map<uint32_t, int64_t>::const_iterator it = last_xr_rr_.find(mid_ntp); 4538469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org if (it == last_xr_rr_.end()) { 4548469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org return false; 4558469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org } 4568469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org *time_ms = it->second; 4578469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org return true; 4588469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org} 4598469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org 460f7c5776d4254e31e51107388a05c66d14108a8afErik Språngrtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildSR(const RtcpContext& ctx) { 46161be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng for (int i = (RTCP_NUMBER_OF_SR - 2); i >= 0; i--) { 46261be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // shift old 463242e22b055940be70b1df3031e2363b0d02397b2Erik Språng last_send_report_[i + 1] = last_send_report_[i]; 464242e22b055940be70b1df3031e2363b0d02397b2Erik Språng last_rtcp_time_[i + 1] = last_rtcp_time_[i]; 46561be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng } 466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 467f7c5776d4254e31e51107388a05c66d14108a8afErik Språng last_rtcp_time_[0] = Clock::NtpToMs(ctx.ntp_sec_, ctx.ntp_frac_); 468f7c5776d4254e31e51107388a05c66d14108a8afErik Språng last_send_report_[0] = (ctx.ntp_sec_ << 16) + (ctx.ntp_frac_ >> 16); 469470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 47061be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // The timestamp of this RTCP packet should be estimated as the timestamp of 47161be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // the frame being captured at this moment. We are calculating that 47261be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // timestamp as the last frame's timestamp + the time since the last frame 47361be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // was captured. 474bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng uint32_t rtp_timestamp = 475bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng start_timestamp_ + last_rtp_timestamp_ + 476bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng (clock_->TimeInMilliseconds() - last_frame_capture_time_ms_) * 477f7c5776d4254e31e51107388a05c66d14108a8afErik Språng (ctx.feedback_state_.frequency_hz / 1000); 478bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng 479f7c5776d4254e31e51107388a05c66d14108a8afErik Språng rtcp::SenderReport* report = new rtcp::SenderReport(); 480f7c5776d4254e31e51107388a05c66d14108a8afErik Språng report->From(ssrc_); 481f7c5776d4254e31e51107388a05c66d14108a8afErik Språng report->WithNtpSec(ctx.ntp_sec_); 482f7c5776d4254e31e51107388a05c66d14108a8afErik Språng report->WithNtpFrac(ctx.ntp_frac_); 483f7c5776d4254e31e51107388a05c66d14108a8afErik Språng report->WithRtpTimestamp(rtp_timestamp); 484f7c5776d4254e31e51107388a05c66d14108a8afErik Språng report->WithPacketCount(ctx.feedback_state_.packets_sent); 485f7c5776d4254e31e51107388a05c66d14108a8afErik Språng report->WithOctetCount(ctx.feedback_state_.media_bytes_sent); 486bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng 487bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng for (auto it : report_blocks_) 488f7c5776d4254e31e51107388a05c66d14108a8afErik Språng report->WithReportBlock(it.second); 489242e22b055940be70b1df3031e2363b0d02397b2Erik Språng 490bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng report_blocks_.clear(); 491f7c5776d4254e31e51107388a05c66d14108a8afErik Språng 492f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return rtc::scoped_ptr<rtcp::SenderReport>(report); 49361be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng} 494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 495f7c5776d4254e31e51107388a05c66d14108a8afErik Språngrtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildSDES( 496f7c5776d4254e31e51107388a05c66d14108a8afErik Språng const RtcpContext& ctx) { 4970ea42d319e2a18785f5de5fe8d52e0a7a5fd1448Erik Språng size_t length_cname = cname_.length(); 49891d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_CHECK_LT(length_cname, static_cast<size_t>(RTCP_CNAME_SIZE)); 499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 500f7c5776d4254e31e51107388a05c66d14108a8afErik Språng rtcp::Sdes* sdes = new rtcp::Sdes(); 501f7c5776d4254e31e51107388a05c66d14108a8afErik Språng sdes->WithCName(ssrc_, cname_); 502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5030ea42d319e2a18785f5de5fe8d52e0a7a5fd1448Erik Språng for (const auto it : csrc_cnames_) 504f7c5776d4254e31e51107388a05c66d14108a8afErik Språng sdes->WithCName(it.first, it.second); 505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 506f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return rtc::scoped_ptr<rtcp::Sdes>(sdes); 507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 509f7c5776d4254e31e51107388a05c66d14108a8afErik Språngrtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildRR(const RtcpContext& ctx) { 510f7c5776d4254e31e51107388a05c66d14108a8afErik Språng rtcp::ReceiverReport* report = new rtcp::ReceiverReport(); 511f7c5776d4254e31e51107388a05c66d14108a8afErik Språng report->From(ssrc_); 512bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng for (auto it : report_blocks_) 513f7c5776d4254e31e51107388a05c66d14108a8afErik Språng report->WithReportBlock(it.second); 51461be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng 515bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng report_blocks_.clear(); 516f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return rtc::scoped_ptr<rtcp::ReceiverReport>(report); 517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 519f7c5776d4254e31e51107388a05c66d14108a8afErik Språngrtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildPLI(const RtcpContext& ctx) { 520f7c5776d4254e31e51107388a05c66d14108a8afErik Språng rtcp::Pli* pli = new rtcp::Pli(); 521f7c5776d4254e31e51107388a05c66d14108a8afErik Språng pli->From(ssrc_); 522f7c5776d4254e31e51107388a05c66d14108a8afErik Språng pli->To(remote_ssrc_); 523242e22b055940be70b1df3031e2363b0d02397b2Erik Språng 524242e22b055940be70b1df3031e2363b0d02397b2Erik Språng TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), 525242e22b055940be70b1df3031e2363b0d02397b2Erik Språng "RTCPSender::PLI"); 526242e22b055940be70b1df3031e2363b0d02397b2Erik Språng ++packet_type_counter_.pli_packets; 527242e22b055940be70b1df3031e2363b0d02397b2Erik Språng TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_PLICount", 528242e22b055940be70b1df3031e2363b0d02397b2Erik Språng ssrc_, packet_type_counter_.pli_packets); 529242e22b055940be70b1df3031e2363b0d02397b2Erik Språng 530f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return rtc::scoped_ptr<rtcp::Pli>(pli); 531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 533f7c5776d4254e31e51107388a05c66d14108a8afErik Språngrtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildFIR(const RtcpContext& ctx) { 534f7c5776d4254e31e51107388a05c66d14108a8afErik Språng if (!ctx.repeat_) 53562dae190985454188de112e35a16e35fc6e912a4sprang ++sequence_number_fir_; // Do not increase if repetition. 536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 537f7c5776d4254e31e51107388a05c66d14108a8afErik Språng rtcp::Fir* fir = new rtcp::Fir(); 538f7c5776d4254e31e51107388a05c66d14108a8afErik Språng fir->From(ssrc_); 539f7c5776d4254e31e51107388a05c66d14108a8afErik Språng fir->To(remote_ssrc_); 540f7c5776d4254e31e51107388a05c66d14108a8afErik Språng fir->WithCommandSeqNum(sequence_number_fir_); 541242e22b055940be70b1df3031e2363b0d02397b2Erik Språng 542242e22b055940be70b1df3031e2363b0d02397b2Erik Språng TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), 543242e22b055940be70b1df3031e2363b0d02397b2Erik Språng "RTCPSender::FIR"); 544242e22b055940be70b1df3031e2363b0d02397b2Erik Språng ++packet_type_counter_.fir_packets; 545242e22b055940be70b1df3031e2363b0d02397b2Erik Språng TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_FIRCount", 546242e22b055940be70b1df3031e2363b0d02397b2Erik Språng ssrc_, packet_type_counter_.fir_packets); 547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 548f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return rtc::scoped_ptr<rtcp::Fir>(fir); 549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 0 1 2 3 553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 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 554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com | First | Number | PictureID | 556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com*/ 558f7c5776d4254e31e51107388a05c66d14108a8afErik Språngrtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildSLI(const RtcpContext& ctx) { 559f7c5776d4254e31e51107388a05c66d14108a8afErik Språng rtcp::Sli* sli = new rtcp::Sli(); 560f7c5776d4254e31e51107388a05c66d14108a8afErik Språng sli->From(ssrc_); 561f7c5776d4254e31e51107388a05c66d14108a8afErik Språng sli->To(remote_ssrc_); 5620365a27f56aa2d2376d2f356bf70d161c3450244sprang // Crop picture id to 6 least significant bits. 563f7c5776d4254e31e51107388a05c66d14108a8afErik Språng sli->WithPictureId(ctx.picture_id_ & 0x3F); 564242e22b055940be70b1df3031e2363b0d02397b2Erik Språng 565f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return rtc::scoped_ptr<rtcp::Sli>(sli); 566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 567470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 0 1 2 3 570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 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 571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com | PB |0| Payload Type| Native RPSI bit string | 573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com | defined per codec ... | Padding (0) | 575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com*/ 577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com* Note: not generic made for VP8 579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com*/ 580f7c5776d4254e31e51107388a05c66d14108a8afErik Språngrtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildRPSI( 581f7c5776d4254e31e51107388a05c66d14108a8afErik Språng const RtcpContext& ctx) { 582f7c5776d4254e31e51107388a05c66d14108a8afErik Språng if (ctx.feedback_state_.send_payload_type == 0xFF) 583f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return nullptr; 584242e22b055940be70b1df3031e2363b0d02397b2Erik Språng 585f7c5776d4254e31e51107388a05c66d14108a8afErik Språng rtcp::Rpsi* rpsi = new rtcp::Rpsi(); 586f7c5776d4254e31e51107388a05c66d14108a8afErik Språng rpsi->From(ssrc_); 587f7c5776d4254e31e51107388a05c66d14108a8afErik Språng rpsi->To(remote_ssrc_); 588f7c5776d4254e31e51107388a05c66d14108a8afErik Språng rpsi->WithPayloadType(ctx.feedback_state_.send_payload_type); 589f7c5776d4254e31e51107388a05c66d14108a8afErik Språng rpsi->WithPictureId(ctx.picture_id_); 59061be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng 591f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return rtc::scoped_ptr<rtcp::Rpsi>(rpsi); 592470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 594f7c5776d4254e31e51107388a05c66d14108a8afErik Språngrtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildREMB( 595f7c5776d4254e31e51107388a05c66d14108a8afErik Språng const RtcpContext& ctx) { 596f7c5776d4254e31e51107388a05c66d14108a8afErik Språng rtcp::Remb* remb = new rtcp::Remb(); 597f7c5776d4254e31e51107388a05c66d14108a8afErik Språng remb->From(ssrc_); 598dd4edc5813a0331049f53a93ac2404a8899e6ae8sprang for (uint32_t ssrc : remb_ssrcs_) 599f7c5776d4254e31e51107388a05c66d14108a8afErik Språng remb->AppliesTo(ssrc); 600f7c5776d4254e31e51107388a05c66d14108a8afErik Språng remb->WithBitrateBps(remb_bitrate_); 601141c5951f4beda868797c2746002a4b1b267ab2asprang 602242e22b055940be70b1df3031e2363b0d02397b2Erik Språng TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), 603242e22b055940be70b1df3031e2363b0d02397b2Erik Språng "RTCPSender::REMB"); 604242e22b055940be70b1df3031e2363b0d02397b2Erik Språng 605f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return rtc::scoped_ptr<rtcp::Remb>(remb); 606741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org} 607741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org 60861be2a401635eed1d13c169dc104b9ff4a2f477bErik Språngvoid RTCPSender::SetTargetBitrate(unsigned int target_bitrate) { 609242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 610242e22b055940be70b1df3031e2363b0d02397b2Erik Språng tmmbr_send_ = target_bitrate / 1000; 611117c119501e3ed80d12b18979959357e8bf2ba61mflodman@webrtc.org} 612117c119501e3ed80d12b18979959357e8bf2ba61mflodman@webrtc.org 613f7c5776d4254e31e51107388a05c66d14108a8afErik Språngrtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildTMMBR( 614f7c5776d4254e31e51107388a05c66d14108a8afErik Språng const RtcpContext& ctx) { 615f7c5776d4254e31e51107388a05c66d14108a8afErik Språng if (ctx.feedback_state_.module == nullptr) 616f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return nullptr; 61761be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // Before sending the TMMBR check the received TMMBN, only an owner is 61861be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // allowed to raise the bitrate: 61961be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // * If the sender is an owner of the TMMBN -> send TMMBR 62061be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // * If not an owner but the TMMBR would enter the TMMBN -> send TMMBR 62161be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng 62261be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // get current bounding set from RTCP receiver 62361be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng bool tmmbrOwner = false; 62461be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // store in candidateSet, allocates one extra slot 625242e22b055940be70b1df3031e2363b0d02397b2Erik Språng TMMBRSet* candidateSet = tmmbr_help_.CandidateSet(); 62661be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng 627242e22b055940be70b1df3031e2363b0d02397b2Erik Språng // holding critical_section_rtcp_sender_ while calling RTCPreceiver which 628242e22b055940be70b1df3031e2363b0d02397b2Erik Språng // will accuire criticalSectionRTCPReceiver_ is a potental deadlock but 62961be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // since RTCPreceiver is not doing the reverse we should be fine 63061be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng int32_t lengthOfBoundingSet = 6316db6cdc604f9a866991ecf8454eb7f7aa69918eadanilchap ctx.feedback_state_.module->BoundingSet(&tmmbrOwner, candidateSet); 63261be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng 63361be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng if (lengthOfBoundingSet > 0) { 63461be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng for (int32_t i = 0; i < lengthOfBoundingSet; i++) { 635242e22b055940be70b1df3031e2363b0d02397b2Erik Språng if (candidateSet->Tmmbr(i) == tmmbr_send_ && 636242e22b055940be70b1df3031e2363b0d02397b2Erik Språng candidateSet->PacketOH(i) == packet_oh_send_) { 637f7c5776d4254e31e51107388a05c66d14108a8afErik Språng // Do not send the same tuple. 638f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return nullptr; 63961be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng } 640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 64161be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng if (!tmmbrOwner) { 64261be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // use received bounding set as candidate set 64361be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // add current tuple 644242e22b055940be70b1df3031e2363b0d02397b2Erik Språng candidateSet->SetEntry(lengthOfBoundingSet, tmmbr_send_, packet_oh_send_, 645242e22b055940be70b1df3031e2363b0d02397b2Erik Språng ssrc_); 64661be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng int numCandidates = lengthOfBoundingSet + 1; 64761be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng 64861be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // find bounding set 649f7c5776d4254e31e51107388a05c66d14108a8afErik Språng TMMBRSet* boundingSet = nullptr; 650242e22b055940be70b1df3031e2363b0d02397b2Erik Språng int numBoundingSet = tmmbr_help_.FindTMMBRBoundingSet(boundingSet); 65161be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng if (numBoundingSet > 0 || numBoundingSet <= numCandidates) 652242e22b055940be70b1df3031e2363b0d02397b2Erik Språng tmmbrOwner = tmmbr_help_.IsOwner(ssrc_, numBoundingSet); 65361be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng if (!tmmbrOwner) { 654f7c5776d4254e31e51107388a05c66d14108a8afErik Språng // Did not enter bounding set, no meaning to send this request. 655f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return nullptr; 65661be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng } 657470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 65861be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng } 659470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 660f7c5776d4254e31e51107388a05c66d14108a8afErik Språng if (!tmmbr_send_) 661f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return nullptr; 66281a3e60c639b5b05486acd1fb84e376271e50012sprang 663f7c5776d4254e31e51107388a05c66d14108a8afErik Språng rtcp::Tmmbr* tmmbr = new rtcp::Tmmbr(); 664f7c5776d4254e31e51107388a05c66d14108a8afErik Språng tmmbr->From(ssrc_); 665f7c5776d4254e31e51107388a05c66d14108a8afErik Språng tmmbr->To(remote_ssrc_); 666f7c5776d4254e31e51107388a05c66d14108a8afErik Språng tmmbr->WithBitrateKbps(tmmbr_send_); 667f7c5776d4254e31e51107388a05c66d14108a8afErik Språng tmmbr->WithOverhead(packet_oh_send_); 668f7c5776d4254e31e51107388a05c66d14108a8afErik Språng 669f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return rtc::scoped_ptr<rtcp::Tmmbr>(tmmbr); 670470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 671470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 672f7c5776d4254e31e51107388a05c66d14108a8afErik Språngrtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildTMMBN( 673f7c5776d4254e31e51107388a05c66d14108a8afErik Språng const RtcpContext& ctx) { 674242e22b055940be70b1df3031e2363b0d02397b2Erik Språng TMMBRSet* boundingSet = tmmbr_help_.BoundingSetToSend(); 675f7c5776d4254e31e51107388a05c66d14108a8afErik Språng if (boundingSet == nullptr) 676f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return nullptr; 67761be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng 678f7c5776d4254e31e51107388a05c66d14108a8afErik Språng rtcp::Tmmbn* tmmbn = new rtcp::Tmmbn(); 679f7c5776d4254e31e51107388a05c66d14108a8afErik Språng tmmbn->From(ssrc_); 680d83df50e95a73859bee1568ec7375ff832e1d628sprang for (uint32_t i = 0; i < boundingSet->lengthOfSet(); i++) { 681d83df50e95a73859bee1568ec7375ff832e1d628sprang if (boundingSet->Tmmbr(i) > 0) { 682f7c5776d4254e31e51107388a05c66d14108a8afErik Språng tmmbn->WithTmmbr(boundingSet->Ssrc(i), boundingSet->Tmmbr(i), 683f7c5776d4254e31e51107388a05c66d14108a8afErik Språng boundingSet->PacketOH(i)); 684470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 68561be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng } 686d83df50e95a73859bee1568ec7375ff832e1d628sprang 687f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return rtc::scoped_ptr<rtcp::Tmmbn>(tmmbn); 68861be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng} 689470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 690f7c5776d4254e31e51107388a05c66d14108a8afErik Språngrtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildAPP(const RtcpContext& ctx) { 691f7c5776d4254e31e51107388a05c66d14108a8afErik Språng rtcp::App* app = new rtcp::App(); 692f7c5776d4254e31e51107388a05c66d14108a8afErik Språng app->From(ssrc_); 693f7c5776d4254e31e51107388a05c66d14108a8afErik Språng app->WithSubType(app_sub_type_); 694f7c5776d4254e31e51107388a05c66d14108a8afErik Språng app->WithName(app_name_); 695f7c5776d4254e31e51107388a05c66d14108a8afErik Språng app->WithData(app_data_.get(), app_length_); 696470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 697f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return rtc::scoped_ptr<rtcp::App>(app); 698470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 700f7c5776d4254e31e51107388a05c66d14108a8afErik Språngrtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildNACK( 701f7c5776d4254e31e51107388a05c66d14108a8afErik Språng const RtcpContext& ctx) { 702f7c5776d4254e31e51107388a05c66d14108a8afErik Språng rtcp::Nack* nack = new rtcp::Nack(); 703f7c5776d4254e31e51107388a05c66d14108a8afErik Språng nack->From(ssrc_); 704f7c5776d4254e31e51107388a05c66d14108a8afErik Språng nack->To(remote_ssrc_); 705f7c5776d4254e31e51107388a05c66d14108a8afErik Språng nack->WithList(ctx.nack_list_, ctx.nack_size_); 7062dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org 70761be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // Report stats. 70861be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng NACKStringBuilder stringBuilder; 709f7c5776d4254e31e51107388a05c66d14108a8afErik Språng for (int idx = 0; idx < ctx.nack_size_; ++idx) { 710f7c5776d4254e31e51107388a05c66d14108a8afErik Språng stringBuilder.PushNACK(ctx.nack_list_[idx]); 711f7c5776d4254e31e51107388a05c66d14108a8afErik Språng nack_stats_.ReportRequest(ctx.nack_list_[idx]); 71261be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng } 71361be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng packet_type_counter_.nack_requests = nack_stats_.requests(); 71461be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests(); 715242e22b055940be70b1df3031e2363b0d02397b2Erik Språng 716242e22b055940be70b1df3031e2363b0d02397b2Erik Språng TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), 717242e22b055940be70b1df3031e2363b0d02397b2Erik Språng "RTCPSender::NACK", "nacks", 718242e22b055940be70b1df3031e2363b0d02397b2Erik Språng TRACE_STR_COPY(stringBuilder.GetResult().c_str())); 719242e22b055940be70b1df3031e2363b0d02397b2Erik Språng ++packet_type_counter_.nack_packets; 720242e22b055940be70b1df3031e2363b0d02397b2Erik Språng TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_NACKCount", 721242e22b055940be70b1df3031e2363b0d02397b2Erik Språng ssrc_, packet_type_counter_.nack_packets); 722242e22b055940be70b1df3031e2363b0d02397b2Erik Språng 723f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return rtc::scoped_ptr<rtcp::Nack>(nack); 724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 725470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 726f7c5776d4254e31e51107388a05c66d14108a8afErik Språngrtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildBYE(const RtcpContext& ctx) { 727f7c5776d4254e31e51107388a05c66d14108a8afErik Språng rtcp::Bye* bye = new rtcp::Bye(); 728f7c5776d4254e31e51107388a05c66d14108a8afErik Språng bye->From(ssrc_); 729d8ee4f99154691752dd8d2f2d70750554dca7ca7sprang for (uint32_t csrc : csrcs_) 730f7c5776d4254e31e51107388a05c66d14108a8afErik Språng bye->WithCsrc(csrc); 731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 732f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return rtc::scoped_ptr<rtcp::Bye>(bye); 733470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 734470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 735f7c5776d4254e31e51107388a05c66d14108a8afErik Språngrtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildReceiverReferenceTime( 736f7c5776d4254e31e51107388a05c66d14108a8afErik Språng const RtcpContext& ctx) { 73761be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng if (last_xr_rr_.size() >= RTCP_NUMBER_OF_SR) 7388469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org last_xr_rr_.erase(last_xr_rr_.begin()); 7398469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org last_xr_rr_.insert(std::pair<uint32_t, int64_t>( 740f7c5776d4254e31e51107388a05c66d14108a8afErik Språng RTCPUtility::MidNtp(ctx.ntp_sec_, ctx.ntp_frac_), 741f7c5776d4254e31e51107388a05c66d14108a8afErik Språng Clock::NtpToMs(ctx.ntp_sec_, ctx.ntp_frac_))); 7428469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org 743f7c5776d4254e31e51107388a05c66d14108a8afErik Språng rtcp::Xr* xr = new rtcp::Xr(); 744f7c5776d4254e31e51107388a05c66d14108a8afErik Språng xr->From(ssrc_); 7458469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org 746ca28fdcf9f061193671ef71c492ad3cd8c193a59Erik Språng rtcp::Rrtr rrtr; 747fc47ed6c0524d7ee0bc7947f0ad65fcefda34a29Danil Chapovalov rrtr.WithNtp(NtpTime(ctx.ntp_sec_, ctx.ntp_frac_)); 7488469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org 749f7c5776d4254e31e51107388a05c66d14108a8afErik Språng xr->WithRrtr(&rrtr); 750ca28fdcf9f061193671ef71c492ad3cd8c193a59Erik Språng 751ca28fdcf9f061193671ef71c492ad3cd8c193a59Erik Språng // TODO(sprang): Merge XR report sending to contain all of RRTR, DLRR, VOIP? 752ca28fdcf9f061193671ef71c492ad3cd8c193a59Erik Språng 753f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return rtc::scoped_ptr<rtcp::Xr>(xr); 7548469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org} 7558469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org 756f7c5776d4254e31e51107388a05c66d14108a8afErik Språngrtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildDlrr( 757f7c5776d4254e31e51107388a05c66d14108a8afErik Språng const RtcpContext& ctx) { 758f7c5776d4254e31e51107388a05c66d14108a8afErik Språng rtcp::Xr* xr = new rtcp::Xr(); 759f7c5776d4254e31e51107388a05c66d14108a8afErik Språng xr->From(ssrc_); 7608469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org 761ca28fdcf9f061193671ef71c492ad3cd8c193a59Erik Språng rtcp::Dlrr dlrr; 762f7c5776d4254e31e51107388a05c66d14108a8afErik Språng const RtcpReceiveTimeInfo& info = ctx.feedback_state_.last_xr_rr; 763ca28fdcf9f061193671ef71c492ad3cd8c193a59Erik Språng dlrr.WithDlrrItem(info.sourceSSRC, info.lastRR, info.delaySinceLastRR); 7648469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org 765f7c5776d4254e31e51107388a05c66d14108a8afErik Språng xr->WithDlrr(&dlrr); 7668469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org 767f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return rtc::scoped_ptr<rtcp::Xr>(xr); 7688469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org} 7698469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org 770242e22b055940be70b1df3031e2363b0d02397b2Erik Språng// TODO(sprang): Add a unit test for this, or remove if the code isn't used. 771f7c5776d4254e31e51107388a05c66d14108a8afErik Språngrtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildVoIPMetric( 772f7c5776d4254e31e51107388a05c66d14108a8afErik Språng const RtcpContext& context) { 773f7c5776d4254e31e51107388a05c66d14108a8afErik Språng rtcp::Xr* xr = new rtcp::Xr(); 774f7c5776d4254e31e51107388a05c66d14108a8afErik Språng xr->From(ssrc_); 775ca28fdcf9f061193671ef71c492ad3cd8c193a59Erik Språng 776ca28fdcf9f061193671ef71c492ad3cd8c193a59Erik Språng rtcp::VoipMetric voip; 777ca28fdcf9f061193671ef71c492ad3cd8c193a59Erik Språng voip.To(remote_ssrc_); 77891941ae493cb37a4e1250c7d3aad1c7394b5850edanilchap voip.WithVoipMetric(xr_voip_metric_); 779ca28fdcf9f061193671ef71c492ad3cd8c193a59Erik Språng 780f7c5776d4254e31e51107388a05c66d14108a8afErik Språng xr->WithVoipMetric(&voip); 781242e22b055940be70b1df3031e2363b0d02397b2Erik Språng 782f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return rtc::scoped_ptr<rtcp::Xr>(xr); 783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 784470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 78559f20bb735562d245357609799578edeed46be32pbos@webrtc.orgint32_t RTCPSender::SendRTCP(const FeedbackState& feedback_state, 786242e22b055940be70b1df3031e2363b0d02397b2Erik Språng RTCPPacketType packetType, 787242e22b055940be70b1df3031e2363b0d02397b2Erik Språng int32_t nack_size, 788242e22b055940be70b1df3031e2363b0d02397b2Erik Språng const uint16_t* nack_list, 78959f20bb735562d245357609799578edeed46be32pbos@webrtc.org bool repeat, 79059f20bb735562d245357609799578edeed46be32pbos@webrtc.org uint64_t pictureID) { 791242e22b055940be70b1df3031e2363b0d02397b2Erik Språng return SendCompoundRTCP( 792242e22b055940be70b1df3031e2363b0d02397b2Erik Språng feedback_state, std::set<RTCPPacketType>(&packetType, &packetType + 1), 793242e22b055940be70b1df3031e2363b0d02397b2Erik Språng nack_size, nack_list, repeat, pictureID); 794242e22b055940be70b1df3031e2363b0d02397b2Erik Språng} 795242e22b055940be70b1df3031e2363b0d02397b2Erik Språng 796242e22b055940be70b1df3031e2363b0d02397b2Erik Språngint32_t RTCPSender::SendCompoundRTCP( 797242e22b055940be70b1df3031e2363b0d02397b2Erik Språng const FeedbackState& feedback_state, 798f7c5776d4254e31e51107388a05c66d14108a8afErik Språng const std::set<RTCPPacketType>& packet_types, 799242e22b055940be70b1df3031e2363b0d02397b2Erik Språng int32_t nack_size, 800242e22b055940be70b1df3031e2363b0d02397b2Erik Språng const uint16_t* nack_list, 801242e22b055940be70b1df3031e2363b0d02397b2Erik Språng bool repeat, 802242e22b055940be70b1df3031e2363b0d02397b2Erik Språng uint64_t pictureID) { 803f7c5776d4254e31e51107388a05c66d14108a8afErik Språng PacketContainer container(transport_); 804286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 805242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 806da903eaabbb6c6830efcafc3c2ade1d36f511e43pbos if (method_ == RtcpMode::kOff) { 80761be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng LOG(LS_WARNING) << "Can't send rtcp if it is disabled."; 80861be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng return -1; 809286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 81061be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng 811f7c5776d4254e31e51107388a05c66d14108a8afErik Språng // We need to send our NTP even if we haven't received any reports. 812f7c5776d4254e31e51107388a05c66d14108a8afErik Språng uint32_t ntp_sec; 813f7c5776d4254e31e51107388a05c66d14108a8afErik Språng uint32_t ntp_frac; 814f7c5776d4254e31e51107388a05c66d14108a8afErik Språng clock_->CurrentNtp(ntp_sec, ntp_frac); 815f7c5776d4254e31e51107388a05c66d14108a8afErik Språng RtcpContext context(feedback_state, nack_size, nack_list, repeat, pictureID, 816f7c5776d4254e31e51107388a05c66d14108a8afErik Språng ntp_sec, ntp_frac, &container); 817f7c5776d4254e31e51107388a05c66d14108a8afErik Språng 818f7c5776d4254e31e51107388a05c66d14108a8afErik Språng PrepareReport(packet_types, feedback_state); 819f7c5776d4254e31e51107388a05c66d14108a8afErik Språng 820f7c5776d4254e31e51107388a05c66d14108a8afErik Språng auto it = report_flags_.begin(); 821f7c5776d4254e31e51107388a05c66d14108a8afErik Språng while (it != report_flags_.end()) { 822f7c5776d4254e31e51107388a05c66d14108a8afErik Språng auto builder_it = builders_.find(it->type); 823f7c5776d4254e31e51107388a05c66d14108a8afErik Språng RTC_DCHECK(builder_it != builders_.end()); 824f7c5776d4254e31e51107388a05c66d14108a8afErik Språng if (it->is_volatile) { 825f7c5776d4254e31e51107388a05c66d14108a8afErik Språng report_flags_.erase(it++); 826f7c5776d4254e31e51107388a05c66d14108a8afErik Språng } else { 827f7c5776d4254e31e51107388a05c66d14108a8afErik Språng ++it; 828f7c5776d4254e31e51107388a05c66d14108a8afErik Språng } 82961be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng 830f7c5776d4254e31e51107388a05c66d14108a8afErik Språng BuilderFunc func = builder_it->second; 831f7c5776d4254e31e51107388a05c66d14108a8afErik Språng rtc::scoped_ptr<rtcp::RtcpPacket> packet = (this->*func)(context); 832f7c5776d4254e31e51107388a05c66d14108a8afErik Språng if (packet.get() == nullptr) 833f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return -1; 834f7c5776d4254e31e51107388a05c66d14108a8afErik Språng container.Append(packet.release()); 835f7c5776d4254e31e51107388a05c66d14108a8afErik Språng } 836a0218a84d17a727111e2e24cf5af915b1b91c06ehenrike@webrtc.org 837f7c5776d4254e31e51107388a05c66d14108a8afErik Språng if (packet_type_counter_observer_ != nullptr) { 838f7c5776d4254e31e51107388a05c66d14108a8afErik Språng packet_type_counter_observer_->RtcpPacketTypesCounterUpdated( 839f7c5776d4254e31e51107388a05c66d14108a8afErik Språng remote_ssrc_, packet_type_counter_); 840f7c5776d4254e31e51107388a05c66d14108a8afErik Språng } 841242e22b055940be70b1df3031e2363b0d02397b2Erik Språng 842f7c5776d4254e31e51107388a05c66d14108a8afErik Språng RTC_DCHECK(AllVolatileFlagsConsumed()); 843f7c5776d4254e31e51107388a05c66d14108a8afErik Språng } 844f7c5776d4254e31e51107388a05c66d14108a8afErik Språng 845f7c5776d4254e31e51107388a05c66d14108a8afErik Språng size_t bytes_sent = container.SendPackets(); 846f7c5776d4254e31e51107388a05c66d14108a8afErik Språng return bytes_sent == 0 ? -1 : 0; 847f7c5776d4254e31e51107388a05c66d14108a8afErik Språng} 848a0218a84d17a727111e2e24cf5af915b1b91c06ehenrike@webrtc.org 849f7c5776d4254e31e51107388a05c66d14108a8afErik Språngvoid RTCPSender::PrepareReport(const std::set<RTCPPacketType>& packetTypes, 850f7c5776d4254e31e51107388a05c66d14108a8afErik Språng const FeedbackState& feedback_state) { 851242e22b055940be70b1df3031e2363b0d02397b2Erik Språng // Add all flags as volatile. Non volatile entries will not be overwritten 852242e22b055940be70b1df3031e2363b0d02397b2Erik Språng // and all new volatile flags added will be consumed by the end of this call. 853242e22b055940be70b1df3031e2363b0d02397b2Erik Språng SetFlags(packetTypes, true); 854a0218a84d17a727111e2e24cf5af915b1b91c06ehenrike@webrtc.org 85561be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng if (packet_type_counter_.first_packet_time_ms == -1) 856242e22b055940be70b1df3031e2363b0d02397b2Erik Språng packet_type_counter_.first_packet_time_ms = clock_->TimeInMilliseconds(); 85761be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng 858242e22b055940be70b1df3031e2363b0d02397b2Erik Språng bool generate_report; 859242e22b055940be70b1df3031e2363b0d02397b2Erik Språng if (IsFlagPresent(kRtcpSr) || IsFlagPresent(kRtcpRr)) { 860242e22b055940be70b1df3031e2363b0d02397b2Erik Språng // Report type already explicitly set, don't automatically populate. 861242e22b055940be70b1df3031e2363b0d02397b2Erik Språng generate_report = true; 86291d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(ConsumeFlag(kRtcpReport) == false); 863242e22b055940be70b1df3031e2363b0d02397b2Erik Språng } else { 864242e22b055940be70b1df3031e2363b0d02397b2Erik Språng generate_report = 865da903eaabbb6c6830efcafc3c2ade1d36f511e43pbos (ConsumeFlag(kRtcpReport) && method_ == RtcpMode::kReducedSize) || 866da903eaabbb6c6830efcafc3c2ade1d36f511e43pbos method_ == RtcpMode::kCompound; 867242e22b055940be70b1df3031e2363b0d02397b2Erik Språng if (generate_report) 868242e22b055940be70b1df3031e2363b0d02397b2Erik Språng SetFlag(sending_ ? kRtcpSr : kRtcpRr, true); 869286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 870242e22b055940be70b1df3031e2363b0d02397b2Erik Språng 8710ea42d319e2a18785f5de5fe8d52e0a7a5fd1448Erik Språng if (IsFlagPresent(kRtcpSr) || (IsFlagPresent(kRtcpRr) && !cname_.empty())) 872242e22b055940be70b1df3031e2363b0d02397b2Erik Språng SetFlag(kRtcpSdes, true); 873242e22b055940be70b1df3031e2363b0d02397b2Erik Språng 874242e22b055940be70b1df3031e2363b0d02397b2Erik Språng if (generate_report) { 875242e22b055940be70b1df3031e2363b0d02397b2Erik Språng if (!sending_ && xr_send_receiver_reference_time_enabled_) 876242e22b055940be70b1df3031e2363b0d02397b2Erik Språng SetFlag(kRtcpXrReceiverReferenceTime, true); 87761be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng if (feedback_state.has_last_xr_rr) 878242e22b055940be70b1df3031e2363b0d02397b2Erik Språng SetFlag(kRtcpXrDlrrReportBlock, true); 879242e22b055940be70b1df3031e2363b0d02397b2Erik Språng 880242e22b055940be70b1df3031e2363b0d02397b2Erik Språng // generate next time to send an RTCP report 88147a740bc5e36bcaf19385f9d4c0afb0cad070a05danilchap uint32_t minIntervalMs = RTCP_INTERVAL_AUDIO_MS; 88247a740bc5e36bcaf19385f9d4c0afb0cad070a05danilchap 88347a740bc5e36bcaf19385f9d4c0afb0cad070a05danilchap if (!audio_) { 884242e22b055940be70b1df3031e2363b0d02397b2Erik Språng if (sending_) { 88561be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng // Calculate bandwidth for video; 360 / send bandwidth in kbit/s. 88661be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng uint32_t send_bitrate_kbit = feedback_state.send_bitrate / 1000; 88761be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng if (send_bitrate_kbit != 0) 88861be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng minIntervalMs = 360000 / send_bitrate_kbit; 889286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 89061be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng if (minIntervalMs > RTCP_INTERVAL_VIDEO_MS) 89161be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng minIntervalMs = RTCP_INTERVAL_VIDEO_MS; 89261be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng } 89347a740bc5e36bcaf19385f9d4c0afb0cad070a05danilchap // The interval between RTCP packets is varied randomly over the 89447a740bc5e36bcaf19385f9d4c0afb0cad070a05danilchap // range [1/2,3/2] times the calculated interval. 89547a740bc5e36bcaf19385f9d4c0afb0cad070a05danilchap uint32_t timeToNext = 89647a740bc5e36bcaf19385f9d4c0afb0cad070a05danilchap random_.Rand(minIntervalMs * 1 / 2, minIntervalMs * 3 / 2); 897242e22b055940be70b1df3031e2363b0d02397b2Erik Språng next_time_to_send_rtcp_ = clock_->TimeInMilliseconds() + timeToNext; 898a0218a84d17a727111e2e24cf5af915b1b91c06ehenrike@webrtc.org 899286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org StatisticianMap statisticians = 900286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org receive_statistics_->GetActiveStatisticians(); 901a72e7349d52366655076e609e9e32d456da7f5a2danilchap RTC_DCHECK(report_blocks_.empty()); 902a72e7349d52366655076e609e9e32d456da7f5a2danilchap for (auto& it : statisticians) { 903a72e7349d52366655076e609e9e32d456da7f5a2danilchap AddReportBlock(feedback_state, it.first, it.second); 904286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 905286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 906286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org} 907a0218a84d17a727111e2e24cf5af915b1b91c06ehenrike@webrtc.org 908a72e7349d52366655076e609e9e32d456da7f5a2danilchapbool RTCPSender::AddReportBlock(const FeedbackState& feedback_state, 909a72e7349d52366655076e609e9e32d456da7f5a2danilchap uint32_t ssrc, 910a72e7349d52366655076e609e9e32d456da7f5a2danilchap StreamStatistician* statistician) { 911286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org // Do we have receive statistics to send? 91254ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org RtcpStatistics stats; 913286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (!statistician->GetStatistics(&stats, true)) 914286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return false; 915a72e7349d52366655076e609e9e32d456da7f5a2danilchap 916a72e7349d52366655076e609e9e32d456da7f5a2danilchap if (report_blocks_.size() >= RTCP_MAX_REPORT_BLOCKS) { 917a72e7349d52366655076e609e9e32d456da7f5a2danilchap LOG(LS_WARNING) << "Too many report blocks."; 918a72e7349d52366655076e609e9e32d456da7f5a2danilchap return false; 919a72e7349d52366655076e609e9e32d456da7f5a2danilchap } 920a72e7349d52366655076e609e9e32d456da7f5a2danilchap RTC_DCHECK(report_blocks_.find(ssrc) == report_blocks_.end()); 921a72e7349d52366655076e609e9e32d456da7f5a2danilchap rtcp::ReportBlock* block = &report_blocks_[ssrc]; 922a72e7349d52366655076e609e9e32d456da7f5a2danilchap block->To(ssrc); 923a72e7349d52366655076e609e9e32d456da7f5a2danilchap block->WithFractionLost(stats.fraction_lost); 924a72e7349d52366655076e609e9e32d456da7f5a2danilchap if (!block->WithCumulativeLost(stats.cumulative_lost)) { 925a72e7349d52366655076e609e9e32d456da7f5a2danilchap report_blocks_.erase(ssrc); 926a72e7349d52366655076e609e9e32d456da7f5a2danilchap LOG(LS_WARNING) << "Cumulative lost is oversized."; 927a72e7349d52366655076e609e9e32d456da7f5a2danilchap return false; 928a72e7349d52366655076e609e9e32d456da7f5a2danilchap } 929a72e7349d52366655076e609e9e32d456da7f5a2danilchap block->WithExtHighestSeqNum(stats.extended_max_sequence_number); 930a72e7349d52366655076e609e9e32d456da7f5a2danilchap block->WithJitter(stats.jitter); 931a72e7349d52366655076e609e9e32d456da7f5a2danilchap block->WithLastSr(feedback_state.remote_sr); 932286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 933bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng // TODO(sprang): Do we really need separate time stamps for each report? 934bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng // Get our NTP as late as possible to avoid a race. 935bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng uint32_t ntp_secs; 936bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng uint32_t ntp_frac; 937bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng clock_->CurrentNtp(ntp_secs, ntp_frac); 938286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 939bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng // Delay since last received report. 94059f20bb735562d245357609799578edeed46be32pbos@webrtc.org if ((feedback_state.last_rr_ntp_secs != 0) || 94159f20bb735562d245357609799578edeed46be32pbos@webrtc.org (feedback_state.last_rr_ntp_frac != 0)) { 942bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng // Get the 16 lowest bits of seconds and the 16 highest bits of fractions. 943bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng uint32_t now = ntp_secs & 0x0000FFFF; 94461be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng now <<= 16; 945bdc0b0d869e9a14bbfafcbb84e294a13383e6fa6Erik Språng now += (ntp_frac & 0xffff0000) >> 16; 946286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 94761be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng uint32_t receiveTime = feedback_state.last_rr_ntp_secs & 0x0000FFFF; 94861be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng receiveTime <<= 16; 94961be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng receiveTime += (feedback_state.last_rr_ntp_frac & 0xffff0000) >> 16; 950286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 951a72e7349d52366655076e609e9e32d456da7f5a2danilchap block->WithDelayLastSr(now - receiveTime); 952286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 953286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return true; 954470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 955470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 9569334ac2d78f760b37f512ef6c12bff220d1654c1pbos@webrtc.orgvoid RTCPSender::SetCsrcs(const std::vector<uint32_t>& csrcs) { 9579334ac2d78f760b37f512ef6c12bff220d1654c1pbos@webrtc.org assert(csrcs.size() <= kRtpCsrcSize); 958242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 9599334ac2d78f760b37f512ef6c12bff220d1654c1pbos@webrtc.org csrcs_ = csrcs; 960470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 961470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 962d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.orgint32_t RTCPSender::SetApplicationSpecificData(uint8_t subType, 963d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org uint32_t name, 964d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org const uint8_t* data, 965d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org uint16_t length) { 96661be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng if (length % 4 != 0) { 96761be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng LOG(LS_ERROR) << "Failed to SetApplicationSpecificData."; 96861be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng return -1; 96961be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng } 970242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 971242e22b055940be70b1df3031e2363b0d02397b2Erik Språng 972242e22b055940be70b1df3031e2363b0d02397b2Erik Språng SetFlag(kRtcpApp, true); 973242e22b055940be70b1df3031e2363b0d02397b2Erik Språng app_sub_type_ = subType; 974242e22b055940be70b1df3031e2363b0d02397b2Erik Språng app_name_ = name; 975242e22b055940be70b1df3031e2363b0d02397b2Erik Språng app_data_.reset(new uint8_t[length]); 976242e22b055940be70b1df3031e2363b0d02397b2Erik Språng app_length_ = length; 977242e22b055940be70b1df3031e2363b0d02397b2Erik Språng memcpy(app_data_.get(), data, length); 97861be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng return 0; 979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 98161be2a401635eed1d13c169dc104b9ff4a2f477bErik Språngint32_t RTCPSender::SetRTCPVoIPMetrics(const RTCPVoIPMetric* VoIPMetric) { 982242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 983242e22b055940be70b1df3031e2363b0d02397b2Erik Språng memcpy(&xr_voip_metric_, VoIPMetric, sizeof(RTCPVoIPMetric)); 984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 985242e22b055940be70b1df3031e2363b0d02397b2Erik Språng SetFlag(kRtcpXrVoipMetric, true); 98661be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng return 0; 987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 988470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 9898469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.orgvoid RTCPSender::SendRtcpXrReceiverReferenceTime(bool enable) { 990242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 991242e22b055940be70b1df3031e2363b0d02397b2Erik Språng xr_send_receiver_reference_time_enabled_ = enable; 9928469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org} 9938469f7b328ec980f80fa79931b4e07872d0feb23asapersson@webrtc.org 9948d02f5dc7146ebc35c30fc3f7e1cbfa6802486a2asapersson@webrtc.orgbool RTCPSender::RtcpXrReceiverReferenceTime() const { 995242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 996242e22b055940be70b1df3031e2363b0d02397b2Erik Språng return xr_send_receiver_reference_time_enabled_; 9978d02f5dc7146ebc35c30fc3f7e1cbfa6802486a2asapersson@webrtc.org} 9988d02f5dc7146ebc35c30fc3f7e1cbfa6802486a2asapersson@webrtc.org 999470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com// no callbacks allowed inside this function 1000d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.orgint32_t RTCPSender::SetTMMBN(const TMMBRSet* boundingSet, 1001d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org uint32_t maxBitrateKbit) { 1002242e22b055940be70b1df3031e2363b0d02397b2Erik Språng CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); 1003470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1004242e22b055940be70b1df3031e2363b0d02397b2Erik Språng if (0 == tmmbr_help_.SetTMMBRBoundingSetToSend(boundingSet, maxBitrateKbit)) { 1005242e22b055940be70b1df3031e2363b0d02397b2Erik Språng SetFlag(kRtcpTmmbn, true); 100661be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng return 0; 100761be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng } 100861be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng return -1; 1009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 101061be2a401635eed1d13c169dc104b9ff4a2f477bErik Språng 1011242e22b055940be70b1df3031e2363b0d02397b2Erik Språngvoid RTCPSender::SetFlag(RTCPPacketType type, bool is_volatile) { 1012242e22b055940be70b1df3031e2363b0d02397b2Erik Språng report_flags_.insert(ReportFlag(type, is_volatile)); 1013242e22b055940be70b1df3031e2363b0d02397b2Erik Språng} 1014242e22b055940be70b1df3031e2363b0d02397b2Erik Språng 1015242e22b055940be70b1df3031e2363b0d02397b2Erik Språngvoid RTCPSender::SetFlags(const std::set<RTCPPacketType>& types, 1016242e22b055940be70b1df3031e2363b0d02397b2Erik Språng bool is_volatile) { 1017242e22b055940be70b1df3031e2363b0d02397b2Erik Språng for (RTCPPacketType type : types) 1018242e22b055940be70b1df3031e2363b0d02397b2Erik Språng SetFlag(type, is_volatile); 1019242e22b055940be70b1df3031e2363b0d02397b2Erik Språng} 1020242e22b055940be70b1df3031e2363b0d02397b2Erik Språng 1021242e22b055940be70b1df3031e2363b0d02397b2Erik Språngbool RTCPSender::IsFlagPresent(RTCPPacketType type) const { 1022242e22b055940be70b1df3031e2363b0d02397b2Erik Språng return report_flags_.find(ReportFlag(type, false)) != report_flags_.end(); 1023242e22b055940be70b1df3031e2363b0d02397b2Erik Språng} 1024242e22b055940be70b1df3031e2363b0d02397b2Erik Språng 1025242e22b055940be70b1df3031e2363b0d02397b2Erik Språngbool RTCPSender::ConsumeFlag(RTCPPacketType type, bool forced) { 1026242e22b055940be70b1df3031e2363b0d02397b2Erik Språng auto it = report_flags_.find(ReportFlag(type, false)); 1027242e22b055940be70b1df3031e2363b0d02397b2Erik Språng if (it == report_flags_.end()) 1028242e22b055940be70b1df3031e2363b0d02397b2Erik Språng return false; 1029242e22b055940be70b1df3031e2363b0d02397b2Erik Språng if (it->is_volatile || forced) 1030242e22b055940be70b1df3031e2363b0d02397b2Erik Språng report_flags_.erase((it)); 1031242e22b055940be70b1df3031e2363b0d02397b2Erik Språng return true; 1032242e22b055940be70b1df3031e2363b0d02397b2Erik Språng} 1033242e22b055940be70b1df3031e2363b0d02397b2Erik Språng 1034242e22b055940be70b1df3031e2363b0d02397b2Erik Språngbool RTCPSender::AllVolatileFlagsConsumed() const { 1035242e22b055940be70b1df3031e2363b0d02397b2Erik Språng for (const ReportFlag& flag : report_flags_) { 1036242e22b055940be70b1df3031e2363b0d02397b2Erik Språng if (flag.is_volatile) 1037242e22b055940be70b1df3031e2363b0d02397b2Erik Språng return false; 1038242e22b055940be70b1df3031e2363b0d02397b2Erik Språng } 1039242e22b055940be70b1df3031e2363b0d02397b2Erik Språng return true; 1040242e22b055940be70b1df3031e2363b0d02397b2Erik Språng} 1041242e22b055940be70b1df3031e2363b0d02397b2Erik Språng 1042233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprangbool RTCPSender::SendFeedbackPacket(const rtcp::TransportFeedback& packet) { 1043233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang class Sender : public rtcp::RtcpPacket::PacketReadyCallback { 1044233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang public: 10456db6cdc604f9a866991ecf8454eb7f7aa69918eadanilchap explicit Sender(Transport* transport) 1046ac547a653862744d0aae560713f8418ad2852085Peter Boström : transport_(transport), send_failure_(false) {} 1047233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang 1048233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang void OnPacketReady(uint8_t* data, size_t length) override { 10492d566686a23fe93ada58f1c38a0d4b9a0d68556epbos if (!transport_->SendRtcp(data, length)) 1050233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang send_failure_ = true; 1051233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang } 1052233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang 1053233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang Transport* const transport_; 1054233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang bool send_failure_; 105586fd9ed6f9e2a38aa343db8c62764659633231fasprang } sender(transport_); 1056233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang 1057233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang uint8_t buffer[IP_PACKET_SIZE]; 1058233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang return packet.BuildExternalBuffer(buffer, IP_PACKET_SIZE, &sender) && 1059233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang !sender.send_failure_; 1060233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang} 1061233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang 1062d900e8bea84c474696bf0219aed1353ce65ffd8epbos@webrtc.org} // namespace webrtc 1063