bluewater2
bluewater2

Reputation: 160

QImage with QThreads

The following scenario: I got a multiple video stream which I get from OpenCV and display in my QML GUI through a realization of a QQuickImageProvider. A signal is emitted if the images change which causes my images in the GUI to call the providers requestImage(...) function. I don't know much about the underlying realization of QImage and especially about what happens if I pass one of the images from requestImage(...) to my GUI, but the shared memory principle of QImage suggests that there might occur a problem when my OpenCV thread updates the image while it is read/passed/whatever to the GUI. Is that correct?

The approach I planned to do now is add a QMutex to the provider which is locked during image updates and requests alike and in the request function copy the requested image to a new QImage and call the "bits()" function on it, which apparently should cause a deep copy, then unlock the mutex. Does that make sense in this way? And is it necessary?

Thank you

Upvotes: 4

Views: 1360

Answers (2)

UmNyobe
UmNyobe

Reputation: 22890

Read up how implicit sharing work with threading in th Qt documentation. Basically the implicit sharing is enforced by an atomic counter, but you still need to provide thread safety.

The approach I planned to do now is add a QMutex to the provider which is locked during image updates and requests alike and in the request function copy the requested image to a new QImage and call the "bits()" function on it, which apparently should cause a deep copy, then unlock the mutex. Does that make sense in this way? And is it necessary?

The doc says it make sense and that's how it should be done, except that making a deep copy of the QImage is unnecessary. Basically this should be enough for the getter.

QImage getImage() 
{
  m_mutex.lock();
  QImage img(m_image);
  m_mutex.unlock();
  return img;
}

You can probably have a classier version using QMutexLocker.

Upvotes: 1

Siyuan Ren
Siyuan Ren

Reputation: 7844

QImage is one of the classes with implicit sharing (copy-on-write). Thus it is not necessary to manually copy the QImage with locking; simply invoke its copy constructor will do. The copy is shallow, but when your thread tries to update it, it will automatically do a deep copy.

Besides, why are you not passing the QImage in the signal itself?

Upvotes: 0

Related Questions