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 "webkit/media/audio_decoder.h"
8 #include "base/basictypes.h"
9 #include "base/string_util.h"
10 #include "base/time.h"
11 #include "media/base/audio_bus.h"
12 #include "media/base/limits.h"
13 #include "media/filters/audio_file_reader.h"
14 #include "media/filters/in_memory_url_protocol.h"
15 #include "third_party/WebKit/Source/Platform/chromium/public/WebAudioBus.h"
17 using media::AudioBus
;
18 using media::AudioFileReader
;
19 using media::InMemoryUrlProtocol
;
21 using WebKit::WebAudioBus
;
23 namespace webkit_media
{
25 // Decode in-memory audio file data.
26 bool DecodeAudioFileData(
27 WebKit::WebAudioBus
* destination_bus
,
28 const char* data
, size_t data_size
, double sample_rate
) {
29 DCHECK(destination_bus
);
33 // Uses the FFmpeg library for audio file reading.
34 InMemoryUrlProtocol
url_protocol(reinterpret_cast<const uint8
*>(data
),
36 AudioFileReader
reader(&url_protocol
);
41 size_t number_of_channels
= reader
.channels();
42 double file_sample_rate
= reader
.sample_rate();
43 size_t number_of_frames
= static_cast<size_t>(reader
.number_of_frames());
45 // Apply sanity checks to make sure crazy values aren't coming out of
47 if (!number_of_channels
||
48 number_of_channels
> static_cast<size_t>(media::limits::kMaxChannels
) ||
49 file_sample_rate
< media::limits::kMinSampleRate
||
50 file_sample_rate
> media::limits::kMaxSampleRate
)
53 // Allocate and configure the output audio channel data.
54 destination_bus
->initialize(number_of_channels
,
58 // Wrap the channel pointers which will receive the decoded PCM audio.
59 vector
<float*> audio_data
;
60 audio_data
.reserve(number_of_channels
);
61 for (size_t i
= 0; i
< number_of_channels
; ++i
) {
62 audio_data
.push_back(destination_bus
->channelData(i
));
65 scoped_ptr
<AudioBus
> audio_bus
= AudioBus::WrapVector(
66 number_of_frames
, audio_data
);
68 // Decode the audio file data.
69 // TODO(crogers): If our estimate was low, then we still may fail to read
70 // all of the data from the file.
71 size_t actual_frames
= reader
.Read(audio_bus
.get());
73 // Adjust WebKit's bus to account for the actual file length
74 // and valid data read.
75 if (actual_frames
!= number_of_frames
) {
76 DCHECK_LE(actual_frames
, number_of_frames
);
77 destination_bus
->resizeSmaller(actual_frames
);
80 double duration
= actual_frames
/ file_sample_rate
;
82 DVLOG(1) << "Decoded file data -"
84 << " data size: " << data_size
85 << " duration: " << duration
86 << " number of frames: " << actual_frames
87 << " sample rate: " << file_sample_rate
88 << " number of channels: " << number_of_channels
;
90 return actual_frames
> 0;
93 } // namespace webkit_media