[英]qml CaptureSession freezes app on Android
I have a bug when using CaptureSession on Qt6.4, if I use it in a dynamic component, when I destroy it, the app freezes and I have to kill it.我在 Qt6.4 上使用 CaptureSession 时有一个错误,如果我在动态组件中使用它,当我销毁它时,应用程序会冻结,我必须杀死它。 This problem does not exist when I compile for Desktop.
当我为桌面编译时,这个问题不存在。 I tried on Android 11 & 13, the result is the same.
我在 Android 11 和 13 上试过,结果是一样的。
Also it was perfectly working with Qt5 when only using VideoOuput & Camera.仅使用 VideoOuput 和 Camera 时,它也能与 Qt5 完美配合。
I wrote a minimal example using a Loader, that creates the freeze.我使用 Loader 编写了一个最小示例,它创建了冻结。 If someone has an idea to fix it:
如果有人有修复它的想法:
import QtQuick 6.4
import QtQuick.Window 6.4
import QtQuick.Controls 6.4
import QtMultimedia
ApplicationWindow
{
id: window
visible: true
width: Screen.desktopAvailableWidth
height: Screen.desktopAvailableHeight
Loader {
id: loader
anchors.fill: parent
active: activeBtn.checked
sourceComponent: Component {
Item {
id: item
Camera {
id: camera
active: true
focusMode: Camera.FocusModeAutoNear
}
CaptureSession {
camera: camera
videoOutput: videoOutput
}
VideoOutput {
id: videoOutput
anchors.fill: parent
fillMode: VideoOutput.Stretch
}
}
}
}
Button {
id : activeBtn
text: "Active CAM"
checkable: true
anchors {
right: parent.right
bottom: parent.bottom
}
}
}
The app freezes as soon as I unload the component, so when CaptureSession is destroyed.一旦我卸载组件,应用程序就会冻结,因此当 CaptureSession 被销毁时。
I would make sure the Camera
is stopped before destroying the Component
.我会确保在销毁
Component
之前停止Camera
。
In other words, we need to acknowledge on some backends, the camera may be running in a different thread, and, we must make sure we give it sufficient time to terminate the camera and the corresponding VideoOutput
preview before forcibly destroying the QML components.换句话说,我们需要在某些后端承认,相机可能在不同的线程中运行,并且,我们必须确保在强行销毁 QML 组件之前给它足够的时间来终止相机和相应的
VideoOutput
预览。
We can keep your original property binding for starting the camera, ie我们可以保留您的原始属性以启动相机,即
property bool cameraActive: false
Loader {
id: loader
anchors.fill: parent
active: activeBtn.checked || cameraActive
So that will create the component as soon as the Button
is checked, HOWEVER, during the initialization of the Component
, we changed cameraActive = true;
因此,一旦选中
Button
,就会创建组件,但是,在Component
的初始化期间,我们更改了cameraActive = true;
so that it prevents the unchecking of the same Button
to destroy the component.这样它就可以防止取消选中同一个
Button
来销毁组件。
Component.onCompleted: {
cameraActive = true;
}
We use that Button event to stop the Camera
with camera.stop()
.我们使用该 Button 事件通过
camera.stop()
停止Camera
。
Connections {
target: activeBtn
function onCheckedChanged() {
if (!activeBtn.checked && camera.active) {
camera.stop();
}
}
}
As soon as we know the Camera
has stopped with camera.active === false
, then, we change cameraActive = false
and that should resume the destruction of your Component
.一旦我们知道
Camera
已停止并camera.active === false
,我们就会更改cameraActive = false
,这应该会恢复您的Component
的销毁。
Camera {
id: camera
active: true
focusMode: Camera.FocusModeAutoNear
onActiveChanged: cameraActive = active
}
Here's your complete code with all of the above changes.这是包含所有上述更改的完整代码。 Note that I haven't been able to fully verify the code below, so, please treat the code as an educational guide only:
请注意,我无法完全验证下面的代码,因此,请仅将代码视为教育指南:
import QtQuick 6.4
import QtQuick.Window 6.4
import QtQuick.Controls 6.4
import QtMultimedia
ApplicationWindow
{
id: window
visible: true
width: Screen.desktopAvailableWidth
height: Screen.desktopAvailableHeight
property bool cameraActive: false
Loader {
id: loader
anchors.fill: parent
active: activeBtn.checked || cameraActive
sourceComponent: Component {
Item {
id: item
Camera {
id: camera
active: true
focusMode: Camera.FocusModeAutoNear
onActiveChanged: cameraActive = active
}
CaptureSession {
camera: camera
videoOutput: videoOutput
}
VideoOutput {
id: videoOutput
anchors.fill: parent
fillMode: VideoOutput.Stretch
}
Connections {
target: activeBtn
function onCheckedChanged() {
if (!activeBtn.checked && camera.active) {
camera.stop();
}
}
}
Component.onCompleted: {
cameraActive = true;
}
}
}
}
Button {
id : activeBtn
text: "Active CAM"
checkable: true
anchors {
right: parent.right
bottom: parent.bottom
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.