[Interest] QVideoFrame 32 bit formats byte order

Stefan Fabian stefan.fabian.dev at hotmail.com
Fri Nov 15 08:57:24 CET 2019


qRgb() and qRgba() only exist for (A)RGB, though, and I don't have an issue with RGB32 which works as I would expect.
Otherwise, a function that would put the bytes where it wants would be great.
It's just the BGR(A) that doesn't work as documented regardless of whether you treat it as an unsigned integer (as one would expect) or with a fixed in-memory order.
________________________________
Von: Jason H <jhihn at gmx.com>
Gesendet: Freitag, 15. November 2019 00:42
An: Stefan Fabian <stefan.fabian.dev at hotmail.com>
Cc: interest at qt-project.org <interest at qt-project.org>
Betreff: Re: [Interest] QVideoFrame 32 bit formats byte order

Maybe you should use qRgb() or qRgba(...) and let it put the bytes where it wants? also, note that there are qRed(), qBlue(), qGeen(), and qAlpha() which should take care of extracting the aproproate channel for you.

If you told me that in Qt, BGR32 (and BGRA32) is 0xAABBGGRR, I would agree. Note though in openCV, this is an issue. (Blue and Red are swapped in the memory)

Sent: Thursday, November 14, 2019 at 1:54 PM
From: "Stefan Fabian" <stefan.fabian.dev at hotmail.com>
To: "interest at qt-project.org" <interest at qt-project.org>
Subject: [Interest] QVideoFrame 32 bit formats byte order
Hey guys,

I'm interfacing external camera input to Qt/QML (version 5.9.5 on Ubuntu 18.04).
For this, I'm using a custom video source and present the frames using QVideoFrame and QAbstractVideoBuffer.
The image is displayed in QML using a VideoOutput.
Since not all formats can be mapped directly, I have to do some conversions.
The issue:

The formats RGB32 and BGR32 don't act as expected.
According to the docs, the former is 0xffRRGGBB and the latter 0xBBGGRRff. Unfortunately, it is not specified whether the endianness of the computer is used or big-endian.

Here's the conversion to RGB32:

auto output = reinterpret_cast<uint32_t *>(*data);
iterateImage( img, bytes_per_pixel, [ & ]( const uint8_t *stream )
{
  *output = (255U << 24U) | (static_cast<uint32_t>(static_cast<uint8_t>(R( stream, 0, 255 ))) << 16U) |
            (static_cast<uint32_t>(static_cast<uint8_t>(G( stream, 0, 255 ))) << 8U) |
            static_cast<uint32_t>(static_cast<uint8_t>(B( stream, 0, 255 )));
  ++output;
} );

and this is to BGR32:

auto output = reinterpret_cast<uint32_t *>(*data);
iterateImage( img, bytes_per_pixel, [ & ]( const uint8_t *stream )
{
  *output = (static_cast<uint32_t>(static_cast<uint8_t>(B( stream, 0, 255 ))) << 24U) |
            (static_cast<uint32_t>(static_cast<uint8_t>(G( stream, 0, 255 ))) << 16U) |
            (static_cast<uint32_t>(static_cast<uint8_t>(R( stream, 0, 255 ))) << 8U) |
            255U;
  ++output;
} );

The functions B, G, R extract the channels from the pixel at stream and map the values to the given range.
The problem:
Whereas for RGB32, the image is as expected (gray), for BGR32 for some reason the image is semi-transparent red which shouldn't be possible since the B, G, R functions are the same in this case (input is a single channel image).

To test my hypothesis that the order is not as expected I used the following test:

auto output = reinterpret_cast<uint32_t *>(*data);
int count = img.width * img.height / 4;
int i = 0;
iterateImage( img, bytes_per_pixel, [ & ]( const uint8_t *stream )
{
  if ((i / count) == 0) *output = 0xff000000;
  else if ((i / count) == 1) *output = 0x00ff0000;
  else if ((i / count) == 2) *output = 0x0000ff00;
  else if ((i / count) == 3) *output = 0x000000ff;
  ++output;
  ++i;
} );

And indeed the image is 4 bars, from top to bottom: black, blue, green and red.

It appears as if the format for BGR32 (and BGRA32) is actually either 0xAABBGGRR or 0xRRGGBBAA in big-endian. Is this a (known) bug in the docs/implementation or am I missing something?

Best regards,
Stefan Fabian
_______________________________________________ Interest mailing list Interest at qt-project.org https://lists.qt-project.org/listinfo/interest
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20191115/c974f5fd/attachment.html>


More information about the Interest mailing list