Details
-
Bug
-
Resolution: Out of scope
-
Not Evaluated
-
None
-
6.8.1
-
None
-
Windows 10
Description
In the following implementation (see the attached code), I use the same Qt version (6.7.3 and 6.8.1) to implement equivalent code using PySide and Qt respectively. The initial running memory is about 20MB, and after switching to the viewfinder page, it rises to about 200MB respectively. When switching back to the empty page, the Qt implementation will quickly fall back to 20MB, while the PySide version does not fall back at all. I tried many methods, including but not limited to calling the delatelater method and using Python's built-in del method, but none of them worked.
Operating system Windows 10 21H2
Python version 3.11, 3.12
Qt version Qt 6.7.3 msvc2019_64
I used Windows's Task Manager to observe the memory
from PySide6.QtCore import Qt from PySide6.QtGui import QHideEvent, QPainter, QPaintEvent, QShowEvent from PySide6.QtMultimedia import QCamera, QMediaCaptureSession, QMediaDevices, QVideoFrame, QVideoSink from PySide6.QtWidgets import QApplication, QPushButton, QStackedWidget, QVBoxLayout, QWidget class NormalPage(QWidget): def __init__(self, parent: QWidget | None = None) -> None: super().__init__(parent) class ViewfinderPage(QWidget): def __init__(self, parent: QWidget | None = None) -> None: super().__init__(parent) self.videoSink = QVideoSink() self.videoSink.videoFrameChanged.connect(self.onFrameChanged) self.camera = QCamera(QMediaDevices.defaultVideoInput()) self.session = QMediaCaptureSession() self.session.setCamera(self.camera) self.session.setVideoOutput(self.videoSink) self.currentFrame: QVideoFrame | None = None def onFrameChanged(self, frame: QVideoFrame) -> None: self.currentFrame = frame self.update() def showEvent(self, event: QShowEvent) -> None: super().showEvent(event) self.camera.start() def hideEvent(self, event: QHideEvent) -> None: super().hideEvent(event) self.camera.stop() def paintEvent(self, event: QPaintEvent) -> None: super().paintEvent(event) painter = QPainter(self) if self.currentFrame: painter.fillRect( self.rect(), self.currentFrame.toImage().scaled(self.size(), Qt.AspectRatioMode.KeepAspectRatioByExpanding) ) painter.end() class Win(QWidget): def __init__(self) -> None: super().__init__() self.resize(800, 600) self.setWindowTitle("Memory Leak Test") self.mainLayout = QVBoxLayout(self) self.toggleButton = QPushButton("Toggle Page") self.toggleButton.clicked.connect(self.onToggleButtonClicked) self.container = QStackedWidget() self.normalPage = NormalPage() self.viewfinderPage = ViewfinderPage() self.container.addWidget(self.normalPage) self.container.addWidget(self.viewfinderPage) self.setLayout(QVBoxLayout()) self.mainLayout.addWidget(self.container) self.mainLayout.addWidget(self.toggleButton) def onToggleButtonClicked(self) -> None: self.container.setCurrentIndex(1 - self.container.currentIndex()) if __name__ == "__main__": app = QApplication([]) win = Win() win.show() app.exec()
#include <QApplication> #include <QCamera> #include <QCameraDevice> #include <QMediaCaptureSession> #include <QMediaDevices> #include <QPainter> #include <QVideoSink> #include <QWidget> class Widget : public QWidget { public: explicit Widget(QWidget* parent = nullptr) : QWidget(parent) { resize(800, 600); setWindowTitle("Memory Leak Test"); m_videoSink = new QVideoSink(this); connect(m_videoSink, &QVideoSink::videoFrameChanged, this, &Widget::onFrameChanged); m_camera = new QCamera(QMediaDevices::defaultVideoInput()); m_session = new QMediaCaptureSession(this); m_session->setCamera(m_camera); m_session->setVideoOutput(m_videoSink); m_camera->start(); } protected: void paintEvent(QPaintEvent* event) override { QPainter painter{ this }; if (m_currentFrame.isValid()) { painter.drawImage(rect(), m_currentFrame.toImage().scaled(rect().size(), Qt::KeepAspectRatio)); } } private slots: void onFrameChanged(const QVideoFrame& frame) { m_currentFrame = frame; update(); } private: QVideoSink* m_videoSink; QCamera* m_camera; QMediaCaptureSession* m_session; QVideoFrame m_currentFrame; }; int main(int argc, char *argv[]) { QApplication app(argc, argv); Widget w; w.show(); return QApplication::exec(); }
Attachments
Issue Links
- resulted from
-
PYSIDE-2931 Memory leak from QMediaPlayer
-
- Closed
-