File indexing completed on 2024-05-12 04:01:32
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 <cstring> 0009 0010 using namespace Prison; 0011 0012 VideoScannerFrame::VideoScannerFrame() = default; 0013 0014 VideoScannerFrame::VideoScannerFrame(const QVideoFrame &frame, bool isVerticallyFlipped, Format::BarcodeFormats formats) 0015 : m_frame(frame) 0016 , m_formats(formats) 0017 , m_verticallyFlipped(isVerticallyFlipped) 0018 { 0019 } 0020 0021 VideoScannerFrame::~VideoScannerFrame() = default; 0022 0023 int VideoScannerFrame::width() const 0024 { 0025 return m_frame.width(); 0026 } 0027 0028 int VideoScannerFrame::height() const 0029 { 0030 return m_frame.height(); 0031 } 0032 0033 int VideoScannerFrame::bytesPerLine() const 0034 { 0035 return m_frame.bytesPerLine(0); 0036 } 0037 0038 QVideoFrameFormat::PixelFormat VideoScannerFrame::pixelFormat() const 0039 { 0040 return m_frame.pixelFormat(); 0041 } 0042 0043 void VideoScannerFrame::map() 0044 { 0045 if (!m_frameData && m_image.isNull()) { 0046 m_frame.map(QVideoFrame::ReadOnly); 0047 } 0048 } 0049 0050 void VideoScannerFrame::unmap() 0051 { 0052 if (m_frame.isMapped()) { 0053 m_frame.unmap(); 0054 } 0055 } 0056 0057 const uint8_t *VideoScannerFrame::bits() const 0058 { 0059 if (m_frameData) { 0060 return m_frameData; 0061 } 0062 if (!m_image.isNull()) { 0063 return m_image.bits(); 0064 } 0065 0066 Q_ASSERT(m_frame.isMapped()); 0067 return m_frame.bits(0); 0068 } 0069 0070 bool VideoScannerFrame::copyRequired() const 0071 { 0072 return m_frame.handleType() == QVideoFrame::RhiTextureHandle; 0073 } 0074 0075 void VideoScannerFrame::copyFrameData(QByteArray &buffer) 0076 { 0077 Q_ASSERT(m_frame.isMapped()); 0078 0079 const auto size = frameDataSize(); 0080 if (buffer.size() != size) { 0081 buffer.resize(size); 0082 } 0083 std::memcpy(buffer.data(), m_frame.bits(0), size); 0084 m_frameData = reinterpret_cast<const uint8_t *>(buffer.constData()); 0085 } 0086 0087 int VideoScannerFrame::frameDataSize() const 0088 { 0089 Q_ASSERT(m_frame.isMapped()); 0090 0091 switch (m_frame.pixelFormat()) { 0092 case QVideoFrameFormat::Format_YUV420P: 0093 case QVideoFrameFormat::Format_YUV422P: 0094 case QVideoFrameFormat::Format_YV12: 0095 case QVideoFrameFormat::Format_NV12: 0096 case QVideoFrameFormat::Format_NV21: 0097 case QVideoFrameFormat::Format_IMC1: 0098 case QVideoFrameFormat::Format_IMC2: 0099 case QVideoFrameFormat::Format_IMC3: 0100 case QVideoFrameFormat::Format_IMC4: 0101 return m_frame.mappedBytes(0) / 2; 0102 default: 0103 return m_frame.mappedBytes(0); 0104 } 0105 } 0106 0107 bool VideoScannerFrame::needsConversion() const 0108 { 0109 switch (m_frame.pixelFormat()) { 0110 case QVideoFrameFormat::Format_Jpeg: 0111 case QVideoFrameFormat::Format_SamplerExternalOES: 0112 case QVideoFrameFormat::Format_SamplerRect: 0113 return true; 0114 default: 0115 return false; 0116 } 0117 } 0118 0119 void VideoScannerFrame::convertToImage() 0120 { 0121 if (!m_image.isNull()) { 0122 return; 0123 } 0124 0125 Q_ASSERT(m_frame.isMapped()); 0126 m_image = m_frame.toImage(); 0127 m_image.convertTo(QImage::Format_Grayscale8); 0128 } 0129 0130 bool VideoScannerFrame::isVerticallyFlipped() const 0131 { 0132 return m_verticallyFlipped; 0133 } 0134 0135 Format::BarcodeFormats VideoScannerFrame::formats() const 0136 { 0137 return m_formats; 0138 }