Fix unmap in case of early return of frame processing

Added support to image rotate based on the orientation of the frame #199
This commit is contained in:
Nikolaos Ftylitakis 2021-12-07 23:34:44 +02:00
parent 1f819ed0f0
commit 7d3b430b9e
2 changed files with 58 additions and 27 deletions

View File

@ -37,6 +37,21 @@ void QZXingFilter::handleDecodingFinished(bool succeeded)
emit isDecodingChanged();
}
void QZXingFilter::setOrientation(int orientation)
{
if (orientation_ == orientation) {
return;
}
orientation_ = orientation;
emit orientationChanged(orientation_);
}
int QZXingFilter::orientation() const
{
return orientation_;
}
void QZXingFilter::setVideoSink(QObject *videoSink){
m_videoSink = qobject_cast<QVideoSink*>(videoSink);
@ -52,37 +67,48 @@ void QZXingFilter::processFrame(const QVideoFrame &frame) {
const QVideoFrame &f = frame;
#endif // Q_OS_ANDROID
if(isDecoding() || !processThread.isFinished()) return;
if(!isDecoding() && processThread.isFinished()){
decoding = true;
decoding = true;
QImage image = f.toImage();
processThread = QtConcurrent::run([=](){
if(image.isNull())
{
qDebug() << "QZXingFilter error: Cant create image file to process.";
decoding = false;
return;
}
QImage image = f.toImage();
QImage frameToProcess(image);
const QRect& rect = captureRect.toRect();
if (captureRect.isValid() && frameToProcess.size() != rect.size()) {
frameToProcess = image.copy(rect);
}
if (!orientation_) {
decoder.decodeImage(frameToProcess);
} else {
QTransform transformation;
transformation.translate(frameToProcess.rect().center().x(), frameToProcess.rect().center().y());
transformation.rotate(-orientation_);
QImage translatedImage = frameToProcess.transformed(transformation);
decoder.decodeImage(translatedImage);
}
// static int i=0;
// qDebug() << "image.size()" << frameToProcess.size();
// qDebug() << "image.format()" << frameToProcess.format();
// const QString path = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation) + "/qrtest/test_" + QString::number(i++ % 100) + ".png";
// qDebug() << "saving image" << i << "at:" << path << frameToProcess.save(path);
decoder.decodeImage(frameToProcess, frameToProcess.width(), frameToProcess.height());
});
}
#ifdef Q_OS_ANDROID
f.unmap();
#endif
processThread = QtConcurrent::run([=](){
if(image.isNull())
{
qDebug() << "QZXingFilter error: Cant create image file to process.";
decoding = false;
return;
}
QImage frameToProcess(image);
const QRect& rect = captureRect.toRect();
if (captureRect.isValid() && frameToProcess.size() != rect.size()) {
frameToProcess = image.copy(rect);
}
// static int i=0;
// qDebug() << "image.size()" << frameToProcess.size();
// qDebug() << "image.format()" << frameToProcess.format();
// const QString path = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation) + "/qrtest/test_" + QString::number(i++ % 100) + ".png";
// qDebug() << "saving image" << i << "at:" << path << frameToProcess.save(path);
decoder.decodeImage(frameToProcess, frameToProcess.width(), frameToProcess.height());
});
}

View File

@ -32,22 +32,27 @@ class QZXingFilter : public QObject
Q_PROPERTY(QZXing* decoder READ getDecoder)
Q_PROPERTY(QRectF captureRect MEMBER captureRect NOTIFY captureRectChanged)
Q_PROPERTY(QObject* videoSink WRITE setVideoSink)
Q_PROPERTY(int orientation READ orientation WRITE setOrientation NOTIFY orientationChanged)
signals:
void isDecodingChanged();
void decodingFinished(bool succeeded, int decodeTime);
void decodingStarted();
void captureRectChanged();
void orientationChanged(int orientation);
private slots:
void handleDecodingStarted();
void handleDecodingFinished(bool succeeded);
void processFrame(const QVideoFrame &frame);
void setOrientation(int orientation);
int orientation() const;
private: /// Attributes
QZXing decoder;
bool decoding;
QRectF captureRect;
int orientation_;
QVideoSink *m_videoSink;
QFuture<void> processThread;