QVideoFrame::map fails on Ubuntu Touch
-
I am working on an app for Ubuntu Touch, which shall be able to read QR codes. It relies on a custom video filter subclass, however I am unable to extract single images out of the
QVideoFrame
instances. TheQVideoFrame::map
will fail. My research indicates that instead of direct access I must use an OpenGL handle to read a 2D texture, similar to those cases:- https://github.com/stephenquan/MyVideoFilterApp/blob/master/QVideoFrameToQImage.cpp
- https://stackoverflow.com/questions/51102225/qvideoframemap-crashes
- https://forum.qt.io/topic/103430/qvideoframe-map-is-false-in-android
- https://lists.qt-project.org/pipermail/interest/2018-June/030295.html
So I am trying to implement a
QVideoFrame::map
replacement using OpenGL functions.However, although the approach seems to be clear from the above examples, I cannot seem to get a valid
QImage
ouf of theQVideoFrame
. I have a number of uncertainties; I have never worked with OpenGL, and I am also not too familiar with image formats. In fact, I am not working on my own implementation, but instead trying to make theqzxing
library work in my app. I have it working under SailfishOS already (whereQVideoFrame::map
just works), and I am porting my app to Ubuntu Touch.Currently I have this:
QImage img(frame.width(), frame.height(), QImage::Format_RGBA8888); GLuint textureId = frame.handle().toUInt(); QOpenGLContext *ctx = QOpenGLContext::currentContext(); QOpenGLFunctions *f = ctx->functions(); GLuint fbo; f->glGenFramebuffers(1, &fbo); GLuint prevFbo; f->glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint *) &prevFbo); f->glBindFramebuffer(GL_FRAMEBUFFER, fbo); f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0); f->glReadPixels(0, 0, frame.width(), frame.height(), GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); const QString path = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation) + "/qrtest/test.png"; qDebug() << "Saving image at:" << path << img.save(path) << " size: " << img.size() << "/" << img.sizeInBytes();
When I try to save the image to disk (in order to check how it looks, if it even contains anything at all),
QImage::save
will returnfalse
and will print:Saving image at: "/home/phablet/Pictures/qrtest/test.png" false size: QSize(1920, 1088) / 8355840
The input video stream seems to be of the format
QVideFrame::Format_RGB32
, at least this is whatframe.pixelFormat()
reports.
Does this even matter, or willGL_RGBA
work anyway, and I just have to make sureimg
is of the correct format, so the internal buffer is large enough? Would therefore beQImage::Format_RGBA8888
correct?Why is the resulting image seemingly invalid? How can I fix this?
-