rtcp_sender.cc revision 59f20bb735562d245357609799578edeed46be32
1470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 2f6bb77a6f0d250f8c4c2c4dbf059556c00cf8eafpwestin@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 4470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Use of this source code is governed by a BSD-style license 5470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * that can be found in the LICENSE file in the root of the source 6470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * tree. An additional intellectual property rights grant can be found 7470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * in the file PATENTS. All contributing project authors may 8470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * be found in the AUTHORS file in the root of the source tree. 9470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 10470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 11a048d7cb0a5bad5ca49bbcc5273cb4cca28c1710pbos@webrtc.org#include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h" 12470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1312dc1a38ca54a000e4fecfbc6d41138b895c9ca5pbos@webrtc.org#include <assert.h> // assert 1412dc1a38ca54a000e4fecfbc6d41138b895c9ca5pbos@webrtc.org#include <stdlib.h> // rand 159354cc965c04a0c79ea36622043751596a6fd015stefan@webrtc.org#include <string.h> // memcpy 16470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1712dc1a38ca54a000e4fecfbc6d41138b895c9ca5pbos@webrtc.org#include <algorithm> // min 1812dc1a38ca54a000e4fecfbc6d41138b895c9ca5pbos@webrtc.org 19a048d7cb0a5bad5ca49bbcc5273cb4cca28c1710pbos@webrtc.org#include "webrtc/common_types.h" 20a048d7cb0a5bad5ca49bbcc5273cb4cca28c1710pbos@webrtc.org#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h" 21a048d7cb0a5bad5ca49bbcc5273cb4cca28c1710pbos@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 22a048d7cb0a5bad5ca49bbcc5273cb4cca28c1710pbos@webrtc.org#include "webrtc/system_wrappers/interface/trace.h" 23a048d7cb0a5bad5ca49bbcc5273cb4cca28c1710pbos@webrtc.org#include "webrtc/system_wrappers/interface/trace_event.h" 24741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org 25470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comnamespace webrtc { 2626f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org 2726f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.orgusing RTCPUtility::RTCPCnameInformation; 2826f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org 2979b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.comNACKStringBuilder::NACKStringBuilder() : 3079b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com _stream(""), _count(0), _consecutive(false) 3179b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com{ 3279b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com // Empty. 3379b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com} 3479b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com 35f3e4ceee47d747c8868d919c179ecc640b9541f0pbos@webrtc.orgNACKStringBuilder::~NACKStringBuilder() {} 36f3e4ceee47d747c8868d919c179ecc640b9541f0pbos@webrtc.org 372f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgvoid NACKStringBuilder::PushNACK(uint16_t nack) 3879b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com{ 3979b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com if (_count == 0) 4079b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com { 4179b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com _stream << nack; 4279b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com } else if (nack == _prevNack + 1) 4379b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com { 4479b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com _consecutive = true; 4579b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com } else 4679b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com { 4779b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com if (_consecutive) 4879b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com { 4979b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com _stream << "-" << _prevNack; 5079b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com _consecutive = false; 5179b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com } 5279b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com _stream << "," << nack; 5379b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com } 5479b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com _count++; 5579b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com _prevNack = nack; 5679b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com} 5779b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com 5879b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.comstd::string NACKStringBuilder::GetResult() 5979b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com{ 6079b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com if (_consecutive) 6179b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com { 6279b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com _stream << "-" << _prevNack; 6379b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com _consecutive = false; 6479b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com } 6579b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com return _stream.str(); 6679b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com} 6779b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com 6859f20bb735562d245357609799578edeed46be32pbos@webrtc.orgRTCPSender::FeedbackState::FeedbackState(ModuleRtpRtcpImpl* module) 6959f20bb735562d245357609799578edeed46be32pbos@webrtc.org : send_payload_type(module->SendPayloadType()), 7059f20bb735562d245357609799578edeed46be32pbos@webrtc.org frequency_hz(module->CurrentSendFrequencyHz()), 7159f20bb735562d245357609799578edeed46be32pbos@webrtc.org packet_count_sent(module->PacketCountSent()), 7259f20bb735562d245357609799578edeed46be32pbos@webrtc.org byte_count_sent(module->ByteCountSent()), 7359f20bb735562d245357609799578edeed46be32pbos@webrtc.org module(module) { 7459f20bb735562d245357609799578edeed46be32pbos@webrtc.org uint32_t last_ntp_secs = 0, last_ntp_frac = 0, last_remote_sr = 0; 7559f20bb735562d245357609799578edeed46be32pbos@webrtc.org module->LastReceivedNTP(last_ntp_secs, last_ntp_frac, last_remote_sr); 7659f20bb735562d245357609799578edeed46be32pbos@webrtc.org last_rr_ntp_secs = last_ntp_secs; 7759f20bb735562d245357609799578edeed46be32pbos@webrtc.org last_rr_ntp_frac = last_ntp_frac; 7859f20bb735562d245357609799578edeed46be32pbos@webrtc.org remote_sr = last_remote_sr; 7959f20bb735562d245357609799578edeed46be32pbos@webrtc.org 8059f20bb735562d245357609799578edeed46be32pbos@webrtc.org uint32_t send_bitrate = 0, tmp; 8159f20bb735562d245357609799578edeed46be32pbos@webrtc.org module->BitrateSent(&send_bitrate, &tmp, &tmp, &tmp); 8259f20bb735562d245357609799578edeed46be32pbos@webrtc.org this->send_bitrate = send_bitrate; 8359f20bb735562d245357609799578edeed46be32pbos@webrtc.org} 8459f20bb735562d245357609799578edeed46be32pbos@webrtc.org 8559f20bb735562d245357609799578edeed46be32pbos@webrtc.orgRTCPSender::FeedbackState::FeedbackState() 8659f20bb735562d245357609799578edeed46be32pbos@webrtc.org : send_payload_type(0), 8759f20bb735562d245357609799578edeed46be32pbos@webrtc.org frequency_hz(0), 8859f20bb735562d245357609799578edeed46be32pbos@webrtc.org packet_count_sent(0), 8959f20bb735562d245357609799578edeed46be32pbos@webrtc.org byte_count_sent(0), 9059f20bb735562d245357609799578edeed46be32pbos@webrtc.org send_bitrate(0), 9159f20bb735562d245357609799578edeed46be32pbos@webrtc.org last_rr_ntp_secs(0), 9259f20bb735562d245357609799578edeed46be32pbos@webrtc.org last_rr_ntp_frac(0), 9359f20bb735562d245357609799578edeed46be32pbos@webrtc.org remote_sr(0) {} 9459f20bb735562d245357609799578edeed46be32pbos@webrtc.org 952f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgRTCPSender::RTCPSender(const int32_t id, 96470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const bool audio, 9720ed36dada62ad56ec01263fc0eef0ed198f6476stefan@webrtc.org Clock* clock, 98286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org ReceiveStatistics* receive_statistics) : 99470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _id(id), 100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _audio(audio), 101a678a3baee2e680bd521f3a6caf97707fffd6093stefan@webrtc.org _clock(clock), 102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _method(kRtcpOff), 10365573f29222a2139776ac93982836e949ea5f958henrike@webrtc.org _criticalSectionTransport(CriticalSectionWrapper::CreateCriticalSection()), 104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _cbTransport(NULL), 105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 10665573f29222a2139776ac93982836e949ea5f958henrike@webrtc.org _criticalSectionRTCPSender(CriticalSectionWrapper::CreateCriticalSection()), 107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _usingNack(false), 108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _sending(false), 109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _sendTMMBN(false), 110741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org _REMB(false), 111741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org _sendREMB(false), 112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _TMMBR(false), 1135249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org _IJ(false), 114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _nextTimeToSendRTCP(0), 1157c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org start_timestamp_(0), 1167c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org last_rtp_timestamp_(0), 1177c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org last_frame_capture_time_ms_(-1), 118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _SSRC(0), 119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _remoteSSRC(0), 120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _CNAME(), 121286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org receive_statistics_(receive_statistics), 122286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org internal_report_blocks_(), 123286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org external_report_blocks_(), 124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _csrcCNAMEs(), 125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1267da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org _cameraDelayMS(0), 1277da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org 128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _lastSendReport(), 129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _lastRTCPTime(), 130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _CSRCs(0), 132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _CSRC(), 133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _includeCSRCs(true), 134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _sequenceNumberFIR(0), 136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 137741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org _lengthRembSSRC(0), 138741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org _sizeRembSSRC(0), 139741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org _rembSSRC(NULL), 140741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org _rembBitrate(0), 141741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org 142cac787842c480b77ef2747169ecfeaf434a12657pwestin@webrtc.org _tmmbrHelp(), 143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _tmmbr_Send(0), 144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _packetOH_Send(0), 145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _appSend(false), 147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _appSubType(0), 148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _appName(), 149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _appData(NULL), 150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _appLength(0), 151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _xrSendVoIPMetric(false), 15279b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com _xrVoIPMetric(), 15379b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com _nackCount(0), 15479b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com _pliCount(0), 15579b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com _fullIntraRequestCount(0) 156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com memset(_CNAME, 0, sizeof(_CNAME)); 158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com memset(_lastSendReport, 0, sizeof(_lastSendReport)); 159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com memset(_lastRTCPTime, 0, sizeof(_lastRTCPTime)); 160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__); 162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 16426f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.orgRTCPSender::~RTCPSender() { 16526f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org delete [] _rembSSRC; 16626f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org delete [] _appData; 167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 168286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org while (!internal_report_blocks_.empty()) { 169286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org delete internal_report_blocks_.begin()->second; 170286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org internal_report_blocks_.erase(internal_report_blocks_.begin()); 171286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 172286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org while (!external_report_blocks_.empty()) { 1732f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org std::map<uint32_t, RTCPReportBlock*>::iterator it = 174286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org external_report_blocks_.begin(); 17526f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org delete it->second; 176286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org external_report_blocks_.erase(it); 17726f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org } 17826f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org while (!_csrcCNAMEs.empty()) { 1792f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org std::map<uint32_t, RTCPCnameInformation*>::iterator it = 18026f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org _csrcCNAMEs.begin(); 18126f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org delete it->second; 18226f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org _csrcCNAMEs.erase(it); 18326f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org } 18426f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org delete _criticalSectionTransport; 18526f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org delete _criticalSectionRTCPSender; 186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 18726f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, _id, "%s deleted", __FUNCTION__); 188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1902f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comRTCPSender::Init() 192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CriticalSectionScoped lock(_criticalSectionRTCPSender); 194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _method = kRtcpOff; 196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _cbTransport = NULL; 197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _usingNack = false; 198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _sending = false; 199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _sendTMMBN = false; 200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _TMMBR = false; 2015249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org _IJ = false; 202741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org _REMB = false; 203741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org _sendREMB = false; 2047c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org last_rtp_timestamp_ = 0; 2057c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org last_frame_capture_time_ms_ = -1; 2067c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org start_timestamp_ = -1; 207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _SSRC = 0; 208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _remoteSSRC = 0; 2097da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org _cameraDelayMS = 0; 210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _sequenceNumberFIR = 0; 211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _tmmbr_Send = 0; 212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _packetOH_Send = 0; 213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _nextTimeToSendRTCP = 0; 214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _CSRCs = 0; 215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _appSend = false; 216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _appSubType = 0; 217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(_appData) 219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delete [] _appData; 221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _appData = NULL; 222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _appLength = 0; 224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _xrSendVoIPMetric = false; 226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com memset(&_xrVoIPMetric, 0, sizeof(_xrVoIPMetric)); 228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com memset(_CNAME, 0, sizeof(_CNAME)); 229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com memset(_lastSendReport, 0, sizeof(_lastSendReport)); 230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com memset(_lastRTCPTime, 0, sizeof(_lastRTCPTime)); 23179b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com 23279b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com _nackCount = 0; 23379b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com _pliCount = 0; 23479b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com _fullIntraRequestCount = 0; 23579b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com 236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 2402f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgRTCPSender::ChangeUniqueId(const int32_t id) 241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _id = id; 243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2452f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comRTCPSender::RegisterSendTransport(Transport* outgoingTransport) 247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CriticalSectionScoped lock(_criticalSectionTransport); 249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _cbTransport = outgoingTransport; 250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comRTCPMethod 254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comRTCPSender::Status() const 255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CriticalSectionScoped lock(_criticalSectionRTCPSender); 257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return _method; 258470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2602f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 261470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comRTCPSender::SetRTCPStatus(const RTCPMethod method) 262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CriticalSectionScoped lock(_criticalSectionRTCPSender); 264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(method != kRtcpOff) 265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(_audio) 267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 268a678a3baee2e680bd521f3a6caf97707fffd6093stefan@webrtc.org _nextTimeToSendRTCP = _clock->TimeInMilliseconds() + 26920ed36dada62ad56ec01263fc0eef0ed198f6476stefan@webrtc.org (RTCP_INTERVAL_AUDIO_MS/2); 270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else 271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 272a678a3baee2e680bd521f3a6caf97707fffd6093stefan@webrtc.org _nextTimeToSendRTCP = _clock->TimeInMilliseconds() + 27320ed36dada62ad56ec01263fc0eef0ed198f6476stefan@webrtc.org (RTCP_INTERVAL_VIDEO_MS/2); 274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _method = method; 277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.combool 281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comRTCPSender::Sending() const 282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CriticalSectionScoped lock(_criticalSectionRTCPSender); 284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return _sending; 285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2872f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 28859f20bb735562d245357609799578edeed46be32pbos@webrtc.orgRTCPSender::SetSendingStatus(const FeedbackState& feedback_state, bool sending) 289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool sendRTCPBye = false; 291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CriticalSectionScoped lock(_criticalSectionRTCPSender); 293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(_method != kRtcpOff) 295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(sending == false && _sending == true) 297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Trigger RTCP bye 299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sendRTCPBye = true; 300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _sending = sending; 303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(sendRTCPBye) 305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 30659f20bb735562d245357609799578edeed46be32pbos@webrtc.org return SendRTCP(feedback_state, kRtcpBye); 307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.combool 312741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.orgRTCPSender::REMB() const 313741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org{ 314741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 315741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org return _REMB; 316741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org} 317741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org 3182f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 319741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.orgRTCPSender::SetREMBStatus(const bool enable) 320741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org{ 321741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 322741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org _REMB = enable; 323741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org return 0; 324741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org} 325741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org 3262f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 3272f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgRTCPSender::SetREMBData(const uint32_t bitrate, 3282f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org const uint8_t numberOfSSRC, 3292f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org const uint32_t* SSRC) 330741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org{ 331741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 332741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org _rembBitrate = bitrate; 333741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org 334741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org if(_sizeRembSSRC < numberOfSSRC) 335741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org { 336741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org delete [] _rembSSRC; 3372f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org _rembSSRC = new uint32_t[numberOfSSRC]; 338741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org _sizeRembSSRC = numberOfSSRC; 339741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org } 340741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org 341741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org _lengthRembSSRC = numberOfSSRC; 342741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org for (int i = 0; i < numberOfSSRC; i++) 343741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org { 344741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org _rembSSRC[i] = SSRC[i]; 345741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org } 34684dc3d134dca17df970e6a4a3e83543c0729799amflodman@webrtc.org _sendREMB = true; 347741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org return 0; 348741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org} 349741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org 350741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.orgbool 351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comRTCPSender::TMMBR() const 352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CriticalSectionScoped lock(_criticalSectionRTCPSender); 354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return _TMMBR; 355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3572f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comRTCPSender::SetTMMBRStatus(const bool enable) 359470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CriticalSectionScoped lock(_criticalSectionRTCPSender); 361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _TMMBR = enable; 362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3655249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.orgbool 3665249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.orgRTCPSender::IJ() const 3675249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org{ 3685249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 3695249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org return _IJ; 3705249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org} 3715249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org 3722f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 3735249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.orgRTCPSender::SetIJStatus(const bool enable) 3745249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org{ 3755249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 3765249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org _IJ = enable; 3775249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org return 0; 3785249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org} 3795249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org 3807c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.orgvoid RTCPSender::SetStartTimestamp(uint32_t start_timestamp) { 3817c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org start_timestamp_ = start_timestamp; 3827c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org} 3837c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org 3847c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.orgvoid RTCPSender::SetLastRtpTime(uint32_t rtp_timestamp, 3857c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org int64_t capture_time_ms) { 38619da719a5febb4baa6e5dcdef8270792f9d31d6dhenrika@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 3877c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org last_rtp_timestamp_ = rtp_timestamp; 3887c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org if (capture_time_ms < 0) { 3897c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org // We don't currently get a capture time from VoiceEngine. 3907da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org last_frame_capture_time_ms_ = _clock->TimeInMilliseconds(); 3917c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org } else { 3927c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org last_frame_capture_time_ms_ = capture_time_ms; 3937c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org } 3947c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org} 3957c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org 396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 3972f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgRTCPSender::SetSSRC( const uint32_t ssrc) 398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CriticalSectionScoped lock(_criticalSectionRTCPSender); 400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(_SSRC != 0) 402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // not first SetSSRC, probably due to a collision 404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // schedule a new RTCP report 4050644b1dc359c0f9b9b5c03d116b1341a7662bb59pwestin@webrtc.org // make sure that we send a RTP packet 406a678a3baee2e680bd521f3a6caf97707fffd6093stefan@webrtc.org _nextTimeToSendRTCP = _clock->TimeInMilliseconds() + 100; 407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _SSRC = ssrc; 409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 411822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.orgvoid RTCPSender::SetRemoteSSRC(uint32_t ssrc) 412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CriticalSectionScoped lock(_criticalSectionRTCPSender); 414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _remoteSSRC = ssrc; 415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4177da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.orgint32_t 4187da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.orgRTCPSender::SetCameraDelay(const int32_t delayMS) 4197da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org{ 4207da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 4217da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org if(delayMS > 1000 || delayMS < -1000) 4227da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org { 4237da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument, delay can't be larger than 1 sec", __FUNCTION__); 4247da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org return -1; 4257da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org } 4267da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org _cameraDelayMS = delayMS; 4277da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org return 0; 4287da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org} 4297da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org 4302f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t RTCPSender::CNAME(char cName[RTCP_CNAME_SIZE]) { 431f6bb77a6f0d250f8c4c2c4dbf059556c00cf8eafpwestin@webrtc.org assert(cName); 432f6bb77a6f0d250f8c4c2c4dbf059556c00cf8eafpwestin@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 433f6bb77a6f0d250f8c4c2c4dbf059556c00cf8eafpwestin@webrtc.org cName[RTCP_CNAME_SIZE - 1] = 0; 434f6bb77a6f0d250f8c4c2c4dbf059556c00cf8eafpwestin@webrtc.org strncpy(cName, _CNAME, RTCP_CNAME_SIZE - 1); 435f6bb77a6f0d250f8c4c2c4dbf059556c00cf8eafpwestin@webrtc.org return 0; 436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4382f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t RTCPSender::SetCNAME(const char cName[RTCP_CNAME_SIZE]) { 439a990e122c461e24d19e3249718782e671a811eadtommi@webrtc.org if (!cName) 440a990e122c461e24d19e3249718782e671a811eadtommi@webrtc.org return -1; 441a990e122c461e24d19e3249718782e671a811eadtommi@webrtc.org 44226f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 443f6bb77a6f0d250f8c4c2c4dbf059556c00cf8eafpwestin@webrtc.org _CNAME[RTCP_CNAME_SIZE - 1] = 0; 444f6bb77a6f0d250f8c4c2c4dbf059556c00cf8eafpwestin@webrtc.org strncpy(_CNAME, cName, RTCP_CNAME_SIZE - 1); 44526f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org return 0; 446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4482f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t RTCPSender::AddMixedCNAME(const uint32_t SSRC, 4492f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org const char cName[RTCP_CNAME_SIZE]) { 450f6bb77a6f0d250f8c4c2c4dbf059556c00cf8eafpwestin@webrtc.org assert(cName); 45126f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 45226f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org if (_csrcCNAMEs.size() >= kRtpCsrcSize) { 45326f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org return -1; 45426f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org } 45526f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org RTCPCnameInformation* ptr = new RTCPCnameInformation(); 456f6bb77a6f0d250f8c4c2c4dbf059556c00cf8eafpwestin@webrtc.org ptr->name[RTCP_CNAME_SIZE - 1] = 0; 457f6bb77a6f0d250f8c4c2c4dbf059556c00cf8eafpwestin@webrtc.org strncpy(ptr->name, cName, RTCP_CNAME_SIZE - 1); 45826f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org _csrcCNAMEs[SSRC] = ptr; 45926f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org return 0; 46026f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org} 461470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4622f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t RTCPSender::RemoveMixedCNAME(const uint32_t SSRC) { 46326f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 4642f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org std::map<uint32_t, RTCPCnameInformation*>::iterator it = 46526f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org _csrcCNAMEs.find(SSRC); 466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 46726f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org if (it == _csrcCNAMEs.end()) { 468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 46926f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org } 47026f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org delete it->second; 47126f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org _csrcCNAMEs.erase(it); 47226f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org return 0; 473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.combool 476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comRTCPSender::TimeToSendRTCPReport(const bool sendKeyframeBeforeRTP) const 477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com For audio we use a fix 5 sec interval 480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com For video we use 1 sec interval fo a BW smaller than 360 kbit/s, 482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com technicaly we break the max 5% RTCP BW for video below 10 kbit/s but that should be extreamly rare 483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comFrom RFC 3550 486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com MAX RTCP BW is 5% if the session BW 488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com A send report is approximately 65 bytes inc CNAME 489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com A report report is approximately 28 bytes 490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com The RECOMMENDED value for the reduced minimum in seconds is 360 492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com divided by the session bandwidth in kilobits/second. This minimum 493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com is smaller than 5 seconds for bandwidths greater than 72 kb/s. 494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com If the participant has not yet sent an RTCP packet (the variable 496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com initial is true), the constant Tmin is set to 2.5 seconds, else it 497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com is set to 5 seconds. 498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com The interval between RTCP packets is varied randomly over the 500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com range [0.5,1.5] times the calculated interval to avoid unintended 501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com synchronization of all participants 502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if we send 504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com If the participant is a sender (we_sent true), the constant C is 505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com set to the average RTCP packet size (avg_rtcp_size) divided by 25% 506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com of the RTCP bandwidth (rtcp_bw), and the constant n is set to the 507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com number of senders. 508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if we receive only 510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com If we_sent is not true, the constant C is set 511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com to the average RTCP packet size divided by 75% of the RTCP 512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bandwidth. The constant n is set to the number of receivers 513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (members - senders). If the number of senders is greater than 514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 25%, senders and receivers are treated together. 515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com reconsideration NOT required for peer-to-peer 517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "timer reconsideration" is 518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com employed. This algorithm implements a simple back-off mechanism 519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com which causes users to hold back RTCP packet transmission if the 520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com group sizes are increasing. 521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com n = number of members 523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com C = avg_size/(rtcpBW/4) 524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3. The deterministic calculated interval Td is set to max(Tmin, n*C). 526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4. The calculated interval T is set to a number uniformly distributed 528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com between 0.5 and 1.5 times the deterministic calculated interval. 529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5. The resulting value of T is divided by e-3/2=1.21828 to compensate 531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for the fact that the timer reconsideration algorithm converges to 532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com a value of the RTCP bandwidth below the intended average 533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com*/ 534470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5352f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org int64_t now = _clock->TimeInMilliseconds(); 5368738d277a14bef5cd09ca4352e7ea904ae0d196axians@webrtc.org 5378738d277a14bef5cd09ca4352e7ea904ae0d196axians@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 5388738d277a14bef5cd09ca4352e7ea904ae0d196axians@webrtc.org 539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(_method == kRtcpOff) 540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return false; 542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(!_audio && sendKeyframeBeforeRTP) 545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // for video key-frames we want to send the RTCP before the large key-frame 547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // if we have a 100 ms margin 548470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com now += RTCP_SEND_BEFORE_KEY_FRAME_MS; 549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(now > _nextTimeToSendRTCP) 552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return true; 554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else if(now < 0x0000ffff && _nextTimeToSendRTCP > 0xffff0000) // 65 sec margin 556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // wrap 558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return true; 559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return false; 561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5632f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orguint32_t 5642f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgRTCPSender::LastSendReport( uint32_t& lastRTCPTime) 565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CriticalSectionScoped lock(_criticalSectionRTCPSender); 567470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lastRTCPTime = _lastRTCPTime[0]; 569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return _lastSendReport[0]; 570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5722f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orguint32_t 5732f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgRTCPSender::SendTimeOfSendReport(const uint32_t sendReport) 574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CriticalSectionScoped lock(_criticalSectionRTCPSender); 576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // This is only saved when we are the sender 578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if((_lastSendReport[0] == 0) || (sendReport == 0)) 579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 580470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; // will be ignored 581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else 582470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 583470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for(int i = 0; i < RTCP_NUMBER_OF_SR; ++i) 584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( _lastSendReport[i] == sendReport) 586470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 587470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return _lastRTCPTime[i]; 588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 589470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 590470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 591470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 592470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 594286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.orgint32_t RTCPSender::AddExternalReportBlock( 595286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org uint32_t SSRC, 596286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org const RTCPReportBlock* reportBlock) { 597286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 598286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return AddReportBlock(SSRC, &external_report_blocks_, reportBlock); 599286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org} 600286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 601286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.orgint32_t RTCPSender::AddReportBlock( 602286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org uint32_t SSRC, 603286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org std::map<uint32_t, RTCPReportBlock*>* report_blocks, 604286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org const RTCPReportBlock* reportBlock) { 60526f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org if (reportBlock == NULL) { 60626f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, 60726f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org "%s invalid argument", __FUNCTION__); 60826f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org return -1; 60926f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org } 610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 611286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (report_blocks->size() >= RTCP_MAX_REPORT_BLOCKS) { 61226f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, 61326f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org "%s invalid argument", __FUNCTION__); 61426f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org return -1; 61526f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org } 6162f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org std::map<uint32_t, RTCPReportBlock*>::iterator it = 617286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org report_blocks->find(SSRC); 618286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (it != report_blocks->end()) { 6198d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org delete it->second; 620286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org report_blocks->erase(it); 6218d0cd07d0c5e30eacaac4c118f9fd624b11e67abstefan@webrtc.org } 62226f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org RTCPReportBlock* copyReportBlock = new RTCPReportBlock(); 62326f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org memcpy(copyReportBlock, reportBlock, sizeof(RTCPReportBlock)); 624286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org (*report_blocks)[SSRC] = copyReportBlock; 62526f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org return 0; 626470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 628286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.orgint32_t RTCPSender::RemoveExternalReportBlock(uint32_t SSRC) { 62926f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6312f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org std::map<uint32_t, RTCPReportBlock*>::iterator it = 632286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org external_report_blocks_.find(SSRC); 63326f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org 634286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (it == external_report_blocks_.end()) { 635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 63626f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org } 63726f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org delete it->second; 638286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org external_report_blocks_.erase(it); 63926f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org return 0; 640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 64259f20bb735562d245357609799578edeed46be32pbos@webrtc.orgint32_t RTCPSender::BuildSR(const FeedbackState& feedback_state, 64359f20bb735562d245357609799578edeed46be32pbos@webrtc.org uint8_t* rtcpbuffer, 64459f20bb735562d245357609799578edeed46be32pbos@webrtc.org int& pos, 64559f20bb735562d245357609799578edeed46be32pbos@webrtc.org uint32_t NTPsec, 64659f20bb735562d245357609799578edeed46be32pbos@webrtc.org uint32_t NTPfrac) 647470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 648470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // sanity 649470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(pos + 52 >= IP_PACKET_SIZE) 650470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__); 652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -2; 653470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6542f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint32_t RTPtime; 655470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6562f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint32_t posNumberOfReportBlocks = pos; 6572f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80; 658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 659470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Sender report 6602f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)200; 661470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 662470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for(int i = (RTCP_NUMBER_OF_SR-2); i >= 0; i--) 663470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 664470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // shift old 665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _lastSendReport[i+1] = _lastSendReport[i]; 666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _lastRTCPTime[i+1] =_lastRTCPTime[i]; 667470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 668470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 669b8e7f4cc9763a473a9abd8e20d832a734881f99dstefan@webrtc.org _lastRTCPTime[0] = Clock::NtpToMs(NTPsec, NTPfrac); 6707c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org _lastSendReport[0] = (NTPsec << 16) + (NTPfrac >> 16); 671470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6727da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org // The timestamp of this RTCP packet should be estimated as the timestamp of 6737da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org // the frame being captured at this moment. We are calculating that 6747da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org // timestamp as the last frame's timestamp + the time since the last frame 6757da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org // was captured. 6767da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org { 6777da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org // Needs protection since this method is called on the process thread. 6787da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 6797da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org RTPtime = start_timestamp_ + last_rtp_timestamp_ + ( 6807da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org _clock->TimeInMilliseconds() - last_frame_capture_time_ms_) * 68159f20bb735562d245357609799578edeed46be32pbos@webrtc.org (feedback_state.frequency_hz / 1000); 6827da3459b2ac83923c1ccbf11ad24d3f700305febstefan@webrtc.org } 683470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 684470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add sender data 685470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Save for our length field 686470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos++; 687470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos++; 688470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 689470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add our own SSRC 690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 691470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 692470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // NTP 6937c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, NTPsec); 694470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 6957c3523c1a4c828ecb2773c685145fcfbd7c3ceadstefan@webrtc.org ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, NTPfrac); 696470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 697470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, RTPtime); 698470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 700470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com //sender's packet count 70159f20bb735562d245357609799578edeed46be32pbos@webrtc.org ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, 70259f20bb735562d245357609799578edeed46be32pbos@webrtc.org feedback_state.packet_count_sent); 703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 704470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com //sender's octet count 70659f20bb735562d245357609799578edeed46be32pbos@webrtc.org ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, 70759f20bb735562d245357609799578edeed46be32pbos@webrtc.org feedback_state.byte_count_sent); 708470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 709470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 7102f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint8_t numberOfReportBlocks = 0; 711286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org int32_t retVal = WriteAllReportBlocksToBuffer(rtcpbuffer, pos, 712286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org numberOfReportBlocks, 713286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org NTPsec, NTPfrac); 714470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(retVal < 0) 715470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 716470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // 717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return retVal ; 718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 719286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org pos = retVal; 720470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpbuffer[posNumberOfReportBlocks] += numberOfReportBlocks; 721470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 7222f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint16_t len = uint16_t((pos/4) -1); 723470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord16ToBuffer(rtcpbuffer+2, len); 724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 725470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 728286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.orgint32_t RTCPSender::BuildSDEC(uint8_t* rtcpbuffer, int& pos) { 72926f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org size_t lengthCname = strlen(_CNAME); 73026f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org assert(lengthCname < RTCP_CNAME_SIZE); 731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 73226f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org // sanity 73326f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org if(pos + 12 + lengthCname >= IP_PACKET_SIZE) { 73426f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, 73526f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org "%s invalid argument", __FUNCTION__); 73626f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org return -2; 73726f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org } 73826f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org // SDEC Source Description 739470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 74026f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org // We always need to add SDES CNAME 7412f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = static_cast<uint8_t>(0x80 + 1 + _csrcCNAMEs.size()); 7422f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = static_cast<uint8_t>(202); 743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 74426f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org // handle SDES length later on 7452f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint32_t SDESLengthPos = pos; 74626f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org pos++; 74726f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org pos++; 748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 74926f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org // Add our own SSRC 75026f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 75126f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org pos += 4; 752470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 75326f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org // CNAME = 1 7542f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = static_cast<uint8_t>(1); 755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 75626f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org // 7572f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = static_cast<uint8_t>(lengthCname); 758470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 7592f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint16_t SDESLength = 10; 760470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 76126f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org memcpy(&rtcpbuffer[pos], _CNAME, lengthCname); 76226f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org pos += lengthCname; 7632f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org SDESLength += (uint16_t)lengthCname; 764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 7652f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint16_t padding = 0; 76626f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org // We must have a zero field even if we have an even multiple of 4 bytes 76726f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org if ((pos % 4) == 0) { 76826f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org padding++; 76926f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org rtcpbuffer[pos++]=0; 77026f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org } 77126f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org while ((pos % 4) != 0) { 77226f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org padding++; 77326f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org rtcpbuffer[pos++]=0; 77426f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org } 77526f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org SDESLength += padding; 776470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 7772f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org std::map<uint32_t, RTCPUtility::RTCPCnameInformation*>::iterator it = 77826f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org _csrcCNAMEs.begin(); 779470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 78026f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org for(; it != _csrcCNAMEs.end(); it++) { 78126f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org RTCPCnameInformation* cname = it->second; 7822f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint32_t SSRC = it->first; 783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 78426f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org // Add SSRC 78526f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, SSRC); 78626f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org pos += 4; 787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 78826f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org // CNAME = 1 7892f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = static_cast<uint8_t>(1); 790470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 791f6bb77a6f0d250f8c4c2c4dbf059556c00cf8eafpwestin@webrtc.org size_t length = strlen(cname->name); 792f6bb77a6f0d250f8c4c2c4dbf059556c00cf8eafpwestin@webrtc.org assert(length < RTCP_CNAME_SIZE); 793470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 7942f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]= static_cast<uint8_t>(length); 79526f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org SDESLength += 6; 796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 797f6bb77a6f0d250f8c4c2c4dbf059556c00cf8eafpwestin@webrtc.org memcpy(&rtcpbuffer[pos],cname->name, length); 798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 799f6bb77a6f0d250f8c4c2c4dbf059556c00cf8eafpwestin@webrtc.org pos += length; 800f6bb77a6f0d250f8c4c2c4dbf059556c00cf8eafpwestin@webrtc.org SDESLength += length; 8012f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint16_t padding = 0; 802470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 80326f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org // We must have a zero field even if we have an even multiple of 4 bytes 80426f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org if((pos % 4) == 0){ 80526f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org padding++; 80626f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org rtcpbuffer[pos++]=0; 807470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 80826f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org while((pos % 4) != 0){ 80926f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org padding++; 81026f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org rtcpbuffer[pos++] = 0; 81126f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org } 81226f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org SDESLength += padding; 81326f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org } 81426f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org // in 32-bit words minus one and we don't count the header 8152f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint16_t buffer_length = (SDESLength / 4) - 1; 816f6bb77a6f0d250f8c4c2c4dbf059556c00cf8eafpwestin@webrtc.org ModuleRTPUtility::AssignUWord16ToBuffer(rtcpbuffer + SDESLengthPos, 817f6bb77a6f0d250f8c4c2c4dbf059556c00cf8eafpwestin@webrtc.org buffer_length); 81826f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org return 0; 819470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 820470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 8212f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 8222f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgRTCPSender::BuildRR(uint8_t* rtcpbuffer, 823286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org int& pos, 8242f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org const uint32_t NTPsec, 825286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org const uint32_t NTPfrac) 826470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 827470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // sanity one block 828470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(pos + 32 >= IP_PACKET_SIZE) 829470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 830470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -2; 831470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 8322f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint32_t posNumberOfReportBlocks = pos; 833470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 8342f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80; 8352f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)201; 836470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 837470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Save for our length field 838470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos++; 839470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos++; 840470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 841470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add our own SSRC 842470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 843470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 844470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 8452f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint8_t numberOfReportBlocks = 0; 846286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org int retVal = WriteAllReportBlocksToBuffer(rtcpbuffer, pos, 847286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org numberOfReportBlocks, 848286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org NTPsec, NTPfrac); 849470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(retVal < 0) 850470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 851286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return pos; 852470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 853286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org pos = retVal; 854470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpbuffer[posNumberOfReportBlocks] += numberOfReportBlocks; 855470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 8562f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint16_t len = uint16_t((pos)/4 -1); 857470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord16ToBuffer(rtcpbuffer+2, len); 858470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 859470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 860470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 8615249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org// From RFC 5450: Transmission Time Offsets in RTP Streams. 8625249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org// 0 1 2 3 8635249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@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 8645249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 8655249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org// hdr |V=2|P| RC | PT=IJ=195 | length | 8665249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 8675249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org// | inter-arrival jitter | 8685249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 8695249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org// . . 8705249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org// . . 8715249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org// . . 8725249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org// | inter-arrival jitter | 8735249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 8745249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org// 8755249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org// If present, this RTCP packet must be placed after a receiver report 8765249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org// (inside a compound RTCP packet), and MUST have the same value for RC 8775249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org// (reception report count) as the receiver report. 8785249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org 8792f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 8805249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.orgRTCPSender::BuildExtendedJitterReport( 8812f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint8_t* rtcpbuffer, 882286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org int& pos, 8832f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org const uint32_t jitterTransmissionTimeOffset) 8845249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org{ 885286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (external_report_blocks_.size() > 0) 8865249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org { 8875249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, "Not implemented."); 8885249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org return 0; 8895249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org } 8905249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org 8915249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org // sanity 8925249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org if(pos + 8 >= IP_PACKET_SIZE) 8935249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org { 8945249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org return -2; 8955249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org } 8965249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org // add picture loss indicator 8972f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint8_t RC = 1; 8982f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80 + RC; 8992f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)195; 9005249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org 9015249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org // Used fixed length of 2 9022f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 9032f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(1); 9045249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org 9055249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org // Add inter-arrival jitter 9065249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, 9075249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org jitterTransmissionTimeOffset); 9085249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org pos += 4; 9095249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org return 0; 9105249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org} 9115249cc8f77532f3af4f25ad4c5f68dfc4ae8955fasapersson@webrtc.org 9122f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 913286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.orgRTCPSender::BuildPLI(uint8_t* rtcpbuffer, int& pos) 914470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 915470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // sanity 916470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(pos + 12 >= IP_PACKET_SIZE) 917470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 918470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -2; 919470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 920470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // add picture loss indicator 9212f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint8_t FMT = 1; 9222f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80 + FMT; 9232f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)206; 924470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 925470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com //Used fixed length of 2 9262f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 9272f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(2); 928470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 929470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add our own SSRC 930470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 931470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 932470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 933470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add the remote SSRC 934470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _remoteSSRC); 935470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 936470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 937470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 938470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 9392f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t RTCPSender::BuildFIR(uint8_t* rtcpbuffer, 940286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org int& pos, 9412f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org bool repeat) { 9425e954814a8d73ae1d4095bf951cbbaf3e6b6f8eepwestin@webrtc.org // sanity 9435e954814a8d73ae1d4095bf951cbbaf3e6b6f8eepwestin@webrtc.org if(pos + 20 >= IP_PACKET_SIZE) { 9445e954814a8d73ae1d4095bf951cbbaf3e6b6f8eepwestin@webrtc.org return -2; 9455e954814a8d73ae1d4095bf951cbbaf3e6b6f8eepwestin@webrtc.org } 9465e954814a8d73ae1d4095bf951cbbaf3e6b6f8eepwestin@webrtc.org if (!repeat) { 9475e954814a8d73ae1d4095bf951cbbaf3e6b6f8eepwestin@webrtc.org _sequenceNumberFIR++; // do not increase if repetition 9485e954814a8d73ae1d4095bf951cbbaf3e6b6f8eepwestin@webrtc.org } 949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 9505e954814a8d73ae1d4095bf951cbbaf3e6b6f8eepwestin@webrtc.org // add full intra request indicator 9512f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint8_t FMT = 4; 9522f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)0x80 + FMT; 9532f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)206; 954470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 9555e954814a8d73ae1d4095bf951cbbaf3e6b6f8eepwestin@webrtc.org //Length of 4 9562f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)0; 9572f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(4); 958470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 9595e954814a8d73ae1d4095bf951cbbaf3e6b6f8eepwestin@webrtc.org // Add our own SSRC 9605e954814a8d73ae1d4095bf951cbbaf3e6b6f8eepwestin@webrtc.org ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC); 9615e954814a8d73ae1d4095bf951cbbaf3e6b6f8eepwestin@webrtc.org pos += 4; 962470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 9635e954814a8d73ae1d4095bf951cbbaf3e6b6f8eepwestin@webrtc.org // RFC 5104 4.3.1.2. Semantics 9645e954814a8d73ae1d4095bf951cbbaf3e6b6f8eepwestin@webrtc.org // SSRC of media source 9652f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)0; 9662f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)0; 9672f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)0; 9682f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)0; 969470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 9705e954814a8d73ae1d4095bf951cbbaf3e6b6f8eepwestin@webrtc.org // Additional Feedback Control Information (FCI) 9715e954814a8d73ae1d4095bf951cbbaf3e6b6f8eepwestin@webrtc.org ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _remoteSSRC); 9725e954814a8d73ae1d4095bf951cbbaf3e6b6f8eepwestin@webrtc.org pos += 4; 973470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 9742f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_sequenceNumberFIR); 9752f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)0; 9762f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)0; 9772f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)0; 9785e954814a8d73ae1d4095bf951cbbaf3e6b6f8eepwestin@webrtc.org return 0; 979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 981470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 0 1 2 3 983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 985470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com | First | Number | PictureID | 986470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com*/ 9882f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 989286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.orgRTCPSender::BuildSLI(uint8_t* rtcpbuffer, int& pos, const uint8_t pictureID) 990470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 991470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // sanity 992470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(pos + 16 >= IP_PACKET_SIZE) 993470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -2; 995470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 996470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // add slice loss indicator 9972f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint8_t FMT = 2; 9982f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80 + FMT; 9992f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)206; 1000470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com //Used fixed length of 3 10022f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 10032f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(3); 1004470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1005470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add our own SSRC 1006470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 1007470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 1008470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add the remote SSRC 1010470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _remoteSSRC); 1011470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 1012470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1013470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add first, number & picture ID 6 bits 1014470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // first = 0, 13 - bits 1015470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // number = 0x1fff, 13 - bits only ones for now 10162f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint32_t sliField = (0x1fff << 6)+ (0x3f & pictureID); 1017470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, sliField); 1018470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 1019470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1020470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1021470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1022470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 1023470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 0 1 2 3 1024470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1025470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1026470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com | PB |0| Payload Type| Native RPSI bit string | 1027470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1028470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com | defined per codec ... | Padding (0) | 1029470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1030470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com*/ 1031470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 1032470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com* Note: not generic made for VP8 1033470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com*/ 10342f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 10352f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgRTCPSender::BuildRPSI(uint8_t* rtcpbuffer, 1036286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org int& pos, 10372f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org const uint64_t pictureID, 10382f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org const uint8_t payloadType) 1039470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1040470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // sanity 1041470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(pos + 24 >= IP_PACKET_SIZE) 1042470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1043470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -2; 1044470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1045470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // add Reference Picture Selection Indication 10462f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint8_t FMT = 3; 10472f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80 + FMT; 10482f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)206; 1049470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1050470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // calc length 10512f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint32_t bitsRequired = 7; 10522f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint8_t bytesRequired = 1; 1053470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com while((pictureID>>bitsRequired) > 0) 1054470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1055470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bitsRequired += 7; 1056470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bytesRequired++; 1057470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1058470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 10592f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint8_t size = 3; 1060470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(bytesRequired > 6) 1061470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1062470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com size = 5; 1063470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else if(bytesRequired > 2) 1064470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1065470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com size = 4; 1066470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 10672f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 1068470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpbuffer[pos++]=size; 1069470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1070470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add our own SSRC 1071470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 1072470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 1073470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1074470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add the remote SSRC 1075470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _remoteSSRC); 1076470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 1077470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1078470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // calc padding length 10792f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint8_t paddingBytes = 4-((2+bytesRequired)%4); 1080470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(paddingBytes == 4) 1081470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1082470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com paddingBytes = 0; 1083470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1084470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // add padding length in bits 1085470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpbuffer[pos] = paddingBytes*8; // padding can be 0, 8, 16 or 24 1086470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos++; 1087470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1088470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // add payload type 1089470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpbuffer[pos] = payloadType; 1090470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos++; 1091470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1092470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // add picture ID 1093470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for(int i = bytesRequired-1; i > 0; i--) 1094470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 10952f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos] = 0x80 | uint8_t(pictureID >> (i*7)); 1096470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos++; 1097470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1098470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // add last byte of picture ID 10992f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos] = uint8_t(pictureID & 0x7f); 1100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos++; 1101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // add padding 1103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for(int j = 0; j <paddingBytes; j++) 1104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpbuffer[pos] = 0; 1106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos++; 1107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 11112f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 1112286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.orgRTCPSender::BuildREMB(uint8_t* rtcpbuffer, int& pos) 1113741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org{ 1114741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org // sanity 1115741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org if(pos + 20 + 4 * _lengthRembSSRC >= IP_PACKET_SIZE) 1116741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org { 1117741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org return -2; 1118741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org } 1119741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org // add application layer feedback 11202f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint8_t FMT = 15; 11212f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80 + FMT; 11222f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)206; 1123741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org 11242f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 1125741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org rtcpbuffer[pos++]=_lengthRembSSRC + 4; 1126741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org 1127741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org // Add our own SSRC 1128741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 1129741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org pos += 4; 1130741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org 1131741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org // Remote SSRC must be 0 1132741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, 0); 1133741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org pos += 4; 1134741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org 1135741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org rtcpbuffer[pos++]='R'; 1136741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org rtcpbuffer[pos++]='E'; 1137741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org rtcpbuffer[pos++]='M'; 1138741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org rtcpbuffer[pos++]='B'; 1139741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org 1140741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org rtcpbuffer[pos++] = _lengthRembSSRC; 1141741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org // 6 bit Exp 1142741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org // 18 bit mantissa 11432f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint8_t brExp = 0; 11442f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org for(uint32_t i=0; i<64; i++) 1145741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org { 11462f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org if(_rembBitrate <= ((uint32_t)262143 << i)) 1147741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org { 1148741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org brExp = i; 1149741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org break; 1150741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org } 1151741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org } 11522f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org const uint32_t brMantissa = (_rembBitrate >> brExp); 11532f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)((brExp << 2) + ((brMantissa >> 16) & 0x03)); 11542f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(brMantissa >> 8); 11552f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(brMantissa); 1156741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org 1157741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org for (int i = 0; i < _lengthRembSSRC; i++) 1158741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org { 1159741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _rembSSRC[i]); 1160741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org pos += 4; 1161741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org } 1162741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org return 0; 1163741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org} 1164741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org 11659354cc965c04a0c79ea36622043751596a6fd015stefan@webrtc.orgvoid 11669354cc965c04a0c79ea36622043751596a6fd015stefan@webrtc.orgRTCPSender::SetTargetBitrate(unsigned int target_bitrate) 1167741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org{ 1168117c119501e3ed80d12b18979959357e8bf2ba61mflodman@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 1169741da942ecb5b449d71f66aed5d991535b374188pwestin@webrtc.org _tmmbr_Send = target_bitrate / 1000; 1170117c119501e3ed80d12b18979959357e8bf2ba61mflodman@webrtc.org} 1171117c119501e3ed80d12b18979959357e8bf2ba61mflodman@webrtc.org 117259f20bb735562d245357609799578edeed46be32pbos@webrtc.orgint32_t RTCPSender::BuildTMMBR(ModuleRtpRtcpImpl* rtp_rtcp_module, 117359f20bb735562d245357609799578edeed46be32pbos@webrtc.org uint8_t* rtcpbuffer, 117459f20bb735562d245357609799578edeed46be32pbos@webrtc.org int& pos) { 117559f20bb735562d245357609799578edeed46be32pbos@webrtc.org if (rtp_rtcp_module == NULL) 117659f20bb735562d245357609799578edeed46be32pbos@webrtc.org return -1; 1177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Before sending the TMMBR check the received TMMBN, only an owner is allowed to raise the bitrate 1178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // If the sender is an owner of the TMMBN -> send TMMBR 1179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // If not an owner but the TMMBR would enter the TMMBN -> send TMMBR 1180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // get current bounding set from RTCP receiver 1182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool tmmbrOwner = false; 118354536bb6d4073c35524579e6be58888213398af4hta@webrtc.org // store in candidateSet, allocates one extra slot 118454536bb6d4073c35524579e6be58888213398af4hta@webrtc.org TMMBRSet* candidateSet = _tmmbrHelp.CandidateSet(); 1185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 118654536bb6d4073c35524579e6be58888213398af4hta@webrtc.org // holding _criticalSectionRTCPSender while calling RTCPreceiver which 118754536bb6d4073c35524579e6be58888213398af4hta@webrtc.org // will accuire _criticalSectionRTCPReceiver is a potental deadlock but 118854536bb6d4073c35524579e6be58888213398af4hta@webrtc.org // since RTCPreceiver is not doing the reverse we should be fine 118959f20bb735562d245357609799578edeed46be32pbos@webrtc.org int32_t lengthOfBoundingSet = 119059f20bb735562d245357609799578edeed46be32pbos@webrtc.org rtp_rtcp_module->BoundingSet(tmmbrOwner, candidateSet); 1191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(lengthOfBoundingSet > 0) 1193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 11942f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org for (int32_t i = 0; i < lengthOfBoundingSet; i++) 1195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 119654536bb6d4073c35524579e6be58888213398af4hta@webrtc.org if( candidateSet->Tmmbr(i) == _tmmbr_Send && 119754536bb6d4073c35524579e6be58888213398af4hta@webrtc.org candidateSet->PacketOH(i) == _packetOH_Send) 1198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // do not send the same tuple 1200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(!tmmbrOwner) 1204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // use received bounding set as candidate set 1206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // add current tuple 120754536bb6d4073c35524579e6be58888213398af4hta@webrtc.org candidateSet->SetEntry(lengthOfBoundingSet, 120854536bb6d4073c35524579e6be58888213398af4hta@webrtc.org _tmmbr_Send, 120954536bb6d4073c35524579e6be58888213398af4hta@webrtc.org _packetOH_Send, 121054536bb6d4073c35524579e6be58888213398af4hta@webrtc.org _SSRC); 1211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int numCandidates = lengthOfBoundingSet+ 1; 1212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // find bounding set 1214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com TMMBRSet* boundingSet = NULL; 1215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int numBoundingSet = _tmmbrHelp.FindTMMBRBoundingSet(boundingSet); 1216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(numBoundingSet > 0 || numBoundingSet <= numCandidates) 1217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmmbrOwner = _tmmbrHelp.IsOwner(_SSRC, numBoundingSet); 1219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(!tmmbrOwner) 1221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // did not enter bounding set, no meaning to send this request 1223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(_tmmbr_Send) 1229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // sanity 1231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(pos + 20 >= IP_PACKET_SIZE) 1232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -2; 1234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // add TMMBR indicator 12362f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint8_t FMT = 3; 12372f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80 + FMT; 12382f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)205; 1239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com //Length of 4 12412f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 12422f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(4); 1243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add our own SSRC 1245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 1246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 1247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // RFC 5104 4.2.1.2. Semantics 1249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // SSRC of media source 12512f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 12522f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 12532f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 12542f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 1255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Additional Feedback Control Information (FCI) 1257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _remoteSSRC); 1258470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 1259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 12602f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint32_t bitRate = _tmmbr_Send*1000; 12612f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint32_t mmbrExp = 0; 12622f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org for(uint32_t i=0;i<64;i++) 1263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 12642f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org if(bitRate <= ((uint32_t)131071 << i)) 1265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mmbrExp = i; 1267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1268470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 12702f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint32_t mmbrMantissa = (bitRate >> mmbrExp); 1271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 12722f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)((mmbrExp << 2) + ((mmbrMantissa >> 15) & 0x03)); 12732f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(mmbrMantissa >> 7); 12742f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)((mmbrMantissa << 1) + ((_packetOH_Send >> 8)& 0x01)); 12752f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(_packetOH_Send); 1276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 12802f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 1281286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.orgRTCPSender::BuildTMMBN(uint8_t* rtcpbuffer, int& pos) 1282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com TMMBRSet* boundingSet = _tmmbrHelp.BoundingSetToSend(); 1284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(boundingSet == NULL) 1285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // sanity 128954536bb6d4073c35524579e6be58888213398af4hta@webrtc.org if(pos + 12 + boundingSet->lengthOfSet()*8 >= IP_PACKET_SIZE) 1290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__); 1292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -2; 1293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 12942f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint8_t FMT = 4; 1295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // add TMMBN indicator 12962f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80 + FMT; 12972f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)205; 1298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com //Add length later 1300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int posLength = pos; 1301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos++; 1302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos++; 1303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add our own SSRC 1305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 1306470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 1307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // RFC 5104 4.2.2.2. Semantics 1309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // SSRC of media source 13112f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 13122f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 13132f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 13142f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 1315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Additional Feedback Control Information (FCI) 1317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int numBoundingSet = 0; 13182f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org for(uint32_t n=0; n< boundingSet->lengthOfSet(); n++) 1319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 132054536bb6d4073c35524579e6be58888213398af4hta@webrtc.org if (boundingSet->Tmmbr(n) > 0) 1321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 13222f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint32_t tmmbrSSRC = boundingSet->Ssrc(n); 1323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, tmmbrSSRC); 1324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 1325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 13262f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint32_t bitRate = boundingSet->Tmmbr(n) * 1000; 13272f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint32_t mmbrExp = 0; 1328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for(int i=0; i<64; i++) 1329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 13302f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org if(bitRate <= ((uint32_t)131071 << i)) 1331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mmbrExp = i; 1333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 13362f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint32_t mmbrMantissa = (bitRate >> mmbrExp); 13372f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint32_t measuredOH = boundingSet->PacketOH(n); 1338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 13392f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)((mmbrExp << 2) + ((mmbrMantissa >> 15) & 0x03)); 13402f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(mmbrMantissa >> 7); 13412f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)((mmbrMantissa << 1) + ((measuredOH >> 8)& 0x01)); 13422f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(measuredOH); 1343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com numBoundingSet++; 1344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 13462f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint16_t length= (uint16_t)(2+2*numBoundingSet); 13472f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[posLength++]=(uint8_t)(length>>8); 13482f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[posLength]=(uint8_t)(length); 1349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 13522f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 1353286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.orgRTCPSender::BuildAPP(uint8_t* rtcpbuffer, int& pos) 1354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // sanity 1356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(_appData == NULL) 1357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, "%s invalid state", __FUNCTION__); 1359470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(pos + 12 + _appLength >= IP_PACKET_SIZE) 1362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__); 1364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -2; 1365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 13662f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80 + _appSubType; 1367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add APP ID 13692f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)204; 1370470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 13712f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint16_t length = (_appLength>>2) + 2; // include SSRC and name 13722f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(length>>8); 13732f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(length); 1374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add our own SSRC 1376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 1377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 1378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add our application name 1380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _appName); 1381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 1382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add the data 1384470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com memcpy(rtcpbuffer +pos, _appData,_appLength); 1385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += _appLength; 1386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 13892f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 13902f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgRTCPSender::BuildNACK(uint8_t* rtcpbuffer, 1391286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org int& pos, 13922f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org const int32_t nackSize, 13932f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org const uint16_t* nackList, 139479b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com std::string* nackString) 1395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // sanity 1397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(pos + 16 >= IP_PACKET_SIZE) 1398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__); 1400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -2; 1401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 14032f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org // int size, uint16_t* nackList 1404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // add nack list 14052f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint8_t FMT = 1; 14062f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80 + FMT; 14072f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)205; 1408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 14092f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t) 0; 1410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int nackSizePos = pos; 14112f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(3); //setting it to one kNACK signal as default 1412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add our own SSRC 1414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 1415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 1416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add the remote SSRC 1418470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _remoteSSRC); 1419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 1420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 142179b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com NACKStringBuilder stringBuilder; 1422523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org // Build NACK bitmasks and write them to the RTCP message. 1423523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org // The nack list should be sorted and not contain duplicates if one 1424523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org // wants to build the smallest rtcp nack packet. 1425523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org int numOfNackFields = 0; 1426523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org int maxNackFields = std::min<int>(kRtcpMaxNackFields, 1427523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org (IP_PACKET_SIZE - pos) / 4); 1428523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org int i = 0; 1429523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org while (i < nackSize && numOfNackFields < maxNackFields) { 1430523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org stringBuilder.PushNACK(nackList[i]); 1431523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org uint16_t nack = nackList[i++]; 1432523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org uint16_t bitmask = 0; 1433523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org while (i < nackSize) { 1434523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org int shift = static_cast<uint16_t>(nackList[i] - nack) - 1; 1435523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org if (shift >= 0 && shift <= 15) { 1436523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org stringBuilder.PushNACK(nackList[i]); 1437523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org bitmask |= (1 << shift); 1438523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org ++i; 1439523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org } else { 1440523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org break; 1441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1442523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org } 1443523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org // Write the sequence number and the bitmask to the packet. 1444523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org assert(pos + 4 < IP_PACKET_SIZE); 1445523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org ModuleRTPUtility::AssignUWord16ToBuffer(rtcpbuffer + pos, nack); 1446523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org pos += 2; 1447523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org ModuleRTPUtility::AssignUWord16ToBuffer(rtcpbuffer + pos, bitmask); 1448523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org pos += 2; 1449523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org numOfNackFields++; 1450523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org } 1451523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org if (i != nackSize) { 1452523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, 1453523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org "Nack list to large for one packet."); 1454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1455523f93729b8b1295d4ba3826c3ec8acd6835cf99andresp@webrtc.org rtcpbuffer[nackSizePos] = static_cast<uint8_t>(2 + numOfNackFields); 145679b0289bfc9f425d15442b1ecd73c2ae69646326edjee@google.com *nackString = stringBuilder.GetResult(); 1457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 14602f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 1461286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.orgRTCPSender::BuildBYE(uint8_t* rtcpbuffer, int& pos) 1462470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1463470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // sanity 1464470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(pos + 8 >= IP_PACKET_SIZE) 1465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -2; 1467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(_includeCSRCs) 1469470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1470470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add a bye packet 14712f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80 + 1 + _CSRCs; // number of SSRC+CSRCs 14722f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)203; 1473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // length 14752f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 14762f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)(1 + _CSRCs); 1477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add our own SSRC 1479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 1480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 1481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // add CSRCs 1483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for(int i = 0; i < _CSRCs; i++) 1484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _CSRC[i]); 1486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 1487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else 1489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add a bye packet 14912f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80 + 1; // number of SSRC+CSRCs 14922f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)203; 1493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // length 14952f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0; 14962f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)1; 1497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add our own SSRC 1499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 1500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 1501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 15052f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 1506286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.orgRTCPSender::BuildVoIPMetric(uint8_t* rtcpbuffer, int& pos) 1507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // sanity 1509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(pos + 44 >= IP_PACKET_SIZE) 1510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -2; 1512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add XR header 15152f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)0x80; 15162f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++]=(uint8_t)207; 1517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 15182f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint32_t XRLengthPos = pos; 1519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // handle length later on 1521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos++; 1522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos++; 1523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add our own SSRC 1525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); 1526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 1527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add a VoIP metrics block 1529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpbuffer[pos++]=7; 1530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpbuffer[pos++]=0; 1531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpbuffer[pos++]=0; 1532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpbuffer[pos++]=8; 1533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1534470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add the remote SSRC 1535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _remoteSSRC); 1536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos += 4; 1537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpbuffer[pos++] = _xrVoIPMetric.lossRate; 1539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpbuffer[pos++] = _xrVoIPMetric.discardRate; 1540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpbuffer[pos++] = _xrVoIPMetric.burstDensity; 1541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpbuffer[pos++] = _xrVoIPMetric.gapDensity; 1542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 15432f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.burstDuration >> 8); 15442f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.burstDuration); 15452f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.gapDuration >> 8); 15462f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.gapDuration); 1547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 15482f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.roundTripDelay >> 8); 15492f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.roundTripDelay); 15502f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.endSystemDelay >> 8); 15512f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.endSystemDelay); 1552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpbuffer[pos++] = _xrVoIPMetric.signalLevel; 1554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpbuffer[pos++] = _xrVoIPMetric.noiseLevel; 1555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpbuffer[pos++] = _xrVoIPMetric.RERL; 1556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpbuffer[pos++] = _xrVoIPMetric.Gmin; 1557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpbuffer[pos++] = _xrVoIPMetric.Rfactor; 1559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpbuffer[pos++] = _xrVoIPMetric.extRfactor; 1560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpbuffer[pos++] = _xrVoIPMetric.MOSLQ; 1561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpbuffer[pos++] = _xrVoIPMetric.MOSCQ; 1562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpbuffer[pos++] = _xrVoIPMetric.RXconfig; 1564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpbuffer[pos++] = 0; // reserved 15652f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBnominal >> 8); 15662f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBnominal); 1567470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 15682f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBmax >> 8); 15692f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBmax); 15702f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBabsMax >> 8); 15712f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBabsMax); 1572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 15732f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[XRLengthPos]=(uint8_t)(0); 15742f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org rtcpbuffer[XRLengthPos+1]=(uint8_t)(10); 1575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 157859f20bb735562d245357609799578edeed46be32pbos@webrtc.orgint32_t RTCPSender::SendRTCP(const FeedbackState& feedback_state, 157959f20bb735562d245357609799578edeed46be32pbos@webrtc.org uint32_t packetTypeFlags, 158059f20bb735562d245357609799578edeed46be32pbos@webrtc.org int32_t nackSize, 158159f20bb735562d245357609799578edeed46be32pbos@webrtc.org const uint16_t* nackList, 158259f20bb735562d245357609799578edeed46be32pbos@webrtc.org bool repeat, 158359f20bb735562d245357609799578edeed46be32pbos@webrtc.org uint64_t pictureID) { 1584286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1585286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 1586286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(_method == kRtcpOff) 1587470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1588286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, 1589286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org "%s invalid state", __FUNCTION__); 1590286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return -1; 1591286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1592286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1593286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org uint8_t rtcp_buffer[IP_PACKET_SIZE]; 159459f20bb735562d245357609799578edeed46be32pbos@webrtc.org int rtcp_length = PrepareRTCP(feedback_state, 159559f20bb735562d245357609799578edeed46be32pbos@webrtc.org packetTypeFlags, 159659f20bb735562d245357609799578edeed46be32pbos@webrtc.org nackSize, 159759f20bb735562d245357609799578edeed46be32pbos@webrtc.org nackList, 159859f20bb735562d245357609799578edeed46be32pbos@webrtc.org repeat, 159959f20bb735562d245357609799578edeed46be32pbos@webrtc.org pictureID, 160059f20bb735562d245357609799578edeed46be32pbos@webrtc.org rtcp_buffer, 160159f20bb735562d245357609799578edeed46be32pbos@webrtc.org IP_PACKET_SIZE); 1602286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (rtcp_length < 0) { 1603286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return -1; 1604286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1605286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org // Sanity don't send empty packets. 1606286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (rtcp_length == 0) 1607286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1608286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return -1; 1609286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1610286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return SendToNetwork(rtcp_buffer, static_cast<uint16_t>(rtcp_length)); 1611286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org} 1612a0218a84d17a727111e2e24cf5af915b1b91c06ehenrike@webrtc.org 161359f20bb735562d245357609799578edeed46be32pbos@webrtc.orgint RTCPSender::PrepareRTCP(const FeedbackState& feedback_state, 161459f20bb735562d245357609799578edeed46be32pbos@webrtc.org uint32_t packetTypeFlags, 161559f20bb735562d245357609799578edeed46be32pbos@webrtc.org int32_t nackSize, 161659f20bb735562d245357609799578edeed46be32pbos@webrtc.org const uint16_t* nackList, 161759f20bb735562d245357609799578edeed46be32pbos@webrtc.org bool repeat, 161859f20bb735562d245357609799578edeed46be32pbos@webrtc.org uint64_t pictureID, 161959f20bb735562d245357609799578edeed46be32pbos@webrtc.org uint8_t* rtcp_buffer, 162059f20bb735562d245357609799578edeed46be32pbos@webrtc.org int buffer_size) { 1621286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org uint32_t rtcpPacketTypeFlags = packetTypeFlags; 1622286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org // Collect the received information. 1623286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org uint32_t NTPsec = 0; 1624286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org uint32_t NTPfrac = 0; 1625286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org uint32_t jitterTransmissionOffset = 0; 1626286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org int position = 0; 1627a0218a84d17a727111e2e24cf5af915b1b91c06ehenrike@webrtc.org 1628286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org CriticalSectionScoped lock(_criticalSectionRTCPSender); 1629a0218a84d17a727111e2e24cf5af915b1b91c06ehenrike@webrtc.org 1630286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(_TMMBR ) // Attach TMMBR to send and receive reports. 1631286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1632286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org rtcpPacketTypeFlags |= kRtcpTmmbr; 1633286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1634286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(_appSend) 1635286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1636286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org rtcpPacketTypeFlags |= kRtcpApp; 1637286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org _appSend = false; 1638286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1639286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(_REMB && _sendREMB) 1640286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1641286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org // Always attach REMB to SR if that is configured. Note that REMB is 1642286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org // only sent on one of the RTP modules in the REMB group. 1643286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org rtcpPacketTypeFlags |= kRtcpRemb; 1644286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1645286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(_xrSendVoIPMetric) 1646286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1647286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org rtcpPacketTypeFlags |= kRtcpXrVoipMetric; 1648286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org _xrSendVoIPMetric = false; 1649286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1650286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(_sendTMMBN) // Set when having received a TMMBR. 1651286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1652286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org rtcpPacketTypeFlags |= kRtcpTmmbn; 1653286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org _sendTMMBN = false; 1654286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1655a0218a84d17a727111e2e24cf5af915b1b91c06ehenrike@webrtc.org 1656286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(_method == kRtcpCompound) 1657286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1658286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(_sending) 1659286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1660286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org rtcpPacketTypeFlags |= kRtcpSr; 1661286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } else 1662286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1663286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org rtcpPacketTypeFlags |= kRtcpRr; 1664286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1665286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } else if(_method == kRtcpNonCompound) 1666286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1667286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpReport) 1668286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1669286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(_sending) 1670286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1671286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org rtcpPacketTypeFlags |= kRtcpSr; 1672286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } else 1673286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1674286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org rtcpPacketTypeFlags |= kRtcpRr; 1675286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1676286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1677286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1678286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if( rtcpPacketTypeFlags & kRtcpRr || 1679286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org rtcpPacketTypeFlags & kRtcpSr) 1680286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1681286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org // generate next time to send a RTCP report 1682286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org // seeded from RTP constructor 1683286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org int32_t random = rand() % 1000; 1684286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org int32_t timeToNext = RTCP_INTERVAL_AUDIO_MS; 1685286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 1686286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(_audio) 1687286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1688286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org timeToNext = (RTCP_INTERVAL_AUDIO_MS/2) + 1689286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org (RTCP_INTERVAL_AUDIO_MS*random/1000); 1690286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org }else 1691286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1692286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org uint32_t minIntervalMs = RTCP_INTERVAL_AUDIO_MS; 1693286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(_sending) 1694286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 169559f20bb735562d245357609799578edeed46be32pbos@webrtc.org // Calculate bandwidth for video; 360 / send bandwidth in kbit/s. 169659f20bb735562d245357609799578edeed46be32pbos@webrtc.org uint32_t send_bitrate_kbit = feedback_state.send_bitrate / 1000; 169759f20bb735562d245357609799578edeed46be32pbos@webrtc.org if (send_bitrate_kbit != 0) 169859f20bb735562d245357609799578edeed46be32pbos@webrtc.org minIntervalMs = 360000 / send_bitrate_kbit; 1699286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1700286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(minIntervalMs > RTCP_INTERVAL_VIDEO_MS) 1701286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1702286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org minIntervalMs = RTCP_INTERVAL_VIDEO_MS; 1703286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1704286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org timeToNext = (minIntervalMs/2) + (minIntervalMs*random/1000); 1705286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1706286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org _nextTimeToSendRTCP = _clock->TimeInMilliseconds() + timeToNext; 1707286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1708a0218a84d17a727111e2e24cf5af915b1b91c06ehenrike@webrtc.org 1709286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org // If the data does not fit in the packet we fill it as much as possible. 1710286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org int32_t buildVal = 0; 1711286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 1712286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org // We need to send our NTP even if we haven't received any reports. 1713286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org _clock->CurrentNtp(NTPsec, NTPfrac); 1714286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (ShouldSendReportBlocks(rtcpPacketTypeFlags)) { 1715286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org StatisticianMap statisticians = 1716286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org receive_statistics_->GetActiveStatisticians(); 1717286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (!statisticians.empty()) { 1718286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org StatisticianMap::const_iterator it; 1719286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org int i; 1720286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org for (it = statisticians.begin(), i = 0; it != statisticians.end(); 1721286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org ++it, ++i) { 1722286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org RTCPReportBlock report_block; 172359f20bb735562d245357609799578edeed46be32pbos@webrtc.org if (PrepareReport( 172459f20bb735562d245357609799578edeed46be32pbos@webrtc.org feedback_state, it->second, &report_block, &NTPsec, &NTPfrac)) 1725286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org AddReportBlock(it->first, &internal_report_blocks_, &report_block); 1726286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1727286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (_IJ && !statisticians.empty()) { 1728286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset; 1729286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1730286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org _lastRTCPTime[0] = Clock::NtpToMs(NTPsec, NTPfrac); 1731286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1732286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1733a0218a84d17a727111e2e24cf5af915b1b91c06ehenrike@webrtc.org 1734286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpSr) 1735286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 173659f20bb735562d245357609799578edeed46be32pbos@webrtc.org buildVal = BuildSR(feedback_state, rtcp_buffer, position, NTPsec, NTPfrac); 1737286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (buildVal == -1) { 1738286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return -1; 1739286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } else if (buildVal == -2) { 1740286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return position; 1741286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1742286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org buildVal = BuildSDEC(rtcp_buffer, position); 1743286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (buildVal == -1) { 1744286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return -1; 1745286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } else if (buildVal == -2) { 1746286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return position; 1747286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1748286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org }else if(rtcpPacketTypeFlags & kRtcpRr) 1749286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1750286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org buildVal = BuildRR(rtcp_buffer, position, NTPsec, NTPfrac); 1751286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (buildVal == -1) { 1752286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return -1; 1753286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } else if (buildVal == -2) { 1754286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return position; 1755286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1756286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org // only of set 1757286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(_CNAME[0] != 0) 1758286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1759286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org buildVal = BuildSDEC(rtcp_buffer, position); 1760286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (buildVal == -1) { 1761286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return -1; 1762286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1763286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1764286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1765286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpTransmissionTimeOffset) 1766286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1767286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org // If present, this RTCP packet must be placed after a 1768286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org // receiver report. 1769286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org buildVal = BuildExtendedJitterReport(rtcp_buffer, 1770286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org position, 1771286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org jitterTransmissionOffset); 1772286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (buildVal == -1) { 1773286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return -1; 1774286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } else if (buildVal == -2) { 1775286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return position; 1776286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1777286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1778286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpPli) 1779286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1780286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org buildVal = BuildPLI(rtcp_buffer, position); 1781286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (buildVal == -1) { 1782286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return -1; 1783286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } else if (buildVal == -2) { 1784286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return position; 1785286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1786286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org TRACE_EVENT_INSTANT0("webrtc_rtp", "RTCPSender::PLI"); 1787286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org _pliCount++; 1788286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org TRACE_COUNTER_ID1("webrtc_rtp", "RTCP_PLICount", _SSRC, _pliCount); 1789286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1790286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpFir) 1791286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1792286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org buildVal = BuildFIR(rtcp_buffer, position, repeat); 1793286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (buildVal == -1) { 1794286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return -1; 1795286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } else if (buildVal == -2) { 1796286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return position; 1797286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1798286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org TRACE_EVENT_INSTANT0("webrtc_rtp", "RTCPSender::FIR"); 1799286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org _fullIntraRequestCount++; 1800286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org TRACE_COUNTER_ID1("webrtc_rtp", "RTCP_FIRCount", _SSRC, 1801286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org _fullIntraRequestCount); 1802286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1803286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpSli) 1804286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1805286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org buildVal = BuildSLI(rtcp_buffer, position, (uint8_t)pictureID); 1806286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (buildVal == -1) { 1807286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return -1; 1808286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } else if (buildVal == -2) { 1809286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return position; 1810286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1811286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1812286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpRpsi) 1813286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 181459f20bb735562d245357609799578edeed46be32pbos@webrtc.org const int8_t payloadType = feedback_state.send_payload_type; 1815286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (payloadType == -1) { 1816286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return -1; 1817286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1818286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org buildVal = BuildRPSI(rtcp_buffer, position, pictureID, 1819286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org (uint8_t)payloadType); 1820286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (buildVal == -1) { 1821286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return -1; 1822286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } else if (buildVal == -2) { 1823286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return position; 1824286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1825286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1826286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpRemb) 1827286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1828286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org buildVal = BuildREMB(rtcp_buffer, position); 1829286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (buildVal == -1) { 1830286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return -1; 1831286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } else if (buildVal == -2) { 1832286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return position; 1833286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1834286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org TRACE_EVENT_INSTANT0("webrtc_rtp", "RTCPSender::REMB"); 1835286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1836286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpBye) 1837286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1838286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org buildVal = BuildBYE(rtcp_buffer, position); 1839286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (buildVal == -1) { 1840286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return -1; 1841286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } else if (buildVal == -2) { 1842286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return position; 1843286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1844286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1845286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpApp) 1846286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1847286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org buildVal = BuildAPP(rtcp_buffer, position); 1848286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (buildVal == -1) { 1849286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return -1; 1850286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } else if (buildVal == -2) { 1851286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return position; 1852286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1853286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1854286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpTmmbr) 1855286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 185659f20bb735562d245357609799578edeed46be32pbos@webrtc.org buildVal = BuildTMMBR(feedback_state.module, rtcp_buffer, position); 1857286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (buildVal == -1) { 1858286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return -1; 1859286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } else if (buildVal == -2) { 1860286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return position; 1861286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1862286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1863286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpTmmbn) 1864286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1865286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org buildVal = BuildTMMBN(rtcp_buffer, position); 1866286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (buildVal == -1) { 1867286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return -1; 1868286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } else if (buildVal == -2) { 1869286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return position; 1870286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1871286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1872286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpNack) 1873286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1874286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org std::string nackString; 1875286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org buildVal = BuildNACK(rtcp_buffer, position, nackSize, nackList, 1876286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org &nackString); 1877286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (buildVal == -1) { 1878286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return -1; 1879286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } else if (buildVal == -2) { 1880286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return position; 1881286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1882286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org TRACE_EVENT_INSTANT1("webrtc_rtp", "RTCPSender::NACK", 1883286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org "nacks", TRACE_STR_COPY(nackString.c_str())); 1884286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org _nackCount++; 1885286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org TRACE_COUNTER_ID1("webrtc_rtp", "RTCP_NACKCount", _SSRC, _nackCount); 1886286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1887286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if(rtcpPacketTypeFlags & kRtcpXrVoipMetric) 1888286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org { 1889286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org buildVal = BuildVoIPMetric(rtcp_buffer, position); 1890286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (buildVal == -1) { 1891286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return -1; 1892286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } else if (buildVal == -2) { 1893286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return position; 1894286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1895286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1896286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return position; 1897286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org} 1898a0218a84d17a727111e2e24cf5af915b1b91c06ehenrike@webrtc.org 1899286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.orgbool RTCPSender::ShouldSendReportBlocks(uint32_t rtcp_packet_type) const { 1900286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return Status() == kRtcpCompound || 1901286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org (rtcp_packet_type & kRtcpReport) || 1902286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org (rtcp_packet_type & kRtcpSr) || 1903286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org (rtcp_packet_type & kRtcpRr); 1904286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org} 1905a0218a84d17a727111e2e24cf5af915b1b91c06ehenrike@webrtc.org 190659f20bb735562d245357609799578edeed46be32pbos@webrtc.orgbool RTCPSender::PrepareReport(const FeedbackState& feedback_state, 190759f20bb735562d245357609799578edeed46be32pbos@webrtc.org StreamStatistician* statistician, 1908286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org RTCPReportBlock* report_block, 1909286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org uint32_t* ntp_secs, uint32_t* ntp_frac) { 1910286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org // Do we have receive statistics to send? 1911286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org StreamStatistician::Statistics stats; 1912286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (!statistician->GetStatistics(&stats, true)) 1913286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return false; 1914286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org report_block->fractionLost = stats.fraction_lost; 1915286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org report_block->cumulativeLost = stats.cumulative_lost; 1916286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org report_block->extendedHighSeqNum = 1917286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org stats.extended_max_sequence_number; 1918286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org report_block->jitter = stats.jitter; 1919286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 1920286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org // get our NTP as late as possible to avoid a race 1921286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org _clock->CurrentNtp(*ntp_secs, *ntp_frac); 1922286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 1923286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org // Delay since last received report 1924286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org uint32_t delaySinceLastReceivedSR = 0; 192559f20bb735562d245357609799578edeed46be32pbos@webrtc.org if ((feedback_state.last_rr_ntp_secs != 0) || 192659f20bb735562d245357609799578edeed46be32pbos@webrtc.org (feedback_state.last_rr_ntp_frac != 0)) { 1927286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org // get the 16 lowest bits of seconds and the 16 higest bits of fractions 1928286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org uint32_t now=*ntp_secs&0x0000FFFF; 1929286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org now <<=16; 1930286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org now += (*ntp_frac&0xffff0000)>>16; 1931286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 193259f20bb735562d245357609799578edeed46be32pbos@webrtc.org uint32_t receiveTime = feedback_state.last_rr_ntp_secs&0x0000FFFF; 1933286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org receiveTime <<=16; 193459f20bb735562d245357609799578edeed46be32pbos@webrtc.org receiveTime += (feedback_state.last_rr_ntp_frac&0xffff0000)>>16; 1935286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 1936286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org delaySinceLastReceivedSR = now-receiveTime; 1937286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 1938286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org report_block->delaySinceLastSR = delaySinceLastReceivedSR; 193959f20bb735562d245357609799578edeed46be32pbos@webrtc.org report_block->lastSR = feedback_state.remote_sr; 1940286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return true; 1941470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1942470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 19432f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 19442f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgRTCPSender::SendToNetwork(const uint8_t* dataBuffer, 19452f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org const uint16_t length) 1946470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1947470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CriticalSectionScoped lock(_criticalSectionTransport); 1948470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(_cbTransport) 1949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1950470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(_cbTransport->SendRTCPPacket(_id, dataBuffer, length) > 0) 1951470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1952470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1953470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1954470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1955470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1956470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1957470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 19582f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 1959470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comRTCPSender::SetCSRCStatus(const bool include) 1960470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1961470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _includeCSRCs = include; 1962470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1963470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1964470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 19652f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 19662f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgRTCPSender::SetCSRCs(const uint32_t arrOfCSRC[kRtpCsrcSize], 19672f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org const uint8_t arrLength) 1968470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1969470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(arrLength > kRtpCsrcSize) 1970470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1971470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__); 1972470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(false); 1973470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1974470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1975470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1976470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CriticalSectionScoped lock(_criticalSectionRTCPSender); 1977470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for(int i = 0; i < arrLength;i++) 1979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _CSRC[i] = arrOfCSRC[i]; 1981470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _CSRCs = arrLength; 1983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1985470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 19862f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 19872f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgRTCPSender::SetApplicationSpecificData(const uint8_t subType, 19882f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org const uint32_t name, 19892f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org const uint8_t* data, 19902f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org const uint16_t length) 1991470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1992470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(length %4 != 0) 1993470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__); 1995470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1996470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1997470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CriticalSectionScoped lock(_criticalSectionRTCPSender); 1998470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1999470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(_appData) 2000470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delete [] _appData; 2002470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2003470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2004470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _appSend = true; 2005470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _appSubType = subType; 2006470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _appName = name; 20072f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org _appData = new uint8_t[length]; 2008470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _appLength = length; 2009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com memcpy(_appData, data, length); 2010470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2011470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2012470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 20132f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 2014470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comRTCPSender::SetRTCPVoIPMetrics(const RTCPVoIPMetric* VoIPMetric) 2015470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CriticalSectionScoped lock(_criticalSectionRTCPSender); 2017470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com memcpy(&_xrVoIPMetric, VoIPMetric, sizeof(RTCPVoIPMetric)); 2018470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2019470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _xrSendVoIPMetric = true; 2020470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2021470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2022470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2023470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com// called under critsect _criticalSectionRTCPSender 2024286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.orgint32_t RTCPSender::WriteAllReportBlocksToBuffer( 2025286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org uint8_t* rtcpbuffer, 2026286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org int pos, 2027286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org uint8_t& numberOfReportBlocks, 2028286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org const uint32_t NTPsec, 2029286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org const uint32_t NTPfrac) { 203026f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org // sanity one block 203126f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org if(pos + 24 >= IP_PACKET_SIZE) { 203226f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, 203326f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org "%s invalid argument", __FUNCTION__); 203426f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org return -1; 203526f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org } 2036286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org numberOfReportBlocks = external_report_blocks_.size(); 2037286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org numberOfReportBlocks += internal_report_blocks_.size(); 2038286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if ((pos + numberOfReportBlocks * 24) >= IP_PACKET_SIZE) { 203926f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, 204026f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org "%s invalid argument", __FUNCTION__); 204126f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org return -1; 204226f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org } 2043286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org pos = WriteReportBlocksToBuffer(rtcpbuffer, pos, internal_report_blocks_); 2044286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org while (!internal_report_blocks_.empty()) { 2045286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org delete internal_report_blocks_.begin()->second; 2046286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org internal_report_blocks_.erase(internal_report_blocks_.begin()); 2047286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 2048286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org pos = WriteReportBlocksToBuffer(rtcpbuffer, pos, external_report_blocks_); 2049286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return pos; 2050286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org} 205126f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org 2052286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.orgint32_t RTCPSender::WriteReportBlocksToBuffer( 2053286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org uint8_t* rtcpbuffer, 2054286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org int32_t position, 2055286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org const std::map<uint32_t, RTCPReportBlock*>& report_blocks) { 2056286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org std::map<uint32_t, RTCPReportBlock*>::const_iterator it = 2057286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org report_blocks.begin(); 2058286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org for (; it != report_blocks.end(); it++) { 20592f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org uint32_t remoteSSRC = it->first; 206026f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org RTCPReportBlock* reportBlock = it->second; 206126f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org if (reportBlock) { 206226f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org // Remote SSRC 2063286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+position, remoteSSRC); 2064286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org position += 4; 206526f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org 206626f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org // fraction lost 2067286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org rtcpbuffer[position++] = reportBlock->fractionLost; 206826f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org 206926f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org // cumulative loss 2070286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org ModuleRTPUtility::AssignUWord24ToBuffer(rtcpbuffer+position, 207126f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org reportBlock->cumulativeLost); 2072286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org position += 3; 207326f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org 207426f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org // extended highest seq_no, contain the highest sequence number received 2075286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+position, 207626f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org reportBlock->extendedHighSeqNum); 2077286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org position += 4; 207826f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org 2079286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org // Jitter 2080286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+position, 208126f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org reportBlock->jitter); 2082286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org position += 4; 208326f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org 2084286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+position, 208526f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org reportBlock->lastSR); 2086286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org position += 4; 208726f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org 2088286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+position, 208926f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org reportBlock->delaySinceLastSR); 2090286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org position += 4; 2091470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 209226f8d9c7f3865b9f94ea83d8b67b2ebee1d93f7dpwestin@webrtc.org } 2093286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org return position; 2094470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2095470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2096470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com// no callbacks allowed inside this function 20972f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.orgint32_t 2098470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comRTCPSender::SetTMMBN(const TMMBRSet* boundingSet, 20992f44673d665899ca788ae44247a9a7f4764f5e2bpbos@webrtc.org const uint32_t maxBitrateKbit) 2100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CriticalSectionScoped lock(_criticalSectionRTCPSender); 2102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (0 == _tmmbrHelp.SetTMMBRBoundingSetToSend(boundingSet, maxBitrateKbit)) 2104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _sendTMMBN = true; 2106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2110d900e8bea84c474696bf0219aed1353ce65ffd8epbos@webrtc.org} // namespace webrtc 2111