Linux: Depend on liberation-fonts package for RPMs.
[chromium-blink-merge.git] / content / renderer / pepper / pepper_platform_audio_output.cc
blobf5ae3ba0d2b39344f504e07f5b7030c59227d0f5
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
3 // found in the LICENSE file.
5 #include "content/renderer/pepper/pepper_platform_audio_output.h"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/logging.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "build/build_config.h"
13 #include "content/child/child_process.h"
14 #include "content/common/media/audio_messages.h"
15 #include "content/renderer/media/audio_message_filter.h"
16 #include "content/renderer/pepper/audio_helper.h"
17 #include "content/renderer/render_thread_impl.h"
18 #include "media/base/audio_hardware_config.h"
19 #include "ppapi/shared_impl/ppb_audio_config_shared.h"
21 namespace content {
23 // static
24 PepperPlatformAudioOutput* PepperPlatformAudioOutput::Create(
25 int sample_rate,
26 int frames_per_buffer,
27 int source_render_frame_id,
28 AudioHelper* client) {
29 scoped_refptr<PepperPlatformAudioOutput> audio_output(
30 new PepperPlatformAudioOutput());
31 if (audio_output->Initialize(sample_rate,
32 frames_per_buffer,
33 source_render_frame_id,
34 client)) {
35 // Balanced by Release invoked in
36 // PepperPlatformAudioOutput::ShutDownOnIOThread().
37 audio_output->AddRef();
38 return audio_output.get();
40 return NULL;
43 bool PepperPlatformAudioOutput::StartPlayback() {
44 if (ipc_) {
45 io_task_runner_->PostTask(
46 FROM_HERE,
47 base::Bind(&PepperPlatformAudioOutput::StartPlaybackOnIOThread, this));
48 return true;
50 return false;
53 bool PepperPlatformAudioOutput::StopPlayback() {
54 if (ipc_) {
55 io_task_runner_->PostTask(
56 FROM_HERE,
57 base::Bind(&PepperPlatformAudioOutput::StopPlaybackOnIOThread, this));
58 return true;
60 return false;
63 void PepperPlatformAudioOutput::ShutDown() {
64 // Called on the main thread to stop all audio callbacks. We must only change
65 // the client on the main thread, and the delegates from the I/O thread.
66 client_ = NULL;
67 io_task_runner_->PostTask(
68 FROM_HERE,
69 base::Bind(&PepperPlatformAudioOutput::ShutDownOnIOThread, this));
72 void PepperPlatformAudioOutput::OnStateChanged(
73 media::AudioOutputIPCDelegateState state) {}
75 void PepperPlatformAudioOutput::OnDeviceAuthorized(
76 bool success,
77 const media::AudioParameters& output_params) {
78 NOTREACHED();
81 void PepperPlatformAudioOutput::OnStreamCreated(
82 base::SharedMemoryHandle handle,
83 base::SyncSocket::Handle socket_handle,
84 int length) {
85 #if defined(OS_WIN)
86 DCHECK(handle);
87 DCHECK(socket_handle);
88 #else
89 DCHECK(base::SharedMemory::IsHandleValid(handle));
90 DCHECK_NE(-1, socket_handle);
91 #endif
92 DCHECK(length);
94 if (base::ThreadTaskRunnerHandle::Get().get() == main_task_runner_.get()) {
95 // Must dereference the client only on the main thread. Shutdown may have
96 // occurred while the request was in-flight, so we need to NULL check.
97 if (client_)
98 client_->StreamCreated(handle, length, socket_handle);
99 } else {
100 main_task_runner_->PostTask(
101 FROM_HERE, base::Bind(&PepperPlatformAudioOutput::OnStreamCreated, this,
102 handle, socket_handle, length));
106 void PepperPlatformAudioOutput::OnOutputDeviceSwitched(
107 media::SwitchOutputDeviceResult result) {}
109 void PepperPlatformAudioOutput::OnIPCClosed() { ipc_.reset(); }
111 PepperPlatformAudioOutput::~PepperPlatformAudioOutput() {
112 // Make sure we have been shut down. Warning: this will usually happen on
113 // the I/O thread!
114 DCHECK(!ipc_);
115 DCHECK(!client_);
118 PepperPlatformAudioOutput::PepperPlatformAudioOutput()
119 : client_(NULL),
120 main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
121 io_task_runner_(ChildProcess::current()->io_task_runner()) {
124 bool PepperPlatformAudioOutput::Initialize(int sample_rate,
125 int frames_per_buffer,
126 int source_render_frame_id,
127 AudioHelper* client) {
128 DCHECK(client);
129 client_ = client;
131 RenderThreadImpl* const render_thread = RenderThreadImpl::current();
132 ipc_ = render_thread->audio_message_filter()->CreateAudioOutputIPC(
133 source_render_frame_id);
134 CHECK(ipc_);
136 media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
137 media::CHANNEL_LAYOUT_STEREO,
138 sample_rate,
139 ppapi::kBitsPerAudioOutputSample,
140 frames_per_buffer);
142 io_task_runner_->PostTask(
143 FROM_HERE, base::Bind(&PepperPlatformAudioOutput::InitializeOnIOThread,
144 this, params));
145 return true;
148 void PepperPlatformAudioOutput::InitializeOnIOThread(
149 const media::AudioParameters& params) {
150 DCHECK(io_task_runner_->BelongsToCurrentThread());
151 if (ipc_)
152 ipc_->CreateStream(this, params);
155 void PepperPlatformAudioOutput::StartPlaybackOnIOThread() {
156 DCHECK(io_task_runner_->BelongsToCurrentThread());
157 if (ipc_)
158 ipc_->PlayStream();
161 void PepperPlatformAudioOutput::StopPlaybackOnIOThread() {
162 DCHECK(io_task_runner_->BelongsToCurrentThread());
163 if (ipc_)
164 ipc_->PauseStream();
167 void PepperPlatformAudioOutput::ShutDownOnIOThread() {
168 DCHECK(io_task_runner_->BelongsToCurrentThread());
170 // Make sure we don't call shutdown more than once.
171 if (!ipc_)
172 return;
174 ipc_->CloseStream();
175 ipc_.reset();
177 Release(); // Release for the delegate, balances out the reference taken in
178 // PepperPlatformAudioOutput::Create.
181 } // namespace content