Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. QGraphicsScene and QGraphicsVideoItem extreme high CPU use on Mac

QGraphicsScene and QGraphicsVideoItem extreme high CPU use on Mac

Scheduled Pinned Locked Moved Unsolved Qt for Python
11 Posts 2 Posters 1.8k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    Bouke
    wrote on last edited by
    #1

    Hi all,
    Trying to do a pixmap overlay on video.
    It works fine on Windows, but is extremely CPU hungry on Mac.
    Then, depending on the video codec, I get black flashes.
    Here is my stripped down code:

    from PyQt5 import QtWidgets, QtGui, QtCore, QtMultimediaWidgets, QtMultimedia
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    from PyQt5.QtWidgets import *
    from PyQt5.QtMultimedia import *
    from PyQt5.QtMultimediaWidgets import *
    import sys
    
    VIDEO_WIDTH = 1280
    VIDEO_HEIGHT = 720
    
    ########################################
    #
    ########################################
    class MyVideoView(QGraphicsView):
        def __init__(self, parent=None):
            super(QGraphicsView, self).__init__(parent)
            # self._main = parent
    
            self.setBackgroundBrush(Qt.black)
    
            self._scene = QGraphicsScene(self)
            self.setScene(self._scene)
    
            self._videoItem = QGraphicsVideoItem()
            self._videoItem.setPos(0, 0)
            self._videoItem.setSize(QSizeF(VIDEO_WIDTH, VIDEO_HEIGHT))
            self._scene.addItem(self._videoItem)
    
            self._overlay = QPixmap(VIDEO_WIDTH, VIDEO_HEIGHT)
            self._overlay.fill(QColor(0, 150, 0, 150))
            self._graphicsPixmapItem = self._scene.addPixmap(self._overlay)
    
            self._player = QMediaPlayer(self)
            self._player.setVideoOutput(self._videoItem)
    
        def loadVideo(self, fn):
            self._player.setMedia(QMediaContent(QUrl.fromLocalFile(fn)))
            self._player.play()
    
    class Video(QMainWindow):
    
        def __init__(self, parent=None):
            super(QMainWindow, self).__init__(parent)
            self.setWindowTitle("Video window")
            # self.setContentsMargins(-2, -2, -2, -2)  # get rid of black lines around the vid
            self._splitter = QSplitter(Qt.Vertical)
            self.setCentralWidget(self._splitter)
            self._videoView = MyVideoView(self)
            self._splitter.addWidget(self._videoView)
            self._videoView.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
            self._videoView.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
            self.show()
            self._videoView.loadVideo('/Volumes/Data/videofiles/demo_BITC 2.mov')
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        app.setQuitOnLastWindowClosed(True)
        w = Video()
        sys.exit(app.exec_())
    
    

    What am I missing here?
    Thx,
    Bouke

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      What version of PyQt5 are you using ?
      How did you install it ?
      What version of macOS are you running ?
      Can you tell what model is you machine ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • B Offline
        B Offline
        Bouke
        wrote on last edited by
        #3

        Hi:
        PyQt5 5.9.2, installed with Pip in a Python 3.6.8 venv
        But just updated to 5.14.2, does not seem to make a difference.

        Running OS 10.15.4 on an Imac (Retina, quad core i5, Radeon Pro 555 2 GB)

        Does that help?

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          I forgot, what video codec has issues ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • B Offline
            B Offline
            Bouke
            wrote on last edited by
            #5

            You did not forget, I did not told you :-)
            H264 (x264) does play, although suffering from the high CPU consumption.
            ProRes flickers (black frames alternating video frames).

            The CPU use increases when the window gets bigger.

            I suspect there are too many updates or something like that, Qmediaplayer in a 'bare' surrounding does not have these issues.

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Try using a QOpenGLWidget as viewport of your QGraphicsView.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              B 1 Reply Last reply
              0
              • SGaistS SGaist

                Try using a QOpenGLWidget as viewport of your QGraphicsView.

                B Offline
                B Offline
                Bouke
                wrote on last edited by
                #7

                @SGaist
                Well, I would if I could, but I'm new to Python (and not a real coder, I'm coming from Adobe Director...)
                Do you have any pointers?
                thx,

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Something like:

                  my_scene.setViewport(new QGLWidget())
                  

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  B 1 Reply Last reply
                  0
                  • SGaistS SGaist

                    Something like:

                    my_scene.setViewport(new QGLWidget())
                    
                    B Offline
                    B Offline
                    Bouke
                    wrote on last edited by
                    #9

                    @SGaist
                    Ok, I've added to my QGraphicsView:

                    self.widget = glWidget(self)
                    self.setViewport(self.widget)

                    class glWidget(QGLWidget):
                    def init(self, parent=None):
                    QGLWidget.init(self, parent)

                    B 1 Reply Last reply
                    0
                    • B Bouke

                      @SGaist
                      Ok, I've added to my QGraphicsView:

                      self.widget = glWidget(self)
                      self.setViewport(self.widget)

                      class glWidget(QGLWidget):
                      def init(self, parent=None):
                      QGLWidget.init(self, parent)

                      B Offline
                      B Offline
                      Bouke
                      wrote on last edited by
                      #10

                      that was send out too fast... (Can't I edit my own posts?)
                      CPU use is now reduced to a quarter of what it was before, so that's the good news.
                      The bad news is that the video is displayed twice too big. (Due to my Retina screen I think...)

                      1 Reply Last reply
                      0
                      • B Offline
                        B Offline
                        Bouke
                        wrote on last edited by
                        #11

                        Dirty hack that sorta kinda fixes stuff:

                        from PyQt5 import QtWidgets, QtGui, QtCore, QtMultimediaWidgets, QtMultimedia
                        from PyQt5.QtCore import *
                        from PyQt5.QtGui import *
                        from PyQt5.QtWidgets import *
                        from PyQt5.QtMultimedia import *
                        from PyQt5.QtMultimediaWidgets import *
                        import sys
                        
                        
                        from PyQt5.QtOpenGL import *
                        
                        VIDEO_WIDTH = 1200
                        VIDEO_HEIGHT = int(VIDEO_WIDTH / 16 * 9)å
                        
                        ########################################
                        #
                        ########################################
                        class MyVideoView(QGraphicsView):
                            def __init__(self, parent=None):
                                super(QGraphicsView, self).__init__(parent)
                                # self._main = parent
                        
                                # 9% CPU use, rem out this to get high CPU use (depends on window size, up to 100%)
                                self.widget = glWidget()
                                self.setViewport(self.widget)
                        
                        
                                self.setBackgroundBrush(Qt.black)
                                self._scene = QGraphicsScene(self)
                                self.setScene(self._scene)
                                self._videoItem = QGraphicsVideoItem()
                                # self._videoItem.setPos(0, 0)
                                self._scene.addItem(self._videoItem)
                        
                                self._overlay = QPixmap(VIDEO_WIDTH, VIDEO_HEIGHT)
                                self._overlay.fill(QColor(0, 150, 0, 150))
                                self._graphicsPixmapItem = self._scene.addPixmap(self._overlay)
                        
                                self._player = QMediaPlayer(self)
                                self._player.setVideoOutput(self._videoItem)
                        
                            def loadVideo(self, fn):
                                self._player.setMedia(QMediaContent(QUrl.fromLocalFile(fn)))
                                self._player.play()
                                # self._player.setPlaybackRate(0.5)
                        
                        class glWidget(QGLWidget):
                            def __init__(self, parent=None):
                                QGLWidget.__init__(self, parent)
                        
                        class Video(QMainWindow):
                        
                            def __init__(self, parent=None):
                                super(QMainWindow, self).__init__(parent)
                                self.setWindowTitle("Video window")
                                self._splitter = QSplitter(Qt.Vertical)
                                self.setCentralWidget(self._splitter)
                        
                                self._videoView = MyVideoView(self)
                        
                                self._splitter.addWidget(self._videoView)
                                self._videoView.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
                                self._videoView.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
                                self.show()
                                self._videoView.loadVideo('/Volumes/Data/videofiles/demo_BITC 2.mov')
                                self.resizeEvent(False)
                        
                            def resizeEvent(self, e):
                                # print(dir(QResizeEvent))
                                if not e:
                                    _w = self.geometry().width()
                                    _h = self.geometry().height()
                                else:
                                    _w = e.size().width()
                                    _h = e.size().height()
                        
                        
                                self._videoView._videoItem.setSize(QSizeF(_w / 2, _h / 2))
                        
                                # do not get a feedback loop
                                try:
                                    if self.ignorscaling:
                                        self.ignorscaling = False
                                        return
                                except:
                                    pass
                                self.ignorscaling = True
                        
                                # order of stuff is important here!
                                self._videoView._videoItem.setSize(QSizeF(_w, _h))
                                _w = self._videoView._videoItem.sceneBoundingRect().right()
                                _h = self._videoView._videoItem.sceneBoundingRect().bottom() - self._videoView._videoItem.sceneBoundingRect().top()
                        
                                self.resize(_w, _h)
                        
                        
                        if __name__ == '__main__':
                            app = QApplication(sys.argv)
                            app.setQuitOnLastWindowClosed(True)
                            w = Video()
                            sys.exit(app.exec_())
                        
                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved