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 #ifndef PRISON_VIDEOSCANNERFRAME_P_H 0007 #define PRISON_VIDEOSCANNERFRAME_P_H 0008 0009 #include "format.h" 0010 0011 #include <QImage> 0012 #include <QMetaType> 0013 #include <QVideoFrame> 0014 0015 namespace Prison 0016 { 0017 0018 /** 0019 * A single frame from a video feed handed over to the barcode scanner worker thread. 0020 * 0021 * This abstracts three possible states: 0022 * - direct data access to the original frame data, when possible 0023 * - access to an internal copy of at least the luminescence part of the raw frame data 0024 * if access is only possible in the render thread and the raw format is consumeable 0025 * by ZXing 0026 * - a decoded 8bit grayscale QImage of the frame content, if the raw frame data is only 0027 * accessible in the render thread and the native frame format is not consumeable by 0028 * ZXing directly 0029 * 0030 * @internal 0031 */ 0032 class VideoScannerFrame 0033 { 0034 public: 0035 explicit VideoScannerFrame(); 0036 explicit VideoScannerFrame(const QVideoFrame &frame, bool verticallyFlipped, Format::BarcodeFormats formats); 0037 ~VideoScannerFrame(); 0038 0039 int width() const; 0040 int height() const; 0041 int bytesPerLine() const; 0042 QVideoFrameFormat::PixelFormat pixelFormat() const; 0043 0044 /** Map/unmap the frame if needed, ie. if we don't already have a copy. */ 0045 void map(); 0046 void unmap(); 0047 0048 /** Raw frame data, either zero copy or from an internal buffer 0049 * if we were forced to copy. 0050 * Possibly truncated to just the subset that contains all the luminescence 0051 * channel, e.g. for planar formats. 0052 */ 0053 const uint8_t *bits() const; 0054 0055 /** Decides based on the input frame format whether an immediate 0056 * copy in the reader thread is necessary. 0057 */ 0058 bool copyRequired() const; 0059 /** Copy the required subset of the frame data to our internal buffer. 0060 * @note Requires the frame to be mapped. 0061 */ 0062 void copyFrameData(QByteArray &buffer); 0063 0064 /** Returns whether we have a format that ZXing cannot consume without 0065 * prior conversion. These are the formats we need to let Qt convert 0066 * to a QImage first, and in case frame data access is only allowed in 0067 * the render thread, this also has to happen there. 0068 */ 0069 bool needsConversion() const; 0070 /** Convert to grayscale QImage. 0071 * @note Requires the frame to be mapped. 0072 */ 0073 void convertToImage(); 0074 0075 /** The requested barcode formats. */ 0076 Format::BarcodeFormats formats() const; 0077 0078 /** Returns @c true if the raw frame data is vertically flipped compared 0079 * to how it's displayed. This doesn't impact barcode detection as such, 0080 * but it requires corresponding adjustments to the coordinates at which 0081 * a barcode has been detected. 0082 */ 0083 bool isVerticallyFlipped() const; 0084 0085 private: 0086 /** The amount of data to copy. This can be less than the entire frame 0087 * size for planar formats. 0088 * @note Requires the frame to be mapped. 0089 */ 0090 int frameDataSize() const; 0091 0092 QVideoFrame m_frame; 0093 const uint8_t *m_frameData = nullptr; 0094 QImage m_image; 0095 Format::BarcodeFormats m_formats = {}; 0096 bool m_verticallyFlipped = false; 0097 }; 0098 0099 } 0100 0101 Q_DECLARE_METATYPE(Prison::VideoScannerFrame) 0102 0103 #endif // PRISON_VIDEOSCANNERFRAME_P_H