Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Showing video in GUI does not work (black screen)
QtWS25 Last Chance

Showing video in GUI does not work (black screen)

Scheduled Pinned Locked Moved Solved General and Desktop
28 Posts 4 Posters 3.6k Views
  • 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.
  • M Offline
    M Offline
    makopo
    wrote on last edited by
    #1

    Hi there,

    I develop a Qt App that should show a given videoinput on the GUI. For this I use a third-party-library from Blackmagic.
    My program compiles, but when I start the video the frame output area remains black. For transfering frames I use the event loop and in a special VideoScreen class I create a instance of a thread.

    //VideoScreen.cpp
    VideoScreen::VideoScreen(QWidget* parent) :
    	m_previewHelper(nullptr)
    {
    	//Registering the type name of type CComPtr<IDeckLinkVideoFrame>, requires include<QMetaType>
    	//Create and destroy objects of the type dyamically at runtime after registration
    	qRegisterMetaType<CComPtr<IDeckLinkVideoFrame>>("CComPtr<IDeckLinkVideoFrame>");
    
    	m_vsThread = new QThread();
    	m_drawFrame = new VideoScreenHelper(parent);
    	m_drawFrame->moveToThread(m_vsThread);
    
    	QObject::connect(m_drawFrame, &VideoScreenHelper::FrameChanged, this, &VideoScreen::HandleFrame, Qt::QueuedConnection);
    	QObject::connect(m_vsThread, &QThread::finished, m_drawFrame, &QObject::deleteLater); //Deletes VideoScreenHelper object
    	QObject::connect(m_vsThread, &QThread::finished, m_vsThread, &QObject::deleteLater); //Deletes QThread object
    	m_vsThread->start();
    	qDebug() << "VideoScreen Ctor: Thread-ID is " << QThread::currentThreadId();
    }
    

    When I debug the program I see that the event loop has a different thread id than the function which emits a new frame.
    That is the function that emits the frame:

    //VideoScreenHelper.cpp
    HRESULT VideoScreenHelper::DrawFrame(IDeckLinkVideoFrame* frame) {
    	QMetaObject::invokeMethod(this, "FrameChanged", Qt::QueuedConnection, Q_ARG(CComPtr<IDeckLinkVideoFrame>, frame));
    	qDebug() << "VideoScreenHelper: emitting FrameChanged.";
    	return S_OK;
    }
    

    So my question is whats going wrong here? Or is there no problem with the threading? I study many tutorials (1, 2, 3, 4) but I'm not sure if my work is the right way.

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

      Hi,

      Decklink used to have an SDK with examples using Qt, is that not the case anymore ?

      If not, one of the possible solution would be to build a QImage in the callback and send it to be rendered.

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

      M 1 Reply Last reply
      0
      • SGaistS SGaist

        Hi,

        Decklink used to have an SDK with examples using Qt, is that not the case anymore ?

        If not, one of the possible solution would be to build a QImage in the callback and send it to be rendered.

        M Offline
        M Offline
        makopo
        wrote on last edited by
        #3

        @SGaist
        Hi,
        I know, there are examples in the SDK that uses Qt and the signal/slot mechanism. But they are not self-explanatory and I also get a black screen when I compile this examples (yes I have connected the camera and the capture device).

        SGaistS 1 Reply Last reply
        0
        • JoeCFDJ Offline
          JoeCFDJ Offline
          JoeCFD
          wrote on last edited by JoeCFD
          #4

          Not sure why you need a thread to send frames. I simply stream a video to a video sink of qtgstreamer without any thread.

          M 1 Reply Last reply
          0
          • M makopo

            @SGaist
            Hi,
            I know, there are examples in the SDK that uses Qt and the signal/slot mechanism. But they are not self-explanatory and I also get a black screen when I compile this examples (yes I have connected the camera and the capture device).

            SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @makopo I remember having to dig a bit in the code but it was not that arcane.

            Since you do not get any image, the silly question is: did you check the configuration ?
            Did you validate that the acquisition is working with a tool like DaVinici Resolve ?

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

            M 1 Reply Last reply
            0
            • JoeCFDJ JoeCFD

              Not sure why you need a thread to send frames. I simply stream a video to a video sink of qtgstreamer without any thread.

              M Offline
              M Offline
              makopo
              wrote on last edited by
              #6

              @JoeCFD

              I had read that connect and emit have to run in the same thread. That's why I use QThread.

              SGaistS 1 Reply Last reply
              0
              • SGaistS SGaist

                @makopo I remember having to dig a bit in the code but it was not that arcane.

                Since you do not get any image, the silly question is: did you check the configuration ?
                Did you validate that the acquisition is working with a tool like DaVinici Resolve ?

                M Offline
                M Offline
                makopo
                wrote on last edited by
                #7

                @SGaist

                With BM Media Express I get an input stream. So I think the configuration should work.

                1 Reply Last reply
                0
                • M makopo

                  @JoeCFD

                  I had read that connect and emit have to run in the same thread. That's why I use QThread.

                  SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  @makopo said in Showing video in GUI does not work (black screen):

                  @JoeCFD

                  I had read that connect and emit have to run in the same thread. That's why I use QThread.

                  No, otherwise the worker object paradigm would not work. When letting the default connection type (AutoConnection) at emission time it will be decided whether it's a direct call or a queued call.

                  From memory, Decklink uses a callback method so you do not need to have an additional thread running.

                  Did you check the video frame format ? Is it RGB ? If not, do you convert it to something usable by Qt ?

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

                  M 1 Reply Last reply
                  1
                  • SGaistS SGaist

                    @makopo said in Showing video in GUI does not work (black screen):

                    @JoeCFD

                    I had read that connect and emit have to run in the same thread. That's why I use QThread.

                    No, otherwise the worker object paradigm would not work. When letting the default connection type (AutoConnection) at emission time it will be decided whether it's a direct call or a queued call.

                    From memory, Decklink uses a callback method so you do not need to have an additional thread running.

                    Did you check the video frame format ? Is it RGB ? If not, do you convert it to something usable by Qt ?

                    M Offline
                    M Offline
                    makopo
                    wrote on last edited by
                    #9

                    @SGaist said in Showing video in GUI does not work (black screen):

                    @makopo said in Showing video in GUI does not work (black screen):

                    @JoeCFD

                    I had read that connect and emit have to run in the same thread. That's why I use QThread.

                    No, otherwise the worker object paradigm would not work. When letting the default connection type (AutoConnection) at emission time it will be decided whether it's a direct call or a queued call.

                    Well, good to know...
                    The display mode is 1080p25 in YUV. But BM also use this mode in the examples. Actually I get memory problems. Don't know if I have problems with pointers.

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

                      What kind of memory problem ?

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

                      M 1 Reply Last reply
                      0
                      • SGaistS SGaist

                        What kind of memory problem ?

                        M Offline
                        M Offline
                        makopo
                        wrote on last edited by makopo
                        #11

                        @SGaist

                        It is difficult for me to retrace that, because actually the event-loop runs. I tried to work with raw pointers (just out of desperation), and with that I got a read access violation error with code 0xC0000005. The event loop runs for a short inconstant time and than the programm exits with this error. Between that, the debugger detects an c0000374 error. I think it was a buffer overflow because I didn't implement the deletetion of the raw-pointers.

                        But actually there is no problem with pointers I think. As I can see in the console the program with the event loop runs (only the screen is black).

                        VideoScreen: GetScreenPeviewCallback was called. TEST
                        ControlVideo: ScreenPreviewCallback works.
                        ControlVideo: SetCallback works.
                        ControlVideo: Video input is enabled.
                        ControlVideo: Stream has started.
                        VideoScreen: GetScreenPeviewCallback was called. TEST
                        QVideoMeter: VALUE PREVIEWCALLBACK  0x20ee0b32d00
                        QVideoMeter: StartButton clicked. Stream is running.
                        VideoScreenHelper: DrawFrame is called. Thread-ID is  0x3338
                        VideoScreen: HandleFrame method is called. Thread-ID:  0x1628
                        VideoScreenHelper: DrawFrame is called. Thread-ID is  0x3338
                        VideoScreen: HandleFrame method is called. Thread-ID:  0x1628
                        //and so on
                        

                        What strange is, I think, is that GetScreenPreviewCallback is called twice.

                        1 Reply Last reply
                        0
                        • M Offline
                          M Offline
                          makopo
                          wrote on last edited by makopo
                          #12

                          It looks like that there is a problem with the initialized object of the IDeckLinkGLScreenPreviewHelper, I create with CoCreateInstance() and the functions of the QOpenGLWidget class. I use QOpenGLWidget::initializeGL() and QOpenGLWidget()::paintGL to call equal named functions of IDeckLinkGLScreenPreviewHelper.

                          //looks like "m_previewHelper" is null
                          void VideoScreen::initializeGL() {
                              if (m_previewHelper)  m_previewHelper->InitializeGL();
                          }
                          

                          But when I debug the program I get the error message: 0xC0000005: Read access violation at position 0x0000000000000000. Looks like m_previewHelper points to null.
                          Strangely enough, Handleframe (the slot function), which also uses the previewHelper object, is executed.

                          //looks like m_previewHelper is not null
                          void VideoScreen::HandleFrame(CComPtr<IDeckLinkVideoFrame> theFrame) {
                              if (m_previewHelper) m_previewHelper->SetFrame(&(*theFrame));
                          }
                          

                          I had written a function that that calls CoCreateInstance and create with this the previewHelper object. In the constructor I assign this function to the member variable. The variable has the same datatype than the function.

                          //call in constructor
                          m_previewHelper = ScreenPreviewHelperInstance();
                          

                          When I print the value of m_previewHelper I get something like 0x29e3d3a78d0 and so on. m_previewHelper seams to be not null.
                          I did not understand that problem. Did someone of you have an idea whats going wrong?

                          jsulmJ 1 Reply Last reply
                          0
                          • M makopo

                            It looks like that there is a problem with the initialized object of the IDeckLinkGLScreenPreviewHelper, I create with CoCreateInstance() and the functions of the QOpenGLWidget class. I use QOpenGLWidget::initializeGL() and QOpenGLWidget()::paintGL to call equal named functions of IDeckLinkGLScreenPreviewHelper.

                            //looks like "m_previewHelper" is null
                            void VideoScreen::initializeGL() {
                                if (m_previewHelper)  m_previewHelper->InitializeGL();
                            }
                            

                            But when I debug the program I get the error message: 0xC0000005: Read access violation at position 0x0000000000000000. Looks like m_previewHelper points to null.
                            Strangely enough, Handleframe (the slot function), which also uses the previewHelper object, is executed.

                            //looks like m_previewHelper is not null
                            void VideoScreen::HandleFrame(CComPtr<IDeckLinkVideoFrame> theFrame) {
                                if (m_previewHelper) m_previewHelper->SetFrame(&(*theFrame));
                            }
                            

                            I had written a function that that calls CoCreateInstance and create with this the previewHelper object. In the constructor I assign this function to the member variable. The variable has the same datatype than the function.

                            //call in constructor
                            m_previewHelper = ScreenPreviewHelperInstance();
                            

                            When I print the value of m_previewHelper I get something like 0x29e3d3a78d0 and so on. m_previewHelper seams to be not null.
                            I did not understand that problem. Did someone of you have an idea whats going wrong?

                            jsulmJ Offline
                            jsulmJ Offline
                            jsulm
                            Lifetime Qt Champion
                            wrote on last edited by jsulm
                            #13

                            @makopo said in Showing video in GUI does not work (black screen):

                            Did someone of you have an idea whats going wrong?

                            A pointer != nullptr does not mean that it is valid. It can be that the memory it is pointing to was already released. Did you release m_previewHelper somewhere?

                            https://forum.qt.io/topic/113070/qt-code-of-conduct

                            M 1 Reply Last reply
                            0
                            • jsulmJ jsulm

                              @makopo said in Showing video in GUI does not work (black screen):

                              Did someone of you have an idea whats going wrong?

                              A pointer != nullptr does not mean that it is valid. It can be that the memory it is pointing to was already released. Did you release m_previewHelper somewhere?

                              M Offline
                              M Offline
                              makopo
                              wrote on last edited by
                              #14

                              @jsulm
                              I use CComPtrs and with that functions of the IUnknown interface. Also IUnknown::Release.

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

                                Did you consider implementing my suggestion rather than moving theses pointers around ?

                                I don't think there's a guarantee that the buffer they are pointing to will be valid when the callback method is done.

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

                                M 1 Reply Last reply
                                0
                                • SGaistS SGaist

                                  Did you consider implementing my suggestion rather than moving theses pointers around ?

                                  I don't think there's a guarantee that the buffer they are pointing to will be valid when the callback method is done.

                                  M Offline
                                  M Offline
                                  makopo
                                  wrote on last edited by
                                  #16

                                  @SGaist

                                  Did you mean building a QImage in an own method instead of using the DrawFrame method from the callback interface?

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

                                    Build the QImage in the callback and send it further using invokeMethod.

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

                                    M 1 Reply Last reply
                                    0
                                    • SGaistS SGaist

                                      Build the QImage in the callback and send it further using invokeMethod.

                                      M Offline
                                      M Offline
                                      makopo
                                      wrote on last edited by makopo
                                      #18

                                      @SGaist

                                      I found by accident that my program renders a single frame of the camera input, after I start the loop and minimize the GUI of the program. When I reopen the GUI a new frame is rendered and also, as I can see in the console, the paintGL() method of the QOpenGLWidget interface is called. I think the paintGL()method is not implemented well. I will take look to the OpenGL part.

                                      Do you agree that there is a problem with OpenGL? Or do you think the cause of this is the event loop?
                                      Sorry for all this silly questions. I'am not very experienced in programming and this is a studyproject from university. Some thinks sounds new to me.

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

                                        That QOpenGLWidget is new to me, there's no reference to it in your code.

                                        I would recommend minimizing your application so that you can concentrate on the Decklink integration part.

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

                                        M 1 Reply Last reply
                                        0
                                        • SGaistS SGaist

                                          That QOpenGLWidget is new to me, there's no reference to it in your code.

                                          I would recommend minimizing your application so that you can concentrate on the Decklink integration part.

                                          M Offline
                                          M Offline
                                          makopo
                                          wrote on last edited by
                                          #20

                                          I checked the DeckLink intergration and I think there is no problem. I come bck to the OpenGl part and tried to draw a triangle with OpenGL in QOpenGLWidget::paintGL(). The function is called, but the graphic isn't rendered.

                                          void VideoScreen::paintGL() {
                                          	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                                          	glBegin(GL_TRIANGLES);
                                          		glColor3f(1, 0, 0);
                                          		glVertex3f(-0.5, -0.5, 0);
                                          		glColor3f(0, 1, 0);
                                          		glVertex3f(0.5, -0.5, 0);
                                          		glColor3f(1, 0, 0);
                                          		glVertex3f(0.0, -0.5, 0);
                                          	glEnd();
                                          	qDebug() << "VideoScreen: paintGL works";
                                          }
                                          

                                          I also checked QOpenGLWidget::initializeGL() and the call of glClearColor works.

                                          void VideoScreen::initializeGL() {
                                          	initializeOpenGLFunctions();
                                          	glClearColor(1, 1, 0, 1); //after calling this the widget is yellow
                                          	m_previewHelper->InitializeGL();
                                          	qDebug() << "VideoScreen: initalizeGL works.";
                                          }
                                          

                                          The OpenGL context is created in the main-method.

                                          QSurfaceFormat format;
                                          format.setDepthBufferSize(24);
                                          format.setStencilBufferSize(8);
                                          format.setVersion(3, 2);
                                          format.setProfile(QSurfaceFormat::CoreProfile);
                                          QSurfaceFormat::setDefaultFormat(format);
                                          

                                          The QOpenGLWidget part is implemented in a own class.

                                          class OpenGLScreen : public QOpenGLWidget, protected QOpenGLFunctions {};
                                          

                                          I create a instance of the class which inherits from QMainWindow. Then the OpenGLScreen Widget is added to a layout:

                                          QScreen::QScreen(QWidget* parent)
                                              : QMainWindow(parent), 
                                              m_ui(new Ui::MainWindow)
                                          {
                                              m_screen = new OpenGLScreen(parent);
                                              m_horizontalScreen->addWidget(m_screen);
                                          
                                          QWidget::show();
                                          

                                          Thanks for a little hint whats going wrong here.

                                          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