Home | History | Annotate | Download | only in source
      1 /*
      2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include "webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.h"
     12 
     13 #include <assert.h>  // assert
     14 #include <string.h>  // memset
     15 
     16 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
     17 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
     18 
     19 namespace webrtc {
     20 namespace RTCPHelp {
     21 
     22 RTCPPacketInformation::RTCPPacketInformation()
     23     : rtcpPacketTypeFlags(0),
     24       remoteSSRC(0),
     25       nackSequenceNumbers(),
     26       applicationSubType(0),
     27       applicationName(0),
     28       applicationData(),
     29       applicationLength(0),
     30       rtt(0),
     31       interArrivalJitter(0),
     32       sliPictureId(0),
     33       rpsiPictureId(0),
     34       receiverEstimatedMaxBitrate(0),
     35       ntp_secs(0),
     36       ntp_frac(0),
     37       rtp_timestamp(0),
     38       xr_originator_ssrc(0),
     39       xr_dlrr_item(false),
     40       VoIPMetric(nullptr) {}
     41 
     42 RTCPPacketInformation::~RTCPPacketInformation()
     43 {
     44     delete [] applicationData;
     45     delete VoIPMetric;
     46 }
     47 
     48 void
     49 RTCPPacketInformation::AddVoIPMetric(const RTCPVoIPMetric* metric)
     50 {
     51     VoIPMetric = new RTCPVoIPMetric();
     52     memcpy(VoIPMetric, metric, sizeof(RTCPVoIPMetric));
     53 }
     54 
     55 void RTCPPacketInformation::AddApplicationData(const uint8_t* data,
     56                                                const uint16_t size) {
     57     uint8_t* oldData = applicationData;
     58     uint16_t oldLength = applicationLength;
     59 
     60     // Don't copy more than kRtcpAppCode_DATA_SIZE bytes.
     61     uint16_t copySize = size;
     62     if (size > kRtcpAppCode_DATA_SIZE) {
     63         copySize = kRtcpAppCode_DATA_SIZE;
     64     }
     65 
     66     applicationLength += copySize;
     67     applicationData = new uint8_t[applicationLength];
     68 
     69     if (oldData)
     70     {
     71         memcpy(applicationData, oldData, oldLength);
     72         memcpy(applicationData+oldLength, data, copySize);
     73         delete [] oldData;
     74     } else
     75     {
     76         memcpy(applicationData, data, copySize);
     77     }
     78 }
     79 
     80 void
     81 RTCPPacketInformation::ResetNACKPacketIdArray()
     82 {
     83   nackSequenceNumbers.clear();
     84 }
     85 
     86 void
     87 RTCPPacketInformation::AddNACKPacket(const uint16_t packetID)
     88 {
     89   if (nackSequenceNumbers.size() >= kSendSideNackListSizeSanity) {
     90     return;
     91   }
     92   nackSequenceNumbers.push_back(packetID);
     93 }
     94 
     95 void
     96 RTCPPacketInformation::AddReportInfo(
     97     const RTCPReportBlockInformation& report_block_info)
     98 {
     99   this->rtt = report_block_info.RTT;
    100   report_blocks.push_back(report_block_info.remoteReceiveBlock);
    101 }
    102 
    103 RTCPReportBlockInformation::RTCPReportBlockInformation():
    104     remoteReceiveBlock(),
    105     remoteMaxJitter(0),
    106     RTT(0),
    107     minRTT(0),
    108     maxRTT(0),
    109     avgRTT(0),
    110     numAverageCalcs(0)
    111 {
    112     memset(&remoteReceiveBlock,0,sizeof(remoteReceiveBlock));
    113 }
    114 
    115 RTCPReportBlockInformation::~RTCPReportBlockInformation()
    116 {
    117 }
    118 
    119 RTCPReceiveInformation::RTCPReceiveInformation()
    120     : lastTimeReceived(0),
    121       lastFIRSequenceNumber(-1),
    122       lastFIRRequest(0),
    123       readyForDelete(false) {
    124 }
    125 
    126 RTCPReceiveInformation::~RTCPReceiveInformation() {
    127 }
    128 
    129 // Increase size of TMMBRSet if needed, and also take care of
    130 // the _tmmbrSetTimeouts vector.
    131 void RTCPReceiveInformation::VerifyAndAllocateTMMBRSet(
    132     const uint32_t minimumSize) {
    133   if (minimumSize > TmmbrSet.sizeOfSet()) {
    134     TmmbrSet.VerifyAndAllocateSetKeepingData(minimumSize);
    135     // make sure that our buffers are big enough
    136     _tmmbrSetTimeouts.reserve(minimumSize);
    137   }
    138 }
    139 
    140 void RTCPReceiveInformation::InsertTMMBRItem(
    141     const uint32_t senderSSRC,
    142     const RTCPUtility::RTCPPacketRTPFBTMMBRItem& TMMBRItem,
    143     const int64_t currentTimeMS) {
    144   // serach to see if we have it in our list
    145   for (uint32_t i = 0; i < TmmbrSet.lengthOfSet(); i++)  {
    146     if (TmmbrSet.Ssrc(i) == senderSSRC) {
    147       // we already have this SSRC in our list update it
    148       TmmbrSet.SetEntry(i,
    149                         TMMBRItem.MaxTotalMediaBitRate,
    150                         TMMBRItem.MeasuredOverhead,
    151                         senderSSRC);
    152       _tmmbrSetTimeouts[i] = currentTimeMS;
    153       return;
    154     }
    155   }
    156   VerifyAndAllocateTMMBRSet(TmmbrSet.lengthOfSet() + 1);
    157   TmmbrSet.AddEntry(TMMBRItem.MaxTotalMediaBitRate,
    158                     TMMBRItem.MeasuredOverhead,
    159                     senderSSRC);
    160   _tmmbrSetTimeouts.push_back(currentTimeMS);
    161 }
    162 
    163 int32_t RTCPReceiveInformation::GetTMMBRSet(
    164     const uint32_t sourceIdx,
    165     const uint32_t targetIdx,
    166     TMMBRSet* candidateSet,
    167     const int64_t currentTimeMS) {
    168   if (sourceIdx >= TmmbrSet.lengthOfSet()) {
    169     return -1;
    170   }
    171   if (targetIdx >= candidateSet->sizeOfSet()) {
    172     return -1;
    173   }
    174   // use audio define since we don't know what interval the remote peer is using
    175   if (currentTimeMS - _tmmbrSetTimeouts[sourceIdx] >
    176       5 * RTCP_INTERVAL_AUDIO_MS) {
    177     // value timed out
    178     TmmbrSet.RemoveEntry(sourceIdx);
    179     _tmmbrSetTimeouts.erase(_tmmbrSetTimeouts.begin() + sourceIdx);
    180     return -1;
    181   }
    182   candidateSet->SetEntry(targetIdx,
    183                          TmmbrSet.Tmmbr(sourceIdx),
    184                          TmmbrSet.PacketOH(sourceIdx),
    185                          TmmbrSet.Ssrc(sourceIdx));
    186   return 0;
    187 }
    188 
    189 void RTCPReceiveInformation::VerifyAndAllocateBoundingSet(
    190     const uint32_t minimumSize) {
    191   TmmbnBoundingSet.VerifyAndAllocateSet(minimumSize);
    192 }
    193 }  // namespace RTCPHelp
    194 }  // namespace webrtc
    195