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 "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
9 #include "base/location.h" | 9 #include "base/location.h" |
10 #include "base/message_loop/message_loop_proxy.h" | 10 #include "base/message_loop/message_loop_proxy.h" |
(...skipping 13 matching lines...) Expand all Loading... |
24 | 24 |
25 static uint16 ReadLE16(const uint8* data, size_t data_size, int read_offset) { | 25 static uint16 ReadLE16(const uint8* data, size_t data_size, int read_offset) { |
26 DCHECK(data); | 26 DCHECK(data); |
27 uint16 value = 0; | 27 uint16 value = 0; |
28 DCHECK_LE(read_offset + sizeof(value), data_size); | 28 DCHECK_LE(read_offset + sizeof(value), data_size); |
29 memcpy(&value, data + read_offset, sizeof(value)); | 29 memcpy(&value, data + read_offset, sizeof(value)); |
30 return base::ByteSwapToLE16(value); | 30 return base::ByteSwapToLE16(value); |
31 } | 31 } |
32 | 32 |
33 // Returns true if the decode result was end of stream. | 33 // Returns true if the decode result was end of stream. |
34 static inline bool IsEndOfStream(int decoded_size, | 34 static inline bool is_end_of_stream(int decoded_size, |
35 const scoped_refptr<DecoderBuffer>& input) { | 35 const scoped_refptr<DecoderBuffer>& input) { |
36 // Two conditions to meet to declare end of stream for this decoder: | 36 // Two conditions to meet to declare end of stream for this decoder: |
37 // 1. Opus didn't output anything. | 37 // 1. Opus didn't output anything. |
38 // 2. An end of stream buffer is received. | 38 // 2. An end of stream buffer is received. |
39 return decoded_size == 0 && input->IsEndOfStream(); | 39 return decoded_size == 0 && input->is_end_of_stream(); |
40 } | 40 } |
41 | 41 |
42 // The Opus specification is part of IETF RFC 6716: | 42 // The Opus specification is part of IETF RFC 6716: |
43 // http://tools.ietf.org/html/rfc6716 | 43 // http://tools.ietf.org/html/rfc6716 |
44 | 44 |
45 // Opus uses Vorbis channel mapping, and Vorbis channel mapping specifies | 45 // Opus uses Vorbis channel mapping, and Vorbis channel mapping specifies |
46 // mappings for up to 8 channels. This information is part of the Vorbis I | 46 // mappings for up to 8 channels. This information is part of the Vorbis I |
47 // Specification: | 47 // Specification: |
48 // http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html | 48 // http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html |
49 static const int kMaxVorbisChannels = 8; | 49 static const int kMaxVorbisChannels = 8; |
50 | 50 |
51 // Opus allows for decode of S16 or float samples. OpusAudioDecoder always uses | 51 // Opus allows for decode of S16 or float samples. OpusAudioDecoder always uses |
52 // S16 samples. | 52 // S16 samples. |
53 static const int kBitsPerChannel = 16; | 53 static const int kBitsPerChannel = 16; |
54 static const int kBytesPerChannel = kBitsPerChannel / 8; | 54 static const int kBytesPerChannel = kBitsPerChannel / 8; |
55 | 55 |
56 // Maximum packet size used in Xiph's opusdec and FFmpeg's libopusdec. | 56 // Maximum packet size used in Xiph's opusdec and FFmpeg's libopusdec. |
57 static const int kMaxOpusOutputPacketSizeSamples = 960 * 6 * kMaxVorbisChannels; | 57 static const int kMaxOpusOutputPacketSizeSamples = 960 * 6 * kMaxVorbisChannels; |
58 static const int kMaxOpusOutputPacketSizeBytes = | 58 static const int kMaxOpusOutputPacketSizeBytes = |
59 kMaxOpusOutputPacketSizeSamples * kBytesPerChannel; | 59 kMaxOpusOutputPacketSizeSamples * kBytesPerChannel; |
60 | 60 |
61 static void RemapOpusChannelLayout(const uint8* opus_mapping, | 61 static void RemapOpusChannelLayout(const uint8* opus_mapping, int num_channels, |
62 int num_channels, | |
63 uint8* channel_layout) { | 62 uint8* channel_layout) { |
64 DCHECK_LE(num_channels, kMaxVorbisChannels); | 63 DCHECK_LE(num_channels, kMaxVorbisChannels); |
65 | 64 |
66 // Opus uses Vorbis channel layout. | 65 // Opus uses Vorbis channel layout. |
67 const int32 num_layouts = kMaxVorbisChannels; | 66 const int32 num_layouts = kMaxVorbisChannels; |
68 const int32 num_layout_values = kMaxVorbisChannels; | 67 const int32 num_layout_values = kMaxVorbisChannels; |
69 | 68 |
70 // Vorbis channel ordering for streams with >= 2 channels: | 69 // Vorbis channel ordering for streams with >= 2 channels: |
71 // 2 Channels | 70 // 2 Channels |
72 // L, R | 71 // L, R |
(...skipping 10 matching lines...) Expand all Loading... |
83 // 8 Channels (7.1) | 82 // 8 Channels (7.1) |
84 // Front L, Center, Front R, Side L, Side R, Back L, Back R, LFE | 83 // Front L, Center, Front R, Side L, Side R, Back L, Back R, LFE |
85 // | 84 // |
86 // Channel ordering information is taken from section 4.3.9 of the Vorbis I | 85 // Channel ordering information is taken from section 4.3.9 of the Vorbis I |
87 // Specification: | 86 // Specification: |
88 // http://xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-800004.3.9 | 87 // http://xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-800004.3.9 |
89 | 88 |
90 // These are the FFmpeg channel layouts expressed using the position of each | 89 // These are the FFmpeg channel layouts expressed using the position of each |
91 // channel in the output stream from libopus. | 90 // channel in the output stream from libopus. |
92 const uint8 kFFmpegChannelLayouts[num_layouts][num_layout_values] = { | 91 const uint8 kFFmpegChannelLayouts[num_layouts][num_layout_values] = { |
93 { 0 }, | 92 {0}, |
94 | 93 |
95 // Stereo: No reorder. | 94 // Stereo: No reorder. |
96 { 0, 1 }, | 95 {0, 1}, |
97 | 96 |
98 // 3 Channels, from Vorbis order to: | 97 // 3 Channels, from Vorbis order to: |
99 // L, R, Center | 98 // L, R, Center |
100 { 0, 2, 1 }, | 99 {0, 2, 1}, |
101 | 100 |
102 // 4 Channels: No reorder. | 101 // 4 Channels: No reorder. |
103 { 0, 1, 2, 3 }, | 102 {0, 1, 2, 3}, |
104 | 103 |
105 // 5 Channels, from Vorbis order to: | 104 // 5 Channels, from Vorbis order to: |
106 // Front L, Front R, Center, Back L, Back R | 105 // Front L, Front R, Center, Back L, Back R |
107 { 0, 2, 1, 3, 4 }, | 106 {0, 2, 1, 3, 4}, |
108 | 107 |
109 // 6 Channels (5.1), from Vorbis order to: | 108 // 6 Channels (5.1), from Vorbis order to: |
110 // Front L, Front R, Center, LFE, Back L, Back R | 109 // Front L, Front R, Center, LFE, Back L, Back R |
111 { 0, 2, 1, 5, 3, 4 }, | 110 {0, 2, 1, 5, 3, 4}, |
112 | 111 |
113 // 7 Channels (6.1), from Vorbis order to: | 112 // 7 Channels (6.1), from Vorbis order to: |
114 // Front L, Front R, Front Center, LFE, Side L, Side R, Back Center | 113 // Front L, Front R, Front Center, LFE, Side L, Side R, Back Center |
115 { 0, 2, 1, 6, 3, 4, 5 }, | 114 {0, 2, 1, 6, 3, 4, 5}, |
116 | 115 |
117 // 8 Channels (7.1), from Vorbis order to: | 116 // 8 Channels (7.1), from Vorbis order to: |
118 // Front L, Front R, Center, LFE, Back L, Back R, Side L, Side R | 117 // Front L, Front R, Center, LFE, Back L, Back R, Side L, Side R |
119 { 0, 2, 1, 7, 5, 6, 3, 4 }, | 118 {0, 2, 1, 7, 5, 6, 3, 4}, |
120 }; | 119 }; |
121 | 120 |
122 // Reorder the channels to produce the same ordering as FFmpeg, which is | 121 // Reorder the channels to produce the same ordering as FFmpeg, which is |
123 // what the pipeline expects. | 122 // what the pipeline expects. |
124 const uint8* vorbis_layout_offset = kFFmpegChannelLayouts[num_channels - 1]; | 123 const uint8* vorbis_layout_offset = kFFmpegChannelLayouts[num_channels - 1]; |
125 for (int channel = 0; channel < num_channels; ++channel) | 124 for (int channel = 0; channel < num_channels; ++channel) |
126 channel_layout[channel] = opus_mapping[vorbis_layout_offset[channel]]; | 125 channel_layout[channel] = opus_mapping[vorbis_layout_offset[channel]]; |
127 } | 126 } |
128 | 127 |
129 // Opus Header contents: | 128 // Opus Header contents: |
(...skipping 18 matching lines...) Expand all Loading... |
148 // - right | 147 // - right |
149 // - else | 148 // - else |
150 // - stream = byte-M | 149 // - stream = byte-M |
151 | 150 |
152 // Default audio output channel layout. Used to initialize |stream_map| in | 151 // Default audio output channel layout. Used to initialize |stream_map| in |
153 // OpusHeader, and passed to opus_multistream_decoder_create() when the header | 152 // OpusHeader, and passed to opus_multistream_decoder_create() when the header |
154 // does not contain mapping information. The values are valid only for mono and | 153 // does not contain mapping information. The values are valid only for mono and |
155 // stereo output: Opus streams with more than 2 channels require a stream map. | 154 // stereo output: Opus streams with more than 2 channels require a stream map. |
156 static const int kMaxChannelsWithDefaultLayout = 2; | 155 static const int kMaxChannelsWithDefaultLayout = 2; |
157 static const uint8 kDefaultOpusChannelLayout[kMaxChannelsWithDefaultLayout] = { | 156 static const uint8 kDefaultOpusChannelLayout[kMaxChannelsWithDefaultLayout] = { |
158 0, 1 }; | 157 0, 1 |
| 158 }; |
159 | 159 |
160 // Size of the Opus header excluding optional mapping information. | 160 // Size of the Opus header excluding optional mapping information. |
161 static const int kOpusHeaderSize = 19; | 161 static const int kOpusHeaderSize = 19; |
162 | 162 |
163 // Offset to the channel count byte in the Opus header. | 163 // Offset to the channel count byte in the Opus header. |
164 static const int kOpusHeaderChannelsOffset = 9; | 164 static const int kOpusHeaderChannelsOffset = 9; |
165 | 165 |
166 // Offset to the pre-skip value in the Opus header. | 166 // Offset to the pre-skip value in the Opus header. |
167 static const int kOpusHeaderSkipSamplesOffset = 10; | 167 static const int kOpusHeaderSkipSamplesOffset = 10; |
168 | 168 |
(...skipping 10 matching lines...) Expand all Loading... |
179 static const int kOpusHeaderNumCoupledOffset = kOpusHeaderNumStreamsOffset + 1; | 179 static const int kOpusHeaderNumCoupledOffset = kOpusHeaderNumStreamsOffset + 1; |
180 static const int kOpusHeaderStreamMapOffset = kOpusHeaderNumStreamsOffset + 2; | 180 static const int kOpusHeaderStreamMapOffset = kOpusHeaderNumStreamsOffset + 2; |
181 | 181 |
182 struct OpusHeader { | 182 struct OpusHeader { |
183 OpusHeader() | 183 OpusHeader() |
184 : channels(0), | 184 : channels(0), |
185 skip_samples(0), | 185 skip_samples(0), |
186 channel_mapping(0), | 186 channel_mapping(0), |
187 num_streams(0), | 187 num_streams(0), |
188 num_coupled(0) { | 188 num_coupled(0) { |
189 memcpy(stream_map, | 189 memcpy(stream_map, kDefaultOpusChannelLayout, |
190 kDefaultOpusChannelLayout, | |
191 kMaxChannelsWithDefaultLayout); | 190 kMaxChannelsWithDefaultLayout); |
192 } | 191 } |
193 int channels; | 192 int channels; |
194 int skip_samples; | 193 int skip_samples; |
195 int channel_mapping; | 194 int channel_mapping; |
196 int num_streams; | 195 int num_streams; |
197 int num_coupled; | 196 int num_coupled; |
198 uint8 stream_map[kMaxVorbisChannels]; | 197 uint8 stream_map[kMaxVorbisChannels]; |
199 }; | 198 }; |
200 | 199 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 const scoped_refptr<base::MessageLoopProxy>& message_loop) | 243 const scoped_refptr<base::MessageLoopProxy>& message_loop) |
245 : message_loop_(message_loop), | 244 : message_loop_(message_loop), |
246 weak_factory_(this), | 245 weak_factory_(this), |
247 demuxer_stream_(NULL), | 246 demuxer_stream_(NULL), |
248 opus_decoder_(NULL), | 247 opus_decoder_(NULL), |
249 bits_per_channel_(0), | 248 bits_per_channel_(0), |
250 channel_layout_(CHANNEL_LAYOUT_NONE), | 249 channel_layout_(CHANNEL_LAYOUT_NONE), |
251 samples_per_second_(0), | 250 samples_per_second_(0), |
252 last_input_timestamp_(kNoTimestamp()), | 251 last_input_timestamp_(kNoTimestamp()), |
253 output_bytes_to_drop_(0), | 252 output_bytes_to_drop_(0), |
254 skip_samples_(0) { | 253 skip_samples_(0) {} |
255 } | |
256 | 254 |
257 void OpusAudioDecoder::Initialize( | 255 void OpusAudioDecoder::Initialize(DemuxerStream* stream, |
258 DemuxerStream* stream, | 256 const PipelineStatusCB& status_cb, |
259 const PipelineStatusCB& status_cb, | 257 const StatisticsCB& statistics_cb) { |
260 const StatisticsCB& statistics_cb) { | |
261 DCHECK(message_loop_->BelongsToCurrentThread()); | 258 DCHECK(message_loop_->BelongsToCurrentThread()); |
262 PipelineStatusCB initialize_cb = BindToCurrentLoop(status_cb); | 259 PipelineStatusCB initialize_cb = BindToCurrentLoop(status_cb); |
263 | 260 |
264 if (demuxer_stream_) { | 261 if (demuxer_stream_) { |
265 // TODO(scherkus): initialization currently happens more than once in | 262 // TODO(scherkus): initialization currently happens more than once in |
266 // PipelineIntegrationTest.BasicPlayback. | 263 // PipelineIntegrationTest.BasicPlayback. |
267 LOG(ERROR) << "Initialize has already been called."; | 264 LOG(ERROR) << "Initialize has already been called."; |
268 CHECK(false); | 265 CHECK(false); |
269 } | 266 } |
270 | 267 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 // TODO(scherkus): should we require Stop() to be called? this might end up | 314 // TODO(scherkus): should we require Stop() to be called? this might end up |
318 // getting called on a random thread due to refcounting. | 315 // getting called on a random thread due to refcounting. |
319 CloseDecoder(); | 316 CloseDecoder(); |
320 } | 317 } |
321 | 318 |
322 void OpusAudioDecoder::ReadFromDemuxerStream() { | 319 void OpusAudioDecoder::ReadFromDemuxerStream() { |
323 DCHECK(!read_cb_.is_null()); | 320 DCHECK(!read_cb_.is_null()); |
324 demuxer_stream_->Read(base::Bind(&OpusAudioDecoder::BufferReady, weak_this_)); | 321 demuxer_stream_->Read(base::Bind(&OpusAudioDecoder::BufferReady, weak_this_)); |
325 } | 322 } |
326 | 323 |
327 void OpusAudioDecoder::BufferReady( | 324 void OpusAudioDecoder::BufferReady(DemuxerStream::Status status, |
328 DemuxerStream::Status status, | 325 const scoped_refptr<DecoderBuffer>& input) { |
329 const scoped_refptr<DecoderBuffer>& input) { | |
330 DCHECK(message_loop_->BelongsToCurrentThread()); | 326 DCHECK(message_loop_->BelongsToCurrentThread()); |
331 DCHECK(!read_cb_.is_null()); | 327 DCHECK(!read_cb_.is_null()); |
332 DCHECK_EQ(status != DemuxerStream::kOk, !input.get()) << status; | 328 DCHECK_EQ(status != DemuxerStream::kOk, !input.get()) << status; |
333 | 329 |
334 if (status == DemuxerStream::kAborted) { | 330 if (status == DemuxerStream::kAborted) { |
335 DCHECK(!input.get()); | 331 DCHECK(!input.get()); |
336 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); | 332 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); |
337 return; | 333 return; |
338 } | 334 } |
339 | 335 |
340 if (status == DemuxerStream::kConfigChanged) { | 336 if (status == DemuxerStream::kConfigChanged) { |
341 DCHECK(!input.get()); | 337 DCHECK(!input.get()); |
342 DVLOG(1) << "Config changed."; | 338 DVLOG(1) << "Config changed."; |
343 | 339 |
344 if (!ConfigureDecoder()) { | 340 if (!ConfigureDecoder()) { |
345 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); | 341 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); |
346 return; | 342 return; |
347 } | 343 } |
348 | 344 |
349 ResetTimestampState(); | 345 ResetTimestampState(); |
350 ReadFromDemuxerStream(); | 346 ReadFromDemuxerStream(); |
351 return; | 347 return; |
352 } | 348 } |
353 | 349 |
354 DCHECK_EQ(status, DemuxerStream::kOk); | 350 DCHECK_EQ(status, DemuxerStream::kOk); |
355 DCHECK(input.get()); | 351 DCHECK(input.get()); |
356 | 352 |
357 // Libopus does not buffer output. Decoding is complete when an end of stream | 353 // Libopus does not buffer output. Decoding is complete when an end of stream |
358 // input buffer is received. | 354 // input buffer is received. |
359 if (input->IsEndOfStream()) { | 355 if (input->is_end_of_stream()) { |
360 base::ResetAndReturn(&read_cb_).Run(kOk, DataBuffer::create_eos_buffer()); | 356 base::ResetAndReturn(&read_cb_).Run(kOk, DataBuffer::create_eos_buffer()); |
361 return; | 357 return; |
362 } | 358 } |
363 | 359 |
364 // Make sure we are notified if http://crbug.com/49709 returns. Issue also | 360 // Make sure we are notified if http://crbug.com/49709 returns. Issue also |
365 // occurs with some damaged files. | 361 // occurs with some damaged files. |
366 if (input->GetTimestamp() == kNoTimestamp() && | 362 if (input->get_timestamp() == kNoTimestamp() && |
367 output_timestamp_helper_->base_timestamp() == kNoTimestamp()) { | 363 output_timestamp_helper_->base_timestamp() == kNoTimestamp()) { |
368 DVLOG(1) << "Received a buffer without timestamps!"; | 364 DVLOG(1) << "Received a buffer without timestamps!"; |
369 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); | 365 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); |
370 return; | 366 return; |
371 } | 367 } |
372 | 368 |
373 if (last_input_timestamp_ != kNoTimestamp() && | 369 if (last_input_timestamp_ != kNoTimestamp() && |
374 input->GetTimestamp() != kNoTimestamp() && | 370 input->get_timestamp() != kNoTimestamp() && |
375 input->GetTimestamp() < last_input_timestamp_) { | 371 input->get_timestamp() < last_input_timestamp_) { |
376 base::TimeDelta diff = input->GetTimestamp() - last_input_timestamp_; | 372 base::TimeDelta diff = input->get_timestamp() - last_input_timestamp_; |
377 DVLOG(1) << "Input timestamps are not monotonically increasing! " | 373 DVLOG(1) << "Input timestamps are not monotonically increasing! " |
378 << " ts " << input->GetTimestamp().InMicroseconds() << " us" | 374 << " ts " << input->get_timestamp().InMicroseconds() << " us" |
379 << " diff " << diff.InMicroseconds() << " us"; | 375 << " diff " << diff.InMicroseconds() << " us"; |
380 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); | 376 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); |
381 return; | 377 return; |
382 } | 378 } |
383 | 379 |
384 last_input_timestamp_ = input->GetTimestamp(); | 380 last_input_timestamp_ = input->get_timestamp(); |
385 | 381 |
386 scoped_refptr<DataBuffer> output_buffer; | 382 scoped_refptr<DataBuffer> output_buffer; |
387 | 383 |
388 if (!Decode(input, &output_buffer)) { | 384 if (!Decode(input, &output_buffer)) { |
389 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); | 385 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); |
390 return; | 386 return; |
391 } | 387 } |
392 | 388 |
393 if (output_buffer.get()) { | 389 if (output_buffer.get()) { |
394 // Execute callback to return the decoded audio. | 390 // Execute callback to return the decoded audio. |
(...skipping 28 matching lines...) Expand all Loading... |
423 if (config.bits_per_channel() != kBitsPerChannel) { | 419 if (config.bits_per_channel() != kBitsPerChannel) { |
424 DLOG(ERROR) << "16 bit samples required."; | 420 DLOG(ERROR) << "16 bit samples required."; |
425 return false; | 421 return false; |
426 } | 422 } |
427 | 423 |
428 if (config.is_encrypted()) { | 424 if (config.is_encrypted()) { |
429 DLOG(ERROR) << "Encrypted audio stream not supported."; | 425 DLOG(ERROR) << "Encrypted audio stream not supported."; |
430 return false; | 426 return false; |
431 } | 427 } |
432 | 428 |
433 if (opus_decoder_ && | 429 if (opus_decoder_ && (bits_per_channel_ != config.bits_per_channel() || |
434 (bits_per_channel_ != config.bits_per_channel() || | 430 channel_layout_ != config.channel_layout() || |
435 channel_layout_ != config.channel_layout() || | 431 samples_per_second_ != config.samples_per_second())) { |
436 samples_per_second_ != config.samples_per_second())) { | |
437 DVLOG(1) << "Unsupported config change :"; | 432 DVLOG(1) << "Unsupported config change :"; |
438 DVLOG(1) << "\tbits_per_channel : " << bits_per_channel_ | 433 DVLOG(1) << "\tbits_per_channel : " << bits_per_channel_ << " -> " |
439 << " -> " << config.bits_per_channel(); | 434 << config.bits_per_channel(); |
440 DVLOG(1) << "\tchannel_layout : " << channel_layout_ | 435 DVLOG(1) << "\tchannel_layout : " << channel_layout_ << " -> " |
441 << " -> " << config.channel_layout(); | 436 << config.channel_layout(); |
442 DVLOG(1) << "\tsample_rate : " << samples_per_second_ | 437 DVLOG(1) << "\tsample_rate : " << samples_per_second_ << " -> " |
443 << " -> " << config.samples_per_second(); | 438 << config.samples_per_second(); |
444 return false; | 439 return false; |
445 } | 440 } |
446 | 441 |
447 // Clean up existing decoder if necessary. | 442 // Clean up existing decoder if necessary. |
448 CloseDecoder(); | 443 CloseDecoder(); |
449 | 444 |
450 // Allocate the output buffer if necessary. | 445 // Allocate the output buffer if necessary. |
451 if (!output_buffer_) | 446 if (!output_buffer_) |
452 output_buffer_.reset(new int16[kMaxOpusOutputPacketSizeSamples]); | 447 output_buffer_.reset(new int16[kMaxOpusOutputPacketSizeSamples]); |
453 | 448 |
454 // Parse the Opus header. | 449 // Parse the Opus header. |
455 OpusHeader opus_header; | 450 OpusHeader opus_header; |
456 ParseOpusHeader(config.extra_data(), config.extra_data_size(), | 451 ParseOpusHeader(config.extra_data(), config.extra_data_size(), config, |
457 config, | |
458 &opus_header); | 452 &opus_header); |
459 | 453 |
460 skip_samples_ = opus_header.skip_samples; | 454 skip_samples_ = opus_header.skip_samples; |
461 | 455 |
462 if (skip_samples_ > 0) | 456 if (skip_samples_ > 0) |
463 output_bytes_to_drop_ = skip_samples_ * config.bytes_per_frame(); | 457 output_bytes_to_drop_ = skip_samples_ * config.bytes_per_frame(); |
464 | 458 |
465 uint8 channel_mapping[kMaxVorbisChannels]; | 459 uint8 channel_mapping[kMaxVorbisChannels]; |
466 memcpy(&channel_mapping, | 460 memcpy(&channel_mapping, kDefaultOpusChannelLayout, |
467 kDefaultOpusChannelLayout, | |
468 kMaxChannelsWithDefaultLayout); | 461 kMaxChannelsWithDefaultLayout); |
469 | 462 |
470 if (channel_count > kMaxChannelsWithDefaultLayout) { | 463 if (channel_count > kMaxChannelsWithDefaultLayout) { |
471 RemapOpusChannelLayout(opus_header.stream_map, | 464 RemapOpusChannelLayout(opus_header.stream_map, channel_count, |
472 channel_count, | |
473 channel_mapping); | 465 channel_mapping); |
474 } | 466 } |
475 | 467 |
476 // Init Opus. | 468 // Init Opus. |
477 int status = OPUS_INVALID_STATE; | 469 int status = OPUS_INVALID_STATE; |
478 opus_decoder_ = opus_multistream_decoder_create(config.samples_per_second(), | 470 opus_decoder_ = opus_multistream_decoder_create( |
479 channel_count, | 471 config.samples_per_second(), channel_count, opus_header.num_streams, |
480 opus_header.num_streams, | 472 opus_header.num_coupled, channel_mapping, &status); |
481 opus_header.num_coupled, | |
482 channel_mapping, | |
483 &status); | |
484 if (!opus_decoder_ || status != OPUS_OK) { | 473 if (!opus_decoder_ || status != OPUS_OK) { |
485 LOG(ERROR) << "opus_multistream_decoder_create failed status=" | 474 LOG(ERROR) << "opus_multistream_decoder_create failed status=" |
486 << opus_strerror(status); | 475 << opus_strerror(status); |
487 return false; | 476 return false; |
488 } | 477 } |
489 | 478 |
490 // TODO(tomfinegan): Handle audio delay once the matroska spec is updated | 479 // TODO(tomfinegan): Handle audio delay once the matroska spec is updated |
491 // to represent the value. | 480 // to represent the value. |
492 | 481 |
493 bits_per_channel_ = config.bits_per_channel(); | 482 bits_per_channel_ = config.bits_per_channel(); |
(...skipping 12 matching lines...) Expand all Loading... |
506 } | 495 } |
507 | 496 |
508 void OpusAudioDecoder::ResetTimestampState() { | 497 void OpusAudioDecoder::ResetTimestampState() { |
509 output_timestamp_helper_->SetBaseTimestamp(kNoTimestamp()); | 498 output_timestamp_helper_->SetBaseTimestamp(kNoTimestamp()); |
510 last_input_timestamp_ = kNoTimestamp(); | 499 last_input_timestamp_ = kNoTimestamp(); |
511 output_bytes_to_drop_ = 0; | 500 output_bytes_to_drop_ = 0; |
512 } | 501 } |
513 | 502 |
514 bool OpusAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& input, | 503 bool OpusAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& input, |
515 scoped_refptr<DataBuffer>* output_buffer) { | 504 scoped_refptr<DataBuffer>* output_buffer) { |
516 const int samples_decoded = | 505 const int samples_decoded = opus_multistream_decode( |
517 opus_multistream_decode(opus_decoder_, | 506 opus_decoder_, input->get_data(), input->get_data_size(), |
518 input->GetData(), input->GetDataSize(), | 507 &output_buffer_[0], kMaxOpusOutputPacketSizeSamples, 0); |
519 &output_buffer_[0], | |
520 kMaxOpusOutputPacketSizeSamples, | |
521 0); | |
522 if (samples_decoded < 0) { | 508 if (samples_decoded < 0) { |
523 LOG(ERROR) << "opus_multistream_decode failed for" | 509 LOG(ERROR) << "opus_multistream_decode failed for" |
524 << " timestamp: " << input->GetTimestamp().InMicroseconds() | 510 << " timestamp: " << input->get_timestamp().InMicroseconds() |
525 << " us, duration: " << input->GetDuration().InMicroseconds() | 511 << " us, duration: " << input->get_duration().InMicroseconds() |
526 << " us, packet size: " << input->GetDataSize() << " bytes with" | 512 << " us, packet size: " << input->get_data_size() |
| 513 << " bytes with" |
527 << " status: " << opus_strerror(samples_decoded); | 514 << " status: " << opus_strerror(samples_decoded); |
528 return false; | 515 return false; |
529 } | 516 } |
530 | 517 |
531 uint8* decoded_audio_data = reinterpret_cast<uint8*>(&output_buffer_[0]); | 518 uint8* decoded_audio_data = reinterpret_cast<uint8*>(&output_buffer_[0]); |
532 int decoded_audio_size = samples_decoded * | 519 int decoded_audio_size = |
| 520 samples_decoded * |
533 demuxer_stream_->audio_decoder_config().bytes_per_frame(); | 521 demuxer_stream_->audio_decoder_config().bytes_per_frame(); |
534 DCHECK_LE(decoded_audio_size, kMaxOpusOutputPacketSizeBytes); | 522 DCHECK_LE(decoded_audio_size, kMaxOpusOutputPacketSizeBytes); |
535 | 523 |
536 if (output_timestamp_helper_->base_timestamp() == kNoTimestamp() && | 524 if (output_timestamp_helper_->base_timestamp() == kNoTimestamp() && |
537 !input->IsEndOfStream()) { | 525 !input->is_end_of_stream()) { |
538 DCHECK(input->GetTimestamp() != kNoTimestamp()); | 526 DCHECK(input->get_timestamp() != kNoTimestamp()); |
539 output_timestamp_helper_->SetBaseTimestamp(input->GetTimestamp()); | 527 output_timestamp_helper_->SetBaseTimestamp(input->get_timestamp()); |
540 } | 528 } |
541 | 529 |
542 if (decoded_audio_size > 0 && output_bytes_to_drop_ > 0) { | 530 if (decoded_audio_size > 0 && output_bytes_to_drop_ > 0) { |
543 int dropped_size = std::min(decoded_audio_size, output_bytes_to_drop_); | 531 int dropped_size = std::min(decoded_audio_size, output_bytes_to_drop_); |
544 DCHECK_EQ(dropped_size % kBytesPerChannel, 0); | 532 DCHECK_EQ(dropped_size % kBytesPerChannel, 0); |
545 decoded_audio_data += dropped_size; | 533 decoded_audio_data += dropped_size; |
546 decoded_audio_size -= dropped_size; | 534 decoded_audio_size -= dropped_size; |
547 output_bytes_to_drop_ -= dropped_size; | 535 output_bytes_to_drop_ -= dropped_size; |
548 } | 536 } |
549 | 537 |
550 if (decoded_audio_size > 0) { | 538 if (decoded_audio_size > 0) { |
551 // Copy the audio samples into an output buffer. | 539 // Copy the audio samples into an output buffer. |
552 *output_buffer = DataBuffer::copy_from( | 540 *output_buffer = |
553 decoded_audio_data, decoded_audio_size); | 541 DataBuffer::copy_from(decoded_audio_data, decoded_audio_size); |
554 (*output_buffer)->set_timestamp(output_timestamp_helper_->GetTimestamp()); | 542 (*output_buffer)->set_timestamp(output_timestamp_helper_->GetTimestamp()); |
555 (*output_buffer)->set_duration( | 543 (*output_buffer)->set_duration( |
556 output_timestamp_helper_->GetDuration(decoded_audio_size)); | 544 output_timestamp_helper_->GetDuration(decoded_audio_size)); |
557 output_timestamp_helper_->AddBytes(decoded_audio_size); | 545 output_timestamp_helper_->AddBytes(decoded_audio_size); |
558 } | 546 } |
559 | 547 |
560 // Decoding finished successfully, update statistics. | 548 // Decoding finished successfully, update statistics. |
561 PipelineStatistics statistics; | 549 PipelineStatistics statistics; |
562 statistics.audio_bytes_decoded = decoded_audio_size; | 550 statistics.audio_bytes_decoded = decoded_audio_size; |
563 statistics_cb_.Run(statistics); | 551 statistics_cb_.Run(statistics); |
564 | 552 |
565 return true; | 553 return true; |
566 } | 554 } |
567 | 555 |
568 } // namespace media | 556 } // namespace media |
OLD | NEW |