| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/filters/opus_audio_decoder.h" | 5 #include "media/filters/opus_audio_decoder.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #include "base/single_thread_task_runner.h" | 9 #include "base/single_thread_task_runner.h" |
| 10 #include "base/sys_byteorder.h" | 10 #include "base/sys_byteorder.h" |
| 11 #include "media/base/audio_buffer.h" | 11 #include "media/base/audio_buffer.h" |
| 12 #include "media/base/audio_decoder_config.h" | 12 #include "media/base/audio_decoder_config.h" |
| 13 #include "media/base/audio_discard_helper.h" | 13 #include "media/base/audio_discard_helper.h" |
| 14 #include "media/base/bind_to_current_loop.h" | 14 #include "media/base/bind_to_current_loop.h" |
| 15 #include "media/base/decoder_buffer.h" | 15 #include "media/base/decoder_buffer.h" |
| 16 #include "media/base/timestamp_constants.h" | 16 #include "media/base/timestamp_constants.h" |
| 17 #include "media/filters/opus_constants.h" |
| 17 #include "third_party/opus/src/include/opus.h" | 18 #include "third_party/opus/src/include/opus.h" |
| 18 #include "third_party/opus/src/include/opus_multistream.h" | 19 #include "third_party/opus/src/include/opus_multistream.h" |
| 19 | 20 |
| 20 namespace media { | 21 namespace media { |
| 21 | 22 |
| 22 static uint16 ReadLE16(const uint8* data, size_t data_size, int read_offset) { | 23 static uint16 ReadLE16(const uint8* data, size_t data_size, int read_offset) { |
| 23 uint16 value = 0; | 24 uint16 value = 0; |
| 24 DCHECK_LE(read_offset + sizeof(value), data_size); | 25 DCHECK_LE(read_offset + sizeof(value), data_size); |
| 25 memcpy(&value, data + read_offset, sizeof(value)); | 26 memcpy(&value, data + read_offset, sizeof(value)); |
| 26 return base::ByteSwapToLE16(value); | 27 return base::ByteSwapToLE16(value); |
| 27 } | 28 } |
| 28 | 29 |
| 29 // The Opus specification is part of IETF RFC 6716: | 30 // The Opus specification is part of IETF RFC 6716: |
| 30 // http://tools.ietf.org/html/rfc6716 | 31 // http://tools.ietf.org/html/rfc6716 |
| 31 | 32 |
| 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 | |
| 34 // Specification: | |
| 35 // http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html | |
| 36 static const int kMaxVorbisChannels = 8; | |
| 37 | |
| 38 // Maximum packet size used in Xiph's opusdec and FFmpeg's libopusdec. | 33 // Maximum packet size used in Xiph's opusdec and FFmpeg's libopusdec. |
| 39 static const int kMaxOpusOutputPacketSizeSamples = 960 * 6; | 34 static const int kMaxOpusOutputPacketSizeSamples = 960 * 6; |
| 40 | 35 |
| 41 static void RemapOpusChannelLayout(const uint8* opus_mapping, | 36 static void RemapOpusChannelLayout(const uint8* opus_mapping, |
| 42 int num_channels, | 37 int num_channels, |
| 43 uint8* channel_layout) { | 38 uint8* channel_layout) { |
| 44 DCHECK_LE(num_channels, kMaxVorbisChannels); | 39 DCHECK_LE(num_channels, OPUS_MAX_VORBIS_CHANNELS); |
| 45 | |
| 46 // Opus uses Vorbis channel layout. | |
| 47 const int32 num_layouts = kMaxVorbisChannels; | |
| 48 const int32 num_layout_values = kMaxVorbisChannels; | |
| 49 | |
| 50 // Vorbis channel ordering for streams with >= 2 channels: | |
| 51 // 2 Channels | |
| 52 // L, R | |
| 53 // 3 Channels | |
| 54 // L, Center, R | |
| 55 // 4 Channels | |
| 56 // Front L, Front R, Back L, Back R | |
| 57 // 5 Channels | |
| 58 // Front L, Center, Front R, Back L, Back R | |
| 59 // 6 Channels (5.1) | |
| 60 // Front L, Center, Front R, Back L, Back R, LFE | |
| 61 // 7 channels (6.1) | |
| 62 // Front L, Front Center, Front R, Side L, Side R, Back Center, LFE | |
| 63 // 8 Channels (7.1) | |
| 64 // Front L, Center, Front R, Side L, Side R, Back L, Back R, LFE | |
| 65 // | |
| 66 // Channel ordering information is taken from section 4.3.9 of the Vorbis I | |
| 67 // Specification: | |
| 68 // http://xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-800004.3.9 | |
| 69 | |
| 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] = { | |
| 73 { 0 }, | |
| 74 | |
| 75 // Stereo: No reorder. | |
| 76 { 0, 1 }, | |
| 77 | |
| 78 // 3 Channels, from Vorbis order to: | |
| 79 // L, R, Center | |
| 80 { 0, 2, 1 }, | |
| 81 | |
| 82 // 4 Channels: No reorder. | |
| 83 { 0, 1, 2, 3 }, | |
| 84 | |
| 85 // 5 Channels, from Vorbis order to: | |
| 86 // Front L, Front R, Center, Back L, Back R | |
| 87 { 0, 2, 1, 3, 4 }, | |
| 88 | |
| 89 // 6 Channels (5.1), from Vorbis order to: | |
| 90 // Front L, Front R, Center, LFE, Back L, Back R | |
| 91 { 0, 2, 1, 5, 3, 4 }, | |
| 92 | |
| 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 }, | |
| 96 | |
| 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 }, | |
| 100 }; | |
| 101 | 40 |
| 102 // Reorder the channels to produce the same ordering as FFmpeg, which is | 41 // Reorder the channels to produce the same ordering as FFmpeg, which is |
| 103 // what the pipeline expects. | 42 // what the pipeline expects. |
| 104 const uint8* vorbis_layout_offset = kFFmpegChannelLayouts[num_channels - 1]; | 43 const uint8* vorbis_layout_offset = |
| 44 kFFmpegChannelDecodingLayouts[num_channels - 1]; |
| 105 for (int channel = 0; channel < num_channels; ++channel) | 45 for (int channel = 0; channel < num_channels; ++channel) |
| 106 channel_layout[channel] = opus_mapping[vorbis_layout_offset[channel]]; | 46 channel_layout[channel] = opus_mapping[vorbis_layout_offset[channel]]; |
| 107 } | 47 } |
| 108 | 48 |
| 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) | |
| 118 // | |
| 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 | |
| 123 // - if (C<2*M) | |
| 124 // - stream = byte/2 | |
| 125 // - if (byte&0x1 == 0) | |
| 126 // - left | |
| 127 // else | |
| 128 // - right | |
| 129 // - else | |
| 130 // - stream = byte-M | |
| 131 | |
| 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 | |
| 136 // stream map. | |
| 137 static const int kMaxChannelsWithDefaultLayout = 2; | |
| 138 static const uint8 kDefaultOpusChannelLayout[kMaxChannelsWithDefaultLayout] = { | |
| 139 0, 1 }; | |
| 140 | |
| 141 // Size of the Opus extra data excluding optional mapping information. | |
| 142 static const int kOpusExtraDataSize = 19; | |
| 143 | |
| 144 // Offset to the channel count byte in the Opus extra data. | |
| 145 static const int kOpusExtraDataChannelsOffset = 9; | |
| 146 | |
| 147 // Offset to the pre-skip value in the Opus extra data. | |
| 148 static const int kOpusExtraDataSkipSamplesOffset = 10; | |
| 149 | |
| 150 // Offset to the gain value in the Opus extra data. | |
| 151 static const int kOpusExtraDataGainOffset = 16; | |
| 152 | |
| 153 // Offset to the channel mapping byte in the Opus extra data. | |
| 154 static const int kOpusExtraDataChannelMappingOffset = 18; | |
| 155 | |
| 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 | |
| 162 // values. | |
| 163 static const int kOpusExtraDataNumStreamsOffset = kOpusExtraDataSize; | |
| 164 static const int kOpusExtraDataNumCoupledOffset = | |
| 165 kOpusExtraDataNumStreamsOffset + 1; | |
| 166 static const int kOpusExtraDataStreamMapOffset = | |
| 167 kOpusExtraDataNumStreamsOffset + 2; | |
| 168 | |
| 169 struct OpusExtraData { | 49 struct OpusExtraData { |
| 170 OpusExtraData() | 50 OpusExtraData() |
| 171 : channels(0), | 51 : channels(0), |
| 172 skip_samples(0), | 52 skip_samples(0), |
| 173 channel_mapping(0), | 53 channel_mapping(0), |
| 174 num_streams(0), | 54 num_streams(0), |
| 175 num_coupled(0), | 55 num_coupled(0), |
| 176 gain_db(0), | 56 gain_db(0), |
| 177 stream_map() { | 57 stream_map() { |
| 178 memcpy(stream_map, | 58 memcpy(stream_map, |
| 179 kDefaultOpusChannelLayout, | 59 kDefaultOpusChannelLayout, |
| 180 kMaxChannelsWithDefaultLayout); | 60 OPUS_MAX_CHANNELS_WITH_DEFAULT_LAYOUT); |
| 181 } | 61 } |
| 182 int channels; | 62 int channels; |
| 183 uint16 skip_samples; | 63 uint16 skip_samples; |
| 184 int channel_mapping; | 64 int channel_mapping; |
| 185 int num_streams; | 65 int num_streams; |
| 186 int num_coupled; | 66 int num_coupled; |
| 187 int16 gain_db; | 67 int16 gain_db; |
| 188 uint8 stream_map[kMaxVorbisChannels]; | 68 uint8 stream_map[OPUS_MAX_VORBIS_CHANNELS]; |
| 189 }; | 69 }; |
| 190 | 70 |
| 191 // Returns true when able to successfully parse and store Opus extra data in | 71 // 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, | 72 // |extra_data|. Based on opus header parsing code in libopusdec from FFmpeg, |
| 193 // and opus_header from Xiph's opus-tools project. | 73 // and opus_header from Xiph's opus-tools project. |
| 194 static bool ParseOpusExtraData(const uint8* data, int data_size, | 74 static bool ParseOpusExtraData(const uint8* data, int data_size, |
| 195 const AudioDecoderConfig& config, | 75 const AudioDecoderConfig& config, |
| 196 OpusExtraData* extra_data) { | 76 OpusExtraData* extra_data) { |
| 197 if (data_size < kOpusExtraDataSize) { | 77 if (data_size < OPUS_EXTRADATA_SIZE) { |
| 198 DLOG(ERROR) << "Extra data size is too small:" << data_size; | 78 DLOG(ERROR) << "Extra data size is too small:" << data_size; |
| 199 return false; | 79 return false; |
| 200 } | 80 } |
| 201 | 81 |
| 202 extra_data->channels = *(data + kOpusExtraDataChannelsOffset); | 82 extra_data->channels = *(data + OPUS_EXTRADATA_CHANNELS_OFFSET); |
| 203 | 83 |
| 204 if (extra_data->channels <= 0 || extra_data->channels > kMaxVorbisChannels) { | 84 if (extra_data->channels <= 0 || |
| 85 extra_data->channels > OPUS_MAX_VORBIS_CHANNELS) { |
| 205 DLOG(ERROR) << "invalid channel count in extra data: " | 86 DLOG(ERROR) << "invalid channel count in extra data: " |
| 206 << extra_data->channels; | 87 << extra_data->channels; |
| 207 return false; | 88 return false; |
| 208 } | 89 } |
| 209 | 90 |
| 210 extra_data->skip_samples = | 91 extra_data->skip_samples = |
| 211 ReadLE16(data, data_size, kOpusExtraDataSkipSamplesOffset); | 92 ReadLE16(data, data_size, OPUS_EXTRADATA_SKIP_SAMPLES_OFFSET); |
| 212 extra_data->gain_db = static_cast<int16>( | 93 extra_data->gain_db = |
| 213 ReadLE16(data, data_size, kOpusExtraDataGainOffset)); | 94 static_cast<int16>(ReadLE16(data, data_size, OPUS_EXTRADATA_GAIN_OFFSET)); |
| 214 | 95 |
| 215 extra_data->channel_mapping = *(data + kOpusExtraDataChannelMappingOffset); | 96 extra_data->channel_mapping = *(data + OPUS_EXTRADATA_CHANNEL_MAPPING_OFFSET); |
| 216 | 97 |
| 217 if (!extra_data->channel_mapping) { | 98 if (!extra_data->channel_mapping) { |
| 218 if (extra_data->channels > kMaxChannelsWithDefaultLayout) { | 99 if (extra_data->channels > OPUS_MAX_CHANNELS_WITH_DEFAULT_LAYOUT) { |
| 219 DLOG(ERROR) << "Invalid extra data, missing stream map."; | 100 DLOG(ERROR) << "Invalid extra data, missing stream map."; |
| 220 return false; | 101 return false; |
| 221 } | 102 } |
| 222 | 103 |
| 223 extra_data->num_streams = 1; | 104 extra_data->num_streams = 1; |
| 224 extra_data->num_coupled = | 105 extra_data->num_coupled = |
| 225 (ChannelLayoutToChannelCount(config.channel_layout()) > 1) ? 1 : 0; | 106 (ChannelLayoutToChannelCount(config.channel_layout()) > 1) ? 1 : 0; |
| 226 return true; | 107 return true; |
| 227 } | 108 } |
| 228 | 109 |
| 229 if (data_size < kOpusExtraDataStreamMapOffset + extra_data->channels) { | 110 if (data_size < OPUS_EXTRADATA_STREAM_MAP_OFFSET + extra_data->channels) { |
| 230 DLOG(ERROR) << "Invalid stream map; insufficient data for current channel " | 111 DLOG(ERROR) << "Invalid stream map; insufficient data for current channel " |
| 231 << "count: " << extra_data->channels; | 112 << "count: " << extra_data->channels; |
| 232 return false; | 113 return false; |
| 233 } | 114 } |
| 234 | 115 |
| 235 extra_data->num_streams = *(data + kOpusExtraDataNumStreamsOffset); | 116 extra_data->num_streams = *(data + OPUS_EXTRADATA_NUM_STREAMS_OFFSET); |
| 236 extra_data->num_coupled = *(data + kOpusExtraDataNumCoupledOffset); | 117 extra_data->num_coupled = *(data + OPUS_EXTRADATA_NUM_COUPLED_OFFSET); |
| 237 | 118 |
| 238 if (extra_data->num_streams + extra_data->num_coupled != extra_data->channels) | 119 if (extra_data->num_streams + extra_data->num_coupled != extra_data->channels) |
| 239 DVLOG(1) << "Inconsistent channel mapping."; | 120 DVLOG(1) << "Inconsistent channel mapping."; |
| 240 | 121 |
| 241 for (int i = 0; i < extra_data->channels; ++i) | 122 for (int i = 0; i < extra_data->channels; ++i) |
| 242 extra_data->stream_map[i] = *(data + kOpusExtraDataStreamMapOffset + i); | 123 extra_data->stream_map[i] = *(data + OPUS_EXTRADATA_STREAM_MAP_OFFSET + i); |
| 243 return true; | 124 return true; |
| 244 } | 125 } |
| 245 | 126 |
| 246 OpusAudioDecoder::OpusAudioDecoder( | 127 OpusAudioDecoder::OpusAudioDecoder( |
| 247 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) | 128 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) |
| 248 : task_runner_(task_runner), opus_decoder_(nullptr) {} | 129 : task_runner_(task_runner), opus_decoder_(nullptr) {} |
| 249 | 130 |
| 250 std::string OpusAudioDecoder::GetDisplayName() const { | 131 std::string OpusAudioDecoder::GetDisplayName() const { |
| 251 return "OpusAudioDecoder"; | 132 return "OpusAudioDecoder"; |
| 252 } | 133 } |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 } | 217 } |
| 337 | 218 |
| 338 bool OpusAudioDecoder::ConfigureDecoder() { | 219 bool OpusAudioDecoder::ConfigureDecoder() { |
| 339 if (config_.codec() != kCodecOpus) { | 220 if (config_.codec() != kCodecOpus) { |
| 340 DVLOG(1) << "Codec must be kCodecOpus."; | 221 DVLOG(1) << "Codec must be kCodecOpus."; |
| 341 return false; | 222 return false; |
| 342 } | 223 } |
| 343 | 224 |
| 344 const int channel_count = | 225 const int channel_count = |
| 345 ChannelLayoutToChannelCount(config_.channel_layout()); | 226 ChannelLayoutToChannelCount(config_.channel_layout()); |
| 346 if (!config_.IsValidConfig() || channel_count > kMaxVorbisChannels) { | 227 if (!config_.IsValidConfig() || channel_count > OPUS_MAX_VORBIS_CHANNELS) { |
| 347 DLOG(ERROR) << "Invalid or unsupported audio stream -" | 228 DLOG(ERROR) << "Invalid or unsupported audio stream -" |
| 348 << " codec: " << config_.codec() | 229 << " codec: " << config_.codec() |
| 349 << " channel count: " << channel_count | 230 << " channel count: " << channel_count |
| 350 << " channel layout: " << config_.channel_layout() | 231 << " channel layout: " << config_.channel_layout() |
| 351 << " bits per channel: " << config_.bits_per_channel() | 232 << " bits per channel: " << config_.bits_per_channel() |
| 352 << " samples per second: " << config_.samples_per_second(); | 233 << " samples per second: " << config_.samples_per_second(); |
| 353 return false; | 234 return false; |
| 354 } | 235 } |
| 355 | 236 |
| 356 if (config_.is_encrypted()) { | 237 if (config_.is_encrypted()) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 376 return false; | 257 return false; |
| 377 } | 258 } |
| 378 | 259 |
| 379 if (config_.codec_delay() != opus_extra_data.skip_samples) { | 260 if (config_.codec_delay() != opus_extra_data.skip_samples) { |
| 380 DLOG(ERROR) << "Invalid file. Codec Delay in container does not match the " | 261 DLOG(ERROR) << "Invalid file. Codec Delay in container does not match the " |
| 381 << "value in Opus Extra Data. " << config_.codec_delay() | 262 << "value in Opus Extra Data. " << config_.codec_delay() |
| 382 << " vs " << opus_extra_data.skip_samples; | 263 << " vs " << opus_extra_data.skip_samples; |
| 383 return false; | 264 return false; |
| 384 } | 265 } |
| 385 | 266 |
| 386 uint8 channel_mapping[kMaxVorbisChannels] = {0}; | 267 uint8 channel_mapping[OPUS_MAX_VORBIS_CHANNELS] = {0}; |
| 387 memcpy(&channel_mapping, | 268 memcpy(&channel_mapping, |
| 388 kDefaultOpusChannelLayout, | 269 kDefaultOpusChannelLayout, |
| 389 kMaxChannelsWithDefaultLayout); | 270 OPUS_MAX_CHANNELS_WITH_DEFAULT_LAYOUT); |
| 390 | 271 |
| 391 if (channel_count > kMaxChannelsWithDefaultLayout) { | 272 if (channel_count > OPUS_MAX_CHANNELS_WITH_DEFAULT_LAYOUT) { |
| 392 RemapOpusChannelLayout(opus_extra_data.stream_map, | 273 RemapOpusChannelLayout(opus_extra_data.stream_map, |
| 393 channel_count, | 274 channel_count, |
| 394 channel_mapping); | 275 channel_mapping); |
| 395 } | 276 } |
| 396 | 277 |
| 397 // Init Opus. | 278 // Init Opus. |
| 398 int status = OPUS_INVALID_STATE; | 279 int status = OPUS_INVALID_STATE; |
| 399 opus_decoder_ = opus_multistream_decoder_create(config_.samples_per_second(), | 280 opus_decoder_ = opus_multistream_decoder_create(config_.samples_per_second(), |
| 400 channel_count, | 281 channel_count, |
| 401 opus_extra_data.num_streams, | 282 opus_extra_data.num_streams, |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 output_buffer->get()->TrimEnd(trim_frames); | 354 output_buffer->get()->TrimEnd(trim_frames); |
| 474 | 355 |
| 475 // Handles discards and timestamping. Discard the buffer if more data needed. | 356 // Handles discards and timestamping. Discard the buffer if more data needed. |
| 476 if (!discard_helper_->ProcessBuffers(input, *output_buffer)) | 357 if (!discard_helper_->ProcessBuffers(input, *output_buffer)) |
| 477 *output_buffer = nullptr; | 358 *output_buffer = nullptr; |
| 478 | 359 |
| 479 return true; | 360 return true; |
| 480 } | 361 } |
| 481 | 362 |
| 482 } // namespace media | 363 } // namespace media |
| OLD | NEW |