Solved Showing video in GUI does not work (black screen)
-
Build the QImage in the callback and send it further using invokeMethod.
-
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. -
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.
-
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 theOpenGLScreen
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.
-
I don't see any projection matrix initialization.
In your code are you sure you are properly setting up the texture to be painted if using a texture for the video image ?
-
Thanks for advice. I tried to initialize the projection matrix in
QOpenGLWidget::resizeGL(int w, int h)
, but I also get an empty widget.void VideoScreen::resizeGL(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); qDebug() << "VideoScreen: resizeGl works"; }
According to the decklink documention the texture should be generated with a special interface, called
IDeckLinkScreenPreviewHelper
.
So inVideoScreen::paintGL()
a call ofm_screenPreviewHelper->PaintGL()
should render Texture and Shader. But it is not deeply descripted in the documentation. Also in concerning sample code Shaders and Textures are not used.
When I includem_screenPreviewHelper->PaintGL()
I get a black widget. After minimizing the main window paintGL is called and after reopening the window too. With this I get a single (freezed) frame rendered. -
Can you provide a link to the actual Decklink example you are using as reference ?
-
You can finde the sample code here: QuadPreview. The SDK is not shared with github e.g. , so I uploaded it to private cloud.
In this Qt example the matrix identity and the perspective are set with the QMatrix4x4 class. Is this modern way for initializing a matrix? Or is there no difference between
glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); glMatrixMode(GL_MODELVIEW);
and
m_proj.setToIdentity(); m_proj.perspective(45.0f, GLfloat(w) / h, 0.01f, 100.0f);
-
I fixed the issue with calling
QWidget::update()
inQOpenGLWidget::paintGL()
. Now the videostream works. -
Glad you found a solution and thanks for sharing !
Note that this is a rather unexpected solution has you should not need to do that.
-
@SGaist said in Showing video in GUI does not work (black screen):
Note that this is a rather unexpected solution has you should not need to do that.
That sounds unsatisfactory. In fact signal an slot runs in the same thread.
In another source I found that signal and connect should run in the same thread. In my code these are different. -
Signals and slots are not required to be handled in objects belonging to the same thread.