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
{
178 kDefaultOpusChannelLayout
,
179 kMaxChannelsWithDefaultLayout
);
187 uint8 stream_map
[kMaxVorbisChannels
];
190 // Returns true when able to successfully parse and store Opus extra data in
191 // |extra_data|. Based on opus header parsing code in libopusdec from FFmpeg,
192 // and opus_header from Xiph's opus-tools project.
193 static bool ParseOpusExtraData(const uint8
* data
, int data_size
,
194 const AudioDecoderConfig
& config
,
195 OpusExtraData
* extra_data
) {
196 if (data_size
< kOpusExtraDataSize
) {
197 DLOG(ERROR
) << "Extra data size is too small:" << data_size
;
201 extra_data
->channels
= *(data
+ kOpusExtraDataChannelsOffset
);
203 if (extra_data
->channels
<= 0 || extra_data
->channels
> kMaxVorbisChannels
) {
204 DLOG(ERROR
) << "invalid channel count in extra data: "
205 << extra_data
->channels
;
209 extra_data
->skip_samples
=
210 ReadLE16(data
, data_size
, kOpusExtraDataSkipSamplesOffset
);
211 extra_data
->gain_db
= static_cast<int16
>(
212 ReadLE16(data
, data_size
, kOpusExtraDataGainOffset
));
214 extra_data
->channel_mapping
= *(data
+ kOpusExtraDataChannelMappingOffset
);
216 if (!extra_data
->channel_mapping
) {
217 if (extra_data
->channels
> kMaxChannelsWithDefaultLayout
) {
218 DLOG(ERROR
) << "Invalid extra data, missing stream map.";
222 extra_data
->num_streams
= 1;
223 extra_data
->num_coupled
=
224 (ChannelLayoutToChannelCount(config
.channel_layout()) > 1) ? 1 : 0;
228 if (data_size
< kOpusExtraDataStreamMapOffset
+ extra_data
->channels
) {
229 DLOG(ERROR
) << "Invalid stream map; insufficient data for current channel "
230 << "count: " << extra_data
->channels
;
234 extra_data
->num_streams
= *(data
+ kOpusExtraDataNumStreamsOffset
);
235 extra_data
->num_coupled
= *(data
+ kOpusExtraDataNumCoupledOffset
);
237 if (extra_data
->num_streams
+ extra_data
->num_coupled
!= extra_data
->channels
)
238 DVLOG(1) << "Inconsistent channel mapping.";
240 for (int i
= 0; i
< extra_data
->channels
; ++i
)
241 extra_data
->stream_map
[i
] = *(data
+ kOpusExtraDataStreamMapOffset
+ i
);
245 OpusAudioDecoder::OpusAudioDecoder(
246 const scoped_refptr
<base::SingleThreadTaskRunner
>& task_runner
)
247 : task_runner_(task_runner
),
249 start_input_timestamp_(kNoTimestamp()) {}
251 void OpusAudioDecoder::Initialize(const AudioDecoderConfig
& config
,
252 const PipelineStatusCB
& status_cb
,
253 const OutputCB
& output_cb
) {
254 DCHECK(task_runner_
->BelongsToCurrentThread());
255 PipelineStatusCB initialize_cb
= BindToCurrentLoop(status_cb
);
258 output_cb_
= BindToCurrentLoop(output_cb
);
260 if (!ConfigureDecoder()) {
261 initialize_cb
.Run(DECODER_ERROR_NOT_SUPPORTED
);
265 initialize_cb
.Run(PIPELINE_OK
);
268 void OpusAudioDecoder::Decode(const scoped_refptr
<DecoderBuffer
>& buffer
,
269 const DecodeCB
& decode_cb
) {
270 DCHECK(task_runner_
->BelongsToCurrentThread());
271 DCHECK(!decode_cb
.is_null());
273 DecodeBuffer(buffer
, BindToCurrentLoop(decode_cb
));
276 void OpusAudioDecoder::Reset(const base::Closure
& closure
) {
277 DCHECK(task_runner_
->BelongsToCurrentThread());
279 opus_multistream_decoder_ctl(opus_decoder_
, OPUS_RESET_STATE
);
280 ResetTimestampState();
281 task_runner_
->PostTask(FROM_HERE
, closure
);
284 void OpusAudioDecoder::Stop() {
285 DCHECK(task_runner_
->BelongsToCurrentThread());
290 opus_multistream_decoder_ctl(opus_decoder_
, OPUS_RESET_STATE
);
291 ResetTimestampState();
295 OpusAudioDecoder::~OpusAudioDecoder() {
296 DCHECK(!opus_decoder_
);
299 void OpusAudioDecoder::DecodeBuffer(
300 const scoped_refptr
<DecoderBuffer
>& input
,
301 const DecodeCB
& decode_cb
) {
302 DCHECK(task_runner_
->BelongsToCurrentThread());
303 DCHECK(!decode_cb
.is_null());
306 // Libopus does not buffer output. Decoding is complete when an end of stream
307 // input buffer is received.
308 if (input
->end_of_stream()) {
313 // Make sure we are notified if http://crbug.com/49709 returns. Issue also
314 // occurs with some damaged files.
315 if (input
->timestamp() == kNoTimestamp()) {
316 DLOG(ERROR
) << "Received a buffer without timestamps!";
317 decode_cb
.Run(kDecodeError
);
321 // Apply the necessary codec delay.
322 if (start_input_timestamp_
== kNoTimestamp())
323 start_input_timestamp_
= input
->timestamp();
324 if (!discard_helper_
->initialized() &&
325 input
->timestamp() == start_input_timestamp_
) {
326 discard_helper_
->Reset(config_
.codec_delay());
329 scoped_refptr
<AudioBuffer
> output_buffer
;
331 if (!Decode(input
, &output_buffer
)) {
332 decode_cb
.Run(kDecodeError
);
337 output_cb_
.Run(output_buffer
);
343 bool OpusAudioDecoder::ConfigureDecoder() {
344 if (config_
.codec() != kCodecOpus
) {
345 DVLOG(1) << "Codec must be kCodecOpus.";
349 const int channel_count
=
350 ChannelLayoutToChannelCount(config_
.channel_layout());
351 if (!config_
.IsValidConfig() || channel_count
> kMaxVorbisChannels
) {
352 DLOG(ERROR
) << "Invalid or unsupported audio stream -"
353 << " codec: " << config_
.codec()
354 << " channel count: " << channel_count
355 << " channel layout: " << config_
.channel_layout()
356 << " bits per channel: " << config_
.bits_per_channel()
357 << " samples per second: " << config_
.samples_per_second();
361 if (config_
.is_encrypted()) {
362 DLOG(ERROR
) << "Encrypted audio stream not supported.";
366 // Clean up existing decoder if necessary.
369 // Parse the Opus Extra Data.
370 OpusExtraData opus_extra_data
;
371 if (!ParseOpusExtraData(config_
.extra_data(), config_
.extra_data_size(),
376 if (config_
.codec_delay() < 0) {
377 DLOG(ERROR
) << "Invalid file. Incorrect value for codec delay: "
378 << config_
.codec_delay();
382 if (config_
.codec_delay() != opus_extra_data
.skip_samples
) {
383 DLOG(ERROR
) << "Invalid file. Codec Delay in container does not match the "
384 << "value in Opus Extra Data. " << config_
.codec_delay()
385 << " vs " << opus_extra_data
.skip_samples
;
389 uint8 channel_mapping
[kMaxVorbisChannels
] = {0};
390 memcpy(&channel_mapping
,
391 kDefaultOpusChannelLayout
,
392 kMaxChannelsWithDefaultLayout
);
394 if (channel_count
> kMaxChannelsWithDefaultLayout
) {
395 RemapOpusChannelLayout(opus_extra_data
.stream_map
,
401 int status
= OPUS_INVALID_STATE
;
402 opus_decoder_
= opus_multistream_decoder_create(config_
.samples_per_second(),
404 opus_extra_data
.num_streams
,
405 opus_extra_data
.num_coupled
,
408 if (!opus_decoder_
|| status
!= OPUS_OK
) {
409 DLOG(ERROR
) << "opus_multistream_decoder_create failed status="
410 << opus_strerror(status
);
414 status
= opus_multistream_decoder_ctl(
415 opus_decoder_
, OPUS_SET_GAIN(opus_extra_data
.gain_db
));
416 if (status
!= OPUS_OK
) {
417 DLOG(ERROR
) << "Failed to set OPUS header gain; status="
418 << opus_strerror(status
);
422 discard_helper_
.reset(
423 new AudioDiscardHelper(config_
.samples_per_second(), 0));
424 start_input_timestamp_
= kNoTimestamp();
428 void OpusAudioDecoder::CloseDecoder() {
430 opus_multistream_decoder_destroy(opus_decoder_
);
431 opus_decoder_
= NULL
;
435 void OpusAudioDecoder::ResetTimestampState() {
436 discard_helper_
->Reset(
437 discard_helper_
->TimeDeltaToFrames(config_
.seek_preroll()));
440 bool OpusAudioDecoder::Decode(const scoped_refptr
<DecoderBuffer
>& input
,
441 scoped_refptr
<AudioBuffer
>* output_buffer
) {
442 // Allocate a buffer for the output samples.
443 *output_buffer
= AudioBuffer::CreateBuffer(
444 config_
.sample_format(),
445 config_
.channel_layout(),
446 ChannelLayoutToChannelCount(config_
.channel_layout()),
447 config_
.samples_per_second(),
448 kMaxOpusOutputPacketSizeSamples
);
449 const int buffer_size
=
450 output_buffer
->get()->channel_count() *
451 output_buffer
->get()->frame_count() *
452 SampleFormatToBytesPerChannel(config_
.sample_format());
454 float* float_output_buffer
= reinterpret_cast<float*>(
455 output_buffer
->get()->channel_data()[0]);
456 const int frames_decoded
=
457 opus_multistream_decode_float(opus_decoder_
,
464 if (frames_decoded
< 0) {
465 DLOG(ERROR
) << "opus_multistream_decode failed for"
466 << " timestamp: " << input
->timestamp().InMicroseconds()
467 << " us, duration: " << input
->duration().InMicroseconds()
468 << " us, packet size: " << input
->data_size() << " bytes with"
469 << " status: " << opus_strerror(frames_decoded
);
473 // Trim off any extraneous allocation.
474 DCHECK_LE(frames_decoded
, output_buffer
->get()->frame_count());
475 const int trim_frames
= output_buffer
->get()->frame_count() - frames_decoded
;
477 output_buffer
->get()->TrimEnd(trim_frames
);
479 // Handles discards and timestamping. Discard the buffer if more data needed.
480 if (!discard_helper_
->ProcessBuffers(input
, *output_buffer
))
481 *output_buffer
= NULL
;