QPixmap load from raw RGB data (from libvlc)
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);
void RenderSurface::paintEvent(QPaintEvent *event)
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:
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.
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
void writeBMPHeader (unsigned char* buffer, unsigned int width, unsigned int height, unsigned int imageDataOffset)
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.
I'm actually developing on a Windows machine and I'd like to have something cross-platform.