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;