summaryrefslogtreecommitdiffstats
path: root/ppapi/examples
diff options
context:
space:
mode:
authoryzshen@chromium.org <yzshen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-05 02:44:18 +0000
committeryzshen@chromium.org <yzshen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-05 02:44:18 +0000
commit4f01c76ed760e674cb86f2b0a17a779431e2aa71 (patch)
treea2d874fb3f21b65e07f0d75db567487f6bd4a38a /ppapi/examples
parent4afef6e27ecbcf6430c5d37881eca04c6b1f8d78 (diff)
downloadchromium_src-4f01c76ed760e674cb86f2b0a17a779431e2aa71.zip
chromium_src-4f01c76ed760e674cb86f2b0a17a779431e2aa71.tar.gz
chromium_src-4f01c76ed760e674cb86f2b0a17a779431e2aa71.tar.bz2
Introduce PPB_AudioInput_Dev v0.3 and refactor the device enumeration code:
- Add MonitorDeviceChange() for PPB_AudioInput_Dev. - Change EnumerateDevices() to use PP_ArrayOutput. - Move device enumeration code out of the audio input implementation, so that it can be shared by video capture. - Update the audio_input manual test. - Add unittests for the device enumeration code. TEST=None BUG=137799 Review URL: https://chromiumcodereview.appspot.com/11411047 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@171132 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/examples')
-rw-r--r--ppapi/examples/audio_input/audio_input.cc107
-rw-r--r--ppapi/examples/audio_input/audio_input.html97
2 files changed, 146 insertions, 58 deletions
diff --git a/ppapi/examples/audio_input/audio_input.cc b/ppapi/examples/audio_input/audio_input.cc
index 11efa63..e2df2b8 100644
--- a/ppapi/examples/audio_input/audio_input.cc
+++ b/ppapi/examples/audio_input/audio_input.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdlib.h>
#include <string.h>
#include <algorithm>
@@ -32,6 +33,7 @@ namespace {
const PP_AudioSampleRate kSampleFrequency = PP_AUDIOSAMPLERATE_44100;
const uint32_t kSampleCount = 1024;
const uint32_t kChannelCount = 1;
+const char* const kDelimiter = "#__#";
} // namespace
@@ -48,6 +50,7 @@ class MyInstance : public pp::Instance {
waiting_for_flush_completion_(false) {
}
virtual ~MyInstance() {
+ device_detector_.MonitorDeviceChange(NULL, NULL);
audio_input_.Close();
delete[] samples_;
@@ -62,7 +65,7 @@ class MyInstance : public pp::Instance {
samples_ = new int16_t[sample_count_ * channel_count_];
memset(samples_, 0, sample_count_ * channel_count_ * sizeof(int16_t));
- audio_input_ = pp::AudioInput_Dev(this);
+ device_detector_ = pp::AudioInput_Dev(this);
// Try to ensure that we pick up a new set of samples between each
// timer-generated repaint.
@@ -88,10 +91,15 @@ class MyInstance : public pp::Instance {
if (message_data.is_string()) {
std::string event = message_data.AsString();
if (event == "PageInitialized") {
+ int32_t result = device_detector_.MonitorDeviceChange(
+ &MyInstance::MonitorDeviceChangeCallback, this);
+ if (result != PP_OK)
+ PostMessage(pp::Var("MonitorDeviceChangeFailed"));
+
pp::CompletionCallbackWithOutput<std::vector<pp::DeviceRef_Dev> >
callback = callback_factory_.NewCallbackWithOutput(
&MyInstance::EnumerateDevicesFinished);
- int32_t result = audio_input_.EnumerateDevices(callback);
+ result = device_detector_.EnumerateDevices(callback);
if (result != PP_OK_COMPLETIONPENDING)
PostMessage(pp::Var("EnumerationFailed"));
} else if (event == "UseDefault") {
@@ -100,13 +108,20 @@ class MyInstance : public pp::Instance {
Stop();
} else if (event == "Start") {
Start();
- }
- } else if (message_data.is_number()) {
- int index = message_data.AsInt();
- if (index >= 0 && index < static_cast<int>(devices_.size())) {
- Open(devices_[index]);
- } else {
- PP_NOTREACHED();
+ } else if (event.find("Monitor:") == 0) {
+ std::string index_str = event.substr(strlen("Monitor:"));
+ int index = atoi(index_str.c_str());
+ if (index >= 0 && index < static_cast<int>(monitor_devices_.size()))
+ Open(monitor_devices_[index]);
+ else
+ PP_NOTREACHED();
+ } else if (event.find("Enumerate:") == 0) {
+ std::string index_str = event.substr(strlen("Enumerate:"));
+ int index = atoi(index_str.c_str());
+ if (index >= 0 && index < static_cast<int>(enumerate_devices_.size()))
+ Open(enumerate_devices_[index]);
+ else
+ PP_NOTREACHED();
}
}
}
@@ -184,24 +199,10 @@ class MyInstance : public pp::Instance {
return image;
}
- // TODO(viettrungluu): Danger! We really should lock, but which thread
- // primitives to use? In any case, the |StopCapture()| in the destructor
- // shouldn't return until this callback is done, so at least we should be
- // writing to a valid region of memory.
- static void CaptureCallback(const void* samples,
- uint32_t num_bytes,
- void* ctx) {
- MyInstance* thiz = static_cast<MyInstance*>(ctx);
- uint32_t buffer_size =
- thiz->sample_count_ * thiz->channel_count_ * sizeof(int16_t);
- PP_DCHECK(num_bytes <= buffer_size);
- PP_DCHECK(num_bytes % (thiz->channel_count_ * sizeof(int16_t)) == 0);
- memcpy(thiz->samples_, samples, num_bytes);
- memset(reinterpret_cast<char*>(thiz->samples_) + num_bytes, 0,
- buffer_size - num_bytes);
- }
-
void Open(const pp::DeviceRef_Dev& device) {
+ audio_input_.Close();
+ audio_input_ = pp::AudioInput_Dev(this);
+
pp::AudioConfig config = pp::AudioConfig(this,
kSampleFrequency,
sample_count_);
@@ -225,13 +226,11 @@ class MyInstance : public pp::Instance {
void EnumerateDevicesFinished(int32_t result,
std::vector<pp::DeviceRef_Dev>& devices) {
- static const char* const kDelimiter = "#__#";
-
if (result == PP_OK) {
- devices_.swap(devices);
- std::string device_names;
- for (size_t index = 0; index < devices_.size(); ++index) {
- pp::Var name = devices_[index].GetName();
+ enumerate_devices_.swap(devices);
+ std::string device_names = "Enumerate:";
+ for (size_t index = 0; index < enumerate_devices_.size(); ++index) {
+ pp::Var name = enumerate_devices_[index].GetName();
PP_DCHECK(name.is_string());
if (index != 0)
@@ -253,6 +252,43 @@ class MyInstance : public pp::Instance {
}
}
+ // TODO(viettrungluu): Danger! We really should lock, but which thread
+ // primitives to use? In any case, the |StopCapture()| in the destructor
+ // shouldn't return until this callback is done, so at least we should be
+ // writing to a valid region of memory.
+ static void CaptureCallback(const void* samples,
+ uint32_t num_bytes,
+ void* ctx) {
+ MyInstance* thiz = static_cast<MyInstance*>(ctx);
+ uint32_t buffer_size =
+ thiz->sample_count_ * thiz->channel_count_ * sizeof(int16_t);
+ PP_DCHECK(num_bytes <= buffer_size);
+ PP_DCHECK(num_bytes % (thiz->channel_count_ * sizeof(int16_t)) == 0);
+ memcpy(thiz->samples_, samples, num_bytes);
+ memset(reinterpret_cast<char*>(thiz->samples_) + num_bytes, 0,
+ buffer_size - num_bytes);
+ }
+
+ static void MonitorDeviceChangeCallback(void* user_data,
+ uint32_t device_count,
+ const PP_Resource devices[]) {
+ MyInstance* thiz = static_cast<MyInstance*>(user_data);
+
+ std::string device_names = "Monitor:";
+ thiz->monitor_devices_.clear();
+ thiz->monitor_devices_.reserve(device_count);
+ for (size_t index = 0; index < device_count; ++index) {
+ thiz->monitor_devices_.push_back(pp::DeviceRef_Dev(devices[index]));
+ pp::Var name = thiz->monitor_devices_.back().GetName();
+ PP_DCHECK(name.is_string());
+
+ if (index != 0)
+ device_names += kDelimiter;
+ device_names += name.AsString();
+ }
+ thiz->PostMessage(pp::Var(device_names));
+ }
+
pp::CompletionCallbackFactory<MyInstance> callback_factory_;
uint32_t sample_count_;
@@ -267,9 +303,14 @@ class MyInstance : public pp::Instance {
bool pending_paint_;
bool waiting_for_flush_completion_;
+ // There is no need to have two resources to do capturing and device detecting
+ // separately. However, this makes the code of monitoring device change
+ // easier.
pp::AudioInput_Dev audio_input_;
+ pp::AudioInput_Dev device_detector_;
- std::vector<pp::DeviceRef_Dev> devices_;
+ std::vector<pp::DeviceRef_Dev> enumerate_devices_;
+ std::vector<pp::DeviceRef_Dev> monitor_devices_;
};
class MyModule : public pp::Module {
diff --git a/ppapi/examples/audio_input/audio_input.html b/ppapi/examples/audio_input/audio_input.html
index 8fa043c..2c764bb 100644
--- a/ppapi/examples/audio_input/audio_input.html
+++ b/ppapi/examples/audio_input/audio_input.html
@@ -8,13 +8,17 @@
<head>
<title>Audio Input Example</title>
<script type="text/javascript">
- var device_array = [];
+ var monitor_device_array = [];
+ var enumerate_device_array = [];
+ var monitor_notification_count = 0;
function HandleMessage(message_event) {
if (message_event.data) {
var status = document.getElementById('status');
if (message_event.data == 'EnumerationFailed') {
status.innerText = 'Device enumeration failed!';
+ } else if (message_event.data == 'MonitorDeviceChangeFailed') {
+ status.innerText = 'Monitor device change failed!';
} else if (message_event.data == 'OpenFailed') {
status.innerText = 'Open device failed!';
} else if (message_event.data == 'StartFailed') {
@@ -22,23 +26,60 @@
} else if (message_event.data == 'StopFailed') {
status.innerText = 'Stop capturing failed!';
} else {
- device_array = message_event.data.split('#__#');
-
- var list = document.getElementById('device_list');
- for (var i = 0; i < device_array.length; ++i) {
- var list_item = document.createElement('li');
- var link = document.createElement('a');
- link.href = 'javascript:UseDesignatedDevice(' + i + ');';
- link.innerText = device_array[i];
- list_item.appendChild(link);
- list.appendChild(list_item);
- }
+ AddDevices(message_event.data);
}
}
}
- function UseDesignatedDevice(index) {
- UseDevice(device_array[index], index);
+ function AddDevices(command) {
+ var serialized_names = '';
+ var is_monitor = false;
+ if (command.search('Monitor:') == 0) {
+ serialized_names = command.substr(8);
+ is_monitor = true;
+ monitor_notification_count++;
+ var counter = document.getElementById('notification_counter');
+ counter.innerText = monitor_notification_count;
+ } else if (command.search('Enumerate:') == 0) {
+ serialized_names = command.substr(10);
+ } else {
+ status.innerText = 'Unrecognized command!';
+ return;
+ }
+
+ var storage = serialized_names.length != 0 ?
+ serialized_names.split('#__#') : [];
+ if (is_monitor)
+ monitor_device_array = storage;
+ else
+ enumerate_device_array = storage;
+
+ var list = document.getElementById(
+ is_monitor ? 'monitor_list' : 'enumerate_list');
+ while (list.firstChild)
+ list.removeChild(list.firstChild);
+
+ for (var i = 0; i < storage.length; ++i) {
+ AppendDevice(
+ list, storage[i],
+ 'javascript:UseDesignatedDevice(' + is_monitor + ',' + i + ');');
+ }
+ }
+
+ function AppendDevice(list, text, href) {
+ var list_item = document.createElement('li');
+ var link = document.createElement('a');
+ link.href = href;
+ link.innerText = text;
+ list_item.appendChild(link);
+ list.appendChild(list_item);
+ }
+
+ function UseDesignatedDevice(is_monitor, index) {
+ if (is_monitor)
+ UseDevice(monitor_device_array[index], 'Monitor:' + index);
+ else
+ UseDevice(enumerate_device_array[index], 'Enumerate:' + index);
}
function UseDefaultDevice() {
@@ -50,12 +91,6 @@
in_use_device.innerText = display_text;
var plugin = document.getElementById('plugin');
plugin.postMessage(command);
-
- var available_devices = document.getElementById('available_devices');
- available_devices.parentNode.removeChild(available_devices);
-
- var control_panel = document.getElementById('control_panel');
- control_panel.style.display = 'block';
}
function Stop() {
@@ -70,7 +105,7 @@
function Initialize() {
var plugin = document.getElementById('plugin');
- plugin.addEventListener('message', HandleMessage, false);
+ plugin.addEventListener('message', HandleMessage, false)
plugin.postMessage('PageInitialized');
}
@@ -86,14 +121,26 @@
</div>
<div id="available_devices">
Available device(s), choose one to open:
- <ul id="device_list">
+ <ul>
<li><a href="javascript:UseDefaultDevice();">
- Default - use interface version 0.2 and NULL device ref</a></li>
+ Default - use NULL device ref</a></li>
</ul>
+ <div>
+ <ul>List retrieved by MonitorDeviceChange(), will change when
+ pluging/unpluging devices: (Notifications received:
+ <span style="font-weight:bold" id="notification_counter">0</span>
+ )</ul>
+ <ul id="monitor_list"/>
+ </div>
+ <div>
+ <ul>List retrieved by EnumerateDevices(), never updated after the page is
+ initialized:</ul>
+ <ul id="enumerate_list"/>
+ </div>
</div>
- <div id="control_panel" style="display:none">
+ <div id="control_panel">
<a href="javascript:Stop();">Stop</a>
- <a href="javascript:Start();">Start</a>
+ <a href="javascript:Start();">Start</a> (known issue: crbug.com/161058)
</div>
<div id="status"></div>
</body>