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 }