tor-browser

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

neteq_replacement_input.cc (4312B)


      1 /*
      2 *  Copyright (c) 2016 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/neteq/tools/neteq_replacement_input.h"
     12 
     13 #include <algorithm>
     14 #include <cstdint>
     15 #include <memory>
     16 #include <optional>
     17 #include <set>
     18 #include <utility>
     19 
     20 #include "modules/audio_coding/neteq/tools/fake_decode_from_file.h"
     21 #include "modules/audio_coding/neteq/tools/neteq_input.h"
     22 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
     23 #include "rtc_base/checks.h"
     24 
     25 namespace webrtc {
     26 namespace test {
     27 
     28 NetEqReplacementInput::NetEqReplacementInput(
     29    std::unique_ptr<NetEqInput> source,
     30    uint8_t replacement_payload_type,
     31    const std::set<uint8_t>& comfort_noise_types,
     32    const std::set<uint8_t>& forbidden_types)
     33    : source_(std::move(source)),
     34      replacement_payload_type_(replacement_payload_type),
     35      comfort_noise_types_(comfort_noise_types),
     36      forbidden_types_(forbidden_types) {
     37  RTC_CHECK(source_);
     38  packet_ = source_->PopPacket();
     39  ReplacePacket();
     40 }
     41 
     42 std::optional<int64_t> NetEqReplacementInput::NextPacketTime() const {
     43  return packet_ ? std::optional(packet_->arrival_time().ms()) : std::nullopt;
     44 }
     45 
     46 std::optional<int64_t> NetEqReplacementInput::NextOutputEventTime() const {
     47  return source_->NextOutputEventTime();
     48 }
     49 
     50 std::optional<NetEqInput::SetMinimumDelayInfo>
     51 NetEqReplacementInput::NextSetMinimumDelayInfo() const {
     52  return source_->NextSetMinimumDelayInfo();
     53 }
     54 
     55 std::unique_ptr<RtpPacketReceived> NetEqReplacementInput::PopPacket() {
     56  std::unique_ptr<RtpPacketReceived> to_return = std::move(packet_);
     57  while (true) {
     58    packet_ = source_->PopPacket();
     59    if (!packet_)
     60      break;
     61    if (!packet_->payload().empty()) {
     62      // Not padding only. Good to go. Skip this packet otherwise.
     63      break;
     64    }
     65  }
     66  ReplacePacket();
     67  return to_return;
     68 }
     69 
     70 void NetEqReplacementInput::AdvanceOutputEvent() {
     71  source_->AdvanceOutputEvent();
     72 }
     73 
     74 void NetEqReplacementInput::AdvanceSetMinimumDelay() {
     75  source_->AdvanceSetMinimumDelay();
     76 }
     77 
     78 bool NetEqReplacementInput::ended() const {
     79  return source_->ended();
     80 }
     81 
     82 const RtpPacketReceived* NetEqReplacementInput::NextPacket() const {
     83  return source_->NextPacket();
     84 }
     85 
     86 void NetEqReplacementInput::ReplacePacket() {
     87  if (!source_->NextPacketTime()) {
     88    // End of input. Cannot do proper replacement on the very last packet, so we
     89    // delete it instead.
     90    packet_.reset();
     91    return;
     92  }
     93 
     94  RTC_DCHECK(packet_);
     95 
     96  RTC_CHECK_EQ(forbidden_types_.count(packet_->PayloadType()), 0)
     97      << "Payload type " << static_cast<int>(packet_->PayloadType())
     98      << " is forbidden.";
     99 
    100  // Check if this packet is comfort noise.
    101  if (comfort_noise_types_.count(packet_->PayloadType()) != 0) {
    102    // If CNG, simply insert a zero-energy one-byte payload.
    103    uint8_t cng_payload[1] = {127};  // Max attenuation of CNG.
    104    packet_->SetPayload(cng_payload);
    105    return;
    106  }
    107 
    108  const RtpPacketReceived* next_packet = source_->NextPacket();
    109  RTC_DCHECK(next_packet);
    110  uint8_t payload[12];
    111  constexpr uint32_t kMaxFrameSize = 120 * 48;
    112  const uint32_t timestamp_diff =
    113      next_packet->Timestamp() - packet_->Timestamp();
    114  uint32_t frame_size = last_frame_size_timestamps_;
    115  if (timestamp_diff > 0) {
    116    frame_size = std::min(frame_size, timestamp_diff);
    117  }
    118  const bool opus_dtx = packet_->payload_size() <= 2;
    119  if (next_packet->SequenceNumber() == packet_->SequenceNumber() + 1 &&
    120      timestamp_diff <= kMaxFrameSize && timestamp_diff > 0 && !opus_dtx) {
    121    // Packets are in order and the timestamp diff is valid.
    122    frame_size = timestamp_diff;
    123    last_frame_size_timestamps_ = frame_size;
    124  }
    125  RTC_DCHECK_LE(frame_size, kMaxFrameSize);
    126  RTC_DCHECK_GT(frame_size, 0);
    127  FakeDecodeFromFile::PrepareEncoded(packet_->Timestamp(), frame_size,
    128                                     packet_->payload_size(), payload);
    129  packet_->SetPayload(payload);
    130  packet_->SetPayloadType(replacement_payload_type_);
    131  return;
    132 }
    133 
    134 }  // namespace test
    135 }  // namespace webrtc