1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 11cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org#include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h" 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 133f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <assert.h> // assert 143f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <stdlib.h> // rand 15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <string.h> // memcpy 16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 173f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <algorithm> // min 183f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org 19cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org#include "webrtc/common_types.h" 20cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h" 21cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 2299681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org#include "webrtc/system_wrappers/interface/logging.h" 23cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org#include "webrtc/system_wrappers/interface/trace_event.h" 24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc { 26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgusing RTCPUtility::RTCPCnameInformation; 28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 29dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.comNACKStringBuilder::NACKStringBuilder() : 30dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com _stream(""), _count(0), _consecutive(false) 31dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com{ 32dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com // Empty. 33dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com} 34dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com 359d71e286a6c8fa79d30fc6f55e0e6071de5d37e3pbos@webrtc.orgNACKStringBuilder::~NACKStringBuilder() {} 369d71e286a6c8fa79d30fc6f55e0e6071de5d37e3pbos@webrtc.org 37b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgvoid NACKStringBuilder::PushNACK(uint16_t nack) 38dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com{ 39dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com if (_count == 0) 40dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com { 41dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com _stream << nack; 42dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com } else if (nack == _prevNack + 1) 43dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com { 44dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com _consecutive = true; 45dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com } else 46dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com { 47dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com if (_consecutive) 48dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com { 49dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com _stream << "-" << _prevNack; 50dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com _consecutive = false; 51dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com } 52dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com _stream << "," << nack; 53dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com } 54dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com _count++; 55dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com _prevNack = nack; 56dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com} 57dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com 58dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.comstd::string NACKStringBuilder::GetResult() 59dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com{ 60dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com if (_consecutive) 61dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com { 62dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com _stream << "-" << _prevNack; 63dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com _consecutive = false; 64dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com } 65dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com return _stream.str(); 66dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com} 67dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com 684e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.orgRTCPSender::FeedbackState::FeedbackState() 694e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org : send_payload_type(0), 704e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org frequency_hz(0), 71442dbd4c3639676395c03d8a47562f650f2c378fpbos@webrtc.org packets_sent(0), 72442dbd4c3639676395c03d8a47562f650f2c378fpbos@webrtc.org media_bytes_sent(0), 734e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org send_bitrate(0), 744e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org last_rr_ntp_secs(0), 754e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org last_rr_ntp_frac(0), 76d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org remote_sr(0), 77d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org has_last_xr_rr(false) {} 784e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org 79b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgRTCPSender::RTCPSender(const int32_t id, 80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const bool audio, 819858fc8df331a4111dc996469bcf027c4f986556stefan@webrtc.org Clock* clock, 82a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org ReceiveStatistics* receive_statistics) : 83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _id(id), 84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _audio(audio), 851bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org _clock(clock), 86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _method(kRtcpOff), 87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _criticalSectionTransport(CriticalSectionWrapper::CreateCriticalSection()), 88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _cbTransport(NULL), 89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _criticalSectionRTCPSender(CriticalSectionWrapper::CreateCriticalSection()), 91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _usingNack(false), 92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _sending(false), 93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _sendTMMBN(false), 94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _REMB(false), 95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _sendREMB(false), 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _TMMBR(false), 97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _IJ(false), 98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _nextTimeToSendRTCP(0), 99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org start_timestamp_(0), 100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org last_rtp_timestamp_(0), 101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org last_frame_capture_time_ms_(-1), 102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _SSRC(0), 103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _remoteSSRC(0), 104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _CNAME(), 105a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org receive_statistics_(receive_statistics), 106a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org internal_report_blocks_(), 107a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org external_report_blocks_(), 108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _csrcCNAMEs(), 109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 11073ebe67b3e6f0a65efed02efd4eee4dfb1b7729estefan@webrtc.org _cameraDelayMS(0), 11173ebe67b3e6f0a65efed02efd4eee4dfb1b7729estefan@webrtc.org 112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _lastSendReport(), 113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _lastRTCPTime(), 114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 115d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org last_xr_rr_(), 116d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _CSRCs(0), 118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _CSRC(), 119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _includeCSRCs(true), 120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _sequenceNumberFIR(0), 122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _lengthRembSSRC(0), 124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _sizeRembSSRC(0), 125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _rembSSRC(NULL), 126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _rembBitrate(0), 127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _tmmbrHelp(), 129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _tmmbr_Send(0), 130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _packetOH_Send(0), 131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _appSend(false), 133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _appSubType(0), 134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _appName(), 135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _appData(NULL), 136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _appLength(0), 137d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org 138d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org xrSendReceiverReferenceTimeEnabled_(false), 139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _xrSendVoIPMetric(false), 1404a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org _xrVoIPMetric() 141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(_CNAME, 0, sizeof(_CNAME)); 143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(_lastSendReport, 0, sizeof(_lastSendReport)); 144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(_lastRTCPTime, 0, sizeof(_lastRTCPTime)); 145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTCPSender::~RTCPSender() { 148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete [] _rembSSRC; 149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete [] _appData; 150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 151a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org while (!internal_report_blocks_.empty()) { 152a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org delete internal_report_blocks_.begin()->second; 153a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org internal_report_blocks_.erase(internal_report_blocks_.begin()); 154a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 155a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org while (!external_report_blocks_.empty()) { 156b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org std::map<uint32_t, RTCPReportBlock*>::iterator it = 157a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org external_report_blocks_.begin(); 158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete it->second; 159a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org external_report_blocks_.erase(it); 160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org while (!_csrcCNAMEs.empty()) { 162b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org std::map<uint32_t, RTCPCnameInformation*>::iterator it = 163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _csrcCNAMEs.begin(); 164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete it->second; 165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _csrcCNAMEs.erase(it); 166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete _criticalSectionTransport; 168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete _criticalSectionRTCPSender; 169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 171b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t 172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTCPSender::RegisterSendTransport(Transport* outgoingTransport) 173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionTransport); 175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _cbTransport = outgoingTransport; 176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTCPMethod 180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTCPSender::Status() const 181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return _method; 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 186b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t 187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTCPSender::SetRTCPStatus(const RTCPMethod method) 188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(method != kRtcpOff) 191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(_audio) 193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1941bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org _nextTimeToSendRTCP = _clock->TimeInMilliseconds() + 1959858fc8df331a4111dc996469bcf027c4f986556stefan@webrtc.org (RTCP_INTERVAL_AUDIO_MS/2); 196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else 197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1981bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org _nextTimeToSendRTCP = _clock->TimeInMilliseconds() + 1999858fc8df331a4111dc996469bcf027c4f986556stefan@webrtc.org (RTCP_INTERVAL_VIDEO_MS/2); 200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _method = method; 203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool 207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTCPSender::Sending() const 208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return _sending; 211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 213b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t 2144e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.orgRTCPSender::SetSendingStatus(const FeedbackState& feedback_state, bool sending) 215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool sendRTCPBye = false; 217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(_method != kRtcpOff) 221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(sending == false && _sending == true) 223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Trigger RTCP bye 225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sendRTCPBye = true; 226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _sending = sending; 229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(sendRTCPBye) 231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 2324e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org return SendRTCP(feedback_state, kRtcpBye); 233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool 238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTCPSender::REMB() const 239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return _REMB; 242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 244b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t 245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTCPSender::SetREMBStatus(const bool enable) 246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _REMB = enable; 249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 252b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t 253b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgRTCPSender::SetREMBData(const uint32_t bitrate, 254b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org const uint8_t numberOfSSRC, 255b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org const uint32_t* SSRC) 256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _rembBitrate = bitrate; 25909da1a78127b1e5719daaf452f03d2012edad0dcstefan@webrtc.org 260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(_sizeRembSSRC < numberOfSSRC) 261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete [] _rembSSRC; 263b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org _rembSSRC = new uint32_t[numberOfSSRC]; 264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _sizeRembSSRC = numberOfSSRC; 26509da1a78127b1e5719daaf452f03d2012edad0dcstefan@webrtc.org } 266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _lengthRembSSRC = numberOfSSRC; 268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (int i = 0; i < numberOfSSRC; i++) 26909da1a78127b1e5719daaf452f03d2012edad0dcstefan@webrtc.org { 270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _rembSSRC[i] = SSRC[i]; 271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _sendREMB = true; 2735374dabd9f79f8f04c8b237a944771a46db25f27stefan@webrtc.org // Send a REMB immediately if we have a new REMB. The frequency of REMBs is 2745374dabd9f79f8f04c8b237a944771a46db25f27stefan@webrtc.org // throttled by the caller. 2755374dabd9f79f8f04c8b237a944771a46db25f27stefan@webrtc.org _nextTimeToSendRTCP = _clock->TimeInMilliseconds(); 276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool 280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTCPSender::TMMBR() const 281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return _TMMBR; 284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 286b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t 287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTCPSender::SetTMMBRStatus(const bool enable) 288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _TMMBR = enable; 291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool 295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTCPSender::IJ() const 296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return _IJ; 299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 301b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t 302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTCPSender::SetIJStatus(const bool enable) 303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _IJ = enable; 306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid RTCPSender::SetStartTimestamp(uint32_t start_timestamp) { 3100cb22cf7e4f9531a0f218e27c8ea0d0620cf05d7pbos@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org start_timestamp_ = start_timestamp; 312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid RTCPSender::SetLastRtpTime(uint32_t rtp_timestamp, 315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int64_t capture_time_ms) { 3161d25eacc9444fecc13c8b2ada929b531841df730henrika@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org last_rtp_timestamp_ = rtp_timestamp; 318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (capture_time_ms < 0) { 319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // We don't currently get a capture time from VoiceEngine. 32073ebe67b3e6f0a65efed02efd4eee4dfb1b7729estefan@webrtc.org last_frame_capture_time_ms_ = _clock->TimeInMilliseconds(); 321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org last_frame_capture_time_ms_ = capture_time_ms; 323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid 327b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgRTCPSender::SetSSRC( const uint32_t ssrc) 328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(_SSRC != 0) 332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // not first SetSSRC, probably due to a collision 334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // schedule a new RTCP report 335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // make sure that we send a RTP packet 3361bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org _nextTimeToSendRTCP = _clock->TimeInMilliseconds() + 100; 337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _SSRC = ssrc; 339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 3417fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.orgvoid RTCPSender::SetRemoteSSRC(uint32_t ssrc) 342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _remoteSSRC = ssrc; 345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 34773ebe67b3e6f0a65efed02efd4eee4dfb1b7729estefan@webrtc.orgint32_t 34873ebe67b3e6f0a65efed02efd4eee4dfb1b7729estefan@webrtc.orgRTCPSender::SetCameraDelay(const int32_t delayMS) 34973ebe67b3e6f0a65efed02efd4eee4dfb1b7729estefan@webrtc.org{ 35073ebe67b3e6f0a65efed02efd4eee4dfb1b7729estefan@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 35173ebe67b3e6f0a65efed02efd4eee4dfb1b7729estefan@webrtc.org if(delayMS > 1000 || delayMS < -1000) 35273ebe67b3e6f0a65efed02efd4eee4dfb1b7729estefan@webrtc.org { 35399681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org LOG(LS_WARNING) << "Delay can't be larger than 1 second: " 35499681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org << delayMS << " ms"; 35573ebe67b3e6f0a65efed02efd4eee4dfb1b7729estefan@webrtc.org return -1; 35673ebe67b3e6f0a65efed02efd4eee4dfb1b7729estefan@webrtc.org } 35773ebe67b3e6f0a65efed02efd4eee4dfb1b7729estefan@webrtc.org _cameraDelayMS = delayMS; 35873ebe67b3e6f0a65efed02efd4eee4dfb1b7729estefan@webrtc.org return 0; 35973ebe67b3e6f0a65efed02efd4eee4dfb1b7729estefan@webrtc.org} 36073ebe67b3e6f0a65efed02efd4eee4dfb1b7729estefan@webrtc.org 361b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t RTCPSender::SetCNAME(const char cName[RTCP_CNAME_SIZE]) { 362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!cName) 363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _CNAME[RTCP_CNAME_SIZE - 1] = 0; 367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org strncpy(_CNAME, cName, RTCP_CNAME_SIZE - 1); 368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 371b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t RTCPSender::AddMixedCNAME(const uint32_t SSRC, 372b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org const char cName[RTCP_CNAME_SIZE]) { 373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(cName); 374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_csrcCNAMEs.size() >= kRtpCsrcSize) { 376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RTCPCnameInformation* ptr = new RTCPCnameInformation(); 379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ptr->name[RTCP_CNAME_SIZE - 1] = 0; 380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org strncpy(ptr->name, cName, RTCP_CNAME_SIZE - 1); 381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _csrcCNAMEs[SSRC] = ptr; 382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 385b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t RTCPSender::RemoveMixedCNAME(const uint32_t SSRC) { 386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 387b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org std::map<uint32_t, RTCPCnameInformation*>::iterator it = 388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _csrcCNAMEs.find(SSRC); 389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (it == _csrcCNAMEs.end()) { 391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete it->second; 394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _csrcCNAMEs.erase(it); 395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool 399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTCPSender::TimeToSendRTCPReport(const bool sendKeyframeBeforeRTP) const 400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org For audio we use a fix 5 sec interval 403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org For video we use 1 sec interval fo a BW smaller than 360 kbit/s, 4055374dabd9f79f8f04c8b237a944771a46db25f27stefan@webrtc.org technicaly we break the max 5% RTCP BW for video below 10 kbit/s but 4065374dabd9f79f8f04c8b237a944771a46db25f27stefan@webrtc.org that should be extremely rare 407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgFrom RFC 3550 410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org MAX RTCP BW is 5% if the session BW 412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org A send report is approximately 65 bytes inc CNAME 4135374dabd9f79f8f04c8b237a944771a46db25f27stefan@webrtc.org A receiver report is approximately 28 bytes 414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org The RECOMMENDED value for the reduced minimum in seconds is 360 416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org divided by the session bandwidth in kilobits/second. This minimum 417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org is smaller than 5 seconds for bandwidths greater than 72 kb/s. 418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org If the participant has not yet sent an RTCP packet (the variable 420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org initial is true), the constant Tmin is set to 2.5 seconds, else it 421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org is set to 5 seconds. 422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org The interval between RTCP packets is varied randomly over the 424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org range [0.5,1.5] times the calculated interval to avoid unintended 425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org synchronization of all participants 426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if we send 428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org If the participant is a sender (we_sent true), the constant C is 429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org set to the average RTCP packet size (avg_rtcp_size) divided by 25% 430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org of the RTCP bandwidth (rtcp_bw), and the constant n is set to the 431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org number of senders. 432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if we receive only 434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org If we_sent is not true, the constant C is set 435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org to the average RTCP packet size divided by 75% of the RTCP 436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bandwidth. The constant n is set to the number of receivers 437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (members - senders). If the number of senders is greater than 438b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 25%, senders and receivers are treated together. 439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 440b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org reconsideration NOT required for peer-to-peer 441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "timer reconsideration" is 442b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org employed. This algorithm implements a simple back-off mechanism 443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org which causes users to hold back RTCP packet transmission if the 444b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org group sizes are increasing. 445b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 446b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org n = number of members 447b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org C = avg_size/(rtcpBW/4) 448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 3. The deterministic calculated interval Td is set to max(Tmin, n*C). 450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 451b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 4. The calculated interval T is set to a number uniformly distributed 452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org between 0.5 and 1.5 times the deterministic calculated interval. 453b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 454b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 5. The resulting value of T is divided by e-3/2=1.21828 to compensate 455b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for the fact that the timer reconsideration algorithm converges to 456b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org a value of the RTCP bandwidth below the intended average 457b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org*/ 458b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 459b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org int64_t now = _clock->TimeInMilliseconds(); 460b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 461b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 462b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 463b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(_method == kRtcpOff) 464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 465b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return false; 466b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 467b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(!_audio && sendKeyframeBeforeRTP) 469b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 470b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // for video key-frames we want to send the RTCP before the large key-frame 471b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // if we have a 100 ms margin 472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org now += RTCP_SEND_BEFORE_KEY_FRAME_MS; 473b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 4755374dabd9f79f8f04c8b237a944771a46db25f27stefan@webrtc.org if(now >= _nextTimeToSendRTCP) 476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return true; 478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if(now < 0x0000ffff && _nextTimeToSendRTCP > 0xffff0000) // 65 sec margin 480b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 481b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // wrap 482b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return true; 483b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 484b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return false; 485b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 486b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 487b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orguint32_t 488b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgRTCPSender::LastSendReport( uint32_t& lastRTCPTime) 489b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 490b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 491b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 492b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lastRTCPTime = _lastRTCPTime[0]; 493b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return _lastSendReport[0]; 494b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 495b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 496b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orguint32_t 497b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgRTCPSender::SendTimeOfSendReport(const uint32_t sendReport) 498b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 499b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 500b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 501b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // This is only saved when we are the sender 502b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if((_lastSendReport[0] == 0) || (sendReport == 0)) 503b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 504b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; // will be ignored 505b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else 506b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 507b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for(int i = 0; i < RTCP_NUMBER_OF_SR; ++i) 508b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 509b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if( _lastSendReport[i] == sendReport) 510b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 511b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return _lastRTCPTime[i]; 512b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 513b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 514b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 515b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 516b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 517b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 518d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.orgbool RTCPSender::SendTimeOfXrRrReport(uint32_t mid_ntp, 519d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org int64_t* time_ms) const { 520d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 521d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org 522d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org if (last_xr_rr_.empty()) { 523d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org return false; 524d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org } 525d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org std::map<uint32_t, int64_t>::const_iterator it = last_xr_rr_.find(mid_ntp); 526d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org if (it == last_xr_rr_.end()) { 527d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org return false; 528d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org } 529d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org *time_ms = it->second; 530d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org return true; 531d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org} 532d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org 5334a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.orgvoid RTCPSender::GetPacketTypeCounter( 5344a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org RtcpPacketTypeCounter* packet_counter) const { 5354a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 5364a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org *packet_counter = packet_type_counter_; 5374a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org} 5384a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org 539a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.orgint32_t RTCPSender::AddExternalReportBlock( 540a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org uint32_t SSRC, 541a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org const RTCPReportBlock* reportBlock) { 542a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 543a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return AddReportBlock(SSRC, &external_report_blocks_, reportBlock); 544a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org} 545a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org 546a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.orgint32_t RTCPSender::AddReportBlock( 547a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org uint32_t SSRC, 548a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org std::map<uint32_t, RTCPReportBlock*>* report_blocks, 549a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org const RTCPReportBlock* reportBlock) { 55099681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org assert(reportBlock); 551b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 552a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (report_blocks->size() >= RTCP_MAX_REPORT_BLOCKS) { 55399681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org LOG(LS_WARNING) << "Too many report blocks."; 554b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 555b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 556b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org std::map<uint32_t, RTCPReportBlock*>::iterator it = 557a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org report_blocks->find(SSRC); 558a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (it != report_blocks->end()) { 559cf4441c9151afe2be8beb01d2ef49fd084d6c243stefan@webrtc.org delete it->second; 560a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org report_blocks->erase(it); 561cf4441c9151afe2be8beb01d2ef49fd084d6c243stefan@webrtc.org } 562b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RTCPReportBlock* copyReportBlock = new RTCPReportBlock(); 563b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(copyReportBlock, reportBlock, sizeof(RTCPReportBlock)); 564a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org (*report_blocks)[SSRC] = copyReportBlock; 565b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 566b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 567b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 568a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.orgint32_t RTCPSender::RemoveExternalReportBlock(uint32_t SSRC) { 569b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 570b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 571b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org std::map<uint32_t, RTCPReportBlock*>::iterator it = 572a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org external_report_blocks_.find(SSRC); 573b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 574a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (it == external_report_blocks_.end()) { 575b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 576b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 577b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete it->second; 578a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org external_report_blocks_.erase(it); 579b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 580b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 581b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 5824e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.orgint32_t RTCPSender::BuildSR(const FeedbackState& feedback_state, 5834e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org uint8_t* rtcpbuffer, 5844e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org int& pos, 5854e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org uint32_t NTPsec, 5864e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org uint32_t NTPfrac) 587b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 588b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // sanity 589b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(pos + 52 >= IP_PACKET_SIZE) 590b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 59199681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org LOG(LS_WARNING) << "Failed to build Sender Report."; 592b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -2; 593b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 594b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint32_t RTPtime; 595b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 596b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint32_t posNumberOfReportBlocks = pos; 597b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80; 598b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 599b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Sender report 600b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)200; 601b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 602b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for(int i = (RTCP_NUMBER_OF_SR-2); i >= 0; i--) 603b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 604b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // shift old 605b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _lastSendReport[i+1] = _lastSendReport[i]; 606b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _lastRTCPTime[i+1] =_lastRTCPTime[i]; 607b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 608b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 6099b5315258a9a931a4fb8b0806a79a4758a1ddc13stefan@webrtc.org _lastRTCPTime[0] = Clock::NtpToMs(NTPsec, NTPfrac); 610b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _lastSendReport[0] = (NTPsec << 16) + (NTPfrac >> 16); 611b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 61273ebe67b3e6f0a65efed02efd4eee4dfb1b7729estefan@webrtc.org // The timestamp of this RTCP packet should be estimated as the timestamp of 61373ebe67b3e6f0a65efed02efd4eee4dfb1b7729estefan@webrtc.org // the frame being captured at this moment. We are calculating that 61473ebe67b3e6f0a65efed02efd4eee4dfb1b7729estefan@webrtc.org // timestamp as the last frame's timestamp + the time since the last frame 61573ebe67b3e6f0a65efed02efd4eee4dfb1b7729estefan@webrtc.org // was captured. 6160cb22cf7e4f9531a0f218e27c8ea0d0620cf05d7pbos@webrtc.org RTPtime = start_timestamp_ + last_rtp_timestamp_ + 6170cb22cf7e4f9531a0f218e27c8ea0d0620cf05d7pbos@webrtc.org (_clock->TimeInMilliseconds() - last_frame_capture_time_ms_) * 6180cb22cf7e4f9531a0f218e27c8ea0d0620cf05d7pbos@webrtc.org (feedback_state.frequency_hz / 1000); 619b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 620b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add sender data 621b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Save for our length field 622b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos++; 623b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos++; 624b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 625b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add our own SSRC 6266aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC); 627b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 628b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // NTP 6296aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, NTPsec); 630b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 6316aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, NTPfrac); 632b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 6336aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, RTPtime); 634b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 635b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 636b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org //sender's packet count 6376aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, 638442dbd4c3639676395c03d8a47562f650f2c378fpbos@webrtc.org feedback_state.packets_sent); 639b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 640b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 641b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org //sender's octet count 6426aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, 643442dbd4c3639676395c03d8a47562f650f2c378fpbos@webrtc.org feedback_state.media_bytes_sent); 644b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 645b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 646b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint8_t numberOfReportBlocks = 0; 647a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org int32_t retVal = WriteAllReportBlocksToBuffer(rtcpbuffer, pos, 648a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org numberOfReportBlocks, 649a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org NTPsec, NTPfrac); 650b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(retVal < 0) 651b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 652b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // 653b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return retVal ; 654b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 655a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org pos = retVal; 656b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[posNumberOfReportBlocks] += numberOfReportBlocks; 657b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 658b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint16_t len = uint16_t((pos/4) -1); 6596aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord16ToBuffer(rtcpbuffer + 2, len); 660b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 661b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 662b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 663b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 664a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.orgint32_t RTCPSender::BuildSDEC(uint8_t* rtcpbuffer, int& pos) { 665b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org size_t lengthCname = strlen(_CNAME); 666b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(lengthCname < RTCP_CNAME_SIZE); 667b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 668b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // sanity 669b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(pos + 12 + lengthCname >= IP_PACKET_SIZE) { 67099681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org LOG(LS_WARNING) << "Failed to build SDEC."; 671b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -2; 672b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 673b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // SDEC Source Description 674b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 675b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // We always need to add SDES CNAME 676b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = static_cast<uint8_t>(0x80 + 1 + _csrcCNAMEs.size()); 677b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = static_cast<uint8_t>(202); 678b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 679b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // handle SDES length later on 680b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint32_t SDESLengthPos = pos; 681b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos++; 682b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos++; 683b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 684b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add our own SSRC 6856aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC); 686b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 687b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 688b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // CNAME = 1 689b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = static_cast<uint8_t>(1); 690b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 691b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // 692b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = static_cast<uint8_t>(lengthCname); 693b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 694b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint16_t SDESLength = 10; 695b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 696b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(&rtcpbuffer[pos], _CNAME, lengthCname); 697b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += lengthCname; 698b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org SDESLength += (uint16_t)lengthCname; 699b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 700b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint16_t padding = 0; 701b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // We must have a zero field even if we have an even multiple of 4 bytes 702b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((pos % 4) == 0) { 703b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org padding++; 704b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++]=0; 705b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 706b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org while ((pos % 4) != 0) { 707b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org padding++; 708b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++]=0; 709b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 710b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SDESLength += padding; 711b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 712b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org std::map<uint32_t, RTCPUtility::RTCPCnameInformation*>::iterator it = 713b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _csrcCNAMEs.begin(); 714b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 715b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for(; it != _csrcCNAMEs.end(); it++) { 716b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RTCPCnameInformation* cname = it->second; 717b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint32_t SSRC = it->first; 718b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 719b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add SSRC 7206aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, SSRC); 721b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 722b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 723b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // CNAME = 1 724b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = static_cast<uint8_t>(1); 725b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 726b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org size_t length = strlen(cname->name); 727b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(length < RTCP_CNAME_SIZE); 728b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 729b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]= static_cast<uint8_t>(length); 730b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SDESLength += 6; 731b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 732b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(&rtcpbuffer[pos],cname->name, length); 733b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 734b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += length; 735b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SDESLength += length; 736b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint16_t padding = 0; 737b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 738b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // We must have a zero field even if we have an even multiple of 4 bytes 739b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if((pos % 4) == 0){ 740b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org padding++; 741b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++]=0; 742b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 743b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org while((pos % 4) != 0){ 744b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org padding++; 745b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++] = 0; 746b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 747b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SDESLength += padding; 748b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 749b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // in 32-bit words minus one and we don't count the header 750b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint16_t buffer_length = (SDESLength / 4) - 1; 7516aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord16ToBuffer(rtcpbuffer + SDESLengthPos, buffer_length); 752b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 753b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 754b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 755b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t 756b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgRTCPSender::BuildRR(uint8_t* rtcpbuffer, 757a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org int& pos, 758b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org const uint32_t NTPsec, 759a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org const uint32_t NTPfrac) 760b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 761b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // sanity one block 762b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(pos + 32 >= IP_PACKET_SIZE) 763b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 764b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -2; 765b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 766b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint32_t posNumberOfReportBlocks = pos; 767b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 768b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80; 769b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)201; 770b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 771b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Save for our length field 772b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos++; 773b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos++; 774b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 775b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add our own SSRC 7766aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC); 777b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 778b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 779b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint8_t numberOfReportBlocks = 0; 780a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org int retVal = WriteAllReportBlocksToBuffer(rtcpbuffer, pos, 781a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org numberOfReportBlocks, 782a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org NTPsec, NTPfrac); 783b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(retVal < 0) 784b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 785a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return pos; 786b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 787a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org pos = retVal; 788b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[posNumberOfReportBlocks] += numberOfReportBlocks; 789b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 790b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint16_t len = uint16_t((pos)/4 -1); 7916aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord16ToBuffer(rtcpbuffer + 2, len); 792b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 793b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 794b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 795b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// From RFC 5450: Transmission Time Offsets in RTP Streams. 796b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// 0 1 2 3 797b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// 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 798b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 799b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// hdr |V=2|P| RC | PT=IJ=195 | length | 800b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 801b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// | inter-arrival jitter | 802b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 803b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// . . 804b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// . . 805b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// . . 806b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// | inter-arrival jitter | 807b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 808b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// 809b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// If present, this RTCP packet must be placed after a receiver report 810b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// (inside a compound RTCP packet), and MUST have the same value for RC 811b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// (reception report count) as the receiver report. 812b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 813b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t 814b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTCPSender::BuildExtendedJitterReport( 815b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint8_t* rtcpbuffer, 816a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org int& pos, 817b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org const uint32_t jitterTransmissionTimeOffset) 818b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 819a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (external_report_blocks_.size() > 0) 820b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 82199681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org // TODO(andresp): Remove external report blocks since they are not 82299681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org // supported. 82399681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org LOG(LS_ERROR) << "Handling of external report blocks not implemented."; 824b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 825b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 826b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 827b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // sanity 828b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(pos + 8 >= IP_PACKET_SIZE) 829b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 830b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -2; 831b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 832b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // add picture loss indicator 833b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint8_t RC = 1; 834b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80 + RC; 835b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)195; 836b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 837b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Used fixed length of 2 838b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 839b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(1); 840b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 841b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add inter-arrival jitter 8426aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, 8436aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org jitterTransmissionTimeOffset); 844b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 845b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 846b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 847b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 848b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t 849a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.orgRTCPSender::BuildPLI(uint8_t* rtcpbuffer, int& pos) 850b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 851b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // sanity 852b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(pos + 12 >= IP_PACKET_SIZE) 853b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 854b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -2; 855b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 856b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // add picture loss indicator 857b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint8_t FMT = 1; 858b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80 + FMT; 859b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)206; 860b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 861b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org //Used fixed length of 2 862b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 863b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(2); 864b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 865b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add our own SSRC 8666aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC); 867b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 868b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 869b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add the remote SSRC 8706aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _remoteSSRC); 871b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 872b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 873b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 874b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 875b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t RTCPSender::BuildFIR(uint8_t* rtcpbuffer, 876a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org int& pos, 877b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org bool repeat) { 878b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // sanity 879b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(pos + 20 >= IP_PACKET_SIZE) { 880b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -2; 881b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 882b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!repeat) { 883b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _sequenceNumberFIR++; // do not increase if repetition 884b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 885b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 886b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // add full intra request indicator 887b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint8_t FMT = 4; 888b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)0x80 + FMT; 889b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)206; 890b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 891b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org //Length of 4 892b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)0; 893b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(4); 894b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 895b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add our own SSRC 8966aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC); 897b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 898b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 899b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // RFC 5104 4.3.1.2. Semantics 900b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // SSRC of media source 901b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)0; 902b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)0; 903b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)0; 904b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)0; 905b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 906b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Additional Feedback Control Information (FCI) 9076aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _remoteSSRC); 908b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 909b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 910b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_sequenceNumberFIR); 911b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)0; 912b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)0; 913b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)0; 914b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 915b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 916b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 917b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 918b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 0 1 2 3 919b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 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 920b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 921b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org | First | Number | PictureID | 922b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 923b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org*/ 924b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t 925a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.orgRTCPSender::BuildSLI(uint8_t* rtcpbuffer, int& pos, const uint8_t pictureID) 926b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 927b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // sanity 928b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(pos + 16 >= IP_PACKET_SIZE) 929b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 930b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -2; 931b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 932b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // add slice loss indicator 933b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint8_t FMT = 2; 934b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80 + FMT; 935b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)206; 936b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 937b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org //Used fixed length of 3 938b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 939b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(3); 940b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 941b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add our own SSRC 9426aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC); 943b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 944b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 945b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add the remote SSRC 9466aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _remoteSSRC); 947b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 948b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 949b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add first, number & picture ID 6 bits 950b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // first = 0, 13 - bits 951b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // number = 0x1fff, 13 - bits only ones for now 952b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint32_t sliField = (0x1fff << 6)+ (0x3f & pictureID); 9536aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, sliField); 954b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 955b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 956b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 957b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 958b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 959b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 0 1 2 3 960b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 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 961b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 962b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org | PB |0| Payload Type| Native RPSI bit string | 963b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 964b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org | defined per codec ... | Padding (0) | 965b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 966b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org*/ 967b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 968b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org* Note: not generic made for VP8 969b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org*/ 970b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t 971b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgRTCPSender::BuildRPSI(uint8_t* rtcpbuffer, 972a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org int& pos, 973b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org const uint64_t pictureID, 974b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org const uint8_t payloadType) 975b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 976b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // sanity 977b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(pos + 24 >= IP_PACKET_SIZE) 978b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 979b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -2; 980b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 981b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // add Reference Picture Selection Indication 982b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint8_t FMT = 3; 983b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80 + FMT; 984b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)206; 985b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 986b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // calc length 987b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint32_t bitsRequired = 7; 988b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint8_t bytesRequired = 1; 989b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org while((pictureID>>bitsRequired) > 0) 990b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 991b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bitsRequired += 7; 992b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bytesRequired++; 993b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 994b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 995b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint8_t size = 3; 996b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(bytesRequired > 6) 997b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 998b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org size = 5; 999b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if(bytesRequired > 2) 1000b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1001b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org size = 4; 1002b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1003b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 1004b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++]=size; 1005b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1006b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add our own SSRC 10076aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC); 1008b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 1009b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1010b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add the remote SSRC 10116aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _remoteSSRC); 1012b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 1013b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1014b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // calc padding length 1015b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint8_t paddingBytes = 4-((2+bytesRequired)%4); 1016b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(paddingBytes == 4) 1017b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1018b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org paddingBytes = 0; 1019b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1020b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // add padding length in bits 1021b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos] = paddingBytes*8; // padding can be 0, 8, 16 or 24 1022b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos++; 1023b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1024b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // add payload type 1025b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos] = payloadType; 1026b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos++; 1027b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1028b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // add picture ID 1029b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for(int i = bytesRequired-1; i > 0; i--) 1030b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1031b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos] = 0x80 | uint8_t(pictureID >> (i*7)); 1032b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos++; 1033b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1034b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // add last byte of picture ID 1035b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos] = uint8_t(pictureID & 0x7f); 1036b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos++; 1037b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1038b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // add padding 1039b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for(int j = 0; j <paddingBytes; j++) 1040b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1041b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos] = 0; 1042b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos++; 1043b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1044b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1045b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1046b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1047b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t 1048a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.orgRTCPSender::BuildREMB(uint8_t* rtcpbuffer, int& pos) 1049b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1050b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // sanity 1051b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(pos + 20 + 4 * _lengthRembSSRC >= IP_PACKET_SIZE) 1052b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1053b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -2; 1054b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1055b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // add application layer feedback 1056b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint8_t FMT = 15; 1057b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80 + FMT; 1058b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)206; 1059b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1060b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 1061b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++]=_lengthRembSSRC + 4; 1062b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1063b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add our own SSRC 10646aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC); 1065b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 1066b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1067b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Remote SSRC must be 0 10686aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, 0); 1069b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 1070b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1071b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++]='R'; 1072b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++]='E'; 1073b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++]='M'; 1074b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++]='B'; 1075b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1076b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++] = _lengthRembSSRC; 1077b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // 6 bit Exp 1078b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // 18 bit mantissa 1079b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint8_t brExp = 0; 1080b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org for(uint32_t i=0; i<64; i++) 1081b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1082b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org if(_rembBitrate <= ((uint32_t)262143 << i)) 1083b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1084b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org brExp = i; 1085b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 1086b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1087b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1088b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org const uint32_t brMantissa = (_rembBitrate >> brExp); 1089b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)((brExp << 2) + ((brMantissa >> 16) & 0x03)); 1090b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(brMantissa >> 8); 1091b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(brMantissa); 1092b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 109309da1a78127b1e5719daaf452f03d2012edad0dcstefan@webrtc.org for (int i = 0; i < _lengthRembSSRC; i++) 10946aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org { 10956aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _rembSSRC[i]); 1096b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 1097b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1098b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1099b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid 1102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTCPSender::SetTargetBitrate(unsigned int target_bitrate) 1103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 1105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _tmmbr_Send = target_bitrate / 1000; 1106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 11084e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.orgint32_t RTCPSender::BuildTMMBR(ModuleRtpRtcpImpl* rtp_rtcp_module, 11094e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org uint8_t* rtcpbuffer, 11104e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org int& pos) { 11114e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org if (rtp_rtcp_module == NULL) 11124e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org return -1; 1113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Before sending the TMMBR check the received TMMBN, only an owner is allowed to raise the bitrate 1114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // If the sender is an owner of the TMMBN -> send TMMBR 1115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // If not an owner but the TMMBR would enter the TMMBN -> send TMMBR 1116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // get current bounding set from RTCP receiver 1118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool tmmbrOwner = false; 1119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // store in candidateSet, allocates one extra slot 1120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org TMMBRSet* candidateSet = _tmmbrHelp.CandidateSet(); 1121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // holding _criticalSectionRTCPSender while calling RTCPreceiver which 1123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // will accuire _criticalSectionRTCPReceiver is a potental deadlock but 1124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // since RTCPreceiver is not doing the reverse we should be fine 11254e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org int32_t lengthOfBoundingSet = 11264e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org rtp_rtcp_module->BoundingSet(tmmbrOwner, candidateSet); 1127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(lengthOfBoundingSet > 0) 1129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1130b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org for (int32_t i = 0; i < lengthOfBoundingSet; i++) 1131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if( candidateSet->Tmmbr(i) == _tmmbr_Send && 1133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org candidateSet->PacketOH(i) == _packetOH_Send) 1134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // do not send the same tuple 1136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(!tmmbrOwner) 1140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // use received bounding set as candidate set 1142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // add current tuple 1143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org candidateSet->SetEntry(lengthOfBoundingSet, 1144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _tmmbr_Send, 1145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _packetOH_Send, 1146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _SSRC); 1147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int numCandidates = lengthOfBoundingSet+ 1; 1148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // find bounding set 1150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org TMMBRSet* boundingSet = NULL; 1151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int numBoundingSet = _tmmbrHelp.FindTMMBRBoundingSet(boundingSet); 1152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(numBoundingSet > 0 || numBoundingSet <= numCandidates) 1153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmmbrOwner = _tmmbrHelp.IsOwner(_SSRC, numBoundingSet); 1155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(!tmmbrOwner) 1157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // did not enter bounding set, no meaning to send this request 1159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(_tmmbr_Send) 1165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // sanity 1167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(pos + 20 >= IP_PACKET_SIZE) 1168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -2; 1170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // add TMMBR indicator 1172b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint8_t FMT = 3; 1173b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80 + FMT; 1174b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)205; 1175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org //Length of 4 1177b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 1178b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(4); 1179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add our own SSRC 11816aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC); 1182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 1183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // RFC 5104 4.2.1.2. Semantics 1185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // SSRC of media source 1187b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 1188b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 1189b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 1190b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 1191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Additional Feedback Control Information (FCI) 11936aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _remoteSSRC); 1194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 1195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1196b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint32_t bitRate = _tmmbr_Send*1000; 1197b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint32_t mmbrExp = 0; 1198b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org for(uint32_t i=0;i<64;i++) 1199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1200b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org if(bitRate <= ((uint32_t)131071 << i)) 1201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mmbrExp = i; 1203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 1204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1206b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint32_t mmbrMantissa = (bitRate >> mmbrExp); 1207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1208b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)((mmbrExp << 2) + ((mmbrMantissa >> 15) & 0x03)); 1209b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(mmbrMantissa >> 7); 1210b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)((mmbrMantissa << 1) + ((_packetOH_Send >> 8)& 0x01)); 1211b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(_packetOH_Send); 1212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1216b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t 1217a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.orgRTCPSender::BuildTMMBN(uint8_t* rtcpbuffer, int& pos) 1218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org TMMBRSet* boundingSet = _tmmbrHelp.BoundingSetToSend(); 1220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(boundingSet == NULL) 1221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // sanity 1225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(pos + 12 + boundingSet->lengthOfSet()*8 >= IP_PACKET_SIZE) 1226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 122799681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org LOG(LS_WARNING) << "Failed to build TMMBN."; 1228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -2; 1229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1230b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint8_t FMT = 4; 1231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // add TMMBN indicator 1232b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80 + FMT; 1233b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)205; 1234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org //Add length later 1236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int posLength = pos; 1237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos++; 1238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos++; 1239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add our own SSRC 12416aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC); 1242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 1243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // RFC 5104 4.2.2.2. Semantics 1245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // SSRC of media source 1247b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 1248b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 1249b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 1250b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 1251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Additional Feedback Control Information (FCI) 1253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int numBoundingSet = 0; 1254b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org for(uint32_t n=0; n< boundingSet->lengthOfSet(); n++) 1255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (boundingSet->Tmmbr(n) > 0) 1257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1258b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint32_t tmmbrSSRC = boundingSet->Ssrc(n); 12596aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, tmmbrSSRC); 1260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 1261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1262b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint32_t bitRate = boundingSet->Tmmbr(n) * 1000; 1263b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint32_t mmbrExp = 0; 1264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for(int i=0; i<64; i++) 1265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1266b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org if(bitRate <= ((uint32_t)131071 << i)) 1267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mmbrExp = i; 1269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 1270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1272b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint32_t mmbrMantissa = (bitRate >> mmbrExp); 1273b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint32_t measuredOH = boundingSet->PacketOH(n); 1274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1275b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)((mmbrExp << 2) + ((mmbrMantissa >> 15) & 0x03)); 1276b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(mmbrMantissa >> 7); 1277b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)((mmbrMantissa << 1) + ((measuredOH >> 8)& 0x01)); 1278b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(measuredOH); 1279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org numBoundingSet++; 1280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1282b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint16_t length= (uint16_t)(2+2*numBoundingSet); 1283b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[posLength++]=(uint8_t)(length>>8); 1284b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[posLength]=(uint8_t)(length); 1285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1288b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t 1289a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.orgRTCPSender::BuildAPP(uint8_t* rtcpbuffer, int& pos) 1290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // sanity 1292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(_appData == NULL) 1293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 129499681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org LOG(LS_WARNING) << "Failed to build app specific."; 1295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(pos + 12 + _appLength >= IP_PACKET_SIZE) 1298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 129999681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org LOG(LS_WARNING) << "Failed to build app specific."; 1300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -2; 1301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1302b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80 + _appSubType; 1303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add APP ID 1305b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)204; 1306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1307b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint16_t length = (_appLength>>2) + 2; // include SSRC and name 1308b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(length>>8); 1309b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(length); 1310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add our own SSRC 13126aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC); 1313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 1314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add our application name 13166aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _appName); 1317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 1318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add the data 1320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(rtcpbuffer +pos, _appData,_appLength); 1321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += _appLength; 1322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1325b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t 1326b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgRTCPSender::BuildNACK(uint8_t* rtcpbuffer, 1327a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org int& pos, 1328b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org const int32_t nackSize, 1329b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org const uint16_t* nackList, 1330dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com std::string* nackString) 1331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // sanity 1333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(pos + 16 >= IP_PACKET_SIZE) 1334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 133599681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org LOG(LS_WARNING) << "Failed to build NACK."; 1336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -2; 1337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1339b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org // int size, uint16_t* nackList 1340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // add nack list 1341b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint8_t FMT = 1; 1342b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80 + FMT; 1343b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)205; 1344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1345b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t) 0; 1346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int nackSizePos = pos; 1347b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(3); //setting it to one kNACK signal as default 1348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add our own SSRC 13506aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC); 1351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 1352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add the remote SSRC 13546aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _remoteSSRC); 1355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 1356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1357dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com NACKStringBuilder stringBuilder; 1358bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org // Build NACK bitmasks and write them to the RTCP message. 1359bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org // The nack list should be sorted and not contain duplicates if one 1360bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org // wants to build the smallest rtcp nack packet. 1361bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org int numOfNackFields = 0; 1362bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org int maxNackFields = std::min<int>(kRtcpMaxNackFields, 1363bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org (IP_PACKET_SIZE - pos) / 4); 1364bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org int i = 0; 1365bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org while (i < nackSize && numOfNackFields < maxNackFields) { 1366bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org stringBuilder.PushNACK(nackList[i]); 1367bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org uint16_t nack = nackList[i++]; 1368bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org uint16_t bitmask = 0; 1369bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org while (i < nackSize) { 1370bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org int shift = static_cast<uint16_t>(nackList[i] - nack) - 1; 1371bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org if (shift >= 0 && shift <= 15) { 1372bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org stringBuilder.PushNACK(nackList[i]); 1373bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org bitmask |= (1 << shift); 1374bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org ++i; 1375bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org } else { 1376bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org break; 1377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1378bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org } 1379bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org // Write the sequence number and the bitmask to the packet. 1380bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org assert(pos + 4 < IP_PACKET_SIZE); 13816aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord16ToBuffer(rtcpbuffer + pos, nack); 1382bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org pos += 2; 13836aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord16ToBuffer(rtcpbuffer + pos, bitmask); 1384bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org pos += 2; 1385bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org numOfNackFields++; 1386bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org } 1387bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org if (i != nackSize) { 138899681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org LOG(LS_WARNING) << "Nack list to large for one packet."; 1389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1390bda02e4a2e5a01cbd41fa0f0e5ad843d304404ccandresp@webrtc.org rtcpbuffer[nackSizePos] = static_cast<uint8_t>(2 + numOfNackFields); 1391dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com *nackString = stringBuilder.GetResult(); 1392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1395b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t 1396a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.orgRTCPSender::BuildBYE(uint8_t* rtcpbuffer, int& pos) 1397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // sanity 1399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(pos + 8 >= IP_PACKET_SIZE) 1400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -2; 1402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(_includeCSRCs) 1404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add a bye packet 1406b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80 + 1 + _CSRCs; // number of SSRC+CSRCs 1407b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)203; 1408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // length 1410b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 1411b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(1 + _CSRCs); 1412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add our own SSRC 14146aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC); 1415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 1416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // add CSRCs 1418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for(int i = 0; i < _CSRCs; i++) 1419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 14206aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _CSRC[i]); 1421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 1422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else 1424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add a bye packet 1426b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80 + 1; // number of SSRC+CSRCs 1427b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)203; 1428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // length 1430b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 1431b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)1; 1432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add our own SSRC 14346aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC); 1435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 1436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1438b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1440d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.orgint32_t RTCPSender::BuildReceiverReferenceTime(uint8_t* buffer, 1441d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org int& pos, 1442d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org uint32_t ntp_sec, 1443d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org uint32_t ntp_frac) { 1444d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org const int kRrTimeBlockLength = 20; 1445d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org if (pos + kRrTimeBlockLength >= IP_PACKET_SIZE) { 1446d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org return -2; 1447d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org } 1448d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org 1449d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org if (last_xr_rr_.size() >= RTCP_NUMBER_OF_SR) { 1450d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org last_xr_rr_.erase(last_xr_rr_.begin()); 1451d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org } 1452d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org last_xr_rr_.insert(std::pair<uint32_t, int64_t>( 1453d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org RTCPUtility::MidNtp(ntp_sec, ntp_frac), 1454d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org Clock::NtpToMs(ntp_sec, ntp_frac))); 1455d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org 1456d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // Add XR header. 1457d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org buffer[pos++] = 0x80; 1458d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org buffer[pos++] = 207; 1459d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org buffer[pos++] = 0; // XR packet length. 1460d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org buffer[pos++] = 4; // XR packet length. 1461d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org 1462d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // Add our own SSRC. 14636aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(buffer + pos, _SSRC); 1464d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org pos += 4; 1465d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org 1466d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // 0 1 2 3 1467d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // 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 1468d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1469d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // | BT=4 | reserved | block length = 2 | 1470d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1471d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // | NTP timestamp, most significant word | 1472d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1473d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // | NTP timestamp, least significant word | 1474d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1475d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org 1476d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // Add Receiver Reference Time Report block. 1477d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org buffer[pos++] = 4; // BT. 1478d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org buffer[pos++] = 0; // Reserved. 1479d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org buffer[pos++] = 0; // Block length. 1480d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org buffer[pos++] = 2; // Block length. 1481d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org 1482d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // NTP timestamp. 14836aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(buffer + pos, ntp_sec); 1484d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org pos += 4; 14856aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(buffer + pos, ntp_frac); 1486d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org pos += 4; 1487d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org 1488d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org return 0; 1489d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org} 1490d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org 1491d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.orgint32_t RTCPSender::BuildDlrr(uint8_t* buffer, 1492d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org int& pos, 1493d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org const RtcpReceiveTimeInfo& info) { 1494d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org const int kDlrrBlockLength = 24; 1495d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org if (pos + kDlrrBlockLength >= IP_PACKET_SIZE) { 1496d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org return -2; 1497d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org } 1498d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org 1499d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // Add XR header. 1500d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org buffer[pos++] = 0x80; 1501d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org buffer[pos++] = 207; 1502d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org buffer[pos++] = 0; // XR packet length. 1503d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org buffer[pos++] = 5; // XR packet length. 1504d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org 1505d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // Add our own SSRC. 15066aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(buffer + pos, _SSRC); 1507d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org pos += 4; 1508d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org 1509d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // 0 1 2 3 1510d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // 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 1511d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1512d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // | BT=5 | reserved | block length | 1513d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 1514d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // | SSRC_1 (SSRC of first receiver) | sub- 1515d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block 1516d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // | last RR (LRR) | 1 1517d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1518d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // | delay since last RR (DLRR) | 1519d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 1520d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // | SSRC_2 (SSRC of second receiver) | sub- 1521d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block 1522d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // : ... : 2 1523d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org 1524d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // Add DLRR sub block. 1525d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org buffer[pos++] = 5; // BT. 1526d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org buffer[pos++] = 0; // Reserved. 1527d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org buffer[pos++] = 0; // Block length. 1528d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org buffer[pos++] = 3; // Block length. 1529d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org 1530d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org // NTP timestamp. 15316aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(buffer + pos, info.sourceSSRC); 1532d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org pos += 4; 15336aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(buffer + pos, info.lastRR); 1534d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org pos += 4; 15356aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(buffer + pos, info.delaySinceLastRR); 1536d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org pos += 4; 1537d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org 1538d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org return 0; 1539d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org} 1540d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org 1541b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t 1542a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.orgRTCPSender::BuildVoIPMetric(uint8_t* rtcpbuffer, int& pos) 1543b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1544b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // sanity 1545b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(pos + 44 >= IP_PACKET_SIZE) 1546b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1547b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -2; 1548b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1549b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1550b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add XR header 1551b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80; 1552b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)207; 1553b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1554b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint32_t XRLengthPos = pos; 1555b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1556b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // handle length later on 1557b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos++; 1558b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos++; 1559b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1560b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add our own SSRC 15616aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC); 1562b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 1563b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1564b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add a VoIP metrics block 1565b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++]=7; 1566b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++]=0; 1567b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++]=0; 1568b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++]=8; 1569b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1570b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Add the remote SSRC 15716aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _remoteSSRC); 1572b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 4; 1573b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1574b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++] = _xrVoIPMetric.lossRate; 1575b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++] = _xrVoIPMetric.discardRate; 1576b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++] = _xrVoIPMetric.burstDensity; 1577b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++] = _xrVoIPMetric.gapDensity; 1578b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1579b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.burstDuration >> 8); 1580b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.burstDuration); 1581b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.gapDuration >> 8); 1582b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.gapDuration); 1583b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1584b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.roundTripDelay >> 8); 1585b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.roundTripDelay); 1586b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.endSystemDelay >> 8); 1587b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.endSystemDelay); 1588b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1589b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++] = _xrVoIPMetric.signalLevel; 1590b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++] = _xrVoIPMetric.noiseLevel; 1591b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++] = _xrVoIPMetric.RERL; 1592b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++] = _xrVoIPMetric.Gmin; 1593b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1594b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++] = _xrVoIPMetric.Rfactor; 1595b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++] = _xrVoIPMetric.extRfactor; 1596b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++] = _xrVoIPMetric.MOSLQ; 1597b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++] = _xrVoIPMetric.MOSCQ; 1598b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1599b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++] = _xrVoIPMetric.RXconfig; 1600b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcpbuffer[pos++] = 0; // reserved 1601b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBnominal >> 8); 1602b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBnominal); 1603b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1604b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBmax >> 8); 1605b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBmax); 1606b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBabsMax >> 8); 1607b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBabsMax); 1608b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1609b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[XRLengthPos]=(uint8_t)(0); 1610b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org rtcpbuffer[XRLengthPos+1]=(uint8_t)(10); 1611b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1612b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1613b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 16144e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.orgint32_t RTCPSender::SendRTCP(const FeedbackState& feedback_state, 16154e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org uint32_t packetTypeFlags, 16164e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org int32_t nackSize, 16174e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org const uint16_t* nackList, 16184e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org bool repeat, 16194e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org uint64_t pictureID) { 1620a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1621a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 1622a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(_method == kRtcpOff) 1623b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 162499681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org LOG(LS_WARNING) << "Can't send rtcp if it is disabled."; 1625a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return -1; 1626a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1627a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1628a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org uint8_t rtcp_buffer[IP_PACKET_SIZE]; 16294e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org int rtcp_length = PrepareRTCP(feedback_state, 16304e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org packetTypeFlags, 16314e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org nackSize, 16324e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org nackList, 16334e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org repeat, 16344e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org pictureID, 16354e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org rtcp_buffer, 16364e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org IP_PACKET_SIZE); 1637a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (rtcp_length < 0) { 1638a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return -1; 1639a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1640a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org // Sanity don't send empty packets. 1641a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (rtcp_length == 0) 1642a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1643a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return -1; 1644a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1645a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return SendToNetwork(rtcp_buffer, static_cast<uint16_t>(rtcp_length)); 1646a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org} 1647c0976d247fedbe48d703f1ef3d5fb0fd70fdab93henrike@webrtc.org 16484e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.orgint RTCPSender::PrepareRTCP(const FeedbackState& feedback_state, 16494e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org uint32_t packetTypeFlags, 16504e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org int32_t nackSize, 16514e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org const uint16_t* nackList, 16524e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org bool repeat, 16534e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org uint64_t pictureID, 16544e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org uint8_t* rtcp_buffer, 16554e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org int buffer_size) { 1656a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org uint32_t rtcpPacketTypeFlags = packetTypeFlags; 1657a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org // Collect the received information. 1658a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org uint32_t NTPsec = 0; 1659a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org uint32_t NTPfrac = 0; 1660a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org uint32_t jitterTransmissionOffset = 0; 1661a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org int position = 0; 1662c0976d247fedbe48d703f1ef3d5fb0fd70fdab93henrike@webrtc.org 1663a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 1664c0976d247fedbe48d703f1ef3d5fb0fd70fdab93henrike@webrtc.org 1665a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(_TMMBR ) // Attach TMMBR to send and receive reports. 1666a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1667a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org rtcpPacketTypeFlags |= kRtcpTmmbr; 1668a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1669a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(_appSend) 1670a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1671a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org rtcpPacketTypeFlags |= kRtcpApp; 1672a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org _appSend = false; 1673a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1674a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(_REMB && _sendREMB) 1675a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1676a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org // Always attach REMB to SR if that is configured. Note that REMB is 1677a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org // only sent on one of the RTP modules in the REMB group. 1678a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org rtcpPacketTypeFlags |= kRtcpRemb; 1679a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1680a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(_xrSendVoIPMetric) 1681a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1682a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org rtcpPacketTypeFlags |= kRtcpXrVoipMetric; 1683a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org _xrSendVoIPMetric = false; 1684a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1685a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(_sendTMMBN) // Set when having received a TMMBR. 1686a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1687a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org rtcpPacketTypeFlags |= kRtcpTmmbn; 1688a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org _sendTMMBN = false; 1689a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1690b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org if (rtcpPacketTypeFlags & kRtcpReport) 1691d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org { 1692b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org if (xrSendReceiverReferenceTimeEnabled_ && !_sending) 1693d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org { 1694d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime; 1695d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org } 1696d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org if (feedback_state.has_last_xr_rr) 1697d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org { 1698d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock; 1699d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org } 1700d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org } 1701a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(_method == kRtcpCompound) 1702a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1703a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(_sending) 1704a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1705a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org rtcpPacketTypeFlags |= kRtcpSr; 1706a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } else 1707a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1708a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org rtcpPacketTypeFlags |= kRtcpRr; 1709a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1710a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } else if(_method == kRtcpNonCompound) 1711a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1712a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpReport) 1713a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1714a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(_sending) 1715a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1716a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org rtcpPacketTypeFlags |= kRtcpSr; 1717a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } else 1718a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1719a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org rtcpPacketTypeFlags |= kRtcpRr; 1720a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1721a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1722a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1723a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if( rtcpPacketTypeFlags & kRtcpRr || 1724a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org rtcpPacketTypeFlags & kRtcpSr) 1725a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1726a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org // generate next time to send a RTCP report 1727a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org // seeded from RTP constructor 1728a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org int32_t random = rand() % 1000; 1729a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org int32_t timeToNext = RTCP_INTERVAL_AUDIO_MS; 1730a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org 1731a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(_audio) 1732a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1733a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org timeToNext = (RTCP_INTERVAL_AUDIO_MS/2) + 1734a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org (RTCP_INTERVAL_AUDIO_MS*random/1000); 1735a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org }else 1736a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1737a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org uint32_t minIntervalMs = RTCP_INTERVAL_AUDIO_MS; 1738a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(_sending) 1739a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 17404e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org // Calculate bandwidth for video; 360 / send bandwidth in kbit/s. 17414e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org uint32_t send_bitrate_kbit = feedback_state.send_bitrate / 1000; 17424e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org if (send_bitrate_kbit != 0) 17434e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org minIntervalMs = 360000 / send_bitrate_kbit; 1744a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1745a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(minIntervalMs > RTCP_INTERVAL_VIDEO_MS) 1746a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1747a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org minIntervalMs = RTCP_INTERVAL_VIDEO_MS; 1748a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1749a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org timeToNext = (minIntervalMs/2) + (minIntervalMs*random/1000); 1750a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1751a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org _nextTimeToSendRTCP = _clock->TimeInMilliseconds() + timeToNext; 1752a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1753c0976d247fedbe48d703f1ef3d5fb0fd70fdab93henrike@webrtc.org 1754a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org // If the data does not fit in the packet we fill it as much as possible. 1755a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org int32_t buildVal = 0; 1756a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org 1757a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org // We need to send our NTP even if we haven't received any reports. 1758a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org _clock->CurrentNtp(NTPsec, NTPfrac); 1759a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (ShouldSendReportBlocks(rtcpPacketTypeFlags)) { 1760a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org StatisticianMap statisticians = 1761a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org receive_statistics_->GetActiveStatisticians(); 1762a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (!statisticians.empty()) { 1763a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org StatisticianMap::const_iterator it; 1764a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org int i; 1765a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org for (it = statisticians.begin(), i = 0; it != statisticians.end(); 1766a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org ++it, ++i) { 1767a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org RTCPReportBlock report_block; 17684e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org if (PrepareReport( 17694e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org feedback_state, it->second, &report_block, &NTPsec, &NTPfrac)) 1770a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org AddReportBlock(it->first, &internal_report_blocks_, &report_block); 1771a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1772a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (_IJ && !statisticians.empty()) { 1773a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset; 1774a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1775a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1776a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1777c0976d247fedbe48d703f1ef3d5fb0fd70fdab93henrike@webrtc.org 1778a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpSr) 1779a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 17804e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org buildVal = BuildSR(feedback_state, rtcp_buffer, position, NTPsec, NTPfrac); 1781a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (buildVal == -1) { 1782a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return -1; 1783a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } else if (buildVal == -2) { 1784a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return position; 1785a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1786a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org buildVal = BuildSDEC(rtcp_buffer, position); 1787a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (buildVal == -1) { 1788a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return -1; 1789a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } else if (buildVal == -2) { 1790a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return position; 1791a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1792a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org }else if(rtcpPacketTypeFlags & kRtcpRr) 1793a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1794a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org buildVal = BuildRR(rtcp_buffer, position, NTPsec, NTPfrac); 1795a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (buildVal == -1) { 1796a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return -1; 1797a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } else if (buildVal == -2) { 1798a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return position; 1799a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1800a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org // only of set 1801a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(_CNAME[0] != 0) 1802a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1803a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org buildVal = BuildSDEC(rtcp_buffer, position); 1804a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (buildVal == -1) { 1805a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return -1; 1806a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1807a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1808a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1809a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpTransmissionTimeOffset) 1810a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1811a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org // If present, this RTCP packet must be placed after a 1812a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org // receiver report. 1813a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org buildVal = BuildExtendedJitterReport(rtcp_buffer, 1814a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org position, 1815a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org jitterTransmissionOffset); 1816a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (buildVal == -1) { 1817a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return -1; 1818a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } else if (buildVal == -2) { 1819a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return position; 1820a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1821a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1822a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpPli) 1823a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1824a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org buildVal = BuildPLI(rtcp_buffer, position); 1825a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (buildVal == -1) { 1826a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return -1; 1827a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } else if (buildVal == -2) { 1828a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return position; 1829a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1830a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org TRACE_EVENT_INSTANT0("webrtc_rtp", "RTCPSender::PLI"); 18314a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org ++packet_type_counter_.pli_packets; 18324a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org TRACE_COUNTER_ID1("webrtc_rtp", "RTCP_PLICount", _SSRC, 18334a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org packet_type_counter_.pli_packets); 1834a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1835a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpFir) 1836a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1837a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org buildVal = BuildFIR(rtcp_buffer, position, repeat); 1838a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (buildVal == -1) { 1839a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return -1; 1840a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } else if (buildVal == -2) { 1841a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return position; 1842a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1843a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org TRACE_EVENT_INSTANT0("webrtc_rtp", "RTCPSender::FIR"); 18444a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org ++packet_type_counter_.fir_packets; 1845a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org TRACE_COUNTER_ID1("webrtc_rtp", "RTCP_FIRCount", _SSRC, 18464a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org packet_type_counter_.fir_packets); 1847a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1848a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpSli) 1849a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1850a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org buildVal = BuildSLI(rtcp_buffer, position, (uint8_t)pictureID); 1851a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (buildVal == -1) { 1852a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return -1; 1853a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } else if (buildVal == -2) { 1854a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return position; 1855a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1856a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1857a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpRpsi) 1858a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 18594e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org const int8_t payloadType = feedback_state.send_payload_type; 1860a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (payloadType == -1) { 1861a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return -1; 1862a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1863a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org buildVal = BuildRPSI(rtcp_buffer, position, pictureID, 1864a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org (uint8_t)payloadType); 1865a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (buildVal == -1) { 1866a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return -1; 1867a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } else if (buildVal == -2) { 1868a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return position; 1869a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1870a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1871a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpRemb) 1872a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1873a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org buildVal = BuildREMB(rtcp_buffer, position); 1874a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (buildVal == -1) { 1875a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return -1; 1876a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } else if (buildVal == -2) { 1877a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return position; 1878a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1879a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org TRACE_EVENT_INSTANT0("webrtc_rtp", "RTCPSender::REMB"); 1880a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1881a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpBye) 1882a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1883a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org buildVal = BuildBYE(rtcp_buffer, position); 1884a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (buildVal == -1) { 1885a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return -1; 1886a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } else if (buildVal == -2) { 1887a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return position; 1888a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1889a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1890a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpApp) 1891a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1892a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org buildVal = BuildAPP(rtcp_buffer, position); 1893a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (buildVal == -1) { 1894a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return -1; 1895a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } else if (buildVal == -2) { 1896a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return position; 1897a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1898a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1899a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpTmmbr) 1900a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 19014e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org buildVal = BuildTMMBR(feedback_state.module, rtcp_buffer, position); 1902a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (buildVal == -1) { 1903a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return -1; 1904a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } else if (buildVal == -2) { 1905a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return position; 1906a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1907a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1908a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpTmmbn) 1909a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1910a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org buildVal = BuildTMMBN(rtcp_buffer, position); 1911a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (buildVal == -1) { 1912a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return -1; 1913a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } else if (buildVal == -2) { 1914a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return position; 1915a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1916a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1917a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpNack) 1918a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1919a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org std::string nackString; 1920a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org buildVal = BuildNACK(rtcp_buffer, position, nackSize, nackList, 1921a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org &nackString); 1922a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (buildVal == -1) { 1923a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return -1; 1924a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } else if (buildVal == -2) { 1925a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return position; 1926a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1927a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org TRACE_EVENT_INSTANT1("webrtc_rtp", "RTCPSender::NACK", 1928a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org "nacks", TRACE_STR_COPY(nackString.c_str())); 19294a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org ++packet_type_counter_.nack_packets; 19304a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org TRACE_COUNTER_ID1("webrtc_rtp", "RTCP_NACKCount", _SSRC, 19314a1556017653ef7702585897b071872e83bd95b9asapersson@webrtc.org packet_type_counter_.nack_packets); 1932a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1933a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpXrVoipMetric) 1934a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org { 1935a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org buildVal = BuildVoIPMetric(rtcp_buffer, position); 1936a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (buildVal == -1) { 1937a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return -1; 1938a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } else if (buildVal == -2) { 1939a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return position; 1940a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1941a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 1942d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org if (rtcpPacketTypeFlags & kRtcpXrReceiverReferenceTime) 1943d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org { 1944d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org buildVal = BuildReceiverReferenceTime(rtcp_buffer, 1945d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org position, 1946d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org NTPsec, 1947d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org NTPfrac); 1948d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org if (buildVal == -1) { 1949d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org return -1; 1950d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org } else if (buildVal == -2) { 1951d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org return position; 1952d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org } 1953d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org } 1954d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org if (rtcpPacketTypeFlags & kRtcpXrDlrrReportBlock) 1955d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org { 1956d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org buildVal = BuildDlrr(rtcp_buffer, position, feedback_state.last_xr_rr); 1957d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org if (buildVal == -1) { 1958d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org return -1; 1959d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org } else if (buildVal == -2) { 1960d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org return position; 1961d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org } 1962d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org } 1963a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return position; 1964a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org} 1965c0976d247fedbe48d703f1ef3d5fb0fd70fdab93henrike@webrtc.org 1966a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.orgbool RTCPSender::ShouldSendReportBlocks(uint32_t rtcp_packet_type) const { 1967a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return Status() == kRtcpCompound || 1968a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org (rtcp_packet_type & kRtcpReport) || 1969a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org (rtcp_packet_type & kRtcpSr) || 1970a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org (rtcp_packet_type & kRtcpRr); 1971a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org} 1972c0976d247fedbe48d703f1ef3d5fb0fd70fdab93henrike@webrtc.org 19734e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.orgbool RTCPSender::PrepareReport(const FeedbackState& feedback_state, 19744e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org StreamStatistician* statistician, 1975a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org RTCPReportBlock* report_block, 1976a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org uint32_t* ntp_secs, uint32_t* ntp_frac) { 1977a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org // Do we have receive statistics to send? 19784f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org RtcpStatistics stats; 1979a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if (!statistician->GetStatistics(&stats, true)) 1980a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return false; 1981a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org report_block->fractionLost = stats.fraction_lost; 1982a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org report_block->cumulativeLost = stats.cumulative_lost; 1983a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org report_block->extendedHighSeqNum = 1984a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org stats.extended_max_sequence_number; 1985a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org report_block->jitter = stats.jitter; 1986a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org 1987a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org // get our NTP as late as possible to avoid a race 1988a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org _clock->CurrentNtp(*ntp_secs, *ntp_frac); 1989a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org 1990a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org // Delay since last received report 1991a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org uint32_t delaySinceLastReceivedSR = 0; 19924e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org if ((feedback_state.last_rr_ntp_secs != 0) || 19934e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org (feedback_state.last_rr_ntp_frac != 0)) { 1994a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org // get the 16 lowest bits of seconds and the 16 higest bits of fractions 1995a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org uint32_t now=*ntp_secs&0x0000FFFF; 1996a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org now <<=16; 1997a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org now += (*ntp_frac&0xffff0000)>>16; 1998a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org 19994e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org uint32_t receiveTime = feedback_state.last_rr_ntp_secs&0x0000FFFF; 2000a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org receiveTime <<=16; 20014e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org receiveTime += (feedback_state.last_rr_ntp_frac&0xffff0000)>>16; 2002a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org 2003a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org delaySinceLastReceivedSR = now-receiveTime; 2004a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 2005a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org report_block->delaySinceLastSR = delaySinceLastReceivedSR; 20064e7777bf0337ddb74b0cc8e5a5f3619d8dd770cfpbos@webrtc.org report_block->lastSR = feedback_state.remote_sr; 2007a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return true; 2008b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 2009b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2010b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t 2011b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgRTCPSender::SendToNetwork(const uint8_t* dataBuffer, 2012b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org const uint16_t length) 2013b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 2014b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionTransport); 2015b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(_cbTransport) 2016b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 2017b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(_cbTransport->SendRTCPPacket(_id, dataBuffer, length) > 0) 2018b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 2019b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 2020b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2021b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2022b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 2023b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 2024b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2025b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t 2026b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTCPSender::SetCSRCStatus(const bool include) 2027b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 20280cb22cf7e4f9531a0f218e27c8ea0d0620cf05d7pbos@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 2029b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _includeCSRCs = include; 2030b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 2031b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 2032b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2033b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t 2034b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgRTCPSender::SetCSRCs(const uint32_t arrOfCSRC[kRtpCsrcSize], 2035b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org const uint8_t arrLength) 2036b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 203799681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org assert(arrLength <= kRtpCsrcSize); 2038b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 2039b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2040b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for(int i = 0; i < arrLength;i++) 2041b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 2042b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _CSRC[i] = arrOfCSRC[i]; 2043b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2044b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _CSRCs = arrLength; 2045b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 2046b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 2047b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2048b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t 2049b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgRTCPSender::SetApplicationSpecificData(const uint8_t subType, 2050b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org const uint32_t name, 2051b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org const uint8_t* data, 2052b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org const uint16_t length) 2053b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 2054b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(length %4 != 0) 2055b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 205699681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org LOG(LS_ERROR) << "Failed to SetApplicationSpecificData."; 2057b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 2058b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2059b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 2060b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2061b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(_appData) 2062b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 2063b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete [] _appData; 2064b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2065b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2066b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _appSend = true; 2067b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _appSubType = subType; 2068b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _appName = name; 2069b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org _appData = new uint8_t[length]; 2070b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _appLength = length; 2071b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(_appData, data, length); 2072b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 2073b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 2074b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2075b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t 2076b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTCPSender::SetRTCPVoIPMetrics(const RTCPVoIPMetric* VoIPMetric) 2077b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 2078b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 2079b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(&_xrVoIPMetric, VoIPMetric, sizeof(RTCPVoIPMetric)); 2080b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2081b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _xrSendVoIPMetric = true; 2082b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 2083b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 2084b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2085d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.orgvoid RTCPSender::SendRtcpXrReceiverReferenceTime(bool enable) { 2086d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 2087d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org xrSendReceiverReferenceTimeEnabled_ = enable; 2088d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org} 2089d6da239905c84110a7c90789df70238afd0f64b6asapersson@webrtc.org 20903dc7ff30185a2d7a597acb69183fca73bd1004d8asapersson@webrtc.orgbool RTCPSender::RtcpXrReceiverReferenceTime() const { 20913dc7ff30185a2d7a597acb69183fca73bd1004d8asapersson@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 20923dc7ff30185a2d7a597acb69183fca73bd1004d8asapersson@webrtc.org return xrSendReceiverReferenceTimeEnabled_; 20933dc7ff30185a2d7a597acb69183fca73bd1004d8asapersson@webrtc.org} 20943dc7ff30185a2d7a597acb69183fca73bd1004d8asapersson@webrtc.org 2095b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// called under critsect _criticalSectionRTCPSender 2096a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.orgint32_t RTCPSender::WriteAllReportBlocksToBuffer( 2097a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org uint8_t* rtcpbuffer, 2098a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org int pos, 2099a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org uint8_t& numberOfReportBlocks, 2100a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org const uint32_t NTPsec, 2101a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org const uint32_t NTPfrac) { 2102a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org numberOfReportBlocks = external_report_blocks_.size(); 2103a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org numberOfReportBlocks += internal_report_blocks_.size(); 2104a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org if ((pos + numberOfReportBlocks * 24) >= IP_PACKET_SIZE) { 210599681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org LOG(LS_WARNING) << "Can't fit all report blocks."; 2106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 2107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2108a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org pos = WriteReportBlocksToBuffer(rtcpbuffer, pos, internal_report_blocks_); 2109a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org while (!internal_report_blocks_.empty()) { 2110a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org delete internal_report_blocks_.begin()->second; 2111a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org internal_report_blocks_.erase(internal_report_blocks_.begin()); 2112a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org } 2113a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org pos = WriteReportBlocksToBuffer(rtcpbuffer, pos, external_report_blocks_); 2114a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return pos; 2115a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org} 2116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2117a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.orgint32_t RTCPSender::WriteReportBlocksToBuffer( 2118a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org uint8_t* rtcpbuffer, 2119a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org int32_t position, 2120a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org const std::map<uint32_t, RTCPReportBlock*>& report_blocks) { 2121a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org std::map<uint32_t, RTCPReportBlock*>::const_iterator it = 2122a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org report_blocks.begin(); 2123a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org for (; it != report_blocks.end(); it++) { 2124b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint32_t remoteSSRC = it->first; 2125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RTCPReportBlock* reportBlock = it->second; 2126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (reportBlock) { 2127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Remote SSRC 21286aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + position, remoteSSRC); 2129a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org position += 4; 2130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // fraction lost 2132a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org rtcpbuffer[position++] = reportBlock->fractionLost; 2133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // cumulative loss 21356aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord24ToBuffer(rtcpbuffer + position, 21366aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org reportBlock->cumulativeLost); 2137a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org position += 3; 2138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // extended highest seq_no, contain the highest sequence number received 21406aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + position, 21416aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org reportBlock->extendedHighSeqNum); 2142a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org position += 4; 2143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2144a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org // Jitter 21456aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + position, 21466aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org reportBlock->jitter); 2147a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org position += 4; 2148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 21496aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + position, 21506aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org reportBlock->lastSR); 2151a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org position += 4; 2152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 21536aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + position, 21546aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org reportBlock->delaySinceLastSR); 2155a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org position += 4; 2156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2158a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org return position; 2159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 2160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// no callbacks allowed inside this function 2162b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t 2163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTCPSender::SetTMMBN(const TMMBRSet* boundingSet, 2164b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org const uint32_t maxBitrateKbit) 2165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 2166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 2167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (0 == _tmmbrHelp.SetTMMBRBoundingSetToSend(boundingSet, maxBitrateKbit)) 2169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 2170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _sendTMMBN = true; 2171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 2172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 2174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 21753b89e10f31160da35b408fd00cb8f89d2b08862dpbos@webrtc.org} // namespace webrtc 2176