@ -42,23 +42,12 @@
//M*/
# include "precomp.hpp"
# include <cassert>
# ifdef CV_CXX11
# define USE_STD_THREADS
# endif
# if defined(__linux__) || defined(LINUX) || defined(__APPLE__) || defined(__ANDROID__) || defined(USE_STD_THREADS)
# include "opencv2/core/utility.hpp"
# ifdef USE_STD_THREADS
# include <thread>
# include <mutex>
# include <condition_variable>
# else //USE_STD_THREADS
# include <pthread.h>
# endif //USE_STD_THREADS
# if defined(DEBUG) || defined(_DEBUG)
# undef DEBUGLOGS
@ -139,49 +128,26 @@ class cv::DetectionBasedTracker::SeparateDetectionWork
}
void setParameters ( const cv : : DetectionBasedTracker : : Parameters & params )
{
# ifdef USE_STD_THREADS
std : : unique_lock < std : : mutex > mtx_lock ( mtx ) ;
# else
pthread_mutex_lock ( & mutex ) ;
# endif
parameters = params ;
# ifndef USE_STD_THREADS
pthread_mutex_unlock ( & mutex ) ;
# endif
}
inline void init ( )
{
# ifdef USE_STD_THREADS
std : : unique_lock < std : : mutex > mtx_lock ( mtx ) ;
# else
pthread_mutex_lock ( & mutex ) ;
# endif
stateThread = STATE_THREAD_STOPPED ;
isObjectDetectingReady = false ;
shouldObjectDetectingResultsBeForgot = false ;
# ifdef USE_STD_THREADS
objectDetectorThreadStartStop . notify_one ( ) ;
# else
pthread_cond_signal ( & ( objectDetectorThreadStartStop ) ) ;
pthread_mutex_unlock ( & mutex ) ;
# endif
}
protected :
DetectionBasedTracker & detectionBasedTracker ;
cv : : Ptr < DetectionBasedTracker : : IDetector > cascadeInThread ;
# ifdef USE_STD_THREADS
std : : thread second_workthread ;
std : : mutex mtx ;
std : : condition_variable objectDetectorRun ;
std : : condition_variable objectDetectorThreadStartStop ;
# else
pthread_t second_workthread ;
pthread_mutex_t mutex ;
pthread_cond_t objectDetectorRun ;
pthread_cond_t objectDetectorThreadStartStop ;
# endif
std : : vector < cv : : Rect > resultDetect ;
volatile bool isObjectDetectingReady ;
volatile bool shouldObjectDetectingResultsBeForgot ;
@ -217,28 +183,6 @@ cv::DetectionBasedTracker::SeparateDetectionWork::SeparateDetectionWork(Detectio
CV_Assert ( _detector ) ;
cascadeInThread = _detector ;
# ifndef USE_STD_THREADS
second_workthread = 0 ;
int res = 0 ;
res = pthread_mutex_init ( & mutex , NULL ) ; //TODO: should be attributes?
if ( res ) {
LOGE ( " ERROR in DetectionBasedTracker::SeparateDetectionWork::SeparateDetectionWork in pthread_mutex_init(&mutex, NULL) is %d " , res ) ;
throw ( std : : exception ( ) ) ;
}
res = pthread_cond_init ( & objectDetectorRun , NULL ) ;
if ( res ) {
LOGE ( " ERROR in DetectionBasedTracker::SeparateDetectionWork::SeparateDetectionWork in pthread_cond_init(&objectDetectorRun,, NULL) is %d " , res ) ;
pthread_mutex_destroy ( & mutex ) ;
throw ( std : : exception ( ) ) ;
}
res = pthread_cond_init ( & objectDetectorThreadStartStop , NULL ) ;
if ( res ) {
LOGE ( " ERROR in DetectionBasedTracker::SeparateDetectionWork::SeparateDetectionWork in pthread_cond_init(&objectDetectorThreadStartStop,, NULL) is %d " , res ) ;
pthread_cond_destroy ( & objectDetectorRun ) ;
pthread_mutex_destroy ( & mutex ) ;
throw ( std : : exception ( ) ) ;
}
# endif
}
cv : : DetectionBasedTracker : : SeparateDetectionWork : : ~ SeparateDetectionWork ( )
@ -246,39 +190,20 @@ cv::DetectionBasedTracker::SeparateDetectionWork::~SeparateDetectionWork()
if ( stateThread ! = STATE_THREAD_STOPPED ) {
LOGE ( " \n \n \n ATTENTION!!! dangerous algorithm error: destructor DetectionBasedTracker::DetectionBasedTracker::~SeparateDetectionWork is called before stopping the workthread " ) ;
}
# ifndef USE_STD_THREADS
pthread_cond_destroy ( & objectDetectorThreadStartStop ) ;
pthread_cond_destroy ( & objectDetectorRun ) ;
pthread_mutex_destroy ( & mutex ) ;
# else
second_workthread . join ( ) ;
# endif
}
bool cv : : DetectionBasedTracker : : SeparateDetectionWork : : run ( )
{
LOGD ( " DetectionBasedTracker::SeparateDetectionWork::run() --- start " ) ;
# ifdef USE_STD_THREADS
std : : unique_lock < std : : mutex > mtx_lock ( mtx ) ;
// unlocked when leaving scope
# else
pthread_mutex_lock ( & mutex ) ;
# endif
if ( stateThread ! = STATE_THREAD_STOPPED ) {
LOGE ( " DetectionBasedTracker::SeparateDetectionWork::run is called while the previous run is not stopped " ) ;
# ifndef USE_STD_THREADS
pthread_mutex_unlock ( & mutex ) ;
# endif
return false ;
}
stateThread = STATE_THREAD_WORKING_SLEEPING ;
# ifdef USE_STD_THREADS
second_workthread = std : : thread ( workcycleObjectDetectorFunction , ( void * ) this ) ; //TODO: add attributes?
objectDetectorThreadStartStop . wait ( mtx_lock ) ;
# else
pthread_create ( & second_workthread , NULL , workcycleObjectDetectorFunction , ( void * ) this ) ; //TODO: add attributes?
pthread_cond_wait ( & objectDetectorThreadStartStop , & mutex ) ;
pthread_mutex_unlock ( & mutex ) ;
# endif
LOGD ( " DetectionBasedTracker::SeparateDetectionWork::run --- end " ) ;
return true ;
}
@ -313,34 +238,18 @@ void cv::DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector()
std : : vector < Rect > objects ;
CV_Assert ( stateThread = = STATE_THREAD_WORKING_SLEEPING ) ;
# ifdef USE_STD_THREADS
std : : unique_lock < std : : mutex > mtx_lock ( mtx ) ;
# else
pthread_mutex_lock ( & mutex ) ;
# endif
{
# ifdef USE_STD_THREADS
objectDetectorThreadStartStop . notify_one ( ) ;
# else
pthread_cond_signal ( & objectDetectorThreadStartStop ) ;
# endif
LOGD ( " DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector() --- before waiting " ) ;
CV_Assert ( stateThread = = STATE_THREAD_WORKING_SLEEPING ) ;
# ifdef USE_STD_THREADS
objectDetectorRun . wait ( mtx_lock ) ;
# else
pthread_cond_wait ( & objectDetectorRun , & mutex ) ;
# endif
if ( isWorking ( ) ) {
stateThread = STATE_THREAD_WORKING_WITH_IMAGE ;
}
LOGD ( " DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector() --- after waiting " ) ;
}
# ifdef USE_STD_THREADS
mtx_lock . unlock ( ) ;
# else
pthread_mutex_unlock ( & mutex ) ;
# endif
bool isFirstStep = true ;
@ -353,34 +262,18 @@ void cv::DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector()
if ( ! isFirstStep ) {
LOGD ( " DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector() --- before waiting " ) ;
CV_Assert ( stateThread = = STATE_THREAD_WORKING_SLEEPING ) ;
# ifdef USE_STD_THREADS
mtx_lock . lock ( ) ;
# else
pthread_mutex_lock ( & mutex ) ;
# endif
if ( ! isWorking ( ) ) { //it is a rare case, but may cause a crash
LOGD ( " DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector() --- go out from the workcycle from inner part of lock just before waiting " ) ;
# ifdef USE_STD_THREADS
mtx_lock . unlock ( ) ;
# else
pthread_mutex_unlock ( & mutex ) ;
# endif
break ;
}
CV_Assert ( stateThread = = STATE_THREAD_WORKING_SLEEPING ) ;
# ifdef USE_STD_THREADS
objectDetectorRun . wait ( mtx_lock ) ;
# else
pthread_cond_wait ( & objectDetectorRun , & mutex ) ;
# endif
if ( isWorking ( ) ) {
stateThread = STATE_THREAD_WORKING_WITH_IMAGE ;
}
# ifdef USE_STD_THREADS
mtx_lock . unlock ( ) ;
# else
pthread_mutex_unlock ( & mutex ) ;
# endif
LOGD ( " DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector() --- after waiting " ) ;
} else {
@ -427,11 +320,7 @@ void cv::DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector()
( void ) ( dt_detect_ms ) ;
LOGI ( " DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector() --- objects num==%d, t_ms=%.4f " , ( int ) objects . size ( ) , dt_detect_ms ) ;
# ifdef USE_STD_THREADS
mtx_lock . lock ( ) ;
# else
pthread_mutex_lock ( & mutex ) ;
# endif
if ( ! shouldObjectDetectingResultsBeForgot ) {
resultDetect = objects ;
isObjectDetectingReady = true ;
@ -443,11 +332,7 @@ void cv::DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector()
if ( isWorking ( ) ) {
stateThread = STATE_THREAD_WORKING_SLEEPING ;
}
# ifdef USE_STD_THREADS
mtx_lock . unlock ( ) ;
# else
pthread_mutex_unlock ( & mutex ) ;
# endif
objects . clear ( ) ;
} // while(isWorking())
@ -458,44 +343,25 @@ void cv::DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector()
void cv : : DetectionBasedTracker : : SeparateDetectionWork : : stop ( )
{
//FIXME: TODO: should add quickStop functionality
# ifdef USE_STD_THREADS
std : : unique_lock < std : : mutex > mtx_lock ( mtx ) ;
# else
pthread_mutex_lock ( & mutex ) ;
# endif
if ( ! isWorking ( ) ) {
# ifdef USE_STD_THREADS
mtx_lock . unlock ( ) ;
# else
pthread_mutex_unlock ( & mutex ) ;
# endif
LOGE ( " SimpleHighguiDemoCore::stop is called but the SimpleHighguiDemoCore pthread is not active " ) ;
stateThread = STATE_THREAD_STOPPING ;
return ;
}
stateThread = STATE_THREAD_STOPPING ;
LOGD ( " DetectionBasedTracker::SeparateDetectionWork::stop: before going to sleep to wait for the signal from the workthread " ) ;
# ifdef USE_STD_THREADS
objectDetectorRun . notify_one ( ) ;
objectDetectorThreadStartStop . wait ( mtx_lock ) ;
LOGD ( " DetectionBasedTracker::SeparateDetectionWork::stop: after receiving the signal from the workthread, stateThread=%d " , ( int ) stateThread ) ;
mtx_lock . unlock ( ) ;
# else
pthread_cond_signal ( & objectDetectorRun ) ;
pthread_cond_wait ( & objectDetectorThreadStartStop , & mutex ) ;
LOGD ( " DetectionBasedTracker::SeparateDetectionWork::stop: after receiving the signal from the workthread, stateThread=%d " , ( int ) stateThread ) ;
pthread_mutex_unlock ( & mutex ) ;
# endif
}
void cv : : DetectionBasedTracker : : SeparateDetectionWork : : resetTracking ( )
{
LOGD ( " DetectionBasedTracker::SeparateDetectionWork::resetTracking " ) ;
# ifdef USE_STD_THREADS
std : : unique_lock < std : : mutex > mtx_lock ( mtx ) ;
# else
pthread_mutex_lock ( & mutex ) ;
# endif
if ( stateThread = = STATE_THREAD_WORKING_WITH_IMAGE ) {
LOGD ( " DetectionBasedTracker::SeparateDetectionWork::resetTracking: since workthread is detecting objects at the moment, we should make cascadeInThread stop detecting and forget the detecting results " ) ;
@ -508,12 +374,7 @@ void cv::DetectionBasedTracker::SeparateDetectionWork::resetTracking()
resultDetect . clear ( ) ;
isObjectDetectingReady = false ;
# ifdef USE_STD_THREADS
mtx_lock . unlock ( ) ;
# else
pthread_mutex_unlock ( & mutex ) ;
# endif
}
bool cv : : DetectionBasedTracker : : SeparateDetectionWork : : communicateWithDetectingThread ( const Mat & imageGray , std : : vector < Rect > & rectsWhereRegions )
@ -529,11 +390,7 @@ bool cv::DetectionBasedTracker::SeparateDetectionWork::communicateWithDetectingT
bool shouldHandleResult = false ;
# ifdef USE_STD_THREADS
std : : unique_lock < std : : mutex > mtx_lock ( mtx ) ;
# else
pthread_mutex_lock ( & mutex ) ;
# endif
if ( isObjectDetectingReady ) {
shouldHandleResult = true ;
@ -562,18 +419,10 @@ bool cv::DetectionBasedTracker::SeparateDetectionWork::communicateWithDetectingT
timeWhenDetectingThreadStartedWork = getTickCount ( ) ;
# ifdef USE_STD_THREADS
objectDetectorRun . notify_one ( ) ;
# else
pthread_cond_signal ( & objectDetectorRun ) ;
# endif
}
# ifdef USE_STD_THREADS
mtx_lock . unlock ( ) ;
# else
pthread_mutex_unlock ( & mutex ) ;
# endif
LOGD ( " DetectionBasedTracker::SeparateDetectionWork::communicateWithDetectingThread: result: shouldHandleResult=%d " , ( shouldHandleResult ? 1 : 0 ) ) ;
return shouldHandleResult ;
@ -1034,5 +883,3 @@ const cv::DetectionBasedTracker::Parameters& DetectionBasedTracker::getParameter
{
return parameters ;
}
# endif //defined(__linux__) || defined(LINUX) || defined(__APPLE__) || defined(__ANDROID__) || defined(USE_STD_THREADS)