[Interest] QVideoFrame 32 bit formats byte order

David M. Cotter dave at kjams.com
Thu Nov 14 21:04:50 CET 2019


I had a similar finding.

i find that QImage::Format_ARGB32 is always 0xBBGGRRAA on both mac and windows

unrelated to video,  but just allocating a QImage

> On Nov 14, 2019, at 11:54 AM, Stefan Fabian <stefan.fabian.dev at hotmail.com> wrote:
> 
> 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 <mailto:Interest at qt-project.org>
> https://lists.qt-project.org/listinfo/interest <https://lists.qt-project.org/listinfo/interest>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20191114/ab8dc17f/attachment.html>


More information about the Interest mailing list