Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QVideoFrame() not accepting a QImage even though the documentation has an example?



  • Hi. My goal is to insert an image into a QGraphicsVideoItem. According to this page, QGraphicsVideoItem, at the very bottom is an example of how to do this.
    Here is the code from that page:

    item = QGraphicsVideoItem()
    graphicsView.scene().addItem(item)
    graphicsView.show()
    img = QImage("images/qt-logo.png").convertToFormat(QImage.Format_ARGB32)
    item.videoSink().setVideoFrame(QVideoFrame(img))
    

    When I try to implement this myself I am getting a TypeError:

    TypeError: 'PySide6.QtMultimedia.QVideoFrame.__init__' called with wrong argument types:
      PySide6.QtMultimedia.QVideoFrame.__init__(QImage)
    Supported signatures:
      PySide6.QtMultimedia.QVideoFrame.__init__()
      PySide6.QtMultimedia.QVideoFrame.__init__(PySide6.QtMultimedia.QVideoFrameFormat)
      PySide6.QtMultimedia.QVideoFrame.__init__(Union[PySide6.QtMultimedia.QVideoFrame, PySide6.QtMultimedia.QVideoFrameFormat])
    

    I'm really confused. I'm still new to Qt and maybe I don't understand the formatting but I'm pretty sure the example on the QGraphicsVideoItem is literally passing in a QImage. I don't have a null image because when I print it out it shows:

    <PySide6.QtGui.QImage(QSize(640, 480),format=QImage::Format_RGB888,depth=24,devicePixelRatio=1,bytesPerLine=1920,sizeInBytes=921600) at 0x00000245D81FE3C0>
    

    Here is the code where I try to implement it:

        def run(self):
            capture = cv2.VideoCapture(1)
            while capture.isOpened():
                status, frame = capture.read()
                if status:
                    frame = self.read_barcodes(frame)
                    h, w, _ = frame.shape
                    self.image = QImage(frame.data, w, h, 3 * w, QImage.Format_RGB888)
                    print(self.image)
                    self.formatted = self.image.convertToFormat(QImage.Format_ARGB32)
                    print(self.formatted)
                    self.converted = QVideoFrame(self.formatted)  # Causes the TypeError here
                    print(self.converted)
                    self.changeFrame.emit(self.converted)
            capture.release()
    

    EDIT: I am using PySide6 and Python 3.10


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Which example is that ?

    The Qt Multimedia module has seen a complete rewrite for the Qt 6 release and your code makes me think of the Qt 5 implementation.

    You can test it with PySide2.



  • @SGaist
    Hey! Thank you for the welcome! I posted the link to the example. It looks like it is for PySide6.2.2. That's what it shows on the link tree:

    Qt for Python 6.2.2 > Qt for Python Documentation > Qt Modules > PySide6.QtMultimediaWidgets
    

    EDIT: Looks like the same example is on the QT6-Dev Documentation as well.

    Documentation on the QVideoFrame for PySide6 does not say it takes a QImage format even though the QGraphicsVideoItem is using an example that is...Maybe a mix up with the rewriting of the documentation?

    class PySide6.QtMultimedia.QVideoFrame¶
    PySide6.QtMultimedia.QVideoFrame(other)
    
    PySide6.QtMultimedia.QVideoFrame(format)
    
    Parameters
    other – PySide6.QtMultimedia.QVideoFrame
    
    format – PySide6.QtMultimedia.QVideoFrameFormat
    
    Constructs a null video frame.
    

  • Lifetime Qt Champion

    Looks like an bug in the documentation as there are currently no constructor overload taking a QImage in Qt 6.



  • @SGaist That's exactly what I was thinking. Would you happen to know use setVideoFrame to input a QImage by other means?


  • Lifetime Qt Champion

    I would create a QVideoFrame of the same format as the QImage, then map it and memcpy the content of the QImage.



  • @SGaist I am unfamiliar with memcpy. Would you be able tp provide an example or link some documentation?



  • @donbfry
    It's a standard C library function. Just Google. No rocket science.



  • @JonB I don't think telling someone to "Just Google" it is something you should be saying on a forum where people go to get help. It contributes nothing to the topic and then later on down the road, someone else that did Google it could be led here and they come across your post that says "Just Google". And no one said it was rocket science. I don't know anything about C or how to use C library functions in Python. I'm fairly new to Python and the Qt framework and the first iteration of Google searches that I did do did not lead me to an answer. So I simply asked if he could provide an example or a link that could lead me down the correct path. I'm not sure why you felt the need to go out of your way and respond with what you did.



  • For anyone else that comes across this post with the same issue, I will update this reply with a solution. I am currently looking into this article, How to Call a C function in Python, in order to learn how to implement @SGaist 's suggested solution.


  • Lifetime Qt Champion

    @donbfry sorry I forgot this was a Python question while I wrote the modus operandi.

    While it's still valid, I don't know of direct replacement of memcpy beside going with the ctypes library. However, I think you should bring that question to the PySide mailing list. You'll find there PySide6 developers/maintainers. They should be able to point you to the right direction regarding this use case.


Log in to reply