I am trying to improve the capture performance of a real-time computer vision program that I am developing to run on an embedded Linux computer using OpenCV. I would like to use multiple threads and a shared memory buffer to separate the tasks of (1) capturing video frames and (2) processing them (a "producer/consumer problem", I believe). I have read up on pthreads, mutex variables, and condition variables but do not understand how they would need to be used with the select()
function.
Right now, video frames are captured using code adapted from the Video4Linux2 Video Capture Example which makes use of select()
. As I understand it, select()
blocks the program until data is available from the webcam, which can be slow and a major waste of time. If possible, I would like to use those wasted CPU cycles to work on image processing. (Of course this means that processing would always have to be done on an image that is "stale" by one frame, but at 30 fps it will be practically real-time anyways).
I have found some example code that uses pthread_mutex_lock()
and pthread_mutex_control()
to protect shared data, but it seems that these would still block the "processing" thread from running while waiting for image data via select()
. To be more concrete, here is some pseudo code to illustrate my concern. (NOTE: I realize that these threads would need to contain loops and other checks like the above linked example to actually work properly.)
void* capture()
{
pthread_mutex_lock(&mutex); // protect shared data
pthread_cond_wait(&space_avail,&mutex); // make sure the buffer has room
/// capture code... ///
select(fd+1, &fds, NULL, NULL, &tv); // waiting for data...
// Want to be processing frames
// during select, but won't the
// processing thread be blocked
// by the mutex lock?
// store image to the frame buffer
/// more capture code... ///
pthread_cond_signal(&data_avail);
pthread_mutex_unlock(&mutex);
}
void* process()
pthread_mutex_lock(&mutex);
pthread_cond_wait(&data_avail);
// access the most recently stored frame from the buffer
/// Do image processing ///
pthread_mutex_signal(&space_avail);
pthread_mutex_unlock(&mutex);
}