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
),
250 start_input_timestamp_(kNoTimestamp()) {}
252 std::string
OpusAudioDecoder::GetDisplayName() const {
253 return "OpusAudioDecoder";
256 void OpusAudioDecoder::Initialize(const AudioDecoderConfig
& config
,
257 const PipelineStatusCB
& status_cb
,
258 const OutputCB
& output_cb
) {
259 DCHECK(task_runner_
->BelongsToCurrentThread());
260 PipelineStatusCB initialize_cb
= BindToCurrentLoop(status_cb
);
263 output_cb_
= BindToCurrentLoop(output_cb
);
265 if (!ConfigureDecoder()) {
266 initialize_cb
.Run(DECODER_ERROR_NOT_SUPPORTED
);
270 initialize_cb
.Run(PIPELINE_OK
);
273 void OpusAudioDecoder::Decode(const scoped_refptr
<DecoderBuffer
>& buffer
,
274 const DecodeCB
& decode_cb
) {
275 DCHECK(task_runner_
->BelongsToCurrentThread());
276 DCHECK(!decode_cb
.is_null());
278 DecodeBuffer(buffer
, BindToCurrentLoop(decode_cb
));
281 void OpusAudioDecoder::Reset(const base::Closure
& closure
) {
282 DCHECK(task_runner_
->BelongsToCurrentThread());
284 opus_multistream_decoder_ctl(opus_decoder_
, OPUS_RESET_STATE
);
285 ResetTimestampState();
286 task_runner_
->PostTask(FROM_HERE
, closure
);
289 OpusAudioDecoder::~OpusAudioDecoder() {
290 DCHECK(task_runner_
->BelongsToCurrentThread());
295 opus_multistream_decoder_ctl(opus_decoder_
, OPUS_RESET_STATE
);
296 ResetTimestampState();
300 void OpusAudioDecoder::DecodeBuffer(
301 const scoped_refptr
<DecoderBuffer
>& input
,
302 const DecodeCB
& decode_cb
) {
303 DCHECK(task_runner_
->BelongsToCurrentThread());
304 DCHECK(!decode_cb
.is_null());
307 // Libopus does not buffer output. Decoding is complete when an end of stream
308 // input buffer is received.
309 if (input
->end_of_stream()) {
314 // Make sure we are notified if http://crbug.com/49709 returns. Issue also
315 // occurs with some damaged files.
316 if (input
->timestamp() == kNoTimestamp()) {
317 DLOG(ERROR
) << "Received a buffer without timestamps!";
318 decode_cb
.Run(kDecodeError
);
322 // Apply the necessary codec delay.
323 if (start_input_timestamp_
== kNoTimestamp())
324 start_input_timestamp_
= input
->timestamp();
325 if (!discard_helper_
->initialized() &&
326 input
->timestamp() == start_input_timestamp_
) {
327 discard_helper_
->Reset(config_
.codec_delay());
330 scoped_refptr
<AudioBuffer
> output_buffer
;
332 if (!Decode(input
, &output_buffer
)) {
333 decode_cb
.Run(kDecodeError
);
337 if (output_buffer
.get()) {
338 output_cb_
.Run(output_buffer
);
344 bool OpusAudioDecoder::ConfigureDecoder() {
345 if (config_
.codec() != kCodecOpus
) {
346 DVLOG(1) << "Codec must be kCodecOpus.";
350 const int channel_count
=
351 ChannelLayoutToChannelCount(config_
.channel_layout());
352 if (!config_
.IsValidConfig() || channel_count
> kMaxVorbisChannels
) {
353 DLOG(ERROR
) << "Invalid or unsupported audio stream -"
354 << " codec: " << config_
.codec()
355 << " channel count: " << channel_count
356 << " channel layout: " << config_
.channel_layout()
357 << " bits per channel: " << config_
.bits_per_channel()
358 << " samples per second: " << config_
.samples_per_second();
362 if (config_
.is_encrypted()) {
363 DLOG(ERROR
) << "Encrypted audio stream not supported.";
367 // Clean up existing decoder if necessary.
370 // Parse the Opus Extra Data.
371 OpusExtraData opus_extra_data
;
372 if (!ParseOpusExtraData(config_
.extra_data(), config_
.extra_data_size(),
377 if (config_
.codec_delay() < 0) {
378 DLOG(ERROR
) << "Invalid file. Incorrect value for codec delay: "
379 << config_
.codec_delay();
383 if (config_
.codec_delay() != opus_extra_data
.skip_samples
) {
384 DLOG(ERROR
) << "Invalid file. Codec Delay in container does not match the "
385 << "value in Opus Extra Data. " << config_
.codec_delay()
386 << " vs " << opus_extra_data
.skip_samples
;
390 uint8 channel_mapping
[kMaxVorbisChannels
] = {0};
391 memcpy(&channel_mapping
,
392 kDefaultOpusChannelLayout
,
393 kMaxChannelsWithDefaultLayout
);
395 if (channel_count
> kMaxChannelsWithDefaultLayout
) {
396 RemapOpusChannelLayout(opus_extra_data
.stream_map
,
402 int status
= OPUS_INVALID_STATE
;
403 opus_decoder_
= opus_multistream_decoder_create(config_
.samples_per_second(),
405 opus_extra_data
.num_streams
,
406 opus_extra_data
.num_coupled
,
409 if (!opus_decoder_
|| status
!= OPUS_OK
) {
410 DLOG(ERROR
) << "opus_multistream_decoder_create failed status="
411 << opus_strerror(status
);
415 status
= opus_multistream_decoder_ctl(
416 opus_decoder_
, OPUS_SET_GAIN(opus_extra_data
.gain_db
));
417 if (status
!= OPUS_OK
) {
418 DLOG(ERROR
) << "Failed to set OPUS header gain; status="
419 << opus_strerror(status
);
423 discard_helper_
.reset(
424 new AudioDiscardHelper(config_
.samples_per_second(), 0));
425 start_input_timestamp_
= kNoTimestamp();
429 void OpusAudioDecoder::CloseDecoder() {
431 opus_multistream_decoder_destroy(opus_decoder_
);
432 opus_decoder_
= NULL
;
436 void OpusAudioDecoder::ResetTimestampState() {
437 discard_helper_
->Reset(
438 discard_helper_
->TimeDeltaToFrames(config_
.seek_preroll()));
441 bool OpusAudioDecoder::Decode(const scoped_refptr
<DecoderBuffer
>& input
,
442 scoped_refptr
<AudioBuffer
>* output_buffer
) {
443 // Allocate a buffer for the output samples.
444 *output_buffer
= AudioBuffer::CreateBuffer(
445 config_
.sample_format(),
446 config_
.channel_layout(),
447 ChannelLayoutToChannelCount(config_
.channel_layout()),
448 config_
.samples_per_second(),
449 kMaxOpusOutputPacketSizeSamples
);
450 const int buffer_size
=
451 output_buffer
->get()->channel_count() *
452 output_buffer
->get()->frame_count() *
453 SampleFormatToBytesPerChannel(config_
.sample_format());
455 float* float_output_buffer
= reinterpret_cast<float*>(
456 output_buffer
->get()->channel_data()[0]);
457 const int frames_decoded
=
458 opus_multistream_decode_float(opus_decoder_
,
465 if (frames_decoded
< 0) {
466 DLOG(ERROR
) << "opus_multistream_decode failed for"
467 << " timestamp: " << input
->timestamp().InMicroseconds()
468 << " us, duration: " << input
->duration().InMicroseconds()
469 << " us, packet size: " << input
->data_size() << " bytes with"
470 << " status: " << opus_strerror(frames_decoded
);
474 // Trim off any extraneous allocation.
475 DCHECK_LE(frames_decoded
, output_buffer
->get()->frame_count());
476 const int trim_frames
= output_buffer
->get()->frame_count() - frames_decoded
;
478 output_buffer
->get()->TrimEnd(trim_frames
);
480 // Handles discards and timestamping. Discard the buffer if more data needed.
481 if (!discard_helper_
->ProcessBuffers(input
, *output_buffer
))
482 *output_buffer
= NULL
;