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

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

Issue 10871051: Convert WebAudio file handlers to use AudioBus. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comments. Created 8 years, 3 months 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
OLDNEW
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/audio_file_reader.h" 5 #include "media/filters/audio_file_reader.h"
6 6
7 #include <string> 7 #include <string>
8 #include "base/basictypes.h" 8 #include "base/basictypes.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "base/time.h" 10 #include "base/time.h"
11 #include "media/audio/audio_util.h" 11 #include "media/base/audio_bus.h"
12 #include "media/ffmpeg/ffmpeg_common.h" 12 #include "media/ffmpeg/ffmpeg_common.h"
13 #include "media/filters/ffmpeg_glue.h" 13 #include "media/filters/ffmpeg_glue.h"
14 14
15 namespace media { 15 namespace media {
16 16
17 AudioFileReader::AudioFileReader(FFmpegURLProtocol* protocol) 17 AudioFileReader::AudioFileReader(FFmpegURLProtocol* protocol)
18 : protocol_(protocol), 18 : protocol_(protocol),
19 format_context_(NULL), 19 format_context_(NULL),
20 codec_context_(NULL), 20 codec_context_(NULL) {
21 codec_(NULL) {
22 } 21 }
23 22
24 AudioFileReader::~AudioFileReader() { 23 AudioFileReader::~AudioFileReader() {
25 Close(); 24 Close();
26 } 25 }
27 26
28 int AudioFileReader::channels() const { 27 int AudioFileReader::channels() const {
29 return codec_context_->channels; 28 return codec_context_->channels;
30 } 29 }
31 30
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 codec_context_ = c; 73 codec_context_ = c;
75 break; 74 break;
76 } 75 }
77 } 76 }
78 77
79 // Get the codec. 78 // Get the codec.
80 if (!codec_context_) 79 if (!codec_context_)
81 return false; 80 return false;
82 81
83 avformat_find_stream_info(format_context_, NULL); 82 avformat_find_stream_info(format_context_, NULL);
84 codec_ = avcodec_find_decoder(codec_context_->codec_id); 83 AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
85 if (codec_) { 84 if (codec) {
86 if ((result = avcodec_open2(codec_context_, codec_, NULL)) < 0) { 85 if ((result = avcodec_open2(codec_context_, codec, NULL)) < 0) {
87 DLOG(WARNING) << "AudioFileReader::Open() : could not open codec -" 86 DLOG(WARNING) << "AudioFileReader::Open() : could not open codec -"
88 << " result: " << result; 87 << " result: " << result;
89 return false; 88 return false;
90 } 89 }
91 } else { 90 } else {
92 DLOG(WARNING) << "AudioFileReader::Open() : could not find codec -" 91 DLOG(WARNING) << "AudioFileReader::Open() : could not find codec -"
93 << " result: " << result; 92 << " result: " << result;
94 return false; 93 return false;
95 } 94 }
96 95
97 return true; 96 return true;
98 } 97 }
99 98
100 void AudioFileReader::Close() { 99 void AudioFileReader::Close() {
101 if (codec_context_ && codec_) 100 if (codec_context_) {
102 avcodec_close(codec_context_); 101 avcodec_close(codec_context_);
103 102 codec_context_ = NULL;
104 codec_context_ = NULL; 103 }
105 codec_ = NULL;
106 104
107 if (format_context_) { 105 if (format_context_) {
108 avformat_close_input(&format_context_); 106 avformat_close_input(&format_context_);
109 format_context_ = NULL; 107 format_context_ = NULL;
110 } 108 }
111 } 109 }
112 110
113 bool AudioFileReader::Read(const std::vector<float*>& audio_data, 111 bool AudioFileReader::Read(AudioBus* audio_bus) {
114 size_t number_of_frames) { 112 DCHECK(format_context_ && codec_context_) <<
115 DCHECK(format_context_ && codec_context_ && codec_) <<
116 "AudioFileReader::Read() : reader is not opened!"; 113 "AudioFileReader::Read() : reader is not opened!";
117 114
118 size_t channels = this->channels(); 115 int channels = this->channels();
119 DCHECK_EQ(audio_data.size(), channels); 116 DCHECK_EQ(audio_bus->channels(), channels);
120 if (audio_data.size() != channels) 117 if (audio_bus->channels() != channels)
121 return false; 118 return false;
122 119
120 size_t bytes_per_sample = av_get_bytes_per_sample(codec_context_->sample_fmt);
121
123 // Holds decoded audio. 122 // Holds decoded audio.
124 scoped_ptr_malloc<AVFrame, ScopedPtrAVFree> av_frame(avcodec_alloc_frame()); 123 scoped_ptr_malloc<AVFrame, ScopedPtrAVFree> av_frame(avcodec_alloc_frame());
125 124
126 // Read until we hit EOF or we've read the requested number of frames. 125 // Read until we hit EOF or we've read the requested number of frames.
127 AVPacket packet; 126 AVPacket packet;
128 int result = 0; 127 int result = 0;
129 size_t current_frame = 0; 128 int current_frame = 0;
130 129
131 while (current_frame < number_of_frames && 130 while (current_frame < audio_bus->frames() &&
132 (result = av_read_frame(format_context_, &packet)) >= 0) { 131 (result = av_read_frame(format_context_, &packet)) >= 0) {
133 avcodec_get_frame_defaults(av_frame.get()); 132 avcodec_get_frame_defaults(av_frame.get());
134 int frame_decoded = 0; 133 int frame_decoded = 0;
135 int result = avcodec_decode_audio4( 134 int result = avcodec_decode_audio4(
136 codec_context_, av_frame.get(), &frame_decoded, &packet); 135 codec_context_, av_frame.get(), &frame_decoded, &packet);
137 av_free_packet(&packet); 136 av_free_packet(&packet);
138 137
139 if (result < 0) { 138 if (result < 0) {
140 DLOG(WARNING) 139 DLOG(WARNING)
141 << "AudioFileReader::Read() : error in avcodec_decode_audio3() -" 140 << "AudioFileReader::Read() : error in avcodec_decode_audio3() -"
142 << result; 141 << result;
143 142 break;
144 // Fail if nothing has been decoded, otherwise return partial data.
145 return current_frame > 0;
146 } 143 }
147 144
148 if (!frame_decoded) 145 if (!frame_decoded)
149 continue; 146 continue;
150 147
151 // Determine the number of sample-frames we just decoded. 148 // Determine the number of sample-frames we just decoded. Check overflow.
152 size_t bytes_per_sample = 149 int frames_read = av_frame->nb_samples;
153 av_get_bytes_per_sample(codec_context_->sample_fmt); 150 if (frames_read < 0)
154 size_t frames_read = av_frame->nb_samples; 151 break;
155 152
156 // Truncate, if necessary, if the destination isn't big enough. 153 // Truncate, if necessary, if the destination isn't big enough.
157 if (current_frame + frames_read > number_of_frames) 154 if (current_frame + frames_read > audio_bus->frames())
158 frames_read = number_of_frames - current_frame; 155 frames_read = audio_bus->frames() - current_frame;
159 156
160 // Deinterleave each channel and convert to 32bit floating-point 157 // Deinterleave each channel and convert to 32bit floating-point
161 // with nominal range -1.0 -> +1.0. 158 // with nominal range -1.0 -> +1.0.
162 for (size_t channel_index = 0; channel_index < channels; 159 audio_bus->FromInterleavedPartial(
163 ++channel_index) { 160 av_frame->data[0], current_frame, frames_read, bytes_per_sample);
164 if (!DeinterleaveAudioChannel(av_frame->data[0],
165 audio_data[channel_index] + current_frame,
166 channels,
167 channel_index,
168 bytes_per_sample,
169 frames_read)) {
170 DLOG(WARNING)
171 << "AudioFileReader::Read() : Unsupported sample format : "
172 << codec_context_->sample_fmt
173 << " codec_->id : " << codec_->id;
174 return false;
175 }
176 }
177 161
178 current_frame += frames_read; 162 current_frame += frames_read;
179 } 163 }
180 164
181 return true; 165 // Zero any remaining frames.
166 audio_bus->ZeroFramesPartial(
167 current_frame, audio_bus->frames() - current_frame);
168
169 // Fail if nothing has been decoded, otherwise return partial data.
170 return current_frame > 0;
182 } 171 }
183 172
184 } // namespace media 173 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698