Thread Implimentation:Spiking the CPU usage and hang the app and system.
I have to show 30 FPS(Frames per second on the QT window), the frames i am receiving is YUV format( Only Y plane has been sent).
- I have implemented a thread which receives the frames and enqueque in a queque.
- Another thread which do following things
a) dequeue the frame extract the Y plane
b)used opencv to convert it to mat (cv::Mat m = cv::cvarrToMat(img11);
c)used opencv to convert the format cv::cvtColor(m,m,CV_YUV2RGB);
QImage qimg = QImage((const unsigned char*) m.data,
// m.cols, m.rows,
// QImage::Format_RGB888); // convert to QImage
d)passed it to label to show the image.
The issue i am facing is it is taking 200percent CPU isage and hangs the computer after running for a minute. Since the frames are coming at the rate of 30 fps it keeps bot the thread busy and also we need to achieve this in order to not loose a single frame, i tried usleep and yeild to make the threads free the resources however its not helping me out, it is having same behavior of hanging the system after a minute.
Kindly provide your inputs for best possible solution to achieve this.
Clearly your hardware can't handle the FPS and the queue grows and fills the memory. I see two things to do: create the QImage directly from the frame & downsample while doing it (pick every second pixel or so).
Perhaps SIMD operations can also speed things up for your case, as it looks that for each pixel, exactly the same operation is necessary.
Additional hint - measure how long it takes for you to process single frame. If it takes longer than the time you've got, you need to optimize the algorithm. Perhaps less conversions/ copying would help. Less info sharing between threads could improve things, too. As well as adding a buffer on UI thread, so that synchronization of painting on QLabel does not jam your other threads.
@Monalisa also, additionally to what the others said,
how to you pass data between threads?
Signal/Slot is, generally speaking, thread safe but it comes with a non neglectable overhang, and using a low lvl api like QMutext could/should be faster
I think you are taking too many steps. If I understand the use case correctly, you are only getting the Y data. Therefore the color components are gone and you are really looking at a gray scale image. A faster implementation would be:
- Dequeue and extract the Y data into an array of 8 bit values
- Create a QImage with a format of QImage::Format_Indexed8 and a pre-defined gray scale color table using the 8 bit data.
That's it. There is no need to involve openCv to convert the image to YUV2 and then create an RGB image that's essentially shades of gray.
Hi and welcome to devnet,
To add to my fellows good suggestions:
- Where are you getting the images from ?
- What size are they ?