I'm want to make use of a Video Filter in a Pyside2(5.12.2)/QML application to further process the camera's frames. I converted the example from the QT docs to Python, but instead of the QVideoFilterRunnable's "run()" method being executed, the constructor is invoked endlessly thus creating one new instance after another. I suspect this might be related to Python's garbage collection - does anyone know how to make the run() method being executed in PySide2?
import sys
from PySide2.QtCore import QUrl, Slot, Signal, Property
from PySide2.QtGui import QGuiApplication
from PySide2.QtQml import QQmlApplicationEngine, qmlRegisterType
from PySide2.QtMultimedia import QVideoFilterRunnable, QAbstractVideoFilter
class MyFilterRunnable(QVideoFilterRunnable):
def __init__(self, filter):
print("init")
self.init = False
self.filter = filter
def run(self, input, surface, flags):
print("run")
return input
class MyVideoFilter(QAbstractVideoFilter):
def createFilterRunnable(self):
return MyFilterRunnable(self)
if __name__ == "__main__":
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
qmlRegisterType(MyVideoFilter, "my.uri", 1, 0, "MyVideoFilter");
engine.load(QUrl.fromLocalFile('qml_test.qml'))
sys.exit(app.exec_())
The QML file:
import QtQuick 2.0
import QtMultimedia 5.4
import QtQuick 2.10
import QtQuick.Controls 2.1
import QtQuick.Window 2.2
import my.uri 1.0
ApplicationWindow {
id: app
width: 640
height: 480
visible: true
Rectangle {
id : cameraUI
anchors.fill: parent
Camera {
id: camera
}
MyVideoFilter {
id: myvideofilter
}
VideoOutput {
id: viewfinder
filters: [ myvideofilter ]
source: camera
}
}
}
Instead of "run" i see countless "init" in the console.
In Python you have to be explicit when doing the inheritance and for this you must use super(), in your case Qt detects that MyFilterRunnable is not a QVideoFilterRunnable so it tries to find another filter and the MyVideoFilter passes the same filter to it so you see that "init" is printed at every moment. Also, what is filter? we do not know, it is not necessary, and since it is not necessary to add parameters as arguments we can omit __init__
:
class MyFilterRunnable(QVideoFilterRunnable):
def run(self, _input, surface, flags):
print("run")
return _input
Even considering the above unfortunately your program will crash due to an unsolved bug: PYSIDE-785. The same happens in PyQt5.