diff --git a/Application/CMakeLists.txt b/Application/CMakeLists.txt index 2e10e9872bf236fcf4ec0103f8e82ad5ac76e9fa..3aad1e3215aab34d9d8a6c49aaee306165499c1e 100644 --- a/Application/CMakeLists.txt +++ b/Application/CMakeLists.txt @@ -841,8 +841,8 @@ if(${TREX_BUILD_OPENCV}) -DWITH_FFMPEG:BOOL=${WITH_FFMPEG} -DWITH_MSMF:BOOL=FALSE -DWITH_IPP:BOOL=FALSE - -DWITH_GTK:BOOL=FALSE - -DWITH_CAIRO:BOOL=FALSE + -DWITH_GTK:BOOL=FALSE + -DWITH_CAIRO:BOOL=FALSE -DWITH_PNG:BOOL=TRUE -DBUILD_PERF_TESTS:BOOL=FALSE -DBUILD_opencv_apps:BOOL=FALSE diff --git a/Application/src/tracker/VideoOpener.cpp b/Application/src/tracker/VideoOpener.cpp index 830d9e5211db93c114d64899e3c6f3ea34ff6139..7ec37f8dd12a4a7682127ff19a76c7d364586cbf 100644 --- a/Application/src/tracker/VideoOpener.cpp +++ b/Application/src/tracker/VideoOpener.cpp @@ -434,51 +434,73 @@ VideoOpener::BufferedVideo::BufferedVideo(const file::Path& path) : _path(path) VideoOpener::BufferedVideo::~BufferedVideo() { _terminate = true; - _terminate_background = true; if(_update_thread) _update_thread->join(); - if(_background_thread) - _background_thread->join(); - _background_video = nullptr; + { + std::lock_guard guard(_background_mutex); + _terminate_background = true; + + if(_background_thread) + _background_thread->join(); + } } void VideoOpener::BufferedVideo::restart_background() { - _terminate_background = true; - if(_background_thread) - _background_thread->join(); - - _terminate_background = false; - - std::lock_guard guard(_frame_mutex); - cv::Mat img; - _background_video->frame(0, img); - if(max(img.cols, img.rows) > 500) - resize_image(img, 500 / double(max(img.cols, img.rows))); - - _background_video_index = 0; - _accumulator = std::make_unique<AveragingAccumulator<>>(TEMP_SETTING(averaging_method).value<averaging_method_t::Class>()); - _accumulator->add(img); + { + std::lock_guard guard(_background_mutex); + if(_background_thread) + _previous_background_thread = std::move(_background_thread); + } _background_thread = std::make_unique<std::thread>([this](){ + { // close old background task, if present + std::lock_guard guard(_background_mutex); + if(_previous_background_thread) { + _terminate_background = true; + _previous_background_thread->join(); + _previous_background_thread = nullptr; + } + _terminate_background = false; + } + + std::unique_ptr<VideoSource> background_video; + uint64_t background_video_index = 0; + std::unique_ptr<AveragingAccumulator<>> accumulator; + + { // open video and load first frame + background_video = std::make_unique<VideoSource>(_path.str()); + + std::lock_guard guard(_frame_mutex); + cv::Mat img; + background_video->frame(0, img); + if(max(img.cols, img.rows) > 500) + resize_image(img, 500 / double(max(img.cols, img.rows))); + + background_video_index = 0; + accumulator = std::make_unique<AveragingAccumulator<>>(TEMP_SETTING(averaging_method).value<averaging_method_t::Class>()); + accumulator->add(img); + } + _terminated_background_task = false; - int step = max(1, int(_background_video->length() / max(2.0, double(TEMP_SETTING(average_samples).value<int>())))); + int step = max(1, int(background_video->length() / max(2.0, double(TEMP_SETTING(average_samples).value<int>())))); cv::Mat flt, img; _number_samples = 0; - while(!_terminate_background && _background_video_index+1+step < _background_video->length()) { - _background_video_index += step; + while(!_terminate_background && background_video_index+1+step < background_video->length()) + { + background_video_index += step; _number_samples += 1; - _background_video->frame(_background_video_index, img); + background_video->frame(background_video_index, img); if(max(img.cols, img.rows) > 500) resize_image(img, 500 / double(max(img.cols, img.rows))); - _accumulator->add(img); + accumulator->add(img); - auto image = _accumulator->finalize(); + auto image = accumulator->finalize(); std::lock_guard guard(_frame_mutex); _background_copy = std::move(image); @@ -494,6 +516,7 @@ void VideoOpener::BufferedVideo::open(std::function<void(const bool)>&& callback int64_t playback_index = 0; Timer video_timer; double seconds_between_frames = 0; + static std::mutex _gpu_mutex; // in case multiple videos are still "open" cv::Mat local; gpuMat background_image; @@ -503,12 +526,9 @@ void VideoOpener::BufferedVideo::open(std::function<void(const bool)>&& callback { std::lock_guard guard(_video_mutex); _video = std::make_unique<VideoSource>(_path.str()); - _video->frame(0, local); local.copyTo(img); - _background_video = std::make_unique<VideoSource>(_path.str()); - playback_index = 0; video_timer.reset(); @@ -541,6 +561,8 @@ void VideoOpener::BufferedVideo::open(std::function<void(const bool)>&& callback _video->frame((size_t)playback_index, local); if(_number_samples.load() > 1) { + std::lock_guard gpu_guard(_gpu_mutex); + local.copyTo(img); if(max(img.cols, img.rows) > 500) resize_image(img, 500 / double(max(img.cols, img.rows))); diff --git a/Application/src/tracker/VideoOpener.h b/Application/src/tracker/VideoOpener.h index 5099670cdf676415be930b257da0c1958d46e6b3..5d88dee2655f590348c4035c6b16a861fd210102 100644 --- a/Application/src/tracker/VideoOpener.h +++ b/Application/src/tracker/VideoOpener.h @@ -28,11 +28,7 @@ public: struct BufferedVideo { file::Path _path; std::unique_ptr<VideoSource> _video; - std::unique_ptr<VideoSource> _background_video; std::unique_ptr<Image> _background_copy; - std::unique_ptr<AveragingAccumulator<>> _accumulator; - //uint64_t _background_samples = 0; - uint64_t _background_video_index = 0; std::atomic<bool> _terminated_background_task = true; std::atomic<size_t> _number_samples = 0; @@ -40,6 +36,8 @@ public: std::mutex _frame_mutex; std::mutex _video_mutex; + std::mutex _background_mutex; + std::unique_ptr<std::thread> _previous_background_thread; std::unique_ptr<Image> _cached_frame; std::atomic<bool> _terminate = false, _terminate_background = false;