From f1298c012312aee69e231d2831abab2c3d76a0a6 Mon Sep 17 00:00:00 2001 From: Calin Crisan Date: Tue, 1 Nov 2016 20:30:54 +0200 Subject: [PATCH] resolutions now can be modulo 8 (on newer motion versions) --- motioneye/config.py | 1 + motioneye/handlers.py | 2 +- motioneye/motionctl.py | 89 ++++++++++++++++++++++++------------------ motioneye/server.py | 2 +- motioneye/update.py | 11 +++++- motioneye/utils.py | 8 +++- motioneye/v4l2ctl.py | 5 ++- 7 files changed, 73 insertions(+), 45 deletions(-) diff --git a/motioneye/config.py b/motioneye/config.py index 7f8e88a..0958f82 100644 --- a/motioneye/config.py +++ b/motioneye/config.py @@ -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']) diff --git a/motioneye/handlers.py b/motioneye/handlers.py index 33fd33a..3cceeb6 100644 --- a/motioneye/handlers.py +++ b/motioneye/handlers.py @@ -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) diff --git a/motioneye/motionctl.py b/motioneye/motionctl.py index 8a7ffde..832ed38 100644 --- a/motioneye/motionctl.py +++ b/motioneye/motionctl.py @@ -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(): diff --git a/motioneye/server.py b/motioneye/server.py index 1e1215f..677953a 100644 --- a/motioneye/server.py +++ b/motioneye/server.py @@ -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 diff --git a/motioneye/update.py b/motioneye/update.py index 0c53b25..265cb97 100644 --- a/motioneye/update.py +++ b/motioneye/update.py @@ -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) diff --git a/motioneye/utils.py b/motioneye/utils.py index 60a0f07..a23cbd4 100644 --- a/motioneye/utils.py +++ b/motioneye/utils.py @@ -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) ] diff --git a/motioneye/v4l2ctl.py b/motioneye/v4l2ctl.py index 6fd4339..c8d84ac 100644 --- a/motioneye/v4l2ctl.py +++ b/motioneye/v4l2ctl.py @@ -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 -- 2.39.5