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@qt-project.org
https://lists.qt-project.org/listinfo/interest

Reply via email to