resolutions now can be modulo 8 (on newer motion versions)
authorCalin Crisan <ccrisan@gmail.com>
Tue, 1 Nov 2016 18:30:54 +0000 (20:30 +0200)
committerCalin Crisan <ccrisan@gmail.com>
Tue, 1 Nov 2016 18:30:54 +0000 (20:30 +0200)
motioneye/config.py
motioneye/handlers.py
motioneye/motionctl.py
motioneye/server.py
motioneye/update.py
motioneye/utils.py
motioneye/v4l2ctl.py

index 7f8e88a9d160b6396eab510cbe61b189098214ac..0958f827b450c743ba0645dbd75d85a829810267 100644 (file)
@@ -1089,6 +1089,7 @@ def motion_camera_dict_to_ui(data):
         if data['netcam_url'].startswith('rtsp'):
             # motion uses the configured width and height for RTSP cameras
             resolutions = utils.COMMON_RESOLUTIONS
+            resolutions = [r for r in resolutions if motionctl.resolution_is_valid(*r)]
             ui['available_resolutions'] = [(str(w) + 'x' + str(h)) for (w, h) in resolutions]
             ui['resolution'] = str(data['width']) + 'x' + str(data['height'])
 
index 33fd33aae605b8924072bef8839f442f9689d09d..3cceeb61a461a06c42f4351054b6a0c65912c04b 100644 (file)
@@ -210,7 +210,7 @@ class MainHandler(BaseHandler):
                 admin_username=config.get_main().get('@admin_username'),
                 has_streaming_auth=motionctl.has_streaming_auth(),
                 has_new_movie_format_support=motionctl.has_new_movie_format_support(),
-                has_motion=bool(motionctl.find_motion()),
+                has_motion=bool(motionctl.find_motion()[0]),
                 mask_width=utils.MASK_WIDTH)
 
 
index 8a7ffdea8713a8cd7495be3c77953de8cc7557e4..832ed38bb19eda55924e7fa8b6745c3ae799be1e 100644 (file)
@@ -50,20 +50,20 @@ def find_motion():
             binary = settings.MOTION_BINARY
         
         else:
-            return None
+            return None, None
 
     else: # autodetect motion binary path
         try:
             binary = subprocess.check_output(['which', 'motion'], stderr=utils.DEV_NULL).strip()
         
         except subprocess.CalledProcessError: # not found
-            return None
+            return None, None
 
     try:
         help = subprocess.check_output(binary + ' -h || true', shell=True)
     
     except subprocess.CalledProcessError: # not found
-        return None
+        return None, None
     
     result = re.findall('motion Version ([^,]+)', help, re.IGNORECASE)
     version = result and result[0] or ''
@@ -94,7 +94,7 @@ def start(deferred=False):
     logging.debug('starting motion')
  
     program = find_motion()
-    if not program:
+    if not program[0]:
         raise Exception('motion executable could not be found')
     
     program, version = program  # @UnusedVariable
@@ -327,21 +327,19 @@ def thread_id_to_camera_id(thread_id):
 
 
 def has_old_config_format():
-    try:
-        binary, version = find_motion()  # @UnusedVariable
-
-        if version.startswith('trunkREV'): # e.g. "trunkREV599"
-            version = int(version[8:])
-            return version <= _LAST_OLD_CONFIG_VERSIONS[0]
+    binary, version = find_motion()
+    if not binary:
+        return False
 
-        elif version.lower().count('git'): # e.g. "Unofficial-Git-a5b5f13" or "3.2.12+git20150927mrdave"
-            return False # all git versions are assumed to be new
+    if version.startswith('trunkREV'): # e.g. "trunkREV599"
+        version = int(version[8:])
+        return version <= _LAST_OLD_CONFIG_VERSIONS[0]
 
-        else: # stable release, should have the format "x.y.z"
-            return update.compare_versions(version, _LAST_OLD_CONFIG_VERSIONS[1]) <= 0
+    elif version.lower().count('git'): # e.g. "Unofficial-Git-a5b5f13" or "3.2.12+git20150927mrdave"
+        return False # all git versions are assumed to be new
 
-    except:
-        return False
+    else: # stable release, should have the format "x.y.z"
+        return update.compare_versions(version, _LAST_OLD_CONFIG_VERSIONS[1]) <= 0
 
 
 def has_streaming_auth():
@@ -349,31 +347,27 @@ def has_streaming_auth():
 
 
 def has_new_movie_format_support():
-    try:
-        binary, version = find_motion()  # @UnusedVariable
-
-        return version.lower().count('git') or update.compare_versions(version, '3.4') >= 0 
-
-    except:
+    binary, version = find_motion()
+    if not binary:
         return False
 
+    return version.lower().count('git') or update.compare_versions(version, '3.4') >= 0 
+
 
 def get_rtsp_support():
-    try:
-        binary, version = find_motion()  # @UnusedVariable
+    binary, version = find_motion()
+    if not binary:
+        return []
 
