PDA

View Full Version : QImage vs QPixmap the eternal dilemma of good drawing performance on linux



MidWay
13th May 2014, 10:37
So some background information about my problem. I have a program which displays images coming from webcam. The program works just fine, but the frame rate never reaches anywhere near the 30 which is coming from the camera. I have pinpointed the issue and it is with converting QVideoFrame to QImage and then drawing the image. On windows this code works fine and the whole drawing process takes about 2ms. On linux it's completely different story, drawing the QImage takes more than 20ms which may not sound like much but when it's added for every frame the framerate drops to half of what it should be.

Now i know drawing QImages is slow on linux environments from doing some research but i have no clue how to convert the QVideoFrame straight to QPixmap which is faster to draw. Using QPixmap::fromImage() is not viable solution because that is slow as well.

Current implementation for drawing the image coming from the webcam.


if(mVFcurrentFrame.map(QAbstractVideoBuffer::ReadO nly))
{
QImage image(mVFcurrentFrame.bits(), mVFcurrentFrame.width(), mVFcurrentFrame.height(), mVFcurrentFrame.bytesPerLine(), imageFormat);
painter->drawImage(0,0,image); //Takes about 20ms
mVFcurrentFrame.unmap();
}

So my questions are:

Is it possible to convert QVideoFrame straight to QPixmap and would it be a viable solution?

Is there some other way i could speed up the drawing process?

anda_skoa
13th May 2014, 11:59
Traditionally a QPixmap refers to an image in the memory of the graphics system, on X11 in the memory managed by the XServer.
A QImage on the other hand is data in the program's memory.

So converting an QImage to a QPixmap meant transferring data and/or using something like shared memory.

However, nowadays that is not necessarily true, as there are various ways of how Qt abstracts the platform's graphics system.

Which Qt version are you using?

Cheers,
_

MidWay
13th May 2014, 12:26
Traditionally a QPixmap refers to an image in the memory of the graphics system, on X11 in the memory managed by the XServer.
A QImage on the other hand is data in the program's memory.

So converting an QImage to a QPixmap meant transferring data and/or using something like shared memory.

However, nowadays that is not necessarily true, as there are various ways of how Qt abstracts the platform's graphics system.

Which Qt version are you using?

Cheers,
_

I'm using Qt 4.74. If there is any additional information you need i'm happy to provide it.

The current flow is

When new QVideoFrame is available it's brought to subclassed QVideoWidgetSurface via VideoWidgetSurface::present(const QVideoFrame &frame) method which calls repaint() and generates the QImage from the QVideoFrame data and draws it.

anda_skoa
13th May 2014, 13:31
You could try experiementing with the -graphicssystem commandline switch (or QApplication::setGraphicsSystem), e.g. checking if there is a difference between "native" and "raster".

If your source can deliver multiple formats, you can also check if you might currently be using one that requires lots of conversions, e.g. different color depth, etc.

Cheers,
_