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. How to solve processCapturedImage slot memory leak?
QtWS25 Last Chance

How to solve processCapturedImage slot memory leak?

Scheduled Pinned Locked Moved Unsolved Mobile and Embedded
9 Posts 5 Posters 527 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.
  • 1 Offline
    1 Offline
    1stetcgoldmedal
    wrote on last edited by
    #1
    #include <QBuffer>
    #include <QCoreApplication>
    #include <QDateTime>
    #include <QJsonDocument>
    #include <QJsonObject>
    #include <QFile>
    #include <QCameraViewfinder>
    
    camera::camera(QObject *parent):QThread(parent)
    {
        const QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
        for (const QCameraInfo &cameraInfo : cameras)//
        {
            qDebug() << cameraInfo.deviceName();
            if(CameraV != nullptr)
            {
                delete CameraV;
                CameraV = nullptr;
            }
            CameraV = new QCamera(cameraInfo);
            if(CameraV != nullptr)
            {
                CameraImageCapture = new QCameraImageCapture(CameraV);
                CameraImageCapture->setCaptureDestination(QCameraImageCapture::CaptureToBuffer);//Not File Only To Buffer
                connect(CameraImageCapture, &QCameraImageCapture::readyForCaptureChanged, this, &camera::CaptureStatusChanged);
                connect(CameraImageCapture, &QCameraImageCapture::imageCaptured, this, &camera::processCapturedImage);
                connect(this, SIGNAL(RequestCapture()), this, SLOT(ImageCapture()));
                CameraV->setCaptureMode(QCamera::CaptureStillImage);
                CameraV->start();
                this->start();
            }
            break;
        }
    }
    void camera::run()
    {
        while(true)
        {
            //emit ReqCurrentSave();
              emit RequestCapture();
            //QThread::sleep(1);
            //QThread::msleep(1);
        }
    }
    
    void camera::ImageCapture()
    {
        if (CameraImageCapture != nullptr && Camera_Available == true)
        {
            CameraImageCapture->capture();
        }
    }
    camera::~camera()
    {
        if (CameraImageCapture != nullptr)
        {
            delete CameraImageCapture;
            CameraImageCapture = nullptr;
        }
    
        if (CameraV != nullptr)
        {
            CameraV->stop();
    
            delete CameraV;
            CameraV = nullptr;
        }
    }
    void camera::CaptureStatusChanged(bool ready)
    {
        qDebug()<<"Chagned to"<<ready;
        this->Camera_Available = ready;
    
    
    }
    
    void camera::processCapturedImage(int requestId, const QImage& img)
    {
        Q_UNUSED(requestId);
    
        qDebug() << "Test!";
    }
    

    OS : raspberry pi3
    RAM : 2G

    After the camera capture is done in the thread, the captured signal is registered(QObject::Connect) in the processCapturedImage slot.
    In that slot, we write the image to public QByteArray(Using Buffer).
    QByteArray is referenced by another class.

    My problem is that I am currently experiencing a memory leak over time.

    The question is:

    1. After the slot ends, are the variables created within the slot automatically freed?
    2. Should variables such as QByteArray, Buffer.Close or Image, declared in slots or passed as arguments, always be returned using delete or delete[]?
    3. Does using QByteArray.Clear() return resources?
    4. What is my problem to memory leak? i tried 1month for solve this..
      Thank you for read it
    jsulmJ 1 Reply Last reply
    0
    • 1 1stetcgoldmedal
      #include <QBuffer>
      #include <QCoreApplication>
      #include <QDateTime>
      #include <QJsonDocument>
      #include <QJsonObject>
      #include <QFile>
      #include <QCameraViewfinder>
      
      camera::camera(QObject *parent):QThread(parent)
      {
          const QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
          for (const QCameraInfo &cameraInfo : cameras)//
          {
              qDebug() << cameraInfo.deviceName();
              if(CameraV != nullptr)
              {
                  delete CameraV;
                  CameraV = nullptr;
              }
              CameraV = new QCamera(cameraInfo);
              if(CameraV != nullptr)
              {
                  CameraImageCapture = new QCameraImageCapture(CameraV);
                  CameraImageCapture->setCaptureDestination(QCameraImageCapture::CaptureToBuffer);//Not File Only To Buffer
                  connect(CameraImageCapture, &QCameraImageCapture::readyForCaptureChanged, this, &camera::CaptureStatusChanged);
                  connect(CameraImageCapture, &QCameraImageCapture::imageCaptured, this, &camera::processCapturedImage);
                  connect(this, SIGNAL(RequestCapture()), this, SLOT(ImageCapture()));
                  CameraV->setCaptureMode(QCamera::CaptureStillImage);
                  CameraV->start();
                  this->start();
              }
              break;
          }
      }
      void camera::run()
      {
          while(true)
          {
              //emit ReqCurrentSave();
                emit RequestCapture();
              //QThread::sleep(1);
              //QThread::msleep(1);
          }
      }
      
      void camera::ImageCapture()
      {
          if (CameraImageCapture != nullptr && Camera_Available == true)
          {
              CameraImageCapture->capture();
          }
      }
      camera::~camera()
      {
          if (CameraImageCapture != nullptr)
          {
              delete CameraImageCapture;
              CameraImageCapture = nullptr;
          }
      
          if (CameraV != nullptr)
          {
              CameraV->stop();
      
              delete CameraV;
              CameraV = nullptr;
          }
      }
      void camera::CaptureStatusChanged(bool ready)
      {
          qDebug()<<"Chagned to"<<ready;
          this->Camera_Available = ready;
      
      
      }
      
      void camera::processCapturedImage(int requestId, const QImage& img)
      {
          Q_UNUSED(requestId);
      
          qDebug() << "Test!";
      }
      

      OS : raspberry pi3
      RAM : 2G

      After the camera capture is done in the thread, the captured signal is registered(QObject::Connect) in the processCapturedImage slot.
      In that slot, we write the image to public QByteArray(Using Buffer).
      QByteArray is referenced by another class.

      My problem is that I am currently experiencing a memory leak over time.

      The question is:

      1. After the slot ends, are the variables created within the slot automatically freed?
      2. Should variables such as QByteArray, Buffer.Close or Image, declared in slots or passed as arguments, always be returned using delete or delete[]?
      3. Does using QByteArray.Clear() return resources?
      4. What is my problem to memory leak? i tried 1month for solve this..
        Thank you for read it
      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @1stetcgoldmedal said in How to solve processCapturedImage slot memory leak?:

      After the slot ends, are the variables created within the slot automatically freed?

      If those were allocated on the stack then yes, else you have to free the memory.

      I don't understand your code. Why do you have an endless loop where you're constantly emitting a signal?!
      Your code also does not show how you actually handle the captured image...

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      J.HilkJ 1 3 Replies Last reply
      0
      • jsulmJ jsulm

        @1stetcgoldmedal said in How to solve processCapturedImage slot memory leak?:

        After the slot ends, are the variables created within the slot automatically freed?

        If those were allocated on the stack then yes, else you have to free the memory.

        I don't understand your code. Why do you have an endless loop where you're constantly emitting a signal?!
        Your code also does not show how you actually handle the captured image...

        J.HilkJ Offline
        J.HilkJ Offline
        J.Hilk
        Moderators
        wrote on last edited by
        #3

        @jsulm the OP is also playing a dangerous game of chicken and who's memory is it.

        I would bet that the RequestCapture signal that if flooding the event system is the presumed "memory leak"


        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


        Q: What's that?
        A: It's blue light.
        Q: What does it do?
        A: It turns blue.

        1 1 Reply Last reply
        2
        • jsulmJ jsulm

          @1stetcgoldmedal said in How to solve processCapturedImage slot memory leak?:

          After the slot ends, are the variables created within the slot automatically freed?

          If those were allocated on the stack then yes, else you have to free the memory.

          I don't understand your code. Why do you have an endless loop where you're constantly emitting a signal?!
          Your code also does not show how you actually handle the captured image...

          1 Offline
          1 Offline
          1stetcgoldmedal
          wrote on last edited by
          #4

          @jsulm

          void camera::processCapturedImage(int requestId, const QImage& img)
          {
              Q_UNUSED(requestId);
              try
              {
                  if (img.isNull() == false)
                  {
                      Image.clear();
                      QBuffer buffer(&Image);
                      buffer.open(QIODevice::WriteOnly);
                      img.save(&buffer, "jpg");
                      buffer.close();
                      Image = qCompress(Image).toBase64();
                      id = QDateTime::currentDateTime().toMSecsSinceEpoch();
                  }
                  else
                  {
                      qDebug()<<"Image is null.";
                  }
              }
              catch(std::exception& e)
              {
                  qDebug() << Q_FUNC_INFO << e.what();
              }
          }
          

          here is image processing method..
          i think..there is no problem.

          1 Reply Last reply
          0
          • J.HilkJ J.Hilk

            @jsulm the OP is also playing a dangerous game of chicken and who's memory is it.

            I would bet that the RequestCapture signal that if flooding the event system is the presumed "memory leak"

            1 Offline
            1 Offline
            1stetcgoldmedal
            wrote on last edited by
            #5

            @J-Hilk
            Chaged Code :

            #include "camera.h"
            #include <QBuffer>
            #include <QCoreApplication>
            #include <QDateTime>
            
            #include <QJsonDocument>
            #include <QJsonObject>
            
            #include <QFile>
            
            #include <QCameraViewfinder>
            
            camera::camera(QObject *parent):QThread(parent)
            {
                const QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
                for (const QCameraInfo &cameraInfo : cameras)//
                {
                    qDebug() << cameraInfo.deviceName();
                    if(CameraV != nullptr)
                    {
                        delete CameraV;
                        CameraV = nullptr;
                    }
                    CameraV = new QCamera(cameraInfo);
                    if(CameraV != nullptr)
                    {
                        CameraImageCapture = new QCameraImageCapture(CameraV);
                        CameraImageCapture->setCaptureDestination(QCameraImageCapture::CaptureToBuffer);//Not File Only To Buffer
                        connect(CameraImageCapture, &QCameraImageCapture::readyForCaptureChanged, this, &camera::CaptureStatusChanged);
                        connect(CameraImageCapture, &QCameraImageCapture::imageCaptured, this, &camera::processCapturedImage);
                        connect(this, SIGNAL(RequestCapture()), this, SLOT(ImageCapture()));
                        CameraV->setCaptureMode(QCamera::CaptureStillImage);
                        CameraV->start();
                        this->start();
                    }
                    break;
                }
            }
            void camera::run()
            {
                while(true)
                {
                    emit ReqCurrentSave();
                    emit RequestCapture();
                    QThread::sleep(1);
                    //QThread::msleep(1);
                }
            }
            
            void camera::ImageCapture()
            {
                if (CameraImageCapture != nullptr && Camera_Available == true)
                {
                    CameraImageCapture->cancelCapture();//CHANGED HERE!
                    CameraImageCapture->capture();
                }
            }
            camera::~camera()
            {
                if (CameraImageCapture != nullptr)
                {
                    delete CameraImageCapture;
                    CameraImageCapture = nullptr;
                }
            
                if (CameraV != nullptr)
                {
                    CameraV->stop();
            
                    delete CameraV;
                    CameraV = nullptr;
                }
            }
            void camera::CaptureStatusChanged(bool ready)
            {
                qDebug()<<"Chagned to"<<ready;
                this->Camera_Available = ready;
            
            
            }
            
            void camera::processCapturedImage(int requestId, const QImage& img)
            {
                Q_UNUSED(requestId);
                try
                {
                    if (img.isNull() == false)
                    {
                        Image.clear();
                        QBuffer buffer(&Image);
                        buffer.open(QIODevice::WriteOnly);
                        img.save(&buffer, "jpg");
                        buffer.close();
                        Image = qCompress(Image).toBase64();
                        id = QDateTime::currentDateTime().toMSecsSinceEpoch();
                    }
                    else
                    {
                        qDebug()<<"Image is null.";
                    }
                }
                catch(std::exception& e)
                {
                    qDebug() << Q_FUNC_INFO << e.what();
                }
            }
            
            

            Edited as above.
            If the image capture signal is faster than the image processing,
            As the images to be processed pile up, the memory will gradually increase.
            So, I put the command to cancel the capture as above.
            However, it seems that the memory usage is slowly increasing.
            Of course, my code doesn't just have a camera class.
            There is also a class that reads values from serial ports.
            It exists as a code that transmits the value received from the image and serial port to the tcp server.
            Most of these also use threads, and at the same time use events.
            I tried tools like valgrind to fix this leak, but it didn't work.
            What could be the problem?
            Would it be better to create and use a bool type temporary variable to capture after the capture process is completed?
            sorry for bad english

            B 1 Reply Last reply
            0
            • 1 1stetcgoldmedal

              @J-Hilk
              Chaged Code :

              #include "camera.h"
              #include <QBuffer>
              #include <QCoreApplication>
              #include <QDateTime>
              
              #include <QJsonDocument>
              #include <QJsonObject>
              
              #include <QFile>
              
              #include <QCameraViewfinder>
              
              camera::camera(QObject *parent):QThread(parent)
              {
                  const QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
                  for (const QCameraInfo &cameraInfo : cameras)//
                  {
                      qDebug() << cameraInfo.deviceName();
                      if(CameraV != nullptr)
                      {
                          delete CameraV;
                          CameraV = nullptr;
                      }
                      CameraV = new QCamera(cameraInfo);
                      if(CameraV != nullptr)
                      {
                          CameraImageCapture = new QCameraImageCapture(CameraV);
                          CameraImageCapture->setCaptureDestination(QCameraImageCapture::CaptureToBuffer);//Not File Only To Buffer
                          connect(CameraImageCapture, &QCameraImageCapture::readyForCaptureChanged, this, &camera::CaptureStatusChanged);
                          connect(CameraImageCapture, &QCameraImageCapture::imageCaptured, this, &camera::processCapturedImage);
                          connect(this, SIGNAL(RequestCapture()), this, SLOT(ImageCapture()));
                          CameraV->setCaptureMode(QCamera::CaptureStillImage);
                          CameraV->start();
                          this->start();
                      }
                      break;
                  }
              }
              void camera::run()
              {
                  while(true)
                  {
                      emit ReqCurrentSave();
                      emit RequestCapture();
                      QThread::sleep(1);
                      //QThread::msleep(1);
                  }
              }
              
              void camera::ImageCapture()
              {
                  if (CameraImageCapture != nullptr && Camera_Available == true)
                  {
                      CameraImageCapture->cancelCapture();//CHANGED HERE!
                      CameraImageCapture->capture();
                  }
              }
              camera::~camera()
              {
                  if (CameraImageCapture != nullptr)
                  {
                      delete CameraImageCapture;
                      CameraImageCapture = nullptr;
                  }
              
                  if (CameraV != nullptr)
                  {
                      CameraV->stop();
              
                      delete CameraV;
                      CameraV = nullptr;
                  }
              }
              void camera::CaptureStatusChanged(bool ready)
              {
                  qDebug()<<"Chagned to"<<ready;
                  this->Camera_Available = ready;
              
              
              }
              
              void camera::processCapturedImage(int requestId, const QImage& img)
              {
                  Q_UNUSED(requestId);
                  try
                  {
                      if (img.isNull() == false)
                      {
                          Image.clear();
                          QBuffer buffer(&Image);
                          buffer.open(QIODevice::WriteOnly);
                          img.save(&buffer, "jpg");
                          buffer.close();
                          Image = qCompress(Image).toBase64();
                          id = QDateTime::currentDateTime().toMSecsSinceEpoch();
                      }
                      else
                      {
                          qDebug()<<"Image is null.";
                      }
                  }
                  catch(std::exception& e)
                  {
                      qDebug() << Q_FUNC_INFO << e.what();
                  }
              }
              
              

              Edited as above.
              If the image capture signal is faster than the image processing,
              As the images to be processed pile up, the memory will gradually increase.
              So, I put the command to cancel the capture as above.
              However, it seems that the memory usage is slowly increasing.
              Of course, my code doesn't just have a camera class.
              There is also a class that reads values from serial ports.
              It exists as a code that transmits the value received from the image and serial port to the tcp server.
              Most of these also use threads, and at the same time use events.
              I tried tools like valgrind to fix this leak, but it didn't work.
              What could be the problem?
              Would it be better to create and use a bool type temporary variable to capture after the capture process is completed?
              sorry for bad english

              B Offline
              B Offline
              BwvB
              wrote on last edited by
              #6

              @1stetcgoldmedal Maybe I missed it, but is the camera destructor ~camera() ever called?

              Christian EhrlicherC 1 2 Replies Last reply
              0
              • B BwvB

                @1stetcgoldmedal Maybe I missed it, but is the camera destructor ~camera() ever called?

                Christian EhrlicherC Offline
                Christian EhrlicherC Offline
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on last edited by Christian Ehrlicher
                #7

                @BwvB said in How to solve processCapturedImage slot memory leak?:

                Maybe I missed it, but is the camera destructor ~camera() ever called?

                Not in your code you showed us but hopefully at the place where you created it before.

                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                Visit the Qt Academy at https://academy.qt.io/catalog

                1 Reply Last reply
                0
                • B BwvB

                  @1stetcgoldmedal Maybe I missed it, but is the camera destructor ~camera() ever called?

                  1 Offline
                  1 Offline
                  1stetcgoldmedal
                  wrote on last edited by
                  #8

                  @BwvB No. it's never called

                  1 Reply Last reply
                  0
                  • jsulmJ jsulm

                    @1stetcgoldmedal said in How to solve processCapturedImage slot memory leak?:

                    After the slot ends, are the variables created within the slot automatically freed?

                    If those were allocated on the stack then yes, else you have to free the memory.

                    I don't understand your code. Why do you have an endless loop where you're constantly emitting a signal?!
                    Your code also does not show how you actually handle the captured image...

                    1 Offline
                    1 Offline
                    1stetcgoldmedal
                    wrote on last edited by
                    #9

                    @jsulm I don't understand your code. Why do you have an endless loop where you're constantly emitting a signal?!
                    i'd like to save image(public QByteArray variable) on realtime.
                    and i send image to server from public attribute (QByteArray Image) in camera class

                                connect(CameraImageCapture, &QCameraImageCapture::imageAvailable, [=] (int id, QVideoFrame v ) {
                                    if (v.isValid()) {
                                        if(v.map(QAbstractVideoBuffer::ReadOnly)) {
                                            Image.clear();
                                            QBuffer buffer(&Image);
                                            buffer.open(QIODevice::WriteOnly);
                                            v.image().save(&buffer, "jpg");
                                            buffer.close();
                                            Image = qCompress(Image).toBase64();
                                            this->id = QDateTime::currentDateTime().toMSecsSinceEpoch();
                                            v.unmap();
                                        }
                                    }
                                });
                    

                    here is my updated code.
                    imageCaptured Signal -> imageAvailable Signal

                    1 Reply Last reply
                    0

                    • Login

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