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

Side by Side Diff: media/audio/simple_sources.cc

Issue 1018293002: Make fake file audio input device not crash when it fails to read. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 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
« no previous file with comments | « media/audio/simple_sources.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // MSVC++ requires this to be set before any other includes to get M_PI. 4 // MSVC++ requires this to be set before any other includes to get M_PI.
5 #define _USE_MATH_DEFINES 5 #define _USE_MATH_DEFINES
6 #include <cmath> 6 #include <cmath>
7 7
8 #include "media/audio/simple_sources.h" 8 #include "media/audio/simple_sources.h"
9 9
10 #include <algorithm> 10 #include <algorithm>
11 11
12 #include "base/files/file.h" 12 #include "base/files/file.h"
13 #include "base/lazy_instance.h" 13 #include "base/lazy_instance.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "media/audio/sounds/wav_audio_handler.h" 15 #include "media/audio/sounds/wav_audio_handler.h"
16 #include "media/base/audio_bus.h" 16 #include "media/base/audio_bus.h"
17 17
18 namespace media { 18 namespace media {
19 19
20 // Opens |wav_filename|, reads it and loads it as a wav file. This function will 20 // Opens |wav_filename|, reads it and loads it as a wav file. This function will
21 // bluntly trigger CHECKs if we can't read the file or if it's malformed. The 21 // return a null pointer if we can't read the file or if it's malformed. The
22 // caller takes ownership of the returned data. The size of the data is stored 22 // caller takes ownership of the returned data. The size of the data is stored
23 // in |read_length|. 23 // in |read_length|.
24 static scoped_ptr<uint8[]> ReadWavFile(const base::FilePath& wav_filename, 24 static scoped_ptr<uint8[]> ReadWavFile(const base::FilePath& wav_filename,
25 size_t* file_length) { 25 size_t* file_length) {
26 base::File wav_file( 26 base::File wav_file(
27 wav_filename, base::File::FLAG_OPEN | base::File::FLAG_READ); 27 wav_filename, base::File::FLAG_OPEN | base::File::FLAG_READ);
28 CHECK(wav_file.IsValid()) 28 if (!wav_file.IsValid()) {
29 << "Failed to read " << wav_filename.value() 29 LOG(ERROR) << "Failed to read " << wav_filename.value()
30 << " as input to the fake device."; 30 << " as input to the fake device.";
31 return nullptr;
32 }
31 33
32 size_t wav_file_length = wav_file.GetLength(); 34 size_t wav_file_length = wav_file.GetLength();
33 CHECK_GT(wav_file_length, 0u) 35 if (wav_file_length == 0u) {
34 << "Input file to fake device is empty: " << wav_filename.value(); 36 LOG(ERROR) << "Input file to fake device is empty: "
37 << wav_filename.value();
38 return nullptr;
39 }
35 40
36 uint8* wav_file_data = new uint8[wav_file_length]; 41 uint8* wav_file_data = new uint8[wav_file_length];
37 size_t read_bytes = wav_file.Read(0, reinterpret_cast<char*>(wav_file_data), 42 size_t read_bytes = wav_file.Read(0, reinterpret_cast<char*>(wav_file_data),
38 wav_file_length); 43 wav_file_length);
39 CHECK_EQ(read_bytes, wav_file_length) 44 if (read_bytes != wav_file_length) {
40 << "Failed to read all bytes of " << wav_filename.value(); 45 LOG(ERROR) << "Failed to read all bytes of " << wav_filename.value();
46 return nullptr;
47 }
41 *file_length = wav_file_length; 48 *file_length = wav_file_length;
42 return scoped_ptr<uint8[]>(wav_file_data); 49 return scoped_ptr<uint8[]>(wav_file_data);
43 } 50 }
44 51
45 // Opens |wav_filename|, reads it and loads it as a wav file. This function will 52 // Opens |wav_filename|, reads it and loads it as a wav file. This function will
46 // bluntly trigger CHECKs if we can't read the file or if it's malformed. 53 // bluntly trigger CHECKs if we can't read the file or if it's malformed.
47 static scoped_ptr<WavAudioHandler> CreateWavAudioHandler( 54 static scoped_ptr<WavAudioHandler> CreateWavAudioHandler(
48 const base::FilePath& wav_filename, const uint8* wav_file_data, 55 const base::FilePath& wav_filename, const uint8* wav_file_data,
49 size_t wav_file_length, const AudioParameters& expected_params) { 56 size_t wav_file_length, const AudioParameters& expected_params) {
50 base::StringPiece wav_data(reinterpret_cast<const char*>(wav_file_data), 57 base::StringPiece wav_data(reinterpret_cast<const char*>(wav_file_data),
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 152
146 void SineWaveAudioSource::Reset() { 153 void SineWaveAudioSource::Reset() {
147 base::AutoLock auto_lock(time_lock_); 154 base::AutoLock auto_lock(time_lock_);
148 time_state_ = 0; 155 time_state_ = 0;
149 } 156 }
150 157
151 FileSource::FileSource(const AudioParameters& params, 158 FileSource::FileSource(const AudioParameters& params,
152 const base::FilePath& path_to_wav_file) 159 const base::FilePath& path_to_wav_file)
153 : params_(params), 160 : params_(params),
154 path_to_wav_file_(path_to_wav_file), 161 path_to_wav_file_(path_to_wav_file),
155 wav_file_read_pos_(0) { 162 wav_file_read_pos_(0),
163 load_failed_(false) {
156 } 164 }
157 165
158 FileSource::~FileSource() { 166 FileSource::~FileSource() {
159 } 167 }
160 168
161 void FileSource::LoadWavFile(const base::FilePath& path_to_wav_file) { 169 void FileSource::LoadWavFile(const base::FilePath& path_to_wav_file) {
170 // Don't try again if we already failed.
171 if (load_failed_)
172 return;
173
162 // Read the file, and put its data in a scoped_ptr so it gets deleted later. 174 // Read the file, and put its data in a scoped_ptr so it gets deleted later.
163 size_t file_length = 0; 175 size_t file_length = 0;
164 wav_file_data_ = ReadWavFile(path_to_wav_file, &file_length); 176 wav_file_data_ = ReadWavFile(path_to_wav_file, &file_length);
177 if (!wav_file_data_) {
178 load_failed_ = true;
179 return;
180 }
181
165 wav_audio_handler_ = CreateWavAudioHandler( 182 wav_audio_handler_ = CreateWavAudioHandler(
166 path_to_wav_file, wav_file_data_.get(), file_length, params_); 183 path_to_wav_file, wav_file_data_.get(), file_length, params_);
167 184
168 // Hook us up so we pull in data from the file into the converter. We need to 185 // Hook us up so we pull in data from the file into the converter. We need to
169 // modify the wav file's audio parameters since we'll be reading small slices 186 // modify the wav file's audio parameters since we'll be reading small slices
170 // of it at a time and not the whole thing (like 10 ms at a time). 187 // of it at a time and not the whole thing (like 10 ms at a time).
171 AudioParameters file_audio_slice( 188 AudioParameters file_audio_slice(
172 wav_audio_handler_->params().format(), 189 wav_audio_handler_->params().format(),
173 wav_audio_handler_->params().channel_layout(), 190 wav_audio_handler_->params().channel_layout(),
174 wav_audio_handler_->params().sample_rate(), 191 wav_audio_handler_->params().sample_rate(),
175 wav_audio_handler_->params().bits_per_sample(), 192 wav_audio_handler_->params().bits_per_sample(),
176 params_.frames_per_buffer()); 193 params_.frames_per_buffer());
177 194
178 file_audio_converter_.reset( 195 file_audio_converter_.reset(
179 new AudioConverter(file_audio_slice, params_, false)); 196 new AudioConverter(file_audio_slice, params_, false));
180 file_audio_converter_->AddInput(this); 197 file_audio_converter_->AddInput(this);
181 } 198 }
182 199
183 int FileSource::OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) { 200 int FileSource::OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) {
184 // Load the file if we haven't already. This load needs to happen on the 201 // Load the file if we haven't already. This load needs to happen on the
185 // audio thread, otherwise we'll run on the UI thread on Mac for instance. 202 // audio thread, otherwise we'll run on the UI thread on Mac for instance.
186 // This will massively delay the first OnMoreData, but we'll catch up. 203 // This will massively delay the first OnMoreData, but we'll catch up.
187 if (!wav_audio_handler_) 204 if (!wav_audio_handler_)
188 LoadWavFile(path_to_wav_file_); 205 LoadWavFile(path_to_wav_file_);
206 if (load_failed_)
207 return 0;
189 208
190 DCHECK(wav_audio_handler_.get()); 209 DCHECK(wav_audio_handler_.get());
191 210
192 // Stop playing if we've played out the whole file. 211 // Stop playing if we've played out the whole file.
193 if (wav_audio_handler_->AtEnd(wav_file_read_pos_)) 212 if (wav_audio_handler_->AtEnd(wav_file_read_pos_))
194 return 0; 213 return 0;
195 214
196 // This pulls data from ProvideInput. 215 // This pulls data from ProvideInput.
197 file_audio_converter_->Convert(audio_bus); 216 file_audio_converter_->Convert(audio_bus);
198 return audio_bus->frames(); 217 return audio_bus->frames();
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 } 296 }
278 297
279 void BeepingSource::OnError(AudioOutputStream* stream) { 298 void BeepingSource::OnError(AudioOutputStream* stream) {
280 } 299 }
281 300
282 void BeepingSource::BeepOnce() { 301 void BeepingSource::BeepOnce() {
283 g_beep_context.Pointer()->SetBeepOnce(true); 302 g_beep_context.Pointer()->SetBeepOnce(true);
284 } 303 }
285 304
286 } // namespace media 305 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/simple_sources.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698