summaryrefslogtreecommitdiffstats
path: root/ppapi/shared_impl
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-02 17:17:21 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-02 17:17:21 +0000
commit5d84d01d904a2e5fa3e17b8d9165e63a20351160 (patch)
treedd87a4d94ed6276dc1551cbc5d3c744eb268cebd /ppapi/shared_impl
parent9a80065bad1506ac11163d597ace3295ddbfa8cb (diff)
downloadchromium_src-5d84d01d904a2e5fa3e17b8d9165e63a20351160.zip
chromium_src-5d84d01d904a2e5fa3e17b8d9165e63a20351160.tar.gz
chromium_src-5d84d01d904a2e5fa3e17b8d9165e63a20351160.tar.bz2
Implement audio proxy for Pepper.
In addition to the basic proxying, this required some changes to the dispatcher and process infrastructure to get the handles of the processes available when I need them so I can duplicate the shared memory handles properly into the different processes. TEST=none BUG=none Review URL: http://codereview.chromium.org/4985001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@68026 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/shared_impl')
-rw-r--r--ppapi/shared_impl/DEPS4
-rw-r--r--ppapi/shared_impl/README.txt2
-rw-r--r--ppapi/shared_impl/audio_impl.cc96
-rw-r--r--ppapi/shared_impl/audio_impl.h85
4 files changed, 187 insertions, 0 deletions
diff --git a/ppapi/shared_impl/DEPS b/ppapi/shared_impl/DEPS
new file mode 100644
index 0000000..84fea55
--- /dev/null
+++ b/ppapi/shared_impl/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+ "+base",
+ "-ppapi/cpp",
+]
diff --git a/ppapi/shared_impl/README.txt b/ppapi/shared_impl/README.txt
new file mode 100644
index 0000000..71ff8d6
--- /dev/null
+++ b/ppapi/shared_impl/README.txt
@@ -0,0 +1,2 @@
+This directory contains implementation code for PPAPI that needs to be shared
+between the backend implemntation in the renderer and in the proxy.
diff --git a/ppapi/shared_impl/audio_impl.cc b/ppapi/shared_impl/audio_impl.cc
new file mode 100644
index 0000000..83b73f6
--- /dev/null
+++ b/ppapi/shared_impl/audio_impl.cc
@@ -0,0 +1,96 @@
+// Copyright (c) 2010 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 "ppapi/shared_impl/audio_impl.h"
+
+#include "base/logging.h"
+
+namespace pp {
+namespace shared_impl {
+
+AudioImpl::AudioImpl()
+ : playing_(false),
+ shared_memory_size_(0),
+ callback_(NULL),
+ user_data_(NULL) {
+}
+
+AudioImpl::~AudioImpl() {
+ // Closing the socket causes the thread to exit - wait for it.
+ socket_->Close();
+ if (audio_thread_.get()) {
+ audio_thread_->Join();
+ audio_thread_.reset();
+ }
+}
+
+void AudioImpl::SetCallback(PPB_Audio_Callback callback, void* user_data) {
+ callback_ = callback;
+ user_data_ = user_data;
+}
+
+void AudioImpl::SetStartPlaybackState() {
+ DCHECK(!playing_);
+ DCHECK(!audio_thread_.get());
+
+ // If the socket doesn't exist, that means that the plugin has started before
+ // the browser has had a chance to create all the shared memory info and
+ // notify us. This is a common case. In this case, we just set the playing_
+ // flag and the playback will automatically start when that data is available
+ // in SetStreamInfo.
+ if (callback_ && socket_.get())
+ StartThread();
+ playing_ = true;
+}
+
+void AudioImpl::SetStopPlaybackState() {
+ DCHECK(playing_);
+
+ if (audio_thread_.get()) {
+ audio_thread_->Join();
+ audio_thread_.reset();
+ }
+ playing_ = false;
+}
+
+void AudioImpl::SetStreamInfo(base::SharedMemoryHandle shared_memory_handle,
+ size_t shared_memory_size,
+ base::SyncSocket::Handle socket_handle) {
+ socket_.reset(new base::SyncSocket(socket_handle));
+ shared_memory_.reset(new base::SharedMemory(shared_memory_handle, false));
+ shared_memory_size_ = shared_memory_size;
+
+ if (callback_) {
+ shared_memory_->Map(shared_memory_size_);
+
+ // In common case StartPlayback() was called before StreamCreated().
+ if (playing_)
+ StartThread();
+ }
+}
+
+void AudioImpl::StartThread() {
+ DCHECK(callback_);
+ DCHECK(!audio_thread_.get());
+ audio_thread_.reset(new base::DelegateSimpleThread(
+ this, "plugin_audio_thread"));
+ audio_thread_->Start();
+}
+
+void AudioImpl::Run() {
+ int pending_data;
+ void* buffer = shared_memory_->memory();
+
+ while (sizeof(pending_data) ==
+ socket_->Receive(&pending_data, sizeof(pending_data)) &&
+ pending_data >= 0) {
+ // Exit the thread on pause.
+ if (pending_data < 0)
+ return;
+ callback_(buffer, shared_memory_size_, user_data_);
+ }
+}
+
+} // namespace shared_impl
+} // namespace pp
diff --git a/ppapi/shared_impl/audio_impl.h b/ppapi/shared_impl/audio_impl.h
new file mode 100644
index 0000000..b4cb077
--- /dev/null
+++ b/ppapi/shared_impl/audio_impl.h
@@ -0,0 +1,85 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_SHARED_IMPL_AUDIO_IMPL_H_
+#define PPAPI_SHARED_IMPL_AUDIO_IMPL_H_
+
+#include "base/scoped_ptr.h"
+#include "base/simple_thread.h"
+#include "base/shared_memory.h"
+#include "base/sync_socket.h"
+#include "ppapi/c/dev/ppb_audio_dev.h"
+
+namespace pp {
+namespace shared_impl {
+
+// Implements the logic to map shared memory and run the audio thread signaled
+// from the sync socket. Both the proxy and the renderer implementation use
+// this code.
+class AudioImpl : public base::DelegateSimpleThread::Delegate {
+ public:
+ AudioImpl();
+ virtual ~AudioImpl();
+
+ bool playing() const { return playing_; }
+
+ // Sets the callback information that the background thread will use. This
+ // is optional. Without a callback, the thread will not be run. This
+ // non-callback mode is used in the renderer with the proxy, since the proxy
+ // handles the callback entirely within the plugin process.
+ void SetCallback(PPB_Audio_Callback callback, void* user_data);
+
+ // Configures the current state to be playing or not. The caller is
+ // responsible for ensuring the new state is the opposite of the current one.
+ //
+ // This is the implementation for PPB_Audio.Start/StopPlayback, except that
+ // it does not actually notify the audio system to stop playback, it just
+ // configures our object to stop generating callbacks. The actual stop
+ // playback request will be done in the derived classes and will be different
+ // from the proxy and the renderer.
+ void SetStartPlaybackState();
+ void SetStopPlaybackState();
+
+ // Sets the shared memory and socket handles. This will automatically start
+ // playback if we're currently set to play.
+ void SetStreamInfo(base::SharedMemoryHandle shared_memory_handle,
+ size_t shared_memory_size,
+ base::SyncSocket::Handle socket_handle);
+
+ private:
+ // Starts execution of the audio thread.
+ void StartThread();
+
+ // DelegateSimpleThread::Delegate implementation. Run on the audio thread.
+ void Run();
+
+ // True if playing the stream.
+ bool playing_;
+
+ // Socket used to notify us when audio is ready to accept new samples. This
+ // pointer is created in StreamCreated().
+ scoped_ptr<base::SyncSocket> socket_;
+
+ // Sample buffer in shared memory. This pointer is created in
+ // StreamCreated(). The memory is only mapped when the audio thread is
+ // created.
+ scoped_ptr<base::SharedMemory> shared_memory_;
+
+ // The size of the sample buffer in bytes.
+ size_t shared_memory_size_;
+
+ // When the callback is set, this thread is spawned for calling it.
+ scoped_ptr<base::DelegateSimpleThread> audio_thread_;
+
+ // Callback to call when audio is ready to accept new samples.
+ PPB_Audio_Callback callback_;
+
+ // User data pointer passed verbatim to the callback function.
+ void* user_data_;
+};
+
+} // namespace shared_impl
+} // namespace pp
+
+#endif // PPAPI_SHARED_IMPL_AUDIO_IMPL_H_