tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Channel.cc (9113B)


      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 "modules/audio_coding/test/Channel.h"
     12 
     13 #include <cstddef>
     14 #include <cstdint>
     15 #include <cstdio>
     16 #include <cstring>
     17 
     18 #include "api/array_view.h"
     19 #include "api/neteq/neteq.h"
     20 #include "api/rtp_headers.h"
     21 #include "api/units/timestamp.h"
     22 #include "modules/audio_coding/include/audio_coding_module_typedefs.h"
     23 #include "rtc_base/checks.h"
     24 #include "rtc_base/strings/string_builder.h"
     25 #include "rtc_base/time_utils.h"
     26 
     27 namespace webrtc {
     28 
     29 int32_t Channel::SendData(AudioFrameType frameType,
     30                          uint8_t payloadType,
     31                          uint32_t timeStamp,
     32                          const uint8_t* payloadData,
     33                          size_t payloadSize,
     34                          int64_t /* absolute_capture_timestamp_ms */) {
     35  RTPHeader rtp_header;
     36  int32_t status;
     37  size_t payloadDataSize = payloadSize;
     38 
     39  rtp_header.markerBit = false;
     40  rtp_header.ssrc = 0;
     41  rtp_header.sequenceNumber =
     42      (external_sequence_number_ < 0)
     43          ? _seqNo++
     44          : static_cast<uint16_t>(external_sequence_number_);
     45  rtp_header.payloadType = payloadType;
     46  rtp_header.timestamp = (external_send_timestamp_ < 0)
     47                             ? timeStamp
     48                             : static_cast<uint32_t>(external_send_timestamp_);
     49 
     50  if (frameType == AudioFrameType::kEmptyFrame) {
     51    // When frame is empty, we should not transmit it. The frame size of the
     52    // next non-empty frame will be based on the previous frame size.
     53    _useLastFrameSize = _lastFrameSizeSample > 0;
     54    return 0;
     55  }
     56 
     57  memcpy(_payloadData, payloadData, payloadDataSize);
     58  if (_isStereo) {
     59    if (_leftChannel) {
     60      _rtp_header = rtp_header;
     61      _leftChannel = false;
     62    } else {
     63      rtp_header = _rtp_header;
     64      _leftChannel = true;
     65    }
     66  }
     67 
     68  _channelCritSect.Lock();
     69  if (_saveBitStream) {
     70    // fwrite(payloadData, sizeof(uint8_t), payloadSize, _bitStreamFile);
     71  }
     72 
     73  if (!_isStereo) {
     74    CalcStatistics(rtp_header, payloadSize);
     75  }
     76  _useLastFrameSize = false;
     77  _lastInTimestamp = timeStamp;
     78  _totalBytes += payloadDataSize;
     79  _channelCritSect.Unlock();
     80 
     81  if (_useFECTestWithPacketLoss) {
     82    _packetLoss += 1;
     83    if (_packetLoss == 3) {
     84      _packetLoss = 0;
     85      return 0;
     86    }
     87  }
     88 
     89  if (num_packets_to_drop_ > 0) {
     90    num_packets_to_drop_--;
     91    return 0;
     92  }
     93 
     94  status = _neteq->InsertPacket(
     95      rtp_header, ArrayView<const uint8_t>(_payloadData, payloadDataSize),
     96      /*receive_time=*/Timestamp::MinusInfinity());
     97 
     98  return status;
     99 }
    100 
    101 // TODO(turajs): rewite this method.
    102 void Channel::CalcStatistics(const RTPHeader& rtp_header, size_t payloadSize) {
    103  int n;
    104  if ((rtp_header.payloadType != _lastPayloadType) &&
    105      (_lastPayloadType != -1)) {
    106    // payload-type is changed.
    107    // we have to terminate the calculations on the previous payload type
    108    // we ignore the last packet in that payload type just to make things
    109    // easier.
    110    for (n = 0; n < MAX_NUM_PAYLOADS; n++) {
    111      if (_lastPayloadType == _payloadStats[n].payloadType) {
    112        _payloadStats[n].newPacket = true;
    113        break;
    114      }
    115    }
    116  }
    117  _lastPayloadType = rtp_header.payloadType;
    118 
    119  bool newPayload = true;
    120  ACMTestPayloadStats* currentPayloadStr = nullptr;
    121  for (n = 0; n < MAX_NUM_PAYLOADS; n++) {
    122    if (rtp_header.payloadType == _payloadStats[n].payloadType) {
    123      newPayload = false;
    124      currentPayloadStr = &_payloadStats[n];
    125      break;
    126    }
    127  }
    128 
    129  if (!newPayload) {
    130    if (!currentPayloadStr->newPacket) {
    131      if (!_useLastFrameSize) {
    132        _lastFrameSizeSample =
    133            (uint32_t)((uint32_t)rtp_header.timestamp -
    134                       (uint32_t)currentPayloadStr->lastTimestamp);
    135      }
    136      RTC_DCHECK_GT(_lastFrameSizeSample, 0);
    137      int k = 0;
    138      for (; k < MAX_NUM_FRAMESIZES; ++k) {
    139        if ((currentPayloadStr->frameSizeStats[k].frameSizeSample ==
    140             _lastFrameSizeSample) ||
    141            (currentPayloadStr->frameSizeStats[k].frameSizeSample == 0)) {
    142          break;
    143        }
    144      }
    145      if (k == MAX_NUM_FRAMESIZES) {
    146        // New frame size found but no space to count statistics on it. Skip it.
    147        printf("No memory to store statistics for payload %d : frame size %d\n",
    148               _lastPayloadType, _lastFrameSizeSample);
    149        return;
    150      }
    151      ACMTestFrameSizeStats* currentFrameSizeStats =
    152          &(currentPayloadStr->frameSizeStats[k]);
    153      currentFrameSizeStats->frameSizeSample = (int16_t)_lastFrameSizeSample;
    154 
    155      // increment the number of encoded samples.
    156      currentFrameSizeStats->totalEncodedSamples += _lastFrameSizeSample;
    157      // increment the number of recveived packets
    158      currentFrameSizeStats->numPackets++;
    159      // increment the total number of bytes (this is based on
    160      // the previous payload we don't know the frame-size of
    161      // the current payload.
    162      currentFrameSizeStats->totalPayloadLenByte +=
    163          currentPayloadStr->lastPayloadLenByte;
    164      // store the maximum payload-size (this is based on
    165      // the previous payload we don't know the frame-size of
    166      // the current payload.
    167      if (currentFrameSizeStats->maxPayloadLen <
    168          currentPayloadStr->lastPayloadLenByte) {
    169        currentFrameSizeStats->maxPayloadLen =
    170            currentPayloadStr->lastPayloadLenByte;
    171      }
    172      // store the current values for the next time
    173      currentPayloadStr->lastTimestamp = rtp_header.timestamp;
    174      currentPayloadStr->lastPayloadLenByte = payloadSize;
    175    } else {
    176      currentPayloadStr->newPacket = false;
    177      currentPayloadStr->lastPayloadLenByte = payloadSize;
    178      currentPayloadStr->lastTimestamp = rtp_header.timestamp;
    179      currentPayloadStr->payloadType = rtp_header.payloadType;
    180      memset(currentPayloadStr->frameSizeStats, 0,
    181             MAX_NUM_FRAMESIZES * sizeof(ACMTestFrameSizeStats));
    182    }
    183  } else {
    184    n = 0;
    185    while (_payloadStats[n].payloadType != -1) {
    186      n++;
    187    }
    188    // first packet
    189    _payloadStats[n].newPacket = false;
    190    _payloadStats[n].lastPayloadLenByte = payloadSize;
    191    _payloadStats[n].lastTimestamp = rtp_header.timestamp;
    192    _payloadStats[n].payloadType = rtp_header.payloadType;
    193    memset(_payloadStats[n].frameSizeStats, 0,
    194           MAX_NUM_FRAMESIZES * sizeof(ACMTestFrameSizeStats));
    195  }
    196 }
    197 
    198 Channel::Channel(int16_t chID)
    199    : _neteq(nullptr),
    200      _seqNo(0),
    201      _bitStreamFile(nullptr),
    202      _saveBitStream(false),
    203      _lastPayloadType(-1),
    204      _isStereo(false),
    205      _leftChannel(true),
    206      _lastInTimestamp(0),
    207      _useLastFrameSize(false),
    208      _lastFrameSizeSample(0),
    209      _packetLoss(0),
    210      _useFECTestWithPacketLoss(false),
    211      _beginTime(TimeMillis()),
    212      _totalBytes(0),
    213      external_send_timestamp_(-1),
    214      external_sequence_number_(-1),
    215      num_packets_to_drop_(0) {
    216  int n;
    217  int k;
    218  for (n = 0; n < MAX_NUM_PAYLOADS; n++) {
    219    _payloadStats[n].payloadType = -1;
    220    _payloadStats[n].newPacket = true;
    221    for (k = 0; k < MAX_NUM_FRAMESIZES; k++) {
    222      _payloadStats[n].frameSizeStats[k].frameSizeSample = 0;
    223      _payloadStats[n].frameSizeStats[k].maxPayloadLen = 0;
    224      _payloadStats[n].frameSizeStats[k].numPackets = 0;
    225      _payloadStats[n].frameSizeStats[k].totalPayloadLenByte = 0;
    226      _payloadStats[n].frameSizeStats[k].totalEncodedSamples = 0;
    227    }
    228  }
    229  if (chID >= 0) {
    230    _saveBitStream = true;
    231    StringBuilder ss;
    232    ss.AppendFormat("bitStream_%d.dat", chID);
    233    _bitStreamFile = fopen(ss.str().c_str(), "wb");
    234  } else {
    235    _saveBitStream = false;
    236  }
    237 }
    238 
    239 Channel::~Channel() {}
    240 
    241 void Channel::RegisterReceiverNetEq(NetEq* neteq) {
    242  _neteq = neteq;
    243  return;
    244 }
    245 
    246 void Channel::ResetStats() {
    247  int n;
    248  int k;
    249  _channelCritSect.Lock();
    250  _lastPayloadType = -1;
    251  for (n = 0; n < MAX_NUM_PAYLOADS; n++) {
    252    _payloadStats[n].payloadType = -1;
    253    _payloadStats[n].newPacket = true;
    254    for (k = 0; k < MAX_NUM_FRAMESIZES; k++) {
    255      _payloadStats[n].frameSizeStats[k].frameSizeSample = 0;
    256      _payloadStats[n].frameSizeStats[k].maxPayloadLen = 0;
    257      _payloadStats[n].frameSizeStats[k].numPackets = 0;
    258      _payloadStats[n].frameSizeStats[k].totalPayloadLenByte = 0;
    259      _payloadStats[n].frameSizeStats[k].totalEncodedSamples = 0;
    260    }
    261  }
    262  _beginTime = TimeMillis();
    263  _totalBytes = 0;
    264  _channelCritSect.Unlock();
    265 }
    266 
    267 uint32_t Channel::LastInTimestamp() {
    268  uint32_t timestamp;
    269  _channelCritSect.Lock();
    270  timestamp = _lastInTimestamp;
    271  _channelCritSect.Unlock();
    272  return timestamp;
    273 }
    274 
    275 double Channel::BitRate() {
    276  double rate;
    277  uint64_t currTime = TimeMillis();
    278  _channelCritSect.Lock();
    279  rate = ((double)_totalBytes * 8.0) / (double)(currTime - _beginTime);
    280  _channelCritSect.Unlock();
    281  return rate;
    282 }
    283 
    284 }  // namespace webrtc