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