summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorn Potter <lorn.potter@gmail.com>2024-03-20 10:55:17 +1000
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2024-04-23 02:55:40 +0000
commit74d5a07f00569bca671a723b51ee5818d3749d48 (patch)
tree09b0dacc7d5d5784f7f8ccc48297efc6c39fc7bb
parent219479431d817079a47e1dbd1d755b32dad685f9 (diff)
wasm: wait for camera ready
also fix up recorder example for handle videoInputChanged Fixes: QTBUG-120622 Change-Id: Icf6be95b1b1e2c299d0810ced1d4d3ff5203f18c Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> (cherry picked from commit 9cc8a43db9e9ba2d951f4503c70ca6cc4cfc0575) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--examples/multimedia/video/recorder/VideoSourceSelect.qml14
-rw-r--r--src/plugins/multimedia/wasm/common/qwasmvideooutput.cpp43
-rw-r--r--src/plugins/multimedia/wasm/common/qwasmvideooutput_p.h1
-rw-r--r--src/plugins/multimedia/wasm/mediacapture/qwasmcamera.cpp13
-rw-r--r--src/plugins/multimedia/wasm/mediacapture/qwasmcamera_p.h2
5 files changed, 52 insertions, 21 deletions
diff --git a/examples/multimedia/video/recorder/VideoSourceSelect.qml b/examples/multimedia/video/recorder/VideoSourceSelect.qml
index 86eded504..7eeed99b9 100644
--- a/examples/multimedia/video/recorder/VideoSourceSelect.qml
+++ b/examples/multimedia/video/recorder/VideoSourceSelect.qml
@@ -46,7 +46,19 @@ Row {
active: windowAvailable
}
- MediaDevices { id: mediaDevices }
+ MediaDevices { id: mediaDevices
+ onVideoInputsChanged: {
+
+ videoSourceModel.populate()
+
+ for (var i = 0; i < videoSourceModel.count; i++) {
+ if (videoSourceModel.get(i).value.type !== 'toggler') {
+ comboBox.currentIndex = i
+ break
+ }
+ }
+ }
+ }
Switch {
id: videoSourceSwitch
diff --git a/src/plugins/multimedia/wasm/common/qwasmvideooutput.cpp b/src/plugins/multimedia/wasm/common/qwasmvideooutput.cpp
index 41b4208d3..764e5f0a5 100644
--- a/src/plugins/multimedia/wasm/common/qwasmvideooutput.cpp
+++ b/src/plugins/multimedia/wasm/common/qwasmvideooutput.cpp
@@ -18,6 +18,7 @@
#include <private/qmemoryvideobuffer_p.h>
#include <private/qvideotexturehelper_p.h>
#include <private/qstdweb_p.h>
+#include <QTimer>
#include <emscripten/bind.h>
#include <emscripten/html5.h>
@@ -96,10 +97,15 @@ void QWasmVideoOutput::start()
}
} break;
case QWasmVideoOutput::Camera: {
+ if (!m_cameraIsReady) {
+ m_shouldBeStarted = true;
+ }
+
emscripten::val stream = m_video["srcObject"];
if (stream.isNull() || stream.isUndefined()) { // camera device
- qCDebug(qWasmMediaVideoOutput) << Q_FUNC_INFO << "ERROR";
+ qCDebug(qWasmMediaVideoOutput) << "ERROR";
emit errorOccured(QMediaPlayer::ResourceError, QStringLiteral("video surface error"));
+ return;
} else {
emscripten::val videoTracks = stream.call<emscripten::val>("getVideoTracks");
if (videoTracks.isNull() || videoTracks.isUndefined()) {
@@ -139,7 +145,7 @@ void QWasmVideoOutput::start()
emscripten::val::module_property("qtVideoFrameTimerCallback"));
} else {
videoFrameTimerCallback();
- }
+ }
}
}
@@ -194,9 +200,10 @@ emscripten::val QWasmVideoOutput::surfaceElement()
void QWasmVideoOutput::setSurface(QVideoSink *surface)
{
- qCDebug(qWasmMediaVideoOutput) << Q_FUNC_INFO << surface << m_wasmSink;
- if (surface == m_wasmSink)
+ if (!surface || surface == m_wasmSink) {
+ qWarning() << "Surface not ready";
return;
+ }
m_wasmSink = surface;
}
@@ -281,6 +288,10 @@ void QWasmVideoOutput::addCameraSourceElement(const std::string &id)
m_video.set("srcObject", stream);
m_cameraIsReady = true;
+ if (m_shouldBeStarted) {
+ start();
+ m_shouldBeStarted = false;
+ }
},
.catchFunc =
[](emscripten::val error) {
@@ -334,8 +345,6 @@ void QWasmVideoOutput::setSource(QIODevice *stream)
// only Safari currently supports Blob with srcObject
m_video.set("srcObject", contentBlob.val());
}
-
- m_video.call<void>("load");
}
void QWasmVideoOutput::setVolume(qreal volume)
@@ -462,7 +471,7 @@ void QWasmVideoOutput::createOffscreenElement(const QSize &offscreenSize)
{
qCDebug(qWasmMediaVideoOutput) << Q_FUNC_INFO;
- if (m_hasVideoFrame)
+ if (m_hasVideoFrame) // VideoFrame does not require offscreen canvas/context
return;
// create offscreen element for grabbing frames
@@ -832,7 +841,7 @@ void QWasmVideoOutput::checkNetworkState()
void QWasmVideoOutput::videoComputeFrame(void *context)
{
if (m_offscreenContext.isUndefined() || m_offscreenContext.isNull()) {
- qCDebug(qWasmMediaVideoOutput) << "canvas context could not be found";
+ qCDebug(qWasmMediaVideoOutput) << "offscreen canvas context could not be found";
return;
}
emscripten::val document = emscripten::val::global("document");
@@ -896,14 +905,15 @@ void QWasmVideoOutput::videoFrameCallback(emscripten::val now, emscripten::val m
<< "ERROR" << "failed to construct VideoFrame";
return;
}
-
emscripten::val frameBytesAllocationSize = oneVideoFrame.call<emscripten::val>("allocationSize");
emscripten::val frameBuffer =
- emscripten::val::global("Uint8Array").new_(frameBytesAllocationSize);
+ emscripten::val::global("Uint8Array").new_(frameBytesAllocationSize);
+ QWasmVideoOutput *wasmVideoOutput =
+ reinterpret_cast<QWasmVideoOutput*>(videoElement["data-qvideocontext"].as<quintptr>());
qstdweb::PromiseCallbacks copyToCallback;
- copyToCallback.thenFunc = [oneVideoFrame, frameBuffer, videoElement]
+ copyToCallback.thenFunc = [wasmVideoOutput, oneVideoFrame, frameBuffer, videoElement]
(emscripten::val frameLayout)
{
if (frameLayout.isNull() || frameLayout.isUndefined()) {
@@ -932,9 +942,6 @@ void QWasmVideoOutput::videoFrameCallback(emscripten::val now, emscripten::val m
textureDescription->strideForWidth(frameFormat.frameWidth())),
frameFormat);
- QWasmVideoOutput *wasmVideoOutput =
- reinterpret_cast<QWasmVideoOutput*>(videoElement["data-qvideocontext"].as<quintptr>());
-
if (!wasmVideoOutput) {
qCDebug(qWasmMediaVideoOutput) << "ERROR:"
<< "data-qvideocontext not found";
@@ -947,14 +954,14 @@ void QWasmVideoOutput::videoFrameCallback(emscripten::val now, emscripten::val m
wasmVideoOutput->m_wasmSink->setVideoFrame(vFrame);
oneVideoFrame.call<emscripten::val>("close");
};
- copyToCallback.catchFunc = [oneVideoFrame, videoElement](emscripten::val error)
+ copyToCallback.catchFunc = [&, wasmVideoOutput, oneVideoFrame, videoElement](emscripten::val error)
{
qCDebug(qWasmMediaVideoOutput) << "Error"
- << QString::fromStdString(error["name"].as<std::string>() )
- << QString::fromStdString(error["message"].as<std::string>() ) ;
+ << QString::fromStdString(error["name"].as<std::string>())
+ << QString::fromStdString(error["message"].as<std::string>()) ;
oneVideoFrame.call<emscripten::val>("close");
- videoElement.call<emscripten::val>("stop");
+ wasmVideoOutput->stop();
return;
};
diff --git a/src/plugins/multimedia/wasm/common/qwasmvideooutput_p.h b/src/plugins/multimedia/wasm/common/qwasmvideooutput_p.h
index 4864df989..474b18e43 100644
--- a/src/plugins/multimedia/wasm/common/qwasmvideooutput_p.h
+++ b/src/plugins/multimedia/wasm/common/qwasmvideooutput_p.h
@@ -119,6 +119,7 @@ private:
bool m_isSeeking = false;
bool m_hasAudio = false;
bool m_cameraIsReady = false;
+ bool m_shouldBeStarted = false;
emscripten::val m_offscreenContext = emscripten::val::undefined();
QSize m_pendingVideoSize;
diff --git a/src/plugins/multimedia/wasm/mediacapture/qwasmcamera.cpp b/src/plugins/multimedia/wasm/mediacapture/qwasmcamera.cpp
index 976d94d96..9bd63b081 100644
--- a/src/plugins/multimedia/wasm/mediacapture/qwasmcamera.cpp
+++ b/src/plugins/multimedia/wasm/mediacapture/qwasmcamera.cpp
@@ -62,8 +62,10 @@ bool QWasmCamera::isActive() const
void QWasmCamera::setActive(bool active)
{
+
if (!m_CaptureSession) {
emit error(QCamera::CameraError, QStringLiteral("video surface error"));
+ m_shouldBeActive = true;
return;
}
@@ -72,9 +74,15 @@ void QWasmCamera::setActive(bool active)
return;
}
- m_cameraOutput->setSurface(m_CaptureSession->videoSink());
+ QVideoSink *sink = m_CaptureSession->videoSink();
+ if (!sink) {
+ qWarning() << Q_FUNC_INFO << "sink not ready";
+ return;
+ }
+ m_cameraOutput->setSurface(m_CaptureSession->videoSink());
m_cameraActive = active;
+ m_shouldBeActive = false;
if (m_cameraActive)
m_cameraOutput->start();
@@ -130,6 +138,9 @@ void QWasmCamera::setCaptureSession(QPlatformMediaCaptureSession *session)
return;
m_CaptureSession = captureSession;
+
+ if (m_shouldBeActive)
+ setActive(true);
}
void QWasmCamera::setFocusMode(QCamera::FocusMode mode)
diff --git a/src/plugins/multimedia/wasm/mediacapture/qwasmcamera_p.h b/src/plugins/multimedia/wasm/mediacapture/qwasmcamera_p.h
index b9399c6de..7bb6d02d7 100644
--- a/src/plugins/multimedia/wasm/mediacapture/qwasmcamera_p.h
+++ b/src/plugins/multimedia/wasm/mediacapture/qwasmcamera_p.h
@@ -74,7 +74,7 @@ private:
void updateCameraFeatures();
QCameraDevice m_cameraDev;
- QWasmMediaCaptureSession *m_CaptureSession;
+ QWasmMediaCaptureSession *m_CaptureSession = nullptr;
bool m_cameraActive = false;
QScopedPointer <QWasmVideoOutput> m_cameraOutput;