]> www.vanbest.org Git - motioneye-debian/commitdiff
implemented server side current picture caching based on a sequence
authorCalin Crisan <ccrisan@gmail.com>
Sun, 24 Nov 2013 13:59:00 +0000 (15:59 +0200)
committerCalin Crisan <ccrisan@gmail.com>
Sun, 24 Nov 2013 13:59:00 +0000 (15:59 +0200)
number

settings_default.py
src/handlers.py
src/mediafiles.py
src/remote.py
static/js/main.js

index 399720b5b9fa85e5f2353c132dd1ac6cb5383a06..1109f51b91c9b5a7a16ab2f281784b8a59bc7619 100644 (file)
@@ -43,3 +43,6 @@ REMOTE_REQUEST_TIMEOUT = 10
 
 # timeout in seconds to wait for an access to a mjpg client before removing it
 MJPG_CLIENT_TIMEOUT = 10
+
+# the maximal number of entries per camera in the current pictures cache
+PICTURE_CACHE_SIZE = 8
index 0bbbb5023b825b775aeae47021a4261207e89ed8..b285aa29a9ea95fe96ae0df12c55be77239908e6 100644 (file)
@@ -541,16 +541,31 @@ class PictureHandler(BaseHandler):
     def current(self, camera_id):
         self.set_header('Content-Type', 'image/jpeg')
         
+        sequence = self.get_argument('seq', None)
+        if sequence:
+            sequence = int(sequence)
+            
+        picture = sequence and mediafiles.get_picture_cache(camera_id, sequence) or None
+        
+        if picture is not None:
+            return self.finish(picture)
+        
         camera_config = config.get_camera(camera_id)
         if camera_config['@proto'] == 'v4l2':
             picture = mediafiles.get_current_picture(camera_config,
                     width=self.get_argument('width', None),
                     height=self.get_argument('height', None))
+            
+            if sequence and picture:
+                mediafiles.set_picture_cache(camera_id, sequence, picture)
 
             self.finish(picture)
         
         else:
             def on_response(picture):
+                if sequence and picture:
+                    mediafiles.set_picture_cache(camera_id, sequence, picture)
+                
                 self.finish(picture)
             
             remote.get_current_picture(
index 5d2eccadefd17a1f49a80e1b5b7285dc92c17d5f..aa0b2e53c63202e630db6303e43a076af18769c8 100644 (file)
@@ -25,12 +25,17 @@ from PIL import Image
 
 import config
 import mjpgclient
+import settings
 import utils
 
 
 _PICTURE_EXTS = ['.jpg']
 _MOVIE_EXTS = ['.avi', '.mp4']
 
+# a dictionary indexed by camera_id containing
+# tuples of (sequence, content)
+_current_pictures_cache = {}
+
 
 def _list_media_files(dir, exts, prefix=None):
     full_paths = []
@@ -302,3 +307,29 @@ def get_current_picture(camera_config, width, height):
     image.save(sio, format='JPEG')
 
     return sio.getvalue()
+
+
+def set_picture_cache(camera_id, sequence, content):
+    global _current_pictures_cache
+    
+    if not content:
+        return
+    
+    cache = _current_pictures_cache.setdefault(camera_id, [])
+    
+    if len(cache) >= settings.PICTURE_CACHE_SIZE:
+        cache.pop(0) # drop the first item
+    
+    cache.append((sequence, content))
+
+
+def get_picture_cache(camera_id, sequence):
+    global _current_pictures_cache
+    
+    cache = _current_pictures_cache.setdefault(camera_id, [])
+
+    for (seq, content) in cache:
+        if seq >= sequence:
+            return content
+        
+    return None
index 83536f18cc70f969830d6a14820022878d03b519..c62bbe040f65443417fd3366bb0832d987acb681 100644 (file)
@@ -22,6 +22,7 @@ from tornado.httpclient import AsyncHTTPClient, HTTPClient, HTTPRequest
 
 import settings
 
+
 _snapshot_cache = {}
 
 
index ff5248f6ea9e457a86b973703887846ce81b61a5..b42b55b6727b137d43839b9a6a97b2ccb84e105d 100644 (file)
@@ -1857,7 +1857,7 @@ function refreshCameraFrames() {
             timestamp /= 500;
         }
         timestamp = Math.round(timestamp);
-        img.src = '/picture/' + cameraId + '/current/?_=' + timestamp + '&width=' + img.width;
+        img.src = '/picture/' + cameraId + '/current/?seq=' + timestamp + '&width=' + img.width;
         img.loading = true;
     }