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. Dealing with Thread-related Stuttering and Lag with QPixmap in pyqt6
Forum Updated to NodeBB v4.3 + New Features

Dealing with Thread-related Stuttering and Lag with QPixmap in pyqt6

Scheduled Pinned Locked Moved Unsolved Qt for Python
4 Posts 2 Posters 478 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.
  • K Offline
    K Offline
    kyrlon
    wrote on last edited by
    #1

    I made a more detailed post on stackoverflow, but I hope here is also an appropriate place to address my issue since I am still hitting a wall. I am facing a troublesome issue with video playback using FFpyPlayer in my pyqt6 application. When running my application with FFpyPlayer, I observe a catch-up time-lapse buffering effect, causing the video playback to accelerate significantly and then return to normal speed intermittently. Moreover, certain videos display stuttering or lag during playback.

    The application uses FFpyPlayer to handle video playback from a UDP stream within a background thread with frames, rendered with PyQt's QPixmap for frame display. The issue seems to arise during the display of frames.

    from PyQt6 import QtGui, QtWidgets, QtCore
    from ffpyplayer.player import MediaPlayer
    import time
    from threading import Thread
    
    class VideoDisplayWidget(QtWidgets.QWidget):
        def __init__(self):
            super().__init__()
            self.player = None
            self.layout = QtWidgets.QVBoxLayout(self)
            self.video_frame_widget = QtWidgets.QLabel()
            self.layout.addWidget(self.video_frame_widget)
            self.frame_rate = 30
    
            self.latest_frame = QtGui.QPixmap()
    
            self.timer = QtCore.QTimer()
            self.timer.setTimerType(QtCore.Qt.TimerType.PreciseTimer)
            self.timer.timeout.connect(self.nextFrameSlot)
            self.timer.start(int(1000.0/self.frame_rate))
    
            self.play()
            self.setLayout(self.layout)
    
        def play(self):
            play_thread = Thread(target=self._play, daemon=True)
            play_thread.start()
        
        def _play(self):
            player = MediaPlayer("udp://127.0.0.1:51234")
            val = ''
            while val != 'eof':
                frame, val = player.get_frame()
                if val != 'eof' and frame is not None:
                    img, t = frame
                    # display img
                    w = img.get_size()[0] 
                    h = img.get_size()[1]
                    data = img.to_bytearray()[0]
    
                    qimage = QtGui.QImage(data, w, h, QtGui.QImage.Format.Format_RGB888)
                    self.latest_frame = QtGui.QPixmap.fromImage(qimage)
                    time.sleep(0.001)
        
        def nextFrameSlot(self):
            self.video_frame_widget.setPixmap(self.latest_frame)
    
    if __name__ == "__main__":
        current_port = 51234
        app = QtWidgets.QApplication([])
        player = VideoDisplayWidget()
        player.show()
    
        exit(app.exec())
    

    Would this be a threads issue? Should I go with something async such as qasync

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

      Hi,

      Your architecture is risky. You are accessing the same data from two different threads without synchronization which means you are pretty lucky it does not crash. Might be thanks to the current Python GIL.

      You should consider using the worker object approach to push the images received further. Depending on the size of the image you receive updating a label might have some performance issues.

      On a side note, since Qt 6.5, the QtMultimedia module uses FFMPEG for its backend. Did you test it ?

      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
      1
      • K Offline
        K Offline
        kyrlon
        wrote on last edited by
        #3

        I have heard of this worker object approach, but is there a set guide on the methodology? And also no I was not aware of the backend using FFmpeg. I might try that as well soon

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

          There's a pretty good explanation in the QThread documentation.

          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

          • Login

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