File indexing completed on 2024-04-28 05:27:34

0001 /*
0002     SPDX-FileCopyrightText: 2023 Aleix Pol Gonzalez <aleixpol@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include "pwhelpers.h"
0008 #include "logging.h"
0009 
0010 QImage::Format SpaToQImageFormat(quint32 format)
0011 {
0012     switch (format) {
0013     case SPA_VIDEO_FORMAT_BGRx:
0014     case SPA_VIDEO_FORMAT_BGRA:
0015         return QImage::Format_RGBA8888_Premultiplied; // Handled in SpaBufferToQImage
0016     case SPA_VIDEO_FORMAT_ABGR:
0017     case SPA_VIDEO_FORMAT_xBGR:
0018         return QImage::Format_ARGB32; // Handled in SpaBufferToQImage
0019     case SPA_VIDEO_FORMAT_BGR:
0020         return QImage::Format_BGR888;
0021     case SPA_VIDEO_FORMAT_RGBx:
0022         return QImage::Format_RGBX8888;
0023     case SPA_VIDEO_FORMAT_RGB:
0024         return QImage::Format_RGB888;
0025     case SPA_VIDEO_FORMAT_RGBA:
0026         return QImage::Format_RGBA8888_Premultiplied;
0027     case SPA_VIDEO_FORMAT_GRAY8:
0028         return QImage::Format_Grayscale8;
0029     default:
0030         qCWarning(PIPEWIRE_LOGGING) << "cannot convert spa format to QImage" << format;
0031         return QImage::Format_RGB32;
0032     }
0033 }
0034 
0035 QImage PWHelpers::SpaBufferToQImage(const uchar *data, int width, int height, qsizetype bytesPerLine, spa_video_format format, PipeWireFrameCleanupFunction *c)
0036 {
0037     c->ref();
0038     switch (format) {
0039     case SPA_VIDEO_FORMAT_BGRx:
0040     case SPA_VIDEO_FORMAT_BGRA:
0041     case SPA_VIDEO_FORMAT_xBGR:
0042     case SPA_VIDEO_FORMAT_ABGR: {
0043         // This is needed because QImage does not support BGRA
0044         // This is obviously a much slower path, it makes sense to avoid it as much as possible
0045         return QImage(data, width, height, bytesPerLine, SpaToQImageFormat(format), &PipeWireFrameCleanupFunction::unref, c).rgbSwapped();
0046     }
0047     case SPA_VIDEO_FORMAT_GRAY8:
0048     case SPA_VIDEO_FORMAT_RGBx:
0049     case SPA_VIDEO_FORMAT_RGB:
0050     case SPA_VIDEO_FORMAT_RGBA:
0051     default:
0052         return QImage(data, width, height, bytesPerLine, SpaToQImageFormat(format), &PipeWireFrameCleanupFunction::unref, c);
0053     }
0054 }
0055 
0056 QImage PipeWireFrameData::toImage() const
0057 {
0058     return PWHelpers::SpaBufferToQImage(static_cast<uchar *>(data), size.width(), size.height(), stride, format, cleanup);
0059 }
0060 
0061 std::shared_ptr<PipeWireFrameData> PipeWireFrameData::copy() const
0062 {
0063     const uint bufferSize = size.height() * stride * 4;
0064     auto newMap = malloc(bufferSize);
0065     memcpy(newMap, data, bufferSize);
0066     return std::make_shared<PipeWireFrameData>(format, newMap, size, stride, new PipeWireFrameCleanupFunction([newMap] {
0067                                                    free(newMap);
0068                                                }));
0069 }