diff options
author | Lorn Potter <lorn.potter@gmail.com> | 2024-03-20 10:55:17 +1000 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2024-04-23 02:55:40 +0000 |
commit | 74d5a07f00569bca671a723b51ee5818d3749d48 (patch) | |
tree | 09b0dacc7d5d5784f7f8ccc48297efc6c39fc7bb | |
parent | 219479431d817079a47e1dbd1d755b32dad685f9 (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>
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; |