1 // Copyright (c) 2012 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.
5 #include "media/filters/opus_audio_decoder.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/sys_byteorder.h"
11 #include "media/base/audio_buffer.h"
12 #include "media/base/audio_decoder_config.h"
13 #include "media/base/audio_discard_helper.h"
14 #include "media/base/bind_to_current_loop.h"
15 #include "media/base/buffers.h"
16 #include "media/base/decoder_buffer.h"
17 #include "third_party/opus/src/include/opus.h"
18 #include "third_party/opus/src/include/opus_multistream.h"
22 static uint16
ReadLE16(const uint8
* data
, size_t data_size
, int read_offset
) {
24 DCHECK_LE(read_offset
+ sizeof(value
), data_size
);
25 memcpy(&value
, data
+ read_offset
, sizeof(value
));
26 return base::ByteSwapToLE16(value
);
29 // The Opus specification is part of IETF RFC 6716:
30 // http://tools.ietf.org/html/rfc6716
32 // Opus uses Vorbis channel mapping, and Vorbis channel mapping specifies
33 // mappings for up to 8 channels. This information is part of the Vorbis I
35 // http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html
36 static const int kMaxVorbisChannels
= 8;
38 // Maximum packet size used in Xiph's opusdec and FFmpeg's libopusdec.
39 static const int kMaxOpusOutputPacketSizeSamples
= 960 * 6;
41 static void RemapOpusChannelLayout(const uint8
* opus_mapping
,
43 uint8
* channel_layout
) {
44 DCHECK_LE(num_channels
, kMaxVorbisChannels
);
46 // Opus uses Vorbis channel layout.
47 const int32 num_layouts
= kMaxVorbisChannels
;
48 const int32 num_layout_values
= kMaxVorbisChannels
;
50 // Vorbis channel ordering for streams with >= 2 channels:
56 // Front L, Front R, Back L, Back R
58 // Front L, Center, Front R, Back L, Back R
60 // Front L, Center, Front R, Back L, Back R, LFE
62 // Front L, Front Center, Front R, Side L, Side R, Back Center, LFE
64 // Front L, Center, Front R, Side L, Side R, Back L, Back R, LFE
66 // Channel ordering information is taken from section 4.3.9 of the Vorbis I
68 // http://xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-800004.3.9
70 // These are the FFmpeg channel layouts expressed using the position of each
71 // channel in the output stream from libopus.
72 const uint8 kFFmpegChannelLayouts
[num_layouts
][num_layout_values
] = {
75 // Stereo: No reorder.
78 // 3 Channels, from Vorbis order to:
82 // 4 Channels: No reorder.
85 // 5 Channels, from Vorbis order to:
86 // Front L, Front R, Center, Back L, Back R
89 // 6 Channels (5.1), from Vorbis order to:
90 // Front L, Front R, Center, LFE, Back L, Back R
93 // 7 Channels (6.1), from Vorbis order to:
94 // Front L, Front R, Front Center, LFE, Side L, Side R, Back Center
95 { 0, 2, 1, 6, 3, 4, 5 },
97 // 8 Channels (7.1), from Vorbis order to:
98 // Front L, Front R, Center, LFE, Back L, Back R, Side L, Side R
99 { 0, 2, 1, 7, 5, 6, 3, 4 },
102 // Reorder the channels to produce the same ordering as FFmpeg, which is
103 // what the pipeline expects.
104 const uint8
* vorbis_layout_offset
= kFFmpegChannelLayouts
[num_channels
- 1];
105 for (int channel
= 0; channel
< num_channels
; ++channel
)
106 channel_layout
[channel
] = opus_mapping
[vorbis_layout_offset
[channel
]];
109 // Opus Extra Data contents:
110 // - "OpusHead" (64 bits)
111 // - version number (8 bits)
112 // - Channels C (8 bits)
113 // - Pre-skip (16 bits)
114 // - Sampling rate (32 bits)
115 // - Gain in dB (16 bits, S7.8)
116 // - Mapping (8 bits, 0=single stream (mono/stereo) 1=Vorbis mapping,
117 // 2..254: reserved, 255: multistream with no mapping)
119 // - if (mapping != 0)
120 // - N = totel number of streams (8 bits)
121 // - M = number of paired streams (8 bits)
122 // - C times channel origin
125 // - if (byte&0x1 == 0)
132 // Default audio output channel layout. Used to initialize |stream_map| in
133 // OpusExtraData, and passed to opus_multistream_decoder_create() when the
134 // extra data does not contain mapping information. The values are valid only
135 // for mono and stereo output: Opus streams with more than 2 channels require a
137 static const int kMaxChannelsWithDefaultLayout
= 2;
138 static const uint8 kDefaultOpusChannelLayout
[kMaxChannelsWithDefaultLayout
] = {
141 // Size of the Opus extra data excluding optional mapping information.
142 static const int kOpusExtraDataSize
= 19;
144 // Offset to the channel count byte in the Opus extra data.
145 static const int kOpusExtraDataChannelsOffset
= 9;
147 // Offset to the pre-skip value in the Opus extra data.
148 static const int kOpusExtraDataSkipSamplesOffset
= 10;
150 // Offset to the gain value in the Opus extra data.
151 static const int kOpusExtraDataGainOffset
= 16;
153 // Offset to the channel mapping byte in the Opus extra data.
154 static const int kOpusExtraDataChannelMappingOffset
= 18;
156 // Extra Data contains a stream map. The mapping values are in extra data beyond
157 // the always present |kOpusExtraDataSize| bytes of data. The mapping data
158 // contains stream count, coupling information, and per channel mapping values:
159 // - Byte 0: Number of streams.
160 // - Byte 1: Number coupled.
161 // - Byte 2: Starting at byte 2 are |extra_data->channels| uint8 mapping
163 static const int kOpusExtraDataNumStreamsOffset
= kOpusExtraDataSize
;
164 static const int kOpusExtraDataNumCoupledOffset
=
165 kOpusExtraDataNumStreamsOffset
+ 1;
166 static const int kOpusExtraDataStreamMapOffset
=
167 kOpusExtraDataNumStreamsOffset
+ 2;
169 struct OpusExtraData
{
179 kDefaultOpusChannelLayout
,
180 kMaxChannelsWithDefaultLayout
);
188 uint8 stream_map
[kMaxVorbisChannels
];
191 // Returns true when able to successfully parse and store Opus extra data in
192 // |extra_data|. Based on opus header parsing code in libopusdec from FFmpeg,
193 // and opus_header from Xiph's opus-tools project.
194 static bool ParseOpusExtraData(const uint8
* data
, int data_size
,
195 const AudioDecoderConfig
& config
,
196 OpusExtraData
* extra_data
) {
197 if (data_size
< kOpusExtraDataSize
) {
198 DLOG(ERROR
) << "Extra data size is too small:" << data_size
;
202 extra_data
->channels
= *(data
+ kOpusExtraDataChannelsOffset
);
204 if (extra_data
->channels
<= 0 || extra_data
->channels
> kMaxVorbisChannels
) {
205 DLOG(ERROR
) << "invalid channel count in extra data: "
206 << extra_data
->channels
;
210 extra_data
->skip_samples
=
211 ReadLE16(data
, data_size
, kOpusExtraDataSkipSamplesOffset
);
212 extra_data
->gain_db
= static_cast<int16
>(
213 ReadLE16(data
, data_size
, kOpusExtraDataGainOffset
));
215 extra_data
->channel_mapping
= *(data
+ kOpusExtraDataChannelMappingOffset
);
217 if (!extra_data
->channel_mapping
) {
218 if (extra_data
->channels
> kMaxChannelsWithDefaultLayout
) {
219 DLOG(ERROR
) << "Invalid extra data, missing stream map.";
223 extra_data
->num_streams
= 1;
224 extra_data
->num_coupled
=
225 (ChannelLayoutToChannelCount(config
.channel_layout()) > 1) ? 1 : 0;
229 if (data_size
< kOpusExtraDataStreamMapOffset
+ extra_data
->channels
) {
230 DLOG(ERROR
) << "Invalid stream map; insufficient data for current channel "
231 << "count: " << extra_data
->channels
;
235 extra_data
->num_streams
= *(data
+ kOpusExtraDataNumStreamsOffset
);
236 extra_data
->num_coupled
= *(data
+ kOpusExtraDataNumCoupledOffset
);
238 if (extra_data
->num_streams
+ extra_data
->num_coupled
!= extra_data
->channels
)
239 DVLOG(1) << "Inconsistent channel mapping.";
241 for (int i
= 0; i
< extra_data
->channels
; ++i
)
242 extra_data
->stream_map
[i
] = *(data
+ kOpusExtraDataStreamMapOffset
+ i
);
246 OpusAudioDecoder::OpusAudioDecoder(
247 const scoped_refptr
<base::SingleThreadTaskRunner
>& task_runner
)
248 : task_runner_(task_runner
), opus_decoder_(nullptr) {}
250 std::string
OpusAudioDecoder::GetDisplayName() const {
251 return "OpusAudioDecoder";
254 void OpusAudioDecoder::Initialize(const AudioDecoderConfig
& config
,
255 const InitCB
& init_cb
,
256 const OutputCB
& output_cb
) {
257 DCHECK(task_runner_
->BelongsToCurrentThread());
258 InitCB bound_init_cb
= BindToCurrentLoop(init_cb
);
261 output_cb_
= BindToCurrentLoop(output_cb
);
263 if (!ConfigureDecoder()) {
264 bound_init_cb
.Run(false);
268 bound_init_cb
.Run(true);
271 void OpusAudioDecoder::Decode(const scoped_refptr
<DecoderBuffer
>& buffer
,
272 const DecodeCB
& decode_cb
) {
273 DCHECK(task_runner_
->BelongsToCurrentThread());
274 DCHECK(!decode_cb
.is_null());
276 DecodeBuffer(buffer
, BindToCurrentLoop(decode_cb
));
279 void OpusAudioDecoder::Reset(const base::Closure
& closure
) {
280 DCHECK(task_runner_
->BelongsToCurrentThread());
282 opus_multistream_decoder_ctl(opus_decoder_
, OPUS_RESET_STATE
);
283 ResetTimestampState();
284 task_runner_
->PostTask(FROM_HERE
, closure
);
287 OpusAudioDecoder::~OpusAudioDecoder() {
288 DCHECK(task_runner_
->BelongsToCurrentThread());
293 opus_multistream_decoder_ctl(opus_decoder_
, OPUS_RESET_STATE
);
297 void OpusAudioDecoder::DecodeBuffer(
298 const scoped_refptr
<DecoderBuffer
>& input
,
299 const DecodeCB
& decode_cb
) {
300 DCHECK(task_runner_
->BelongsToCurrentThread());
301 DCHECK(!decode_cb
.is_null());
304 // Libopus does not buffer output. Decoding is complete when an end of stream
305 // input buffer is received.
306 if (input
->end_of_stream()) {
311 // Make sure we are notified if http://crbug.com/49709 returns. Issue also
312 // occurs with some damaged files.
313 if (input
->timestamp() == kNoTimestamp()) {
314 DLOG(ERROR
) << "Received a buffer without timestamps!";
315 decode_cb
.Run(kDecodeError
);
319 scoped_refptr
<AudioBuffer
> output_buffer
;
321 if (!Decode(input
, &output_buffer
)) {
322 decode_cb
.Run(kDecodeError
);
326 if (output_buffer
.get()) {
327 output_cb_
.Run(output_buffer
);
333 bool OpusAudioDecoder::ConfigureDecoder() {
334 if (config_
.codec() != kCodecOpus
) {
335 DVLOG(1) << "Codec must be kCodecOpus.";
339 const int channel_count
=
340 ChannelLayoutToChannelCount(config_
.channel_layout());
341 if (!config_
.IsValidConfig() || channel_count
> kMaxVorbisChannels
) {
342 DLOG(ERROR
) << "Invalid or unsupported audio stream -"
343 << " codec: " << config_
.codec()
344 << " channel count: " << channel_count
345 << " channel layout: " << config_
.channel_layout()
346 << " bits per channel: " << config_
.bits_per_channel()
347 << " samples per second: " << config_
.samples_per_second();
351 if (config_
.is_encrypted()) {
352 DLOG(ERROR
) << "Encrypted audio stream not supported.";
356 // Clean up existing decoder if necessary.
359 // Parse the Opus Extra Data.
360 OpusExtraData opus_extra_data
;
361 if (!ParseOpusExtraData(config_
.extra_data(), config_
.extra_data_size(),
366 if (config_
.codec_delay() < 0) {
367 DLOG(ERROR
) << "Invalid file. Incorrect value for codec delay: "
368 << config_
.codec_delay();
372 if (config_
.codec_delay() != opus_extra_data
.skip_samples
) {
373 DLOG(ERROR
) << "Invalid file. Codec Delay in container does not match the "
374 << "value in Opus Extra Data. " << config_
.codec_delay()
375 << " vs " << opus_extra_data
.skip_samples
;
379 uint8 channel_mapping
[kMaxVorbisChannels
] = {0};
380 memcpy(&channel_mapping
,
381 kDefaultOpusChannelLayout
,
382 kMaxChannelsWithDefaultLayout
);
384 if (channel_count
> kMaxChannelsWithDefaultLayout
) {
385 RemapOpusChannelLayout(opus_extra_data
.stream_map
,
391 int status
= OPUS_INVALID_STATE
;
392 opus_decoder_
= opus_multistream_decoder_create(config_
.samples_per_second(),
394 opus_extra_data
.num_streams
,
395 opus_extra_data
.num_coupled
,
398 if (!opus_decoder_
|| status
!= OPUS_OK
) {
399 DLOG(ERROR
) << "opus_multistream_decoder_create failed status="
400 << opus_strerror(status
);
404 status
= opus_multistream_decoder_ctl(
405 opus_decoder_
, OPUS_SET_GAIN(opus_extra_data
.gain_db
));
406 if (status
!= OPUS_OK
) {
407 DLOG(ERROR
) << "Failed to set OPUS header gain; status="
408 << opus_strerror(status
);
412 ResetTimestampState();
416 void OpusAudioDecoder::CloseDecoder() {
418 opus_multistream_decoder_destroy(opus_decoder_
);
419 opus_decoder_
= nullptr;
423 void OpusAudioDecoder::ResetTimestampState() {
424 discard_helper_
.reset(
425 new AudioDiscardHelper(config_
.samples_per_second(), 0));
426 discard_helper_
->Reset(config_
.codec_delay());
429 bool OpusAudioDecoder::Decode(const scoped_refptr
<DecoderBuffer
>& input
,
430 scoped_refptr
<AudioBuffer
>* output_buffer
) {
431 // Allocate a buffer for the output samples.
432 *output_buffer
= AudioBuffer::CreateBuffer(
433 config_
.sample_format(),
434 config_
.channel_layout(),
435 ChannelLayoutToChannelCount(config_
.channel_layout()),
436 config_
.samples_per_second(),
437 kMaxOpusOutputPacketSizeSamples
);
438 const int buffer_size
=
439 output_buffer
->get()->channel_count() *
440 output_buffer
->get()->frame_count() *
441 SampleFormatToBytesPerChannel(config_
.sample_format());
443 float* float_output_buffer
= reinterpret_cast<float*>(
444 output_buffer
->get()->channel_data()[0]);
445 const int frames_decoded
=
446 opus_multistream_decode_float(opus_decoder_
,
453 if (frames_decoded
< 0) {
454 DLOG(ERROR
) << "opus_multistream_decode failed for"
455 << " timestamp: " << input
->timestamp().InMicroseconds()
456 << " us, duration: " << input
->duration().InMicroseconds()
457 << " us, packet size: " << input
->data_size() << " bytes with"
458 << " status: " << opus_strerror(frames_decoded
);
462 // Trim off any extraneous allocation.
463 DCHECK_LE(frames_decoded
, output_buffer
->get()->frame_count());
464 const int trim_frames
= output_buffer
->get()->frame_count() - frames_decoded
;
466 output_buffer
->get()->TrimEnd(trim_frames
);
468 // Handles discards and timestamping. Discard the buffer if more data needed.
469 if (!discard_helper_
->ProcessBuffers(input
, *output_buffer
))
470 *output_buffer
= nullptr;