-        if version.startswith('trunkREV'): # e.g. trunkREV599
-            version = int(version[8:])
-            if version > _LAST_OLD_CONFIG_VERSIONS[0]:
-                return ['tcp']
+    if version.startswith('trunkREV'): # e.g. trunkREV599
+        version = int(version[8:])
+        if version > _LAST_OLD_CONFIG_VERSIONS[0]:
+            return ['tcp']
 
-        elif version.lower().count('git') or update.compare_versions(version, '3.4') >= 0:
-            return ['tcp', 'udp'] # all git versions are assumed to support both transport protocols
-        
-        else: # stable release, should be in the format x.y.z
-            return []
-
-    except:
+    elif version.lower().count('git') or update.compare_versions(version, '3.4') >= 0:
+        return ['tcp', 'udp'] # all git versions are assumed to support both transport protocols
+    
+    else: # stable release, should be in the format x.y.z
         return []
 
 
@@ -381,13 +375,30 @@ def needs_ffvb_quirks():
     # versions below 4.0 require a value range of 1..32767
     # for the ffmpeg_variable_bitrate parameter;
     # also the quality is non-linear in this range
-    try:
-        binary, version = find_motion()  # @UnusedVariable
+    
+    binary, version = find_motion()
+    if not binary:
+        return False
+
+    return update.compare_versions(version, '4.0') < 0 
 
-        return update.compare_versions(version, '4.0') < 0 
 
-    except:
+def resolution_is_valid(width, height):
+    # versions below 3.4 require width and height to be modulo 16;
+    # newer versions require them to be modulo 8
+
+    modulo = 8
+    binary, version = find_motion()  # @UnusedVariable
+    if version and not version.lower().count('git') and update.compare_versions(version, '3.4') < 0:
+        modulo = 16
+    
+    if width % modulo:
         return False
+    
+    if height % modulo:
+        return False
+
+    return True
 
 
 def _disable_initial_motion_detection():
index 1e1215f1560cfee2087bea9a7efd1450abf07e17..677953a997cc5e7194ff3815185ad3a4ea805fb5 100644 (file)
@@ -256,7 +256,7 @@ def test_requirements():
         sys.exit(-1)
     
     import motionctl
-    has_motion = motionctl.find_motion() is not None
+    has_motion = motionctl.find_motion()[0] is not None
     
     import mediafiles
     has_ffmpeg = mediafiles.find_ffmpeg() is not None
index 0c53b2537f85abf3fec7ea0ba4d10f46fa6b782f..265cb97ecb92ef0f1fbdd2de55192c9b3828245f 100644 (file)
@@ -35,8 +35,15 @@ def compare_versions(version1, version2):
     version1 = re.sub('[^0-9.]', '', version1)
     version2 = re.sub('[^0-9.]', '', version2)
     
-    version1 = [int(n) for n in version1.split('.')]
-    version2 = [int(n) for n in version2.split('.')]
+    def int_or_0(n):
+        try:
+            return int(n)
+        
+        except:
+            return 0
+
+    version1 = [int_or_0(n) for n in version1.split('.')]
+    version2 = [int_or_0(n) for n in version2.split('.')]
     
     len1 = len(version1)
     len2 = len(version2)
index 60a0f07e5f0e82ad475ad1ceccc658867c8f6cd1..a23cbd4dfcc8319105116165cc3a57f994d7ab46 100644 (file)
@@ -53,18 +53,24 @@ DEV_NULL = open('/dev/null', 'w')
 
 
 COMMON_RESOLUTIONS = [
+    (320, 200),
     (320, 240),
     (640, 480),
     (800, 480),
+    (800, 600),
     (1024, 576),
+    (1024, 600),
     (1024, 768),
     (1280, 720),
+    (1280, 768),
     (1280, 800),
     (1280, 960),
     (1280, 1024),
+    (1440, 900),
     (1440, 960),
     (1440, 1024),
-    (1600, 1200)
+    (1600, 1200),
+    (1920, 1080)
 ]
 
 
index 6fd4339491c633092bdf71a6159a5768c74be524..c8d84acd2089a31c587ef2dbe787bdffd1572cd8 100644 (file)
@@ -110,6 +110,8 @@ def list_devices():
 
 
 def list_resolutions(device):
+    import motionctl
+    
     global _resolutions_cache
     
     device = utils.make_str(device)
@@ -171,7 +173,7 @@ def list_resolutions(device):
         if width < 96 or height < 96: # some reasonable minimal values
             continue
         
-        if width % 16 or height % 16: # ignore non-modulo 16 resolutions
+        if not motionctl.resolution_is_valid(width, height):
             continue
 
         resolutions.add((width, height))
@@ -184,6 +186,7 @@ def list_resolutions(device):
 
         # no resolution returned by v4l2-ctl call, add common default resolutions
         resolutions = utils.COMMON_RESOLUTIONS
+        resolutions = [r for r in resolutions if motionctl.resolution_is_valid(*r)]
 
     resolutions = list(sorted(resolutions, key=lambda r: (r[0], r[1])))
     _resolutions_cache[device] = resolutions