summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorn Potter <lorn.potter@gmail.com>2023-08-11 14:53:06 +1000
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-08-22 05:18:05 +0000
commitd1841e202ce39413a96e4cb0fc5bb8b8066a6f36 (patch)
treee60a34c85f2f28747c2dc85a29eeb16ec4572eef
parentff75ad9bc02676b7eb2d8e8cd4fd9d5c52d04251 (diff)
wasm: use asyncify to await for device enumeration
Fixes: QTBUG-115059 Change-Id: I86a780209d7caf1f2ac4c1709da83fcdb3db1272 Reviewed-by: MikoĊ‚aj Boc <Mikolaj.Boc@qt.io> (cherry picked from commit af0e8d0ce152e3a414e502280e271971fef74ed3) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/multimedia/wasm/qwasmmediadevices.cpp298
-rw-r--r--src/multimedia/wasm/qwasmmediadevices_p.h2
2 files changed, 166 insertions, 134 deletions
diff --git a/src/multimedia/wasm/qwasmmediadevices.cpp b/src/multimedia/wasm/qwasmmediadevices.cpp
index eafa1babf..2f4ff687f 100644
--- a/src/multimedia/wasm/qwasmmediadevices.cpp
+++ b/src/multimedia/wasm/qwasmmediadevices.cpp
@@ -71,6 +71,130 @@ QPlatformAudioSink *QWasmMediaDevices::createAudioSink(const QAudioDevice &devic
return new QWasmAudioSink(deviceInfo.id(), parent);
}
+void QWasmMediaDevices::parseDevices(emscripten::val devices)
+{
+ if (devices.isNull() || devices.isUndefined()) {
+ qWarning() << "Something went wrong enumerating devices";
+ return;
+ }
+
+ QList<std::string> cameraDevicesToRemove = m_cameraDevices.keys();
+ QList<std::string> audioOutputsToRemove;
+ QList<std::string> audioInputsToRemove;
+
+ if (m_firstInit) {
+ m_firstInit = false;
+ qWarning() << "m_audioInputs count" << m_audioInputs.count();
+
+ } else {
+ audioOutputsToRemove = m_audioOutputs.keys();
+ audioInputsToRemove = m_audioInputs.keys();
+ m_audioInputsAdded = false;
+ m_audioOutputsAdded = false;
+ }
+ m_videoInputsAdded = false;
+
+ bool m_videoInputsRemoved = false;
+ bool m_audioInputsRemoved = false;
+ bool m_audioOutputsRemoved = false;
+
+ for (int i = 0; i < devices["length"].as<int>(); i++) {
+
+ emscripten::val mediaDevice = devices[i];
+
+ std::string defaultDeviceLabel = "";
+
+ const std::string deviceKind = mediaDevice["kind"].as<std::string>();
+ const std::string label = mediaDevice["label"].as<std::string>();
+ const std::string deviceId = mediaDevice["deviceId"].as<std::string>();
+
+ qCDebug(qWasmMediaDevices) << QString::fromStdString(deviceKind)
+ << QString::fromStdString(deviceId)
+ << QString::fromStdString(label);
+
+ if (deviceKind.empty())
+ continue;
+
+ if (deviceId == std::string("default")) {
+ // chrome specifies the default device with this as deviceId
+ // and then prepends "Default - " with the name of the device
+ // in the label
+ if (label.empty())
+ continue;
+
+ defaultDeviceLabel = label;
+ continue;
+ }
+
+ const bool isDefault = false; // FIXME
+ // (defaultDeviceLabel.find(label) != std::string::npos);
+
+ if (deviceKind == std::string("videoinput")) {
+ if (!m_cameraDevices.contains(deviceId)) {
+ QCameraDevicePrivate *camera = new QCameraDevicePrivate; // QSharedData
+ camera->id = QString::fromStdString(deviceId).toUtf8();
+ camera->description = QString::fromUtf8(label.c_str());
+ camera->isDefault = isDefault;
+
+ m_cameraDevices.insert(deviceId, camera->create());
+ m_videoInputsAdded = true;
+ }
+ cameraDevicesToRemove.removeOne(deviceId);
+ } else if (deviceKind == std::string("audioinput")) {
+ if (!m_audioInputs.contains(deviceId)) {
+ m_audioInputs.insert(deviceId,
+ (new QWasmAudioDevice(deviceId.c_str(), label.c_str(),
+ isDefault, QAudioDevice::Input))
+ ->create());
+
+ m_audioInputsAdded = true;
+ }
+ audioInputsToRemove.removeOne(deviceId);
+ } else if (deviceKind == std::string("audiooutput")) {
+ if (!m_audioOutputs.contains(deviceId)) {
+ m_audioOutputs.insert(deviceId,
+ (new QWasmAudioDevice(deviceId.c_str(), label.c_str(),
+ isDefault, QAudioDevice::Input))
+ ->create());
+
+ m_audioOutputsAdded = true;
+ }
+ audioOutputsToRemove.removeOne(deviceId);
+ }
+ // if permissions are given label will hold the actual
+ // camera name, such as "Live! Cam Sync 1080p (041e:409d)"
+ }
+ if (!m_firstInit)
+ getOpenALAudioDevices();
+
+ // any left here were removed
+ int j = 0;
+ for (; j < cameraDevicesToRemove.count(); j++) {
+ m_cameraDevices.remove(cameraDevicesToRemove.at(j));
+ }
+ m_videoInputsRemoved = !cameraDevicesToRemove.isEmpty();
+
+ for (j = 0; j < audioInputsToRemove.count(); j++) {
+ m_audioInputs.remove(audioInputsToRemove.at(j));
+ }
+ m_audioInputsRemoved = !audioInputsToRemove.isEmpty();
+
+ for (j = 0; j < audioOutputsToRemove.count(); j++) {
+ m_audioOutputs.remove(audioOutputsToRemove.at(j));
+ }
+ m_audioOutputsRemoved = !audioOutputsToRemove.isEmpty();
+
+ if (m_videoInputsAdded || m_videoInputsRemoved)
+ emit videoInputsChanged();
+ if (m_audioInputsAdded || m_audioInputsRemoved)
+ emit audioInputsChanged();
+ if (m_audioOutputsAdded || m_audioOutputsRemoved)
+ emit audioOutputsChanged();
+
+ m_firstInit = false;
+
+}
+
void QWasmMediaDevices::getMediaDevices()
{
emscripten::val navigator = emscripten::val::global("navigator");
@@ -81,140 +205,44 @@ void QWasmMediaDevices::getMediaDevices()
return;
}
- qstdweb::PromiseCallbacks enumerateDevicesCallback{
- .thenFunc =
- [&](emscripten::val devices) {
- if (devices.isNull() || devices.isUndefined()) {
- qWarning() << "Something went wrong enumerating devices";
- return;
- }
-
- QList<std::string> cameraDevicesToRemove = m_cameraDevices.keys();
- QList<std::string> audioInputsToRemove = m_audioInputs.keys();
- QList<std::string> audioOutputsToRemove = m_audioOutputs.keys();
-
- m_videoInputsAdded = false;
- m_audioInputsAdded = false;
- m_audioOutputsAdded = false;
-
- bool m_videoInputsRemoved = false;
- bool m_audioInputsRemoved = false;
- bool m_audioOutputsRemoved = false;
-
- for (int i = 0; i < devices["length"].as<int>(); i++) {
-
- emscripten::val mediaDevice = devices[i];
-
- std::string defaultDeviceLabel = "";
-
- const std::string deviceKind = mediaDevice["kind"].as<std::string>();
- const std::string label = mediaDevice["label"].as<std::string>();
- const std::string deviceId = mediaDevice["deviceId"].as<std::string>();
-
- qCDebug(qWasmMediaDevices) << QString::fromStdString(deviceKind)
- << QString::fromStdString(deviceId)
- << QString::fromStdString(label);
-
- if (deviceKind.empty())
- continue;
-
- if (deviceId == std::string("default")) {
- // chrome specifies the default device with this as deviceId
- // and then prepends "Default - " with the name of the device
- // in the label
- if (label.empty())
- continue;
-
- defaultDeviceLabel = label;
- continue;
- }
-
- const bool isDefault =
- (defaultDeviceLabel.find(label) != std::string::npos);
-
- if (deviceKind == std::string("videoinput")) {
- if (!m_cameraDevices.contains(deviceId)) {
- QCameraDevicePrivate *camera = new QCameraDevicePrivate; // QSharedData
- camera->id = QString::fromStdString(deviceId).toUtf8();
- camera->description = QString::fromUtf8(label.c_str());
- camera->isDefault = isDefault;
-
- m_cameraDevices.insert(deviceId, camera->create());
- m_videoInputsAdded = true;
- }
- cameraDevicesToRemove.removeOne(deviceId);
-
- } else if (deviceKind == std::string("audioinput")) {
- if (!m_audioInputs.contains(deviceId)) {
- m_audioInputs.insert(deviceId,
- (new QWasmAudioDevice(deviceId.c_str(), label.c_str(),
- isDefault, QAudioDevice::Input))
- ->create());
-
- m_audioInputsAdded = true;
- }
- audioInputsToRemove.removeOne(deviceId);
- } else if (deviceKind == std::string("audiooutput")) {
- if (!m_audioOutputs.contains(deviceId)) {
- m_audioOutputs.insert(deviceId,
- (new QWasmAudioDevice(deviceId.c_str(), label.c_str(),
- isDefault, QAudioDevice::Input))
- ->create());
-
- m_audioOutputsAdded = true;
- }
- audioOutputsToRemove.removeOne(deviceId);
- }
- // if permissions are given label will hold the actual
- // camera name, such as "Live! Cam Sync 1080p (041e:409d)"
- }
-
- // any left here were removed
- int j = 0;
- for (; j < cameraDevicesToRemove.count(); j++) {
- m_cameraDevices.remove(cameraDevicesToRemove.at(j));
- }
- m_videoInputsRemoved = !cameraDevicesToRemove.isEmpty();
-
- for (j = 0; j < audioInputsToRemove.count(); j++) {
- m_audioInputs.remove(audioInputsToRemove.at(j));
- }
- m_audioInputsRemoved = !audioInputsToRemove.isEmpty();
-
- for (j = 0; j < audioOutputsToRemove.count(); j++) {
- m_audioOutputs.remove(audioOutputsToRemove.at(j));
- }
- m_audioOutputsRemoved = !audioOutputsToRemove.isEmpty();
-
- if (m_videoInputsAdded || m_videoInputsRemoved)
- emit videoInputsChanged();
- if (m_audioInputsAdded || m_audioInputsRemoved)
- emit audioInputsChanged();
- if (m_audioOutputsAdded || m_audioOutputsRemoved)
- emit audioOutputsChanged();
-
- },
- .catchFunc =
- [this](emscripten::val error) {
- qWarning() << "mediadevices enumerateDevices fail"
- << QString::fromStdString(error["name"].as<std::string>())
- << QString::fromStdString(error["message"].as<std::string>());
- m_initDone = false;
- }
- };
-
- qstdweb::Promise::make(m_jsMediaDevicesInterface,
- QStringLiteral("enumerateDevices"),
- std::move(enumerateDevicesCallback));
-
- // setup devicechange monitor
- m_deviceChangedCallback = std::make_unique<qstdweb::EventCallback>(
- m_jsMediaDevicesInterface, "devicechange",
- [this, enumerateDevicesCallback](emscripten::val) {
- qstdweb::Promise::make(m_jsMediaDevicesInterface,
- QStringLiteral("enumerateDevices"),
- std::move(enumerateDevicesCallback));
- });
+ if (qstdweb::haveAsyncify()) {
+#ifdef QT_HAVE_EMSCRIPTEN_ASYNCIFY
+ emscripten::val devicesList = m_jsMediaDevicesInterface.call<emscripten::val>("enumerateDevices").await();
+ if (devicesList.isNull() || devicesList.isUndefined()) {
+ qWarning() << "devices list error";
+ return;
+ }
+
+ parseDevices(devicesList);
+#endif
+ } else {
+ qstdweb::PromiseCallbacks enumerateDevicesCallback{
+ .thenFunc =
+ [&](emscripten::val devices) {
+ parseDevices(devices);
+ },
+ .catchFunc =
+ [this](emscripten::val error) {
+ qWarning() << "mediadevices enumerateDevices fail"
+ << QString::fromStdString(error["name"].as<std::string>())
+ << QString::fromStdString(error["message"].as<std::string>());
+ m_initDone = false;
+ }
+ };
+
+ qstdweb::Promise::make(m_jsMediaDevicesInterface,
+ QStringLiteral("enumerateDevices"),
+ std::move(enumerateDevicesCallback));
+
+ // setup devicechange monitor
+ m_deviceChangedCallback = std::make_unique<qstdweb::EventCallback>(
+ m_jsMediaDevicesInterface, "devicechange",
+ [this, enumerateDevicesCallback](emscripten::val) {
+ qstdweb::Promise::make(m_jsMediaDevicesInterface,
+ QStringLiteral("enumerateDevices"),
+ std::move(enumerateDevicesCallback));
+ });
+ }
}
void QWasmMediaDevices::getOpenALAudioDevices()
@@ -228,6 +256,7 @@ void QWasmMediaDevices::getOpenALAudioDevices()
(new QWasmAudioDevice(capture, "WebAssembly audio capture device",
true, QAudioDevice::Input))
->create());
+ m_audioInputsAdded = true;
emit audioInputsChanged();
}
@@ -240,6 +269,7 @@ void QWasmMediaDevices::getOpenALAudioDevices()
->create());
emit audioOutputsChanged();
}
+ m_firstInit = true;
}
QT_END_NAMESPACE
diff --git a/src/multimedia/wasm/qwasmmediadevices_p.h b/src/multimedia/wasm/qwasmmediadevices_p.h
index 77d6ab257..b97036f97 100644
--- a/src/multimedia/wasm/qwasmmediadevices_p.h
+++ b/src/multimedia/wasm/qwasmmediadevices_p.h
@@ -67,6 +67,7 @@ private:
void updateCameraDevices();
void getMediaDevices();
void getOpenALAudioDevices();
+ void parseDevices(emscripten::val devices);
QMap <std::string, QAudioDevice> m_audioOutputs;
QMap <std::string, QAudioDevice> m_audioInputs;
@@ -80,6 +81,7 @@ private:
bool m_audioOutputsAdded = false;
emscripten::val m_jsMediaDevicesInterface = emscripten::val::undefined();
bool m_initDone = false;
+ bool m_firstInit = false;
};
QT_END_NAMESPACE