OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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_header_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 kMaxChannelsWithDefaultLayout); |
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 > kMaxChannelsWithDefaultLayout) { |
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 kMaxChannelsWithDefaultLayout); |
390 | 271 |
391 if (channel_count > kMaxChannelsWithDefaultLayout) { | 272 if (channel_count > kMaxChannelsWithDefaultLayout) { |
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 |
(...skipping 76 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 |