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 74% |
rename from content/browser/renderer_host/media/audio_debug_file_writer.cc |
rename to media/audio/audio_debug_file_writer.cc |
index 1656a1cca232a2d020da4a5df59f96eb597bafdf..85bf3a46c1b9f4a16843ba9fc9b4ad6123e91852 100644 |
--- a/content/browser/renderer_host/media/audio_debug_file_writer.cc |
+++ b/media/audio/audio_debug_file_writer.cc |
@@ -2,19 +2,19 @@ |
// 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 |
-// 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,77 @@ 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_; |
}; |
+AudioDebugFileWriter::OnThreadDeleter::OnThreadDeleter() {} |
+ |
+AudioDebugFileWriter::OnThreadDeleter::OnThreadDeleter( |
+ const OnThreadDeleter& other) |
+ : task_runner_(other.task_runner_) {} |
+ |
+AudioDebugFileWriter::OnThreadDeleter::OnThreadDeleter( |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
+ : task_runner_(task_runner) {} |
+ |
+AudioDebugFileWriter::OnThreadDeleter::~OnThreadDeleter() {} |
+ |
+// AudioFileWriter deleter. Inspired by |
+// content::BrowserThread::DeleteOnFileThread. |
+void AudioDebugFileWriter::OnThreadDeleter::operator()( |
+ AudioDebugFileWriter::AudioFileWriter* ptr) const { |
+ if (!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, |
+ const AudioParameters& params, |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) { |
+ AudioFileWriterUniquePtr file_writer(new AudioFileWriter(params, task_runner), |
+ OnThreadDeleter(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 +267,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 +281,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 +304,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 +327,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 +349,4 @@ bool AudioDebugFileWriter::WillWrite() { |
return !!file_writer_; |
} |
-} // namspace content |
+} // namspace media |