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 }