/** * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "Tracking/AsyncTracker.h" #include namespace MediaVision { namespace Image { AsyncTracker::AsyncTracker(const AsyncTracker& copy) : __baseTracker(copy.__baseTracker.get()->clone()), __result(copy.__result), __isRun(false), __isUpdated(copy.__isUpdated), __copyingPolicy(copy.__copyingPolicy), __mvThread(0) { pthread_mutex_init(&__globalGuard, NULL); pthread_spin_init(&__resultGuard, PTHREAD_PROCESS_SHARED); pthread_spin_init(&__isRunGuard, PTHREAD_PROCESS_SHARED); pthread_spin_init(&__isUpdatedGuard, PTHREAD_PROCESS_SHARED); } AsyncTracker::AsyncTracker( cv::Ptr baseTracker, bool copyingPolicy) : __baseTracker(baseTracker), __result(), __isRun(false), __isUpdated(false), __copyingPolicy(copyingPolicy), __mvThread(0) { pthread_mutex_init(&__globalGuard, NULL); pthread_spin_init(&__resultGuard, PTHREAD_PROCESS_SHARED); pthread_spin_init(&__isRunGuard, PTHREAD_PROCESS_SHARED); pthread_spin_init(&__isUpdatedGuard, PTHREAD_PROCESS_SHARED); } AsyncTracker::~AsyncTracker() { if(isRun()) { pthread_mutex_lock(&__globalGuard); pthread_mutex_unlock(&__globalGuard); } pthread_mutex_destroy(&__globalGuard); pthread_spin_destroy(&__resultGuard); pthread_spin_destroy(&__isRunGuard); pthread_spin_destroy(&__isUpdatedGuard); } bool AsyncTracker::track( const cv::Mat& frame, std::vector& result) { while (pthread_mutex_trylock(&__globalGuard) != 0) return getResult(result); pthread_spin_lock(&__isRunGuard); __isRun = true; pthread_spin_unlock(&__isRunGuard); if (__copyingPolicy) __frame = frame.clone(); else __frame = frame; const int err = pthread_create(&__mvThread, NULL, asyncTrack, this); if (0 == err) { pthread_detach(__mvThread); return getResult(result); } pthread_spin_lock(&__isRunGuard); __isRun = false; pthread_spin_unlock(&__isRunGuard); pthread_mutex_unlock(&__globalGuard); return getResult(result); } void AsyncTracker::reinforcement(const std::vector& location) { /* TODO: Unsafe. Need to redesign. */ __baseTracker->reinforcement(location); pthread_spin_lock(&__resultGuard); __result = location; pthread_spin_unlock(&__resultGuard); } cv::Ptr AsyncTracker::clone() const { return cv::Ptr(new (std::nothrow)AsyncTracker(*this)); } bool AsyncTracker::baseTrack(std::vector& result) { return __baseTracker->track(__frame, result); } void *AsyncTracker::asyncTrack(void *data) { AsyncTracker *tracker = reinterpret_cast(data); std::vector result; tracker->baseTrack(result); pthread_spin_lock(&tracker->__resultGuard); tracker->__result = result; pthread_spin_unlock(&tracker->__resultGuard); pthread_spin_lock(&tracker->__isUpdatedGuard); tracker->__isUpdated = true; pthread_spin_unlock(&tracker->__isUpdatedGuard); pthread_mutex_unlock(&tracker->__globalGuard); pthread_spin_lock(&tracker->__isRunGuard); tracker->__isRun = false; pthread_spin_unlock(&tracker->__isRunGuard); return NULL; } bool AsyncTracker::wait() { if(isRun()) { pthread_mutex_lock(&__globalGuard); pthread_mutex_unlock(&__globalGuard); return true; } return false; } bool AsyncTracker::isRun() { bool result = false; pthread_spin_lock(&__isRunGuard); result = __isRun; pthread_spin_unlock(&__isRunGuard); return result; } bool AsyncTracker::isUpdated(std::vector& result) { bool isUpdated = false; getResult(result); pthread_spin_lock(&__isUpdatedGuard); isUpdated = __isUpdated; __isUpdated = false; pthread_spin_unlock(&__isUpdatedGuard); return isUpdated; } bool AsyncTracker::getResult(std::vector& result) { bool isTracked = false; pthread_spin_lock(&__resultGuard); isTracked = !__result.empty(); result = __result; pthread_spin_unlock(&__resultGuard); return isTracked; } } /* Image */ } /* MediaVision */