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