blob: 9dbecd5e0a07ff0bc7a903efa2631c0a5a9bdab2 [file] [log] [blame]
kwiberg@webrtc.orge04a93b2014-12-09 10:12:53 +00001/*
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/audio_coding/codecs/audio_decoder.h"
12
13#include <assert.h>
14
ossu61a208b2016-09-20 01:38:00 -070015#include <utility>
16
kwibergac554ee2016-09-02 00:39:33 -070017#include "webrtc/base/array_view.h"
kwiberg@webrtc.orge04a93b2014-12-09 10:12:53 +000018#include "webrtc/base/checks.h"
kwibergac554ee2016-09-02 00:39:33 -070019#include "webrtc/base/sanitizer.h"
Peter Boströmd7b7ae82015-12-08 13:41:35 +010020#include "webrtc/base/trace_event.h"
kwiberg@webrtc.orge04a93b2014-12-09 10:12:53 +000021
22namespace webrtc {
23
ossu61a208b2016-09-20 01:38:00 -070024namespace {
25class LegacyFrame final : public AudioDecoder::EncodedAudioFrame {
26 public:
27 LegacyFrame(AudioDecoder* decoder,
28 rtc::Buffer&& payload,
29 bool is_primary_payload)
30 : decoder_(decoder),
31 payload_(std::move(payload)),
32 is_primary_payload_(is_primary_payload) {}
33
34 size_t Duration() const override {
35 int ret;
36 if (is_primary_payload_) {
37 ret = decoder_->PacketDuration(payload_.data(), payload_.size());
38 } else {
39 ret = decoder_->PacketDurationRedundant(payload_.data(), payload_.size());
40 }
41 return (ret < 0) ? 0 : static_cast<size_t>(ret);
42 }
43
44 rtc::Optional<DecodeResult> Decode(
45 rtc::ArrayView<int16_t> decoded) const override {
46 AudioDecoder::SpeechType speech_type = AudioDecoder::kSpeech;
47 int ret;
48 if (is_primary_payload_) {
49 ret = decoder_->Decode(
50 payload_.data(), payload_.size(), decoder_->SampleRateHz(),
51 decoded.size() * sizeof(int16_t), decoded.data(), &speech_type);
52 } else {
53 ret = decoder_->DecodeRedundant(
54 payload_.data(), payload_.size(), decoder_->SampleRateHz(),
55 decoded.size() * sizeof(int16_t), decoded.data(), &speech_type);
56 }
57
58 if (ret < 0)
59 return rtc::Optional<DecodeResult>();
60
61 return rtc::Optional<DecodeResult>({static_cast<size_t>(ret), speech_type});
62 }
63
64 private:
65 AudioDecoder* const decoder_;
66 const rtc::Buffer payload_;
67 const bool is_primary_payload_;
68};
69} // namespace
70
71AudioDecoder::ParseResult::ParseResult() = default;
72AudioDecoder::ParseResult::ParseResult(ParseResult&& b) = default;
73AudioDecoder::ParseResult::ParseResult(uint32_t timestamp,
74 bool primary,
75 std::unique_ptr<EncodedAudioFrame> frame)
76 : timestamp(timestamp), primary(primary), frame(std::move(frame)) {}
77
78AudioDecoder::ParseResult::~ParseResult() = default;
79
80AudioDecoder::ParseResult& AudioDecoder::ParseResult::operator=(
81 ParseResult&& b) = default;
82
83std::vector<AudioDecoder::ParseResult> AudioDecoder::ParsePayload(
84 rtc::Buffer&& payload,
85 uint32_t timestamp,
86 bool is_primary) {
87 std::vector<ParseResult> results;
88 std::unique_ptr<EncodedAudioFrame> frame(
89 new LegacyFrame(this, std::move(payload), is_primary));
90 results.emplace_back(timestamp, is_primary, std::move(frame));
91 return results;
92}
93
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +000094int AudioDecoder::Decode(const uint8_t* encoded, size_t encoded_len,
95 int sample_rate_hz, size_t max_decoded_bytes,
96 int16_t* decoded, SpeechType* speech_type) {
Peter Boströmd7b7ae82015-12-08 13:41:35 +010097 TRACE_EVENT0("webrtc", "AudioDecoder::Decode");
kwibergac554ee2016-09-02 00:39:33 -070098 rtc::MsanCheckInitialized(rtc::MakeArrayView(encoded, encoded_len));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +000099 int duration = PacketDuration(encoded, encoded_len);
Minyue323b1322015-05-25 13:49:37 +0200100 if (duration >= 0 &&
101 duration * Channels() * sizeof(int16_t) > max_decoded_bytes) {
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +0000102 return -1;
103 }
104 return DecodeInternal(encoded, encoded_len, sample_rate_hz, decoded,
105 speech_type);
106}
107
108int AudioDecoder::DecodeRedundant(const uint8_t* encoded, size_t encoded_len,
109 int sample_rate_hz, size_t max_decoded_bytes,
110 int16_t* decoded, SpeechType* speech_type) {
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100111 TRACE_EVENT0("webrtc", "AudioDecoder::DecodeRedundant");
kwibergac554ee2016-09-02 00:39:33 -0700112 rtc::MsanCheckInitialized(rtc::MakeArrayView(encoded, encoded_len));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +0000113 int duration = PacketDurationRedundant(encoded, encoded_len);
Minyue323b1322015-05-25 13:49:37 +0200114 if (duration >= 0 &&
115 duration * Channels() * sizeof(int16_t) > max_decoded_bytes) {
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +0000116 return -1;
117 }
118 return DecodeRedundantInternal(encoded, encoded_len, sample_rate_hz, decoded,
119 speech_type);
120}
121
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +0000122int AudioDecoder::DecodeRedundantInternal(const uint8_t* encoded,
123 size_t encoded_len,
124 int sample_rate_hz, int16_t* decoded,
125 SpeechType* speech_type) {
126 return DecodeInternal(encoded, encoded_len, sample_rate_hz, decoded,
127 speech_type);
kwiberg@webrtc.orge04a93b2014-12-09 10:12:53 +0000128}
129
130bool AudioDecoder::HasDecodePlc() const { return false; }
131
Peter Kastingdce40cf2015-08-24 14:52:23 -0700132size_t AudioDecoder::DecodePlc(size_t num_frames, int16_t* decoded) {
133 return 0;
134}
kwiberg@webrtc.orge04a93b2014-12-09 10:12:53 +0000135
136int AudioDecoder::IncomingPacket(const uint8_t* payload,
137 size_t payload_len,
138 uint16_t rtp_sequence_number,
139 uint32_t rtp_timestamp,
140 uint32_t arrival_timestamp) {
141 return 0;
142}
143
144int AudioDecoder::ErrorCode() { return 0; }
145
minyue@webrtc.orga8cc3442015-02-13 14:01:54 +0000146int AudioDecoder::PacketDuration(const uint8_t* encoded,
147 size_t encoded_len) const {
kwiberg@webrtc.orge04a93b2014-12-09 10:12:53 +0000148 return kNotImplemented;
149}
150
151int AudioDecoder::PacketDurationRedundant(const uint8_t* encoded,
152 size_t encoded_len) const {
153 return kNotImplemented;
154}
155
156bool AudioDecoder::PacketHasFec(const uint8_t* encoded,
157 size_t encoded_len) const {
158 return false;
159}
160
kwiberg@webrtc.orge04a93b2014-12-09 10:12:53 +0000161AudioDecoder::SpeechType AudioDecoder::ConvertSpeechType(int16_t type) {
162 switch (type) {
163 case 0: // TODO(hlundin): Both iSAC and Opus return 0 for speech.
164 case 1:
165 return kSpeech;
166 case 2:
167 return kComfortNoise;
168 default:
169 assert(false);
170 return kSpeech;
171 }
172}
173
174} // namespace webrtc