Important: Please read the Qt Code of Conduct -

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);

    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.

    #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

    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.

  • Thanks!
    I'm actually developing on a Windows machine and I'd like to have something cross-platform.

Log in to reply