How to read VideoCapture as parts in multiple threads
hello,
I have a video of more than 90k frames, and I want to divire it the read into multiple four or more threads for example a video on 20 mins, I want
the first thread read the VideoCapture from 0 to 5 min
the 2th thread read the VideoCapture from 5 to 10 min
the 3th thread read the VideoCapture from 10 to 15 min
the 4th thread read the VideoCapture from 15 to 20 min
I use these functions for Similarity check (PNSR and SSIM), In fact, I have a long video sequence, I want to make the code faster by spliting this sequence loaded in a VideoCapture variable into multiple parts, So, by doing this, I will use threads to process each part simultaneously. this is the need, I hope it's clear.
any help would appreciated.
and you want to keep 90k frames in memory ? it would only require 185GB for HD frames ;)
I already load 90k in VideoCapture variable and I loop through it, I'm using a frame of 480x320 in size. for illustration, we can use less than 90k frames
Are you familiar with the std C++ thread and mutex?
I'm quite enough familiar with c++ thread, however for mutex I've never worked with before.
the problem here with the thread is concurrency and multiple access to the same resource VideoCapture variable? how to deal with it ?
Yeah, you pass in a mutex instantiation into the thread function. You must pass the mutex by reference.
Whenever you want to be thread-safe, you call the mutex's
lock()
function before you use the non-atomic data/functions. Once you're done using the non-atomic data/functions you call the mutex'sunlock()
function.It's that simple: Since you're passing by reference, all threads use the same mutex. The mutex blocks on
lock()
, waiting for the other thread to callunlock()
.On the other hand, you might be able to avoid using a mutex. Just pass the data subset directly into each thread function. That way your main function can immediately call
join()
after all of thethread()
calls.assume, that a VideoCapture is NOT THREADSAFE AT ALL. (it's a matter of internal state, not locks)
@azdoud.y you'd have to use 1 seperate capture per thread
Sorry, I was assuming that these video clips were already stored to disk as images.
@azdoud.y again, please explain the need for multiple threads. which problem are you trying to solve here ?
okey, @berak I will explain
did you profile your code ? where is the bottleneck ?
if it turns out to be the psnr/ssim part,maybe a single producer with several consumers would be a better design ?
if it was too slow in a single thread before, tripling the work load and expect to make it faster, seems absurd.
Noting is absurd if we want to learn something new.
yes, when I profile my code it slows down at psnr/ssim functions
@berak Can you give us some documentation about single producer with several consumers would be a better design, please
maybe:
@berak, you said that I'd have to use 1 separate capture per thread, how can I separate the main capture into sub-capture parts?
start a new VideoCapture object in each of your 3 threads. seek to a certain frameno, and start reading/processing (and please don't put any gui code, like imshow() into any of those threads.)
Why don't you split your video into multiple files in a preprocessing function, and then create an array of VideoCapture objects equivalent to the number of different video files and make them work in parallel?
it a good idea @Pedro Batista, however it will increase the time processing that I need to decrease
@berak, thank you
It will increase if your video is so small that the splitting function would become the bottleneck, which would make your parallel process pointless anyway.. don't forget that creating threads themselves is a overhead process anyway.
You do not need to create new split video files, just know which frames to process in each thread.