0

I have 4 camera objects. Each camera Object refreshes frames independently. I would like to visualize these frames on my videowall class. Basicly, my videowall is just a gridlayout child with draw Widget methods.

Each camera object has imageHolder widget. ImageHolder widget is a child of qOpenglWidget with

void OpenGLImageHolder::display(const QImage* img)
{
    m_image = img;
    this->update();
}

void OpenGLImageHolder::paintEvent(QPaintEvent*)
{

    QPainter painter(this);
    painter.drawImage(this->rect(), *m_image);
}

Each Image Holder has a QTimer and QTimer::timeOut() is connected to OpenGLImageHolder::display().

Unfortunatelly, with this setup, I can visualize only 3 cameras simultaniously. If I add 4th camera, one of three (or two) freezes. I know that display was called, because when I resizeWidget, I get a correct Image update.

What is the right way to make videoWall? Shall I make one openglWidget with its own window, and then draw images directly on this openglWidget? Which tools can I use to profile the behaviour (it seems that standart msvs profiler is not enough).

hagor
  • 304
  • 1
  • 15
  • I once wrote an answer to [SO: Qt C++ Displaying images outside the GUI thread (Boost thread)](https://stackoverflow.com/a/47470395/7478597) which is somehow similar but I wasn't sure whether it applies to your issue. You may have a look at it (e.g. if you are out of ideas). ;-) – Scheff's Cat Sep 21 '18 at 15:52
  • What's the ownership of the `QImage` that's passed by pointer to `OpenGLImageHolder::display`? Whenever I see code like that without any accompanying `new`/`delete` it sets off all sorts of alarm bells. Also, are you using `OpenGL` elsewhere in your code? If not then inheriting from `QOpenGLWidget` seems a bit excessive -- the same job could be done just as easily with `QWidget`. – G.M. Sep 23 '18 at 09:36

1 Answers1

0

My design:

Each camera uses a thread that prepares an image. The image is created when needed or by a timer. When it's ready, the thread signals the main thread.

The main thread handles the signal. Loads the image to the GPU as a texture an draw it by a simple quad.

The trick is to use an unique window, but a different glViewport for each camera.


Other solution is to use a texture for the whole window and update the rectangle each camera uses.

Ripi2
  • 7,031
  • 1
  • 17
  • 33
  • so calling gpu to render takes time, does it? Why does the standart approach (update each widget in it's thread) doesn't work? – hagor Sep 21 '18 at 14:17
  • I answered how to do it with OpenGL. Drawing with OS/Qt API is also valid. Rendering images speed is simliar on both approaches. Updating the window is better done in the main thread, some issues may appear it each thread updates its portion of the screen. – Ripi2 Sep 21 '18 at 14:39
  • @hagor Doing GUI update in multiple threads is a bad idea in general. That's true for Qt as well as for other widget sets. (I remember the same for GTK+/gtkmm V2 and don't believe that it has changed in V3.) The same is true for OpenGL. Concerning the latter, there is only one (active) GL context (AFAIK). Even if access to this context by multiple threads is secured by locking, the multi-threading becomes questionable as concurrent accesses are impossible and serialization would be forced by this locking. – Scheff's Cat Sep 21 '18 at 15:49