From b9569c5fb96e39fea942f1733991acbe54736db7 Mon Sep 17 00:00:00 2001 From: Tobias Junghans Date: Mon, 6 Sep 2021 13:17:06 +0200 Subject: [PATCH] pipewire: fix image format conversion According to the docs, QImage::convertTo() performs an in-place format conversion after *detaching*, i.e. it does not operate on the buffer passed to its constructor (which wouldn't even work if a larger buffer is required for the target format). Therefore two flaws in the current implementation need to be fixed: * memcpy() has to copy the converted image data to the target buffer * the target format should always be QImage::Format_RGBX8888 according to the return value of PWFrameBuffer::depth() - only streams in SPA_VIDEO_FORMAT_RGBx format can be copied directly. This fixes wrong colors in my setup (QEMU VM with Debian Testing and Gnome) where the PipeWire stream is supplied in SPA_VIDEO_FORMAT_BGRx format. --- framebuffers/pipewire/pw_framebuffer.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/framebuffers/pipewire/pw_framebuffer.cpp b/framebuffers/pipewire/pw_framebuffer.cpp index 0cb582e..615140a 100644 --- a/framebuffers/pipewire/pw_framebuffer.cpp +++ b/framebuffers/pipewire/pw_framebuffer.cpp @@ -823,13 +823,14 @@ void PWFrameBuffer::Private::handleFrame(pw_buffer *pwBuffer) cleanup(); } - if (videoFormat->format != SPA_VIDEO_FORMAT_RGB) { + if (videoFormat->format != SPA_VIDEO_FORMAT_RGBx) { const QImage::Format format = videoFormat->format == SPA_VIDEO_FORMAT_BGR ? QImage::Format_BGR888 - : videoFormat->format == SPA_VIDEO_FORMAT_RGBx ? QImage::Format_RGBX8888 + : videoFormat->format == SPA_VIDEO_FORMAT_RGBA ? QImage::Format_RGBA8888 : QImage::Format_RGB32; QImage img((uchar*) q->fb, videoSize.width(), videoSize.height(), dstStride, format); - img.convertTo(QImage::Format_RGB888); + img.convertTo(QImage::Format_RGBX888); + std::memcpy(q->fb, img.constBits(), img.bytesPerLine() * img.height()); } q->tiles.append(QRect(0, 0, videoSize.width(), videoSize.height())); -- GitLab