File indexing completed on 2024-05-12 15:49:09
0001 /* 0002 SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org> 0003 SPDX-License-Identifier: MIT 0004 */ 0005 0006 #include "videoscannerframe_p.h" 0007 0008 #include <QAbstractVideoBuffer> 0009 0010 #include <cstring> 0011 0012 using namespace Prison; 0013 0014 VideoScannerFrame::VideoScannerFrame() = default; 0015 0016 VideoScannerFrame::VideoScannerFrame(const QVideoFrame &frame, bool isVerticallyFlipped, Format::BarcodeFormats formats) 0017 : m_frame(frame) 0018 , m_formats(formats) 0019 , m_verticallyFlipped(isVerticallyFlipped) 0020 { 0021 } 0022 0023 VideoScannerFrame::~VideoScannerFrame() = default; 0024 0025 int VideoScannerFrame::width() const 0026 { 0027 return m_frame.width(); 0028 } 0029 0030 int VideoScannerFrame::height() const 0031 { 0032 return m_frame.height(); 0033 } 0034 0035 int VideoScannerFrame::bytesPerLine() const 0036 { 0037 return m_frame.bytesPerLine(); 0038 } 0039 0040 QVideoFrame::PixelFormat VideoScannerFrame::pixelFormat() const 0041 { 0042 return m_frame.pixelFormat(); 0043 } 0044 0045 void VideoScannerFrame::map() 0046 { 0047 if (!m_frameData && m_image.isNull()) { 0048 m_frame.map(QAbstractVideoBuffer::ReadOnly); 0049 } 0050 } 0051 0052 void VideoScannerFrame::unmap() 0053 { 0054 if (m_frame.isMapped()) { 0055 m_frame.unmap(); 0056 } 0057 } 0058 0059 const uint8_t *VideoScannerFrame::bits() const 0060 { 0061 if (m_frameData) { 0062 return m_frameData; 0063 } 0064 if (!m_image.isNull()) { 0065 return m_image.bits(); 0066 } 0067 0068 Q_ASSERT(m_frame.isMapped()); 0069 return m_frame.bits(); 0070 } 0071 0072 bool VideoScannerFrame::copyRequired() const 0073 { 0074 return m_frame.handleType() == QAbstractVideoBuffer::GLTextureHandle; 0075 } 0076 0077 void VideoScannerFrame::copyFrameData(QByteArray &buffer) 0078 { 0079 Q_ASSERT(m_frame.isMapped()); 0080 0081 const auto size = frameDataSize(); 0082 if (buffer.size() != size) { 0083 buffer.resize(size); 0084 } 0085 std::memcpy(buffer.data(), m_frame.bits(), size); 0086 m_frameData = reinterpret_cast<const uint8_t *>(buffer.constData()); 0087 } 0088 0089 int VideoScannerFrame::frameDataSize() const 0090 { 0091 Q_ASSERT(m_frame.isMapped()); 0092 0093 switch (m_frame.pixelFormat()) { 0094 case QVideoFrame::Format_YUV420P: 0095 case QVideoFrame::Format_YUV422P: 0096 case QVideoFrame::Format_YV12: 0097 case QVideoFrame::Format_NV12: 0098 case QVideoFrame::Format_NV21: 0099 case QVideoFrame::Format_IMC1: 0100 case QVideoFrame::Format_IMC2: 0101 case QVideoFrame::Format_IMC3: 0102 case QVideoFrame::Format_IMC4: 0103 return m_frame.mappedBytes() / 2; 0104 default: 0105 return m_frame.mappedBytes(); 0106 } 0107 } 0108 0109 bool VideoScannerFrame::needsConversion() const 0110 { 0111 switch (m_frame.pixelFormat()) { 0112 case QVideoFrame::Format_RGB565: 0113 case QVideoFrame::Format_RGB555: 0114 case QVideoFrame::Format_ARGB8565_Premultiplied: 0115 case QVideoFrame::Format_BGR565: 0116 case QVideoFrame::Format_BGR555: 0117 case QVideoFrame::Format_BGRA5658_Premultiplied: 0118 case QVideoFrame::Format_Jpeg: 0119 case QVideoFrame::Format_CameraRaw: 0120 case QVideoFrame::Format_AdobeDng: 0121 case QVideoFrame::Format_User: 0122 return true; 0123 default: 0124 return false; 0125 } 0126 } 0127 0128 void VideoScannerFrame::convertToImage() 0129 { 0130 if (!m_image.isNull()) { 0131 return; 0132 } 0133 0134 Q_ASSERT(m_frame.isMapped()); 0135 m_image = m_frame.image(); 0136 m_image.convertTo(QImage::Format_Grayscale8); 0137 } 0138 0139 bool VideoScannerFrame::isVerticallyFlipped() const 0140 { 0141 #ifdef Q_OS_ANDROID 0142 return true; 0143 #endif 0144 return m_verticallyFlipped; 0145 } 0146 0147 Format::BarcodeFormats VideoScannerFrame::formats() const 0148 { 0149 return m_formats; 0150 }