QPixmap load from raw RGB data (from libvlc)
-
Hi,
I'm integrating libvlc with Qt: I've set libvlc to render data to a custom buffer in memory, then for each decoded frame I create a QImage and draw it on a QWidget:@
_nativeImage = QImage(nativeBuffer, nativeWidth, nativeHeight, QImage::Format_ARGB32);
update();
...void RenderSurface::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.drawImage(rect(), _nativeImage, _nativeImage.rect());
}
@This works fine, but it's very inefficient with high resolution images: lots of frame drops.
I wonder if a QPixmap instead of a QImage might speed up a bit the process (I'll try with QGLWidget:: bindTexture() as well).Therefore, is that possibile to create a QPixmap from raw RGB data (actually, vlc is set to render RV32 data)?
I thought that I could just add a BMP header before the raw data buffer and then try as follows:
@
_nativePixmap.loadFromData(nativeBuffer, nativeWidthnativeHeight4, "BMP");
@Strangely, I only get the first frame (correct, but upside-down!!) and no more frames seem to be rendered.
I'm not sure if it's a problem with the BMP header or the RV32 data.
Has anybody any idea?For completeness, I append the code to insert the BMP header:
@
#pragma pack(2)
typedef struct
{
WORD bfType; // must be 'BM' (or 0x4d42)
DWORD bfSize; // size of the whole .bmp file
WORD bfReserved1; // must be 0
WORD bfReserved2; // must be 0
DWORD bfOffBits; // the distance to the beginning of the image data, in bytes, from the beginning of the file; so, to read the image data later on we will move the file pointer to bfOffBits and start reading there.
} BITMAPFILEHEADER;#pragma pack(2)
typedef struct
{
DWORD biSize; // size of the structure, this should always be sizeof(BITMAPINFOHEADER)
LONG biWidth; // image width in pixels
LONG biHeight; // image height in pixels
WORD biPlanes; // bitplanes: number of planes in the image, must be 1
WORD biBitCount; // number of bits per pixel (1, 4, 8, 24 or 32)
DWORD biCompression; // compression type (0=none, 1=RLE-8, 2=RLE-4)
DWORD biSizeImage; // size of image data in bytes (including padding)
LONG biXPelsPerMeter; // pixels per meter X
LONG biYPelsPerMeter; // pixels per meter Y
DWORD biClrUsed; // colors used
DWORD biClrImportant; // important colors
} BITMAPINFOHEADER;void writeBMPHeader (unsigned char* buffer, unsigned int width, unsigned int height, unsigned int imageDataOffset)
{
BITMAPFILEHEADER fileHeader;
BITMAPINFOHEADER infoHeader;memset ( &fileHeader, 0, sizeof (BITMAPFILEHEADER ) );
memset ( &infoHeader, 0, sizeof (BITMAPINFOHEADER ) );fileHeader.bfType = 0x4d42;
fileHeader.bfReserved1 = 0;
fileHeader.bfReserved2 = 0;
fileHeader.bfSize = widthheight4 + imageDataOffset;
fileHeader.bfOffBits = imageDataOffset;infoHeader.biSize = sizeof(BITMAPINFOHEADER);
infoHeader.biWidth = width;
infoHeader.biHeight = height;
infoHeader.biPlanes = 1;
infoHeader.biBitCount = 32;
infoHeader.biCompression = 0;
infoHeader.biSizeImage = widthheight4;
infoHeader.biXPelsPerMeter = 0x0ec4;
infoHeader.biYPelsPerMeter = 0x0ec4;
infoHeader.biClrUsed = 0;
infoHeader.biClrImportant = 0;memcpy( buffer, &fileHeader, sizeof(BITMAPFILEHEADER) );
memcpy( buffer + sizeof(BITMAPFILEHEADER), &infoHeader, sizeof(BITMAPINFOHEADER) );
}
@Thanks for any help!
-
If this is X11 check out QPixmap::x11Info(). On X11 the QPixmap is a server-side buffer and can be accessed directly using more low-level primitives. But before I would try that I would try to render using OpenGL, first.