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

Side by Side Diff: content/browser/renderer_host/media/audio_debug_file_writer.cc

Issue 2620373005: Rename AudioInputWriter -> AudioFileWriter. (Closed)
Patch Set: Created 3 years, 11 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
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "content/browser/renderer_host/media/audio_input_debug_writer.h" 5 #include "content/browser/renderer_host/media/audio_debug_file_writer.h"
6
6 #include <stdint.h> 7 #include <stdint.h>
7 #include <array> 8 #include <array>
8 #include <utility> 9 #include <utility>
10
9 #include "base/logging.h" 11 #include "base/logging.h"
10 #include "base/memory/ptr_util.h" 12 #include "base/memory/ptr_util.h"
11 #include "base/sys_byteorder.h" 13 #include "base/sys_byteorder.h"
12 #include "content/public/browser/browser_thread.h" 14 #include "content/public/browser/browser_thread.h"
13 #include "media/base/audio_bus.h" 15 #include "media/base/audio_bus.h"
14 16
15 namespace content { 17 namespace content {
16 18
17 namespace { 19 namespace {
18 20
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 writer.WriteLE16(kBytesPerSample * 8); 126 writer.WriteLE16(kBytesPerSample * 8);
125 writer.Write(kData); 127 writer.Write(kData);
126 writer.WriteLE32(bytes_in_payload); 128 writer.WriteLE32(bytes_in_payload);
127 } 129 }
128 130
129 } // namespace 131 } // namespace
130 132
131 // Manages the debug recording file and writes to it. Can be created on any 133 // Manages the debug recording file and writes to it. Can be created on any
132 // thread. All the operations must be executed on FILE thread. Must be destroyed 134 // thread. All the operations must be executed on FILE thread. Must be destroyed
133 // on FILE thread. 135 // on FILE thread.
134 class AudioInputDebugWriter::AudioFileWriter { 136 class AudioDebugFileWriter::AudioFileWriter {
135 public: 137 public:
136 static AudioFileWriterUniquePtr Create(const base::FilePath& file_name, 138 static AudioFileWriterUniquePtr Create(const base::FilePath& file_name,
137 const media::AudioParameters& params); 139 const media::AudioParameters& params);
138 140
139 ~AudioFileWriter(); 141 ~AudioFileWriter();
140 142
141 // Write data from |data| to file. 143 // Write data from |data| to file.
142 void Write(const media::AudioBus* data); 144 void Write(const media::AudioBus* data);
143 145
144 private: 146 private:
(...skipping 15 matching lines...) Expand all
160 162
161 // Input audio parameters required to build wave header. 163 // Input audio parameters required to build wave header.
162 const media::AudioParameters params_; 164 const media::AudioParameters params_;
163 165
164 // Intermediate buffer to be written to file. Interleaved 16 bit audio data. 166 // Intermediate buffer to be written to file. Interleaved 16 bit audio data.
165 std::unique_ptr<int16_t[]> interleaved_data_; 167 std::unique_ptr<int16_t[]> interleaved_data_;
166 int interleaved_data_size_; 168 int interleaved_data_size_;
167 }; 169 };
168 170
169 // static 171 // static
170 AudioInputDebugWriter::AudioFileWriterUniquePtr 172 AudioDebugFileWriter::AudioFileWriterUniquePtr
171 AudioInputDebugWriter::AudioFileWriter::Create( 173 AudioDebugFileWriter::AudioFileWriter::Create(
172 const base::FilePath& file_name, 174 const base::FilePath& file_name,
173 const media::AudioParameters& params) { 175 const media::AudioParameters& params) {
174 AudioFileWriterUniquePtr file_writer(new AudioFileWriter(params)); 176 AudioFileWriterUniquePtr file_writer(new AudioFileWriter(params));
175 177
176 // base::Unretained is safe, because destructor is called on FILE thread or on 178 // base::Unretained is safe, because destructor is called on FILE thread or on
177 // FILE message loop destruction. 179 // FILE message loop destruction.
178 BrowserThread::PostTask( 180 BrowserThread::PostTask(
179 BrowserThread::FILE, FROM_HERE, 181 BrowserThread::FILE, FROM_HERE,
180 base::Bind(&AudioFileWriter::CreateRecordingFile, 182 base::Bind(&AudioFileWriter::CreateRecordingFile,
181 base::Unretained(file_writer.get()), file_name)); 183 base::Unretained(file_writer.get()), file_name));
182 return file_writer; 184 return file_writer;
183 } 185 }
184 186
185 AudioInputDebugWriter::AudioFileWriter::AudioFileWriter( 187 AudioDebugFileWriter::AudioFileWriter::AudioFileWriter(
186 const media::AudioParameters& params) 188 const media::AudioParameters& params)
187 : samples_(0), params_(params), interleaved_data_size_(0) { 189 : samples_(0), params_(params), interleaved_data_size_(0) {
188 DCHECK_EQ(params.bits_per_sample(), kBytesPerSample * 8); 190 DCHECK_EQ(params.bits_per_sample(), kBytesPerSample * 8);
189 } 191 }
190 192
191 AudioInputDebugWriter::AudioFileWriter::~AudioFileWriter() { 193 AudioDebugFileWriter::AudioFileWriter::~AudioFileWriter() {
192 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 194 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
193 if (file_.IsValid()) 195 if (file_.IsValid())
194 WriteHeader(); 196 WriteHeader();
195 } 197 }
196 198
197 void AudioInputDebugWriter::AudioFileWriter::Write( 199 void AudioDebugFileWriter::AudioFileWriter::Write(
198 const media::AudioBus* data) { 200 const media::AudioBus* data) {
199 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 201 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
200 if (!file_.IsValid()) 202 if (!file_.IsValid())
201 return; 203 return;
202 204
203 // Convert to 16 bit audio and write to file. 205 // Convert to 16 bit audio and write to file.
204 int data_size = data->frames() * data->channels(); 206 int data_size = data->frames() * data->channels();
205 if (!interleaved_data_ || interleaved_data_size_ < data_size) { 207 if (!interleaved_data_ || interleaved_data_size_ < data_size) {
206 interleaved_data_.reset(new int16_t[data_size]); 208 interleaved_data_.reset(new int16_t[data_size]);
207 interleaved_data_size_ = data_size; 209 interleaved_data_size_ = data_size;
208 } 210 }
209 samples_ += data_size; 211 samples_ += data_size;
210 data->ToInterleaved(data->frames(), sizeof(interleaved_data_[0]), 212 data->ToInterleaved(data->frames(), sizeof(interleaved_data_[0]),
211 interleaved_data_.get()); 213 interleaved_data_.get());
212 214
213 #ifndef ARCH_CPU_LITTLE_ENDIAN 215 #ifndef ARCH_CPU_LITTLE_ENDIAN
214 static_assert(sizeof(interleaved_data_[0]) == sizeof(uint16_t), 216 static_assert(sizeof(interleaved_data_[0]) == sizeof(uint16_t),
215 "Only 2 bytes per channel is supported."); 217 "Only 2 bytes per channel is supported.");
216 for (int i = 0; i < data_size; ++i) 218 for (int i = 0; i < data_size; ++i)
217 interleaved_data_[i] = base::ByteSwapToLE16(interleaved_data_[i]); 219 interleaved_data_[i] = base::ByteSwapToLE16(interleaved_data_[i]);
218 #endif 220 #endif
219 221
220 file_.WriteAtCurrentPos(reinterpret_cast<char*>(interleaved_data_.get()), 222 file_.WriteAtCurrentPos(reinterpret_cast<char*>(interleaved_data_.get()),
221 data_size * sizeof(interleaved_data_[0])); 223 data_size * sizeof(interleaved_data_[0]));
222 } 224 }
223 225
224 void AudioInputDebugWriter::AudioFileWriter::WriteHeader() { 226 void AudioDebugFileWriter::AudioFileWriter::WriteHeader() {
225 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 227 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
226 if (!file_.IsValid()) 228 if (!file_.IsValid())
227 return; 229 return;
228 WavHeaderBuffer buf; 230 WavHeaderBuffer buf;
229 WriteWavHeader(&buf, params_.channels(), params_.sample_rate(), samples_); 231 WriteWavHeader(&buf, params_.channels(), params_.sample_rate(), samples_);
230 file_.Write(0, &buf[0], kWavHeaderSize); 232 file_.Write(0, &buf[0], kWavHeaderSize);
231 233
232 // Write() does not move the cursor if file is not in APPEND mode; Seek() so 234 // Write() does not move the cursor if file is not in APPEND mode; Seek() so
233 // that the header is not overwritten by the following writes. 235 // that the header is not overwritten by the following writes.
234 file_.Seek(base::File::FROM_BEGIN, kWavHeaderSize); 236 file_.Seek(base::File::FROM_BEGIN, kWavHeaderSize);
235 } 237 }
236 238
237 void AudioInputDebugWriter::AudioFileWriter::CreateRecordingFile( 239 void AudioDebugFileWriter::AudioFileWriter::CreateRecordingFile(
238 const base::FilePath& file_name) { 240 const base::FilePath& file_name) {
239 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 241 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
240 DCHECK(!file_.IsValid()); 242 DCHECK(!file_.IsValid());
241 243
242 file_ = base::File(file_name, 244 file_ = base::File(file_name,
243 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); 245 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
244 246
245 if (file_.IsValid()) { 247 if (file_.IsValid()) {
246 WriteHeader(); 248 WriteHeader();
247 return; 249 return;
248 } 250 }
249 251
250 // Note that we do not inform AudioInputDebugWriter that the file creation 252 // Note that we do not inform AudioDebugFileWriter that the file creation
251 // fails, so it will continue to post data to be recorded, which won't 253 // fails, so it will continue to post data to be recorded, which won't
252 // be written to the file. This also won't be reflected in WillWrite(). It's 254 // be written to the file. This also won't be reflected in WillWrite(). It's
253 // fine, because this situation is rare, and all the posting is expected to 255 // fine, because this situation is rare, and all the posting is expected to
254 // happen in case of success anyways. This allows us to save on thread hops 256 // happen in case of success anyways. This allows us to save on thread hops
255 // for error reporting and to avoid dealing with lifetime issues. It also 257 // for error reporting and to avoid dealing with lifetime issues. It also
256 // means file_.IsValid() should always be checked before issuing writes to it. 258 // means file_.IsValid() should always be checked before issuing writes to it.
257 PLOG(ERROR) << "Could not open debug recording file, error=" 259 PLOG(ERROR) << "Could not open debug recording file, error="
258 << file_.error_details(); 260 << file_.error_details();
259 } 261 }
260 262
261 AudioInputDebugWriter::AudioInputDebugWriter( 263 AudioDebugFileWriter::AudioDebugFileWriter(
262 const media::AudioParameters& params) 264 const media::AudioParameters& params)
263 : params_(params) { 265 : params_(params) {
264 client_sequence_checker_.DetachFromSequence(); 266 client_sequence_checker_.DetachFromSequence();
265 } 267 }
266 268
267 AudioInputDebugWriter::~AudioInputDebugWriter() { 269 AudioDebugFileWriter::~AudioDebugFileWriter() {
268 // |file_writer_| will be deleted on FILE thread. 270 // |file_writer_| will be deleted on FILE thread.
269 } 271 }
270 272
271 void AudioInputDebugWriter::Start(const base::FilePath& file_name) { 273 void AudioDebugFileWriter::Start(const base::FilePath& file_name) {
272 DCHECK(client_sequence_checker_.CalledOnValidSequence()); 274 DCHECK(client_sequence_checker_.CalledOnValidSequence());
273 DCHECK(!file_writer_); 275 DCHECK(!file_writer_);
274 file_writer_ = AudioFileWriter::Create(file_name, params_); 276 file_writer_ = AudioFileWriter::Create(file_name, params_);
275 } 277 }
276 278
277 void AudioInputDebugWriter::Stop() { 279 void AudioDebugFileWriter::Stop() {
278 DCHECK(client_sequence_checker_.CalledOnValidSequence()); 280 DCHECK(client_sequence_checker_.CalledOnValidSequence());
279 // |file_writer_| is deleted on FILE thread. 281 // |file_writer_| is deleted on FILE thread.
280 file_writer_.reset(); 282 file_writer_.reset();
281 client_sequence_checker_.DetachFromSequence(); 283 client_sequence_checker_.DetachFromSequence();
282 } 284 }
283 285
284 void AudioInputDebugWriter::Write(std::unique_ptr<media::AudioBus> data) { 286 void AudioDebugFileWriter::Write(std::unique_ptr<media::AudioBus> data) {
285 DCHECK(client_sequence_checker_.CalledOnValidSequence()); 287 DCHECK(client_sequence_checker_.CalledOnValidSequence());
286 if (!file_writer_) 288 if (!file_writer_)
287 return; 289 return;
288 290
289 // base::Unretained for |file_writer_| is safe, see the destructor. 291 // base::Unretained for |file_writer_| is safe, see the destructor.
290 BrowserThread::PostTask( 292 BrowserThread::PostTask(
291 BrowserThread::FILE, FROM_HERE, 293 BrowserThread::FILE, FROM_HERE,
292 // Callback takes ownership of |data|: 294 // Callback takes ownership of |data|:
293 base::Bind(&AudioFileWriter::Write, base::Unretained(file_writer_.get()), 295 base::Bind(&AudioFileWriter::Write, base::Unretained(file_writer_.get()),
294 base::Owned(data.release()))); 296 base::Owned(data.release())));
295 } 297 }
296 298
297 bool AudioInputDebugWriter::WillWrite() { 299 bool AudioDebugFileWriter::WillWrite() {
298 // Note that if this is called from any place other than 300 // Note that if this is called from any place other than
299 // |client_sequence_checker_| then there is a data race here, but it's fine, 301 // |client_sequence_checker_| then there is a data race here, but it's fine,
300 // because Write() will check for |file_writer_|. So, we are not very precise 302 // because Write() will check for |file_writer_|. So, we are not very precise
301 // here, but it's fine: we can afford missing some data or scheduling some 303 // here, but it's fine: we can afford missing some data or scheduling some
302 // no-op writes. 304 // no-op writes.
303 return !!file_writer_; 305 return !!file_writer_;
304 } 306 }
305 307
306 } // namspace content 308 } // namspace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698