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 problem with mapping memory from camera
QtWS25 Last Chance

QVideoFrame problem with mapping memory from camera

Scheduled Pinned Locked Moved Mobile and Embedded
qt5.5android
15 Posts 8 Posters 8.1k 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.
  • K Offline
    K Offline
    kolegs
    wrote on last edited by A Former User
    #1

    Hi,

    I got a problem with mapping memory from camera. I get frames with no problem and can detect pixelmap format(Format_BGR32) but I cannot map the memory.

    What is strange I got no problems when using iOS. Function code below:

    QVideoFrame MyQRCodeFilterRunnable::run(QVideoFrame *input, const QVideoSurfaceFormat &surfaceFormat, RunFlags flags)
    {
        qDebug() << "GOT FRAME";
        if (input->isValid() ) {
    
            if(input->map(QAbstractVideoBuffer::ReadOnly)) //always false(why?) 
            {
                qDebug() << "MAPPED";
                input->unmap();
            }
            qDebug() << input->bits() << input->isReadable() << input->isMapped() << input->pixelFormat();
        }
        return *input;
    }
    

    Maybe I am missing some permissions in manifest?
    So far got:

     <uses-permission android:name="android.permission.CAMERA" />
     <uses-feature android:name="android.hardware.camera" />
     <uses-feature android:name="android.hardware.camera.autofocus" />
    
    D 2 Replies Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      How are you using that function ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • K Offline
        K Offline
        kolegs
        wrote on last edited by
        #3

        The way its written in docs
        QAbstractVideoFilter

        1 Reply Last reply
        0
        • D Offline
          D Offline
          deion
          wrote on last edited by
          #4

          I am having the exact same problem: I am trying to get raw (YUV or RGB) pixel data from the camera in Android. I tried it before in previous versions of Android and it did not work. Now Qt 5.5 is supposed to bring various improvements to the camera, however it does not work. I've used code similar to the one kolegs posted and I get the same results; the only diff is that I check input->handleType() and on Winodws PC this is QAbstractVideoBuffer::NoHandle and the map() function succeeds, while on Android (Galaxy Nexus phone running Android 4.3) handleType() is QAbstractVideoBuffer::GLTextureHandle and the map() function fails...

          I really really wished Digia would release some working example on Android on how to simply capture frame data from the camera. The working qml camera example is pretty USELESS !!!!!

          1 Reply Last reply
          0
          • K Offline
            K Offline
            kolegs
            wrote on last edited by kolegs
            #5

            I got working example but only for iOS(gonna post it later, after cleaning my code) still dont know why Android doesnt work

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Unless I'm mistaken, on Android the data is an OpenGL texture that you might be able to access using handle which would return the texture id.

              Hope it helps

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              D 1 Reply Last reply
              0
              • SGaistS SGaist

                Unless I'm mistaken, on Android the data is an OpenGL texture that you might be able to access using handle which would return the texture id.

                Hope it helps

                D Offline
                D Offline
                deion
                wrote on last edited by
                #7

                @SGaist

                Some working code would be great ! I am not at all an expert on OpenGL and something that I could just copy paste (or start from a working and tested code on Android) would really really help. The camera is pretty useless on Android without being able to access the raw frame data :(

                1 Reply Last reply
                0
                • G Offline
                  G Offline
                  GGenny
                  wrote on last edited by
                  #8

                  Same problem... map fail on QVideoFrame from a QVideoFilterRunnable only in Android but... the image is displayed correctly.

                  Now i try the texture id workaround ( the handler is a GLTextureHandle )

                  1 Reply Last reply
                  0
                  • K kolegs

                    Hi,

                    I got a problem with mapping memory from camera. I get frames with no problem and can detect pixelmap format(Format_BGR32) but I cannot map the memory.

                    What is strange I got no problems when using iOS. Function code below:

                    QVideoFrame MyQRCodeFilterRunnable::run(QVideoFrame *input, const QVideoSurfaceFormat &surfaceFormat, RunFlags flags)
                    {
                        qDebug() << "GOT FRAME";
                        if (input->isValid() ) {
                    
                            if(input->map(QAbstractVideoBuffer::ReadOnly)) //always false(why?) 
                            {
                                qDebug() << "MAPPED";
                                input->unmap();
                            }
                            qDebug() << input->bits() << input->isReadable() << input->isMapped() << input->pixelFormat();
                        }
                        return *input;
                    }
                    

                    Maybe I am missing some permissions in manifest?
                    So far got:

                     <uses-permission android:name="android.permission.CAMERA" />
                     <uses-feature android:name="android.hardware.camera" />
                     <uses-feature android:name="android.hardware.camera.autofocus" />
                    
                    D Offline
                    D Offline
                    Dmitriy Bakhtiyarov
                    wrote on last edited by
                    #9

                    I also have the same problem - on Windows my app work correctly, on Android QVideoFrame::map() always return false.

                    I was try to use QCamera + QAbstractVideoSurface, but on Android QCamera don't start - only change status to QCamera::LoadedStatus, not QCamera::ActiveStatus.

                    1 Reply Last reply
                    0
                    • K kolegs

                      Hi,

                      I got a problem with mapping memory from camera. I get frames with no problem and can detect pixelmap format(Format_BGR32) but I cannot map the memory.

                      What is strange I got no problems when using iOS. Function code below:

                      QVideoFrame MyQRCodeFilterRunnable::run(QVideoFrame *input, const QVideoSurfaceFormat &surfaceFormat, RunFlags flags)
                      {
                          qDebug() << "GOT FRAME";
                          if (input->isValid() ) {
                      
                              if(input->map(QAbstractVideoBuffer::ReadOnly)) //always false(why?) 
                              {
                                  qDebug() << "MAPPED";
                                  input->unmap();
                              }
                              qDebug() << input->bits() << input->isReadable() << input->isMapped() << input->pixelFormat();
                          }
                          return *input;
                      }
                      

                      Maybe I am missing some permissions in manifest?
                      So far got:

                       <uses-permission android:name="android.permission.CAMERA" />
                       <uses-feature android:name="android.hardware.camera" />
                       <uses-feature android:name="android.hardware.camera.autofocus" />
                      
                      D Offline
                      D Offline
                      Dmitriy Bakhtiyarov
                      wrote on last edited by
                      #10

                      @kolegs I create ticket in qt bugtracker

                      and I recv message:
                      "It is normal. On different platforms the frames may come in different formats. In case of Android the frame contains an OpenGL texture handle, not raw pixel data, as GLTextureHandle indicates. To perform non-OpenGL operations on such an image on the CPU, the pixel data has to be read back first.
                      examples/multimedia/video/qmlvideofilter_opencl contains some code for this case too. Check rgbframehelper.h: here the imageWrapper function works both for plain (RGB) frames and ones that contain OpenGL textures. It should help getting started."

                      This example code really work, but very slow - I try to process every 10-th frame in video stream from camera, and I can see freezes in video playback.
                      I think that read-only processing may be asynchronous, but extracting image from opengl texture in another thread failed with segmentation fault(I think problem in opengl context). I continue research and write when fix this problem

                      1 Reply Last reply
                      0
                      • K Offline
                        K Offline
                        kolegs
                        wrote on last edited by
                        #11

                        After all I decided to use QVideoProbe since I didn't need to change anything to the frame(I am using it to decode QR codes).

                        1 Reply Last reply
                        0
                        • G Offline
                          G Offline
                          GGenny
                          wrote on last edited by
                          #12

                          GLTextureHandle workaround works nice as described in the example ( i copy directly the uchar without create QImage ). It should also work the patch ( I create a similar patch to avoid the workaround ) of qandroidvideorendercontrol.cpp, as described in the last patch of :

                          https://codereview.qt-project.org/#/c/124771/

                          T 1 Reply Last reply
                          0
                          • G GGenny

                            GLTextureHandle workaround works nice as described in the example ( i copy directly the uchar without create QImage ). It should also work the patch ( I create a similar patch to avoid the workaround ) of qandroidvideorendercontrol.cpp, as described in the last patch of :

                            https://codereview.qt-project.org/#/c/124771/

                            T Offline
                            T Offline
                            theshadowx
                            wrote on last edited by theshadowx
                            #13

                            @GGenny I have a problem with QVideoFrame and using OpenCV (I don't if I should create a thread for this?).

                            My camera takes images in YUV420P,.

                            QVideoFrame FilterRunnable::run(QVideoFrame *input, const QVideoSurfaceFormat &surfaceFormat, QVideoFilterRunnable::RunFlags flags)
                            {
                                if(input->isValid()){
                                    input->map(QAbstractVideoBuffer::ReadWrite);
                                    /// QVideoFrame to cv::Mat
                                    Mat cvImg = Mat(input->height(),input->width(), CV_8UC3,input->bits(),input->bytesPerLine());
                            
                                    /// Apply Filter
                                    Mat edges;
                            
                                    /// to grayscale
                                    cvtColor(cvImg, edges, COLOR_YUV2GRAY_420);
                            
                                    /// apply filters
                                    GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
                                    Canny(edges, edges, 0, 30, 3);
                            
                                    /// convert to YUV420
                                    cvtColor(edges,edges, COLOR_GRAY2RGB);
                                    cvtColor(edges,edges, COLOR_RGB2YUV_I420);
                            
                                    /// .....   ???
                                }
                            
                                 return *input;
                            }
                            

                            My question is how to return the modified frame ?

                            I tried to use QImage, but unfortunately it doesn't support YUV, so in return I have a blank frame as the surfaceFormat is YUV.

                            As @deion said, there should be more examples about these new features, otherwise they are "pretty USELESS"

                            If this question should be in a new thread, please let me know.

                            Julian GuarinJ 1 Reply Last reply
                            0
                            • T theshadowx

                              @GGenny I have a problem with QVideoFrame and using OpenCV (I don't if I should create a thread for this?).

                              My camera takes images in YUV420P,.

                              QVideoFrame FilterRunnable::run(QVideoFrame *input, const QVideoSurfaceFormat &surfaceFormat, QVideoFilterRunnable::RunFlags flags)
                              {
                                  if(input->isValid()){
                                      input->map(QAbstractVideoBuffer::ReadWrite);
                                      /// QVideoFrame to cv::Mat
                                      Mat cvImg = Mat(input->height(),input->width(), CV_8UC3,input->bits(),input->bytesPerLine());
                              
                                      /// Apply Filter
                                      Mat edges;
                              
                                      /// to grayscale
                                      cvtColor(cvImg, edges, COLOR_YUV2GRAY_420);
                              
                                      /// apply filters
                                      GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
                                      Canny(edges, edges, 0, 30, 3);
                              
                                      /// convert to YUV420
                                      cvtColor(edges,edges, COLOR_GRAY2RGB);
                                      cvtColor(edges,edges, COLOR_RGB2YUV_I420);
                              
                                      /// .....   ???
                                  }
                              
                                   return *input;
                              }
                              

                              My question is how to return the modified frame ?

                              I tried to use QImage, but unfortunately it doesn't support YUV, so in return I have a blank frame as the surfaceFormat is YUV.

                              As @deion said, there should be more examples about these new features, otherwise they are "pretty USELESS"

                              If this question should be in a new thread, please let me know.

                              Julian GuarinJ Offline
                              Julian GuarinJ Offline
                              Julian Guarin
                              wrote on last edited by
                              #14

                              @theshadowx You must input->unmap() to write the buffer. Also check that map() returns true. Otherwise you would have to use OpenGl directly.

                              1 Reply Last reply
                              0
                              • R Offline
                                R Offline
                                rhardih
                                wrote on last edited by
                                #15

                                Can anyone link to an example using an OpenGL texture instead of raw frame data?

                                I'm trying a similar approach as @theshadowx, where I'm passing the mapped bits() to OpenCV for processing. I'm not entirely clear how this would work in the case of the data being an OpenGL texture.

                                CC @SGaist @Julian-Guarin

                                1 Reply Last reply
                                1
                                • KailoKyraK KailoKyra 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