tor-browser

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

legacy_encoded_audio_frame.cc (3481B)


      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/codecs/legacy_encoded_audio_frame.h"
     12 
     13 #include <algorithm>
     14 #include <cstddef>
     15 #include <cstdint>
     16 #include <memory>
     17 #include <optional>
     18 #include <utility>
     19 #include <vector>
     20 
     21 #include "api/array_view.h"
     22 #include "api/audio_codecs/audio_decoder.h"
     23 #include "rtc_base/buffer.h"
     24 #include "rtc_base/checks.h"
     25 
     26 namespace webrtc {
     27 
     28 LegacyEncodedAudioFrame::LegacyEncodedAudioFrame(AudioDecoder* decoder,
     29                                                 Buffer&& payload)
     30    : decoder_(decoder), payload_(std::move(payload)) {}
     31 
     32 LegacyEncodedAudioFrame::~LegacyEncodedAudioFrame() = default;
     33 
     34 size_t LegacyEncodedAudioFrame::Duration() const {
     35  const int ret = decoder_->PacketDuration(payload_.data(), payload_.size());
     36  return (ret < 0) ? 0 : static_cast<size_t>(ret);
     37 }
     38 
     39 std::optional<AudioDecoder::EncodedAudioFrame::DecodeResult>
     40 LegacyEncodedAudioFrame::Decode(ArrayView<int16_t> decoded) const {
     41  AudioDecoder::SpeechType speech_type = AudioDecoder::kSpeech;
     42  const int ret = decoder_->Decode(
     43      payload_.data(), payload_.size(), decoder_->SampleRateHz(),
     44      decoded.size() * sizeof(int16_t), decoded.data(), &speech_type);
     45 
     46  if (ret < 0)
     47    return std::nullopt;
     48 
     49  return DecodeResult{.num_decoded_samples = static_cast<size_t>(ret),
     50                      .speech_type = speech_type};
     51 }
     52 
     53 std::vector<AudioDecoder::ParseResult> LegacyEncodedAudioFrame::SplitBySamples(
     54    AudioDecoder* decoder,
     55    Buffer&& payload,
     56    uint32_t timestamp,
     57    size_t bytes_per_ms,
     58    uint32_t timestamps_per_ms) {
     59  RTC_DCHECK(payload.data());
     60  std::vector<AudioDecoder::ParseResult> results;
     61  size_t split_size_bytes = payload.size();
     62 
     63  // Find a "chunk size" >= 20 ms and < 40 ms.
     64  const size_t min_chunk_size = bytes_per_ms * 20;
     65  if (min_chunk_size >= payload.size()) {
     66    std::unique_ptr<LegacyEncodedAudioFrame> frame(
     67        new LegacyEncodedAudioFrame(decoder, std::move(payload)));
     68    results.emplace_back(timestamp, 0, std::move(frame));
     69  } else {
     70    // Reduce the split size by half as long as `split_size_bytes` is at least
     71    // twice the minimum chunk size (so that the resulting size is at least as
     72    // large as the minimum chunk size).
     73    while (split_size_bytes >= 2 * min_chunk_size) {
     74      split_size_bytes /= 2;
     75    }
     76 
     77    const uint32_t timestamps_per_chunk = static_cast<uint32_t>(
     78        split_size_bytes * timestamps_per_ms / bytes_per_ms);
     79    size_t byte_offset;
     80    uint32_t timestamp_offset;
     81    for (byte_offset = 0, timestamp_offset = 0; byte_offset < payload.size();
     82         byte_offset += split_size_bytes,
     83        timestamp_offset += timestamps_per_chunk) {
     84      split_size_bytes =
     85          std::min(split_size_bytes, payload.size() - byte_offset);
     86      Buffer new_payload(payload.data() + byte_offset, split_size_bytes);
     87      std::unique_ptr<LegacyEncodedAudioFrame> frame(
     88          new LegacyEncodedAudioFrame(decoder, std::move(new_payload)));
     89      results.emplace_back(timestamp + timestamp_offset, 0, std::move(frame));
     90    }
     91  }
     92 
     93  return results;
     94 }
     95 
     96 }  // namespace webrtc