Chromium Code Reviews| Index: media/audio/audio_debug_file_writer.cc |
| diff --git a/content/browser/renderer_host/media/audio_debug_file_writer.cc b/media/audio/audio_debug_file_writer.cc |
| similarity index 75% |
| rename from content/browser/renderer_host/media/audio_debug_file_writer.cc |
| rename to media/audio/audio_debug_file_writer.cc |
| index 1656a1cca232a2d020da4a5df59f96eb597bafdf..53ec01c905f2ce53e79a12dc340cd5849ef9ec1a 100644 |
| --- a/content/browser/renderer_host/media/audio_debug_file_writer.cc |
| +++ b/media/audio/audio_debug_file_writer.cc |
| @@ -1,20 +1,20 @@ |
| -// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| -#include "content/browser/renderer_host/media/audio_debug_file_writer.h" |
| +#include "media/audio/audio_debug_file_writer.h" |
| #include <stdint.h> |
| #include <array> |
| #include <utility> |
| +#include "base/bind.h" |
| #include "base/logging.h" |
| #include "base/memory/ptr_util.h" |
| #include "base/sys_byteorder.h" |
| -#include "content/public/browser/browser_thread.h" |
| #include "media/base/audio_bus.h" |
| -namespace content { |
| +namespace media { |
| namespace { |
| @@ -63,7 +63,9 @@ class CharBufferWriter { |
| size_ += data_size; |
| } |
| - void Write(const char(&data)[4]) { Write(static_cast<const char*>(data), 4); } |
| + void Write(const char (&data)[4]) { |
| + Write(static_cast<const char*>(data), 4); |
| + } |
| void WriteLE16(uint16_t data) { |
| uint16_t val = base::ByteSwapToLE16(data); |
| @@ -131,22 +133,30 @@ void WriteWavHeader(WavHeaderBuffer* buf, |
| } // namespace |
| // Manages the debug recording file and writes to it. Can be created on any |
|
DaleCurtis
2017/02/21 18:00:58
Do we still need this inner class setup?
Henrik Grunell
2017/02/21 21:07:52
I don't think that has changed because of the move
|
| -// thread. All the operations must be executed on FILE thread. Must be destroyed |
| -// on FILE thread. |
| +// thread. All the operations must be executed on |task_runner_|. Must be |
| +// destroyed on |task_runner_|. |
| class AudioDebugFileWriter::AudioFileWriter { |
| public: |
| - static AudioFileWriterUniquePtr Create(const base::FilePath& file_name, |
| - const media::AudioParameters& params); |
| + static AudioFileWriterUniquePtr Create( |
| + const base::FilePath& file_name, |
| + const AudioParameters& params, |
| + scoped_refptr<base::SingleThreadTaskRunner> task_runner); |
| ~AudioFileWriter(); |
| // Write data from |data| to file. |
| - void Write(const media::AudioBus* data); |
| + void Write(const AudioBus* data); |
| + |
| + scoped_refptr<base::SingleThreadTaskRunner> task_runner() { |
| + return task_runner_; |
| + } |
| private: |
| - AudioFileWriter(const media::AudioParameters& params); |
| + AudioFileWriter(const AudioParameters& params, |
| + scoped_refptr<base::SingleThreadTaskRunner> task_runner); |
| - // Write wave header to file. Called on the FILE thread twice: on construction |
| + // Write wave header to file. Called on the |task_runner_| twice: on |
| + // construction |
| // of AudioFileWriter size of the wave data is unknown, so the header is |
| // written with zero sizes; then on destruction it is re-written with the |
| // actual size info accumulated throughout the object lifetime. |
| @@ -161,44 +171,64 @@ class AudioDebugFileWriter::AudioFileWriter { |
| uint64_t samples_; |
| // Input audio parameters required to build wave header. |
| - const media::AudioParameters params_; |
| + const AudioParameters params_; |
| // Intermediate buffer to be written to file. Interleaved 16 bit audio data. |
| std::unique_ptr<int16_t[]> interleaved_data_; |
| int interleaved_data_size_; |
| + |
| + // The task runner this class operates on. |
| + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| }; |
| +// AudioFileWriter deleter. Inspired by |
| +// content::BrowserThread::DeleteOnFileThread. |
| +void AudioDebugFileWriter::DeleteOnFileThread::operator()( |
| + AudioFileWriter* ptr) const { |
| + if (!ptr->task_runner()->DeleteSoon(FROM_HERE, ptr)) { |
| +#if defined(UNIT_TEST) |
| + // Only logged under unit testing because leaks at shutdown |
| + // are acceptable under normal circumstances. |
| + LOG(ERROR) << "DeleteSoon failed for AudioDebugFileWriter::AudioFileWriter"; |
| +#endif |
| + } |
| +} |
| + |
| // static |
| AudioDebugFileWriter::AudioFileWriterUniquePtr |
| AudioDebugFileWriter::AudioFileWriter::Create( |
| const base::FilePath& file_name, |
| - const media::AudioParameters& params) { |
| - AudioFileWriterUniquePtr file_writer(new AudioFileWriter(params)); |
| - |
| - // base::Unretained is safe, because destructor is called on FILE thread or on |
| - // FILE message loop destruction. |
| - BrowserThread::PostTask( |
| - BrowserThread::FILE, FROM_HERE, |
| - base::Bind(&AudioFileWriter::CreateRecordingFile, |
| - base::Unretained(file_writer.get()), file_name)); |
| + const AudioParameters& params, |
| + scoped_refptr<base::SingleThreadTaskRunner> task_runner) { |
| + AudioFileWriterUniquePtr file_writer( |
| + new AudioFileWriter(params, task_runner)); |
| + |
| + // base::Unretained is safe, because destructor is called on |
| + // |task_runner|. |
| + task_runner->PostTask( |
| + FROM_HERE, base::Bind(&AudioFileWriter::CreateRecordingFile, |
| + base::Unretained(file_writer.get()), file_name)); |
| return file_writer; |
| } |
| AudioDebugFileWriter::AudioFileWriter::AudioFileWriter( |
| - const media::AudioParameters& params) |
| - : samples_(0), params_(params), interleaved_data_size_(0) { |
| + const AudioParameters& params, |
| + scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
| + : samples_(0), |
| + params_(params), |
| + interleaved_data_size_(0), |
| + task_runner_(std::move(task_runner)) { |
| DCHECK_EQ(params.bits_per_sample(), kBytesPerSample * 8); |
| } |
| AudioDebugFileWriter::AudioFileWriter::~AudioFileWriter() { |
| - DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| + DCHECK(task_runner_->BelongsToCurrentThread()); |
| if (file_.IsValid()) |
| WriteHeader(); |
| } |
| -void AudioDebugFileWriter::AudioFileWriter::Write( |
| - const media::AudioBus* data) { |
| - DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| +void AudioDebugFileWriter::AudioFileWriter::Write(const AudioBus* data) { |
| + DCHECK(task_runner_->BelongsToCurrentThread()); |
| if (!file_.IsValid()) |
| return; |
| @@ -224,7 +254,7 @@ void AudioDebugFileWriter::AudioFileWriter::Write( |
| } |
| void AudioDebugFileWriter::AudioFileWriter::WriteHeader() { |
| - DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| + DCHECK(task_runner_->BelongsToCurrentThread()); |
| if (!file_.IsValid()) |
| return; |
| WavHeaderBuffer buf; |
| @@ -238,7 +268,7 @@ void AudioDebugFileWriter::AudioFileWriter::WriteHeader() { |
| void AudioDebugFileWriter::AudioFileWriter::CreateRecordingFile( |
| const base::FilePath& file_name) { |
| - DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| + DCHECK(task_runner_->BelongsToCurrentThread()); |
| DCHECK(!file_.IsValid()); |
| file_ = base::File(file_name, |
| @@ -261,19 +291,20 @@ void AudioDebugFileWriter::AudioFileWriter::CreateRecordingFile( |
| } |
| AudioDebugFileWriter::AudioDebugFileWriter( |
| - const media::AudioParameters& params) |
| - : params_(params) { |
| + const AudioParameters& params, |
| + scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) |
| + : params_(params), file_task_runner_(std::move(file_task_runner)) { |
| client_sequence_checker_.DetachFromSequence(); |
| } |
| AudioDebugFileWriter::~AudioDebugFileWriter() { |
| - // |file_writer_| will be deleted on FILE thread. |
| + // |file_writer_| will be deleted on |task_runner_|. |
| } |
| void AudioDebugFileWriter::Start(const base::FilePath& file_name) { |
| DCHECK(client_sequence_checker_.CalledOnValidSequence()); |
| DCHECK(!file_writer_); |
| - file_writer_ = AudioFileWriter::Create(file_name, params_); |
| + file_writer_ = AudioFileWriter::Create(file_name, params_, file_task_runner_); |
| } |
| void AudioDebugFileWriter::Stop() { |
| @@ -283,14 +314,14 @@ void AudioDebugFileWriter::Stop() { |
| client_sequence_checker_.DetachFromSequence(); |
| } |
| -void AudioDebugFileWriter::Write(std::unique_ptr<media::AudioBus> data) { |
| +void AudioDebugFileWriter::Write(std::unique_ptr<AudioBus> data) { |
| DCHECK(client_sequence_checker_.CalledOnValidSequence()); |
| if (!file_writer_) |
| return; |
| // base::Unretained for |file_writer_| is safe, see the destructor. |
| - BrowserThread::PostTask( |
| - BrowserThread::FILE, FROM_HERE, |
| + file_task_runner_->PostTask( |
| + FROM_HERE, |
| // Callback takes ownership of |data|: |
| base::Bind(&AudioFileWriter::Write, base::Unretained(file_writer_.get()), |
| base::Owned(data.release()))); |
| @@ -305,4 +336,4 @@ bool AudioDebugFileWriter::WillWrite() { |
| return !!file_writer_; |
| } |
| -} // namspace content |
| +} // namspace media |