Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. QVideoFrame::map fails on Ubuntu Touch
Forum Updated to NodeBB v4.3 + New Features

QVideoFrame::map fails on Ubuntu Touch

Scheduled Pinned Locked Moved Unsolved Mobile and Embedded
1 Posts 1 Posters 247 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    s710
    wrote on last edited by
    #1

    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. The QVideoFrame::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 the QVideoFrame. 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 the qzxing library work in my app. I have it working under SailfishOS already (where QVideoFrame::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 return false 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 what frame.pixelFormat() reports.
    Does this even matter, or will GL_RGBA work anyway, and I just have to make sure img is of the correct format, so the internal buffer is large enough? Would therefore be QImage::Format_RGBA8888 correct?

    Why is the resulting image seemingly invalid? How can I fix this?

    1 Reply Last reply
    0
    • Z zubozrout referenced this topic on

    • Login

    • Login or register to search.
    • First post
      Last post
    0
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Get Qt Extensions
    • Unsolved