1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/cast/receiver/audio_decoder.h"
6
7 #include <stdint.h>
8
9 #include <utility>
10
11 #include "base/bind.h"
12 #include "base/callback_helpers.h"
13 #include "base/location.h"
14 #include "base/logging.h"
15 #include "base/macros.h"
16 #include "base/memory/ptr_util.h"
17 #include "base/sys_byteorder.h"
18 #include "build/build_config.h"
19 #include "third_party/opus/src/include/opus.h"
20
21 namespace media {
22 namespace cast {
23
24 // Base class that handles the common problem of detecting dropped frames, and
25 // then invoking the Decode() method implemented by the subclasses to convert
26 // the encoded payload data into usable audio data.
27 class AudioDecoder::ImplBase
28 : public base::RefCountedThreadSafe<AudioDecoder::ImplBase> {
29 public:
ImplBase(const scoped_refptr<CastEnvironment> & cast_environment,Codec codec,int num_channels,int sampling_rate)30 ImplBase(const scoped_refptr<CastEnvironment>& cast_environment,
31 Codec codec,
32 int num_channels,
33 int sampling_rate)
34 : cast_environment_(cast_environment),
35 codec_(codec),
36 num_channels_(num_channels),
37 operational_status_(STATUS_UNINITIALIZED) {
38 if (num_channels_ <= 0 || sampling_rate <= 0 || sampling_rate % 100 != 0) {
39 operational_status_ = STATUS_INVALID_CONFIGURATION;
40 }
41 }
42
InitializationResult() const43 OperationalStatus InitializationResult() const {
44 return operational_status_;
45 }
46
DecodeFrame(std::unique_ptr<EncodedFrame> encoded_frame,DecodeFrameCallback callback)47 void DecodeFrame(std::unique_ptr<EncodedFrame> encoded_frame,
48 DecodeFrameCallback callback) {
49 DCHECK_EQ(operational_status_, STATUS_INITIALIZED);
50
51 bool is_continuous = true;
52 DCHECK(!encoded_frame->frame_id.is_null());
53 if (!last_frame_id_.is_null()) {
54 if (encoded_frame->frame_id > (last_frame_id_ + 1)) {
55 RecoverBecauseFramesWereDropped();
56 is_continuous = false;
57 }
58 }
59 last_frame_id_ = encoded_frame->frame_id;
60
61 std::unique_ptr<AudioBus> decoded_audio =
62 Decode(encoded_frame->mutable_bytes(),
63 static_cast<int>(encoded_frame->data.size()));
64 if (!decoded_audio) {
65 VLOG(2) << "Decoding of frame " << encoded_frame->frame_id << " failed.";
66 cast_environment_->PostTask(
67 CastEnvironment::MAIN, FROM_HERE,
68 base::BindOnce(std::move(callback), std::move(decoded_audio), false));
69 return;
70 }
71
72 std::unique_ptr<FrameEvent> event(new FrameEvent());
73 event->timestamp = cast_environment_->Clock()->NowTicks();
74 event->type = FRAME_DECODED;
75 event->media_type = AUDIO_EVENT;
76 event->rtp_timestamp = encoded_frame->rtp_timestamp;
77 event->frame_id = encoded_frame->frame_id;
78 cast_environment_->logger()->DispatchFrameEvent(std::move(event));
79
80 cast_environment_->PostTask(
81 CastEnvironment::MAIN, FROM_HERE,
82 base::BindOnce(std::move(callback), std::move(decoded_audio),
83 is_continuous));
84 }
85
86 protected:
87 friend class base::RefCountedThreadSafe<ImplBase>;
88 virtual ~ImplBase() = default;
89
RecoverBecauseFramesWereDropped()90 virtual void RecoverBecauseFramesWereDropped() {}
91
92 // Note: Implementation of Decode() is allowed to mutate |data|.
93 virtual std::unique_ptr<AudioBus> Decode(uint8_t* data, int len) = 0;
94
95 const scoped_refptr<CastEnvironment> cast_environment_;
96 const Codec codec_;
97 const int num_channels_;
98
99 // Subclass' ctor is expected to set this to STATUS_INITIALIZED.
100 OperationalStatus operational_status_;
101
102 private:
103 FrameId last_frame_id_;
104
105 DISALLOW_COPY_AND_ASSIGN(ImplBase);
106 };
107
108 class AudioDecoder::OpusImpl final : public AudioDecoder::ImplBase {
109 public:
OpusImpl(const scoped_refptr<CastEnvironment> & cast_environment,int num_channels,int sampling_rate)110 OpusImpl(const scoped_refptr<CastEnvironment>& cast_environment,
111 int num_channels,
112 int sampling_rate)
113 : ImplBase(cast_environment,
114 CODEC_AUDIO_OPUS,
115 num_channels,
116 sampling_rate),
117 decoder_memory_(new uint8_t[opus_decoder_get_size(num_channels)]),
118 opus_decoder_(reinterpret_cast<OpusDecoder*>(decoder_memory_.get())),
119 max_samples_per_frame_(kOpusMaxFrameDurationMillis * sampling_rate /
120 1000),
121 buffer_(new float[max_samples_per_frame_ * num_channels]) {
122 if (ImplBase::operational_status_ != STATUS_UNINITIALIZED) {
123 return;
124 }
125 if (opus_decoder_init(opus_decoder_, sampling_rate, num_channels) !=
126 OPUS_OK) {
127 ImplBase::operational_status_ = STATUS_INVALID_CONFIGURATION;
128 return;
129 }
130 ImplBase::operational_status_ = STATUS_INITIALIZED;
131 }
132
133 private:
134 ~OpusImpl() final = default;
135
RecoverBecauseFramesWereDropped()136 void RecoverBecauseFramesWereDropped() final {
137 // Passing nullptr for the input data notifies the decoder of frame loss.
138 const opus_int32 result = opus_decode_float(
139 opus_decoder_, nullptr, 0, buffer_.get(), max_samples_per_frame_, 0);
140 DCHECK_GE(result, 0);
141 }
142
Decode(uint8_t * data,int len)143 std::unique_ptr<AudioBus> Decode(uint8_t* data, int len) final {
144 std::unique_ptr<AudioBus> audio_bus;
145 const opus_int32 num_samples_decoded = opus_decode_float(
146 opus_decoder_, data, len, buffer_.get(), max_samples_per_frame_, 0);
147 if (num_samples_decoded <= 0)
148 return audio_bus; // Decode error.
149
150 // Copy interleaved samples from |buffer_| into a new AudioBus (where
151 // samples are stored in planar format, for each channel).
152 audio_bus = AudioBus::Create(num_channels_, num_samples_decoded);
153 // TODO(miu): This should be moved into AudioBus::FromInterleaved().
154 for (int ch = 0; ch < num_channels_; ++ch) {
155 const float* src = buffer_.get() + ch;
156 const float* const src_end = src + num_samples_decoded * num_channels_;
157 float* dest = audio_bus->channel(ch);
158 for (; src < src_end; src += num_channels_, ++dest)
159 *dest = *src;
160 }
161 return audio_bus;
162 }
163
164 const std::unique_ptr<uint8_t[]> decoder_memory_;
165 OpusDecoder* const opus_decoder_;
166 const int max_samples_per_frame_;
167 const std::unique_ptr<float[]> buffer_;
168
169 // According to documentation in third_party/opus/src/include/opus.h, we must
170 // provide enough space in |buffer_| to contain 120ms of samples. At 48 kHz,
171 // then, that means 5760 samples times the number of channels.
172 static const int kOpusMaxFrameDurationMillis = 120;
173
174 DISALLOW_COPY_AND_ASSIGN(OpusImpl);
175 };
176
177 class AudioDecoder::Pcm16Impl final : public AudioDecoder::ImplBase {
178 public:
Pcm16Impl(const scoped_refptr<CastEnvironment> & cast_environment,int num_channels,int sampling_rate)179 Pcm16Impl(const scoped_refptr<CastEnvironment>& cast_environment,
180 int num_channels,
181 int sampling_rate)
182 : ImplBase(cast_environment,
183 CODEC_AUDIO_PCM16,
184 num_channels,
185 sampling_rate) {
186 if (ImplBase::operational_status_ != STATUS_UNINITIALIZED)
187 return;
188 ImplBase::operational_status_ = STATUS_INITIALIZED;
189 }
190
191 private:
192 ~Pcm16Impl() final = default;
193
Decode(uint8_t * data,int len)194 std::unique_ptr<AudioBus> Decode(uint8_t* data, int len) final {
195 std::unique_ptr<AudioBus> audio_bus;
196 const int num_samples = len / sizeof(int16_t) / num_channels_;
197 if (num_samples <= 0)
198 return audio_bus;
199
200 int16_t* const pcm_data = reinterpret_cast<int16_t*>(data);
201 #if defined(ARCH_CPU_LITTLE_ENDIAN)
202 // Convert endianness.
203 const int num_elements = num_samples * num_channels_;
204 for (int i = 0; i < num_elements; ++i)
205 pcm_data[i] = static_cast<int16_t>(base::NetToHost16(pcm_data[i]));
206 #endif
207 audio_bus = AudioBus::Create(num_channels_, num_samples);
208 audio_bus->FromInterleaved<SignedInt16SampleTypeTraits>(pcm_data,
209 num_samples);
210 return audio_bus;
211 }
212
213 DISALLOW_COPY_AND_ASSIGN(Pcm16Impl);
214 };
215
AudioDecoder(const scoped_refptr<CastEnvironment> & cast_environment,int channels,int sampling_rate,Codec codec)216 AudioDecoder::AudioDecoder(
217 const scoped_refptr<CastEnvironment>& cast_environment,
218 int channels,
219 int sampling_rate,
220 Codec codec)
221 : cast_environment_(cast_environment) {
222 switch (codec) {
223 case CODEC_AUDIO_OPUS:
224 impl_ = new OpusImpl(cast_environment, channels, sampling_rate);
225 break;
226 case CODEC_AUDIO_PCM16:
227 impl_ = new Pcm16Impl(cast_environment, channels, sampling_rate);
228 break;
229 default:
230 NOTREACHED() << "Unknown or unspecified codec.";
231 break;
232 }
233 }
234
235 AudioDecoder::~AudioDecoder() = default;
236
InitializationResult() const237 OperationalStatus AudioDecoder::InitializationResult() const {
238 if (impl_.get())
239 return impl_->InitializationResult();
240 return STATUS_UNSUPPORTED_CODEC;
241 }
242
DecodeFrame(std::unique_ptr<EncodedFrame> encoded_frame,DecodeFrameCallback callback)243 void AudioDecoder::DecodeFrame(std::unique_ptr<EncodedFrame> encoded_frame,
244 DecodeFrameCallback callback) {
245 DCHECK(encoded_frame.get());
246 DCHECK(!callback.is_null());
247 if (!impl_.get() || impl_->InitializationResult() != STATUS_INITIALIZED) {
248 std::move(callback).Run(base::WrapUnique<AudioBus>(nullptr), false);
249 return;
250 }
251 cast_environment_->PostTask(
252 CastEnvironment::AUDIO, FROM_HERE,
253 base::BindOnce(&AudioDecoder::ImplBase::DecodeFrame, impl_,
254 std::move(encoded_frame), std::move(callback)));
255 }
256
257 } // namespace cast
258 } // namespace media
259