Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(992)

Side by Side Diff: media/filters/audio_file_reader.cc

Issue 5550006: Implement WebKitClientImpl::loadAudioResource() to decode in-memory audio fil... (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2010 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.
4
5 #include "media/filters/audio_file_reader.h"
6
7 #include <string>
8 #include "base/basictypes.h"
9 #include "base/string_util.h"
10 #include "base/time.h"
11 #include "media/audio/audio_util.h"
12 #include "media/base/filters.h"
13 #include "media/ffmpeg/ffmpeg_common.h"
14 #include "media/ffmpeg/ffmpeg_util.h"
15 #include "media/filters/ffmpeg_glue.h"
16
17 namespace media {
18
19 AudioFileReader::AudioFileReader(FFmpegURLProtocol* protocol)
20 : protocol_(protocol),
scherkus (not reviewing) 2010/12/11 02:31:12 indent this by extra 2 spaces
Chris Rogers 2010/12/13 20:25:27 Done.
21 format_context_(NULL),
22 codec_context_(NULL),
23 codec_(NULL) {
24 }
25
26 AudioFileReader::~AudioFileReader() {
27 Close();
28 }
29
30 int AudioFileReader::channels() const {
31 return codec_context_->channels;
32 }
33
34 int AudioFileReader::sample_rate() const {
35 return codec_context_->sample_rate;
36 }
37
38 base::TimeDelta AudioFileReader::duration() const {
39 const AVRational av_time_base = {1, AV_TIME_BASE};
40 return ConvertTimestamp(av_time_base, format_context_->duration);
41 }
42
43 int64 AudioFileReader::number_of_frames() const {
44 return duration().InSecondsF() * sample_rate();
45 }
46
47 bool AudioFileReader::Open() {
48 // Add our data reader to the protocol list and get our unique key.
49 std::string key = FFmpegGlue::get()->AddProtocol(protocol_);
50
51 // Open FFmpeg AVFormatContext.
52 DCHECK(!format_context_);
53 AVFormatContext* context = NULL;
54
55 int result = av_open_input_file(&context, key.c_str(), NULL, 0, NULL);
56
57 // Remove our data reader from protocol list since av_open_input_file() setup
58 // the AVFormatContext with the data reader.
59 FFmpegGlue::get()->RemoveProtocol(protocol_);
60
61 if (result) {
62 DLOG(WARNING)
scherkus (not reviewing) 2010/12/11 02:31:12 de-indent by 2 spaces
Chris Rogers 2010/12/13 20:25:27 Done.
63 << "AudioFileReader::Open() : error in av_open_input_file() -"
64 << " result: " << result;
65 return false;
66 }
67
68 DCHECK(context);
69 format_context_ = context;
70
71 // Get the codec context.
72 codec_context_ = NULL;
73 for (unsigned i = 0; i < format_context_->nb_streams; ++i) {
74 AVCodecContext* c = format_context_->streams[i]->codec;
75 if (c->codec_type == CODEC_TYPE_AUDIO) {
76 codec_context_ = c;
77 break;
78 }
79 }
80
81 // Get the codec.
82 if (codec_context_) {
83 av_find_stream_info(format_context_);
84 codec_ = avcodec_find_decoder(codec_context_->codec_id);
85 if (codec_) {
86 if ((result = avcodec_open(codec_context_, codec_)) < 0) {
87 DLOG(WARNING) << "AudioFileReader::Open() : could not open codec -"
88 << " result: " << result;
89 return false;
90 }
91
92 result = av_seek_frame(format_context_, 0, 0, 0);
93 }
94 } else {
95 return false;
scherkus (not reviewing) 2010/12/11 02:31:12 I'd flip this condition around and simply exit ear
Chris Rogers 2010/12/13 20:25:27 Done.
96 }
97
98 return true;
99 }
100
101 void AudioFileReader::Close() {
102 if (codec_context_ && codec_) {
scherkus (not reviewing) 2010/12/11 02:31:12 nit: the rest of this file seems to not include {
Chris Rogers 2010/12/13 20:25:27 Done.
103 avcodec_close(codec_context_);
104 }
105 codec_context_ = NULL;
106 codec_ = NULL;
107
108 if (format_context_) {
109 av_close_input_file(format_context_);
scherkus (not reviewing) 2010/12/11 02:31:12 de-indent by 2 spaces
Chris Rogers 2010/12/13 20:25:27 Done.
110 format_context_ = NULL;
111 }
112 }
113
114 bool AudioFileReader::Read(const std::vector<float*>& audio_data,
115 size_t number_of_frames) {
116 unsigned number_of_channels = channels();
scherkus (not reviewing) 2010/12/11 02:31:12 we haven't used unsigned anywhere in the media cod
Chris Rogers 2010/12/13 20:25:27 Done.
117 DCHECK_EQ(audio_data.size(), number_of_channels);
118 if (audio_data.size() != number_of_channels)
119 return false;
120
121 DCHECK(format_context_ && codec_context_);
122 if (!format_context_ || !codec_context_) {
123 DLOG(WARNING) << "AudioFileReader::Read() : reader is not opened!";
124 return false;
125 }
126
127 int16* output_buffer =
scherkus (not reviewing) 2010/12/11 02:31:12 crazy ffmpeg stuff: you must use av_malloc()!! ot
Chris Rogers 2010/12/13 20:25:27 Done.
128 static_cast<int16*>(malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE));
scherkus (not reviewing) 2010/12/11 02:31:12 indent by extra 2 spaces
Chris Rogers 2010/12/13 20:25:27 Done.
129
130 // Read until we hit EOF or we've read the requested number of frames.
131 AVPacket avpkt;
132 av_init_packet(&avpkt);
133
134 int result = 0;
135 unsigned current_frame = 0;
scherkus (not reviewing) 2010/12/11 02:31:12 unsigned -> size_t
Chris Rogers 2010/12/13 20:25:27 Done.
136
137 while (current_frame < number_of_frames
138 && (result = av_read_frame(format_context_, &avpkt)) >= 0) {
scherkus (not reviewing) 2010/12/11 02:31:12 nit: && should be at end of last line + following
Chris Rogers 2010/12/13 20:25:27 Done.
139 int out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
140 result = avcodec_decode_audio3(codec_context_,
141 output_buffer,
142 &out_size,
143 &avpkt);
144
145 if (result < 0) {
146 DLOG(WARNING)
147 << "AudioFileReader::Read() : error in avcodec_decode_audio3() -"
148 << result;
149 free(output_buffer);
150 return false;
151 }
152
153 // Determine the number of sample-frames we just decoded.
154 size_t sample_byte_size =
155 av_get_bits_per_sample_fmt(codec_context_->sample_fmt) >> 3;
scherkus (not reviewing) 2010/12/11 02:31:12 indent by extra 2 spaces
Chris Rogers 2010/12/13 20:25:27 Done.
156 unsigned frames_read = out_size / (number_of_channels * sample_byte_size);
scherkus (not reviewing) 2010/12/11 02:31:12 unsigned -> size_t
Chris Rogers 2010/12/13 20:25:27 Done.
157
158 // Truncate, if necessary, if the destination isn't big enough.
159 if (current_frame + frames_read > number_of_frames) {
160 frames_read = static_cast<int>(number_of_frames) - current_frame;
scherkus (not reviewing) 2010/12/11 02:31:12 is cast needed here? it looks like frames_read, n
Chris Rogers 2010/12/13 20:25:27 Done.
161 }
162
163 // Deinterleave each channel and convert to 32bit floating-point
164 // with nominal range -1.0 -> +1.0.
165 for (unsigned channel_index = 0; channel_index < number_of_channels;
scherkus (not reviewing) 2010/12/11 02:31:12 unsigned -> size_t OR unsinged -> int, number_of_c
Chris Rogers 2010/12/13 20:25:27 Done.
166 ++channel_index) {
167 if (!DeinterleaveAudioChannel(output_buffer,
168 audio_data[channel_index] + current_frame,
169 codec_context_->sample_fmt,
170 number_of_channels,
171 channel_index,
172 frames_read)) {
173 DLOG(WARNING)
174 << "AudioFileReader::Read() : Unsupported sample format : "
175 << codec_context_->sample_fmt
176 << " codec_->id : " << codec_->id;
177 return false;
178 }
179 }
180
181 current_frame += frames_read;
182 }
183
184 free(output_buffer);
185 return true; // success
scherkus (not reviewing) 2010/12/11 02:31:12 no need for comment
Chris Rogers 2010/12/13 20:25:27 Done.
186 }
187
188 InMemoryDataReader::InMemoryDataReader(const char* data, int64 size)
189 : data_(data),
scherkus (not reviewing) 2010/12/11 02:31:12 indent by 2 extra spaces
Chris Rogers 2010/12/13 20:25:27 Done.
190 size_(size),
191 position_(0) {
192 }
193
194 int InMemoryDataReader::Read(int size, uint8* data) {
195 if (size < 0)
196 return -1;
197
198 int64 available_bytes = size_ - position_;
199 if (size > available_bytes)
200 size = available_bytes;
201
202 memcpy(data, data_ + position_, size);
203 position_ += size;
204 return size;
205 }
206
207 bool InMemoryDataReader::GetPosition(int64* position_out) {
208 if (position_out)
209 *position_out = position_;
210 return true;
211 }
212
213 bool InMemoryDataReader::SetPosition(int64 position) {
214 if (position >= size_)
215 return false;
216 position_ = position;
217 return true;
218 }
219
220 bool InMemoryDataReader::GetSize(int64* size_out) {
221 if (size_out)
222 *size_out = size_;
223 return true;
224 }
225
226 bool InMemoryDataReader::IsStreaming() {
227 return false;
228 }
229
230 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698