QtMultimedia app freezes when switching between cameras on a captureSession
-
Hi,
As I was doing exercises from the QML Book - Image capture chapter 11, I wanted to capture a video stream from a camera selected from a combobox, and then switch to another camera in the combobox, then change the camera in the captureSession so it now renders the selected camera video stream output.
Problem is, as I was following the example, I found a few inconsistencies like getting a list of cameras into the combobox (which I worked around), but the problem is that as I switch cameras in the captureSession, the application completely freezes, this happens mostly when more than one camera is attached at my computer and of course more than one item in the combobox, so I fear something might be missing.
Here is a proof of concept of the issue, please anyone feel free to check it out and tell me if I'm missing something or doing something wrong when switching the captureSession camera so my app doesn't freeze. I'm using Qt 6.5 LTS from the commercial distribution on Windows 11.
PoC Link: https://github.com/raul-guerrero/WebcamSwitchPoC
Here is my Main.qml just so you can review here as well:
import QtQuick import QtQuick.Window import QtQuick.Controls import QtMultimedia Window { width: 800 height: 600 visible: true title: qsTr("Hello World") property Camera previousCamera: null MediaDevices { id: mediaDevices } CaptureSession { id: captureSession videoOutput: videoOutput camera: Camera { cameraDevice: mediaDevices.defaultVideoInput active: true } onCameraChanged: { console.log("triggered onCameraChanged event") captureSession.camera.start() } } Item { x: 20 y: 20 width: 640 height: 480 VideoOutput { id: videoOutput anchors.fill: parent } } ComboBox { id: combobox_select_camera x: 670 y: 20 width: 110 height: 32 model: ListModel { Component.onCompleted: function() { previousCamera = captureSession.camera for (var i = 0; i < mediaDevices.videoInputs.length; i++) { this.append({ description: mediaDevices.videoInputs[i].description }) } } } textRole: "description" displayText: captureSession.camera.cameraDevice.description onActivated: function (index) { if (previousCamera != null && previousCamera.cameraDevice.description !== mediaDevices.videoInputs[index].description) { if (previousCamera.active) { previousCamera.stop() } captureSession.camera.cameraDevice = mediaDevices.videoInputs[index] previousCamera = captureSession.camera } } } }
Thanks
-
Hi,
As I was doing exercises from the QML Book - Image capture chapter 11, I wanted to capture a video stream from a camera selected from a combobox, and then switch to another camera in the combobox, then change the camera in the captureSession so it now renders the selected camera video stream output.
Problem is, as I was following the example, I found a few inconsistencies like getting a list of cameras into the combobox (which I worked around), but the problem is that as I switch cameras in the captureSession, the application completely freezes, this happens mostly when more than one camera is attached at my computer and of course more than one item in the combobox, so I fear something might be missing.
Here is a proof of concept of the issue, please anyone feel free to check it out and tell me if I'm missing something or doing something wrong when switching the captureSession camera so my app doesn't freeze. I'm using Qt 6.5 LTS from the commercial distribution on Windows 11.
PoC Link: https://github.com/raul-guerrero/WebcamSwitchPoC
Here is my Main.qml just so you can review here as well:
import QtQuick import QtQuick.Window import QtQuick.Controls import QtMultimedia Window { width: 800 height: 600 visible: true title: qsTr("Hello World") property Camera previousCamera: null MediaDevices { id: mediaDevices } CaptureSession { id: captureSession videoOutput: videoOutput camera: Camera { cameraDevice: mediaDevices.defaultVideoInput active: true } onCameraChanged: { console.log("triggered onCameraChanged event") captureSession.camera.start() } } Item { x: 20 y: 20 width: 640 height: 480 VideoOutput { id: videoOutput anchors.fill: parent } } ComboBox { id: combobox_select_camera x: 670 y: 20 width: 110 height: 32 model: ListModel { Component.onCompleted: function() { previousCamera = captureSession.camera for (var i = 0; i < mediaDevices.videoInputs.length; i++) { this.append({ description: mediaDevices.videoInputs[i].description }) } } } textRole: "description" displayText: captureSession.camera.cameraDevice.description onActivated: function (index) { if (previousCamera != null && previousCamera.cameraDevice.description !== mediaDevices.videoInputs[index].description) { if (previousCamera.active) { previousCamera.stop() } captureSession.camera.cameraDevice = mediaDevices.videoInputs[index] previousCamera = captureSession.camera } } } }
Thanks
-
Ok so I finally got it working.
The problem seems to be the integration between camera, video output and capture session, every time you want to change camera you have to recreate all objects in the UI for it to work again.
I would have expected that this would be handled internally by the aforementioned objects but it seems it's not the case.
I updated the repo with a working version where I dynamically destroy and recreate the dependent objects and it works now. -