Спасибо @karlphillip за то, что указал мне правильное направление. Выполнение звонков на cvCaptureFromCAM
в отдельном потоке работает. Когда камера отключается, возвращаемое значение равно NULL
.
Однако, похоже, что эта функция не является поточно-ориентированной. Но простой мьютекс для блокировки одновременных вызовов на cvCaptureFromCAM
, кажется, делает свое дело. Я использовал boost::thread
, для этого примера, но можно легко настроить это.
В глобальном масштабе:
// Create a mutex used to prevent simultaneous calls to cvCaptureFromCAM
boost::shared_mutex mtxCapture;
// Flag to notify when we're done.
// NOTE: not bothering w/mutex for this example for simplicity's sake
bool done = false;
Точка входа выглядит примерно так:
int main()
{
// Create the work and the capture monitoring threads
boost::thread workThread(&Work);
boost::thread camMonitorThread(&CamMonitor);
while (! done)
{
// Do whatever
}
// Wait for threads to close themselves
workThread.join();
camMonitorThread.join();
return 0;
}
Рабочий поток прост. Единственное предостережение в том, что вам нужно заблокировать мьютекс, чтобы вы не получали одновременные звонки на cvCaptureFromCAM
.
// Work Thread
void Work()
{
Capture * capture = NULL;
mtxCapture.lock(); // Lock calls to cvCaptureFromCAM
capture = cvCaptureFromCAM(-1); // Get the capture object
mtxCapture.unlock(); // Release lock on calls to cvCaptureFromCAM
//TODO: check capture != NULL...
while (! done)
{
// Do work
}
// Release capture
cvReleaseCapture(&capture);
}
И, наконец, поток мониторинга захвата, предложенный @karlphillip, за исключением заблокированного вызова cvCaptureFromCAM
. В моих тестах звонки на cvReleaseCapture
были довольно медленными. Я положил вызов cvWaitKey
в конце цикла, потому что не хочу, чтобы его постоянно слышали.
void CamMonitor()
{
while (! done)
{
CvCapture * capture = NULL;
mtxCapture.lock(); // Lock calls to cvCaptureFromCAM
capture = cvCaptureFromCAM(-1); // Get the capture object
mtxCapture.unlock(); // Release lock on calls to cvCaptureFromCAM
if (capture == NULL)
done = true; // NOTE: not a thread-safe write...
else
cvReleaseCapture(&capture);
// Wait a while, we don't need to be constantly checking.
cvWaitKey(2500);
}
Я, вероятно, в конечном итоге реализую флаг готовности, который сможет определить, не подключена ли камера обратно. Но это выходит за рамки этого примера. Надеюсь, кто-то найдет это полезным. Еще раз спасибо, @ karlphillip.