I have three periodic real-time tasks that execute simultaneously, each on a different processor(core) for video capturing using OpenCV.
In order to synchronize between the three tasks, I used an array of cv::Mat
and each time I swap the index in order to avoid a data race. Thanks to the answers to my previous post on buffer reading/writing synchronization, I come up with this solution :
cv::Mat frame[3];
int frame_index_write = 0;
int frame_index_read = 1;
int frame_index_read_ = 2;
int SwapIndex(int *fi){
return *fi = (*fi + 1) % 3;
}
Now, the first task grabs a capture and stores it in a buffer and broadcast a signal to the other tasks, so they can get the captured frames :
while (1)
{
capture.grab();
capture.retrieve(frame[frame_index_write], CHANNEL);
SwapIndex(&frame_index_write);
pthread_cond_broadcast(&synch_condition); /* After capturing the frame
signal the displaying tasks*/
}
The second task gets the captured frame and displays it:
while (1)
{
pthread_cond_wait(&synch_condition, &frame_rw); /*wait for the capturing
func to send a signal*/
if (frame[frame_index_read].data)
{
cv::imshow(CAPTURED_IMAGE_WINDOW_NAME, frame[frame_index_read]);
SwapIndex(&frame_index_read);
cv::waitKey(1);
}
else{
std::cout << "Frame reading error" << std::endl;
}
}
The third task gets the captured frame and applies an edge detection process before displaying it :
while (1)
{
pthread_cond_wait(&synch_condition, &frame_rw); /*wait for the capturing
func to send a signal*/
if (frame[frame_index_read_].data)
{
cv::cvtColor(frame[frame_index_read_], gray_capture, cv::COLOR_BGR2GRAY);
cv::blur(gray_capture, detected_edges, cv::Size(3, 3));
cv::Canny(detected_edges, detected_edges, 0, 100, 3);
cv::imshow(EDGE_IMAGE_WINDOW_NAME, detected_edges);
SwapIndex(&frame_index_read_);
cv::waitKey(1);
}
else{
std::cout << "Frame reading error" << std::endl;
}
}
My code seems to work perfectly and the results were also as expected but when I stop the execution on the terminal I got the following output indicating an error :
VIDIOC_DQBUF: Invalid argument
OpenCV Error: Bad argument (Unknown array type) in cvarrToMat, file /build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/core/src/matrix.cpp, line 943 terminate called after throwing an instance of 'cv::Exception' what(): /build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/core/src/matrix.cpp:943: error: (-5) Unknown array type in function cvarrToMat
Is there a way to handle this kind of error?
The complete code is hosted at Github
Any help would be so greatly appreciated on this topic.