From: Calin Crisan Date: Sat, 28 Sep 2013 16:42:04 +0000 (+0300) Subject: implemented v4l2ctl X-Git-Url: http://www.vanbest.org/gitweb/?a=commitdiff_plain;h=8321defad446113ce44809670f373f97accd8ab5;p=motioneye-debian implemented v4l2ctl --- diff --git a/doc/todo.txt b/doc/todo.txt index 05005c7..2ff1d97 100644 --- a/doc/todo.txt +++ b/doc/todo.txt @@ -1,5 +1,6 @@ -> group @config rules to top -> browser compatibility test +-> requirements test -> hint text next to section titles -> clickable hints -> authentication diff --git a/src/handlers.py b/src/handlers.py index 2278593..2453173 100644 --- a/src/handlers.py +++ b/src/handlers.py @@ -6,6 +6,7 @@ from tornado.web import RequestHandler, HTTPError import config import template +import v4l2ctl class BaseHandler(RequestHandler): @@ -36,6 +37,9 @@ class ConfigHandler(BaseHandler): elif op == 'list': self.list_cameras() + elif op == 'list_devices': + self.list_devices() + else: raise HTTPError(400, 'unknown operation') @@ -116,6 +120,11 @@ class ConfigHandler(BaseHandler): self.finish_json({'cameras': cameras}) + def list_devices(self): + logging.debug('listing devices') + + self.finish_json({'devices': v4l2ctl.list_devices()}) + def add_camera(self): logging.debug('adding new camera') diff --git a/src/server.py b/src/server.py index 864507c..de0edb0 100644 --- a/src/server.py +++ b/src/server.py @@ -11,7 +11,7 @@ application = Application( (r'^/$', handlers.MainHandler), (r'^/config/main/(?Pset|get)/?$', handlers.ConfigHandler), (r'^/config/(?P\d+)/(?Pget|set|rem)/?$', handlers.ConfigHandler), - (r'^/config/(?Padd|list)/?$', handlers.ConfigHandler), + (r'^/config/(?Padd|list|list_devices)/?$', handlers.ConfigHandler), (r'^/snapshot/(?P\d+)/(?Pcurrent|list)/?$', handlers.SnapshotHandler), (r'^/snapshot/(?P\d+)/(?Pdownload)/(?P.+)/?$', handlers.SnapshotHandler), (r'^/movie/(?P\d+)/(?Plist)/?$', handlers.MovieHandler), diff --git a/src/v4l2ctl.py b/src/v4l2ctl.py index e69de29..e634b9d 100644 --- a/src/v4l2ctl.py +++ b/src/v4l2ctl.py @@ -0,0 +1,113 @@ + +import logging +import re +import subprocess + + +def list_devices(): + logging.debug('listing v4l devices...') + + devices = [] + + output = subprocess.check_output('v4l2-ctl --list-devices', shell=True) + + name = None + for line in output.split('\n'): + if line.startswith('\t'): + device = line.strip() + devices.append((device, name)) + + logging.debug('found device %(name)s: %(device)s' % { + 'name': name, 'device': device}) + + else: + name = line.split('(')[0].strip() + + return devices + + +def list_resolutions(device): + logging.debug('listing resolutions of device %(device)s...' % {'device': device}) + + resolutions = set() + output = subprocess.check_output('v4l2-ctl -d %(device)s --list-formats-ext | grep -oE "[0-9]+x[0-9]+"' % { + 'device': device}, shell=True) + + for pair in output.split('\n'): + pair = pair.strip() + if not pair: + continue + + width, height = pair.split('x') + width = int(width) + height = int(height) + + resolutions.add((width, height)) + + logging.debug('found resolution %(width)sx%(height)s for device %(device)s' % { + 'device': device, 'width': width, 'height': height}) + + return list(sorted(resolutions, key=lambda r: (r[0], r[1]))) + + +def set_brightness(device, value): + _set_ctrl(device, 'brightness', value) + + +def set_contrast(device, value): + _set_ctrl(device, 'contrast', value) + + +def set_saturation(device, value): + _set_ctrl(device, 'saturation', value) + + +def set_hue(device, value): + _set_ctrl(device, 'hue', value) + + +def _set_ctrl(device, control, value): + controls = _list_ctrls(device) + properties = controls.get(control) + if properties is None: + logging.warn('control %(control)s not found for device %(device)s' % { + 'control': control, 'device': device}) + + return + + # adjust the value range + if 'min' in properties and 'max' in properties: + min_value = int(properties['min']) + max_value = int(properties['max']) + + value = min_value + value * float(max_value - min_value) / 255 + + else: + logging.warn('min and max values not found for control %(control)s of device %(device)s' % { + 'control': control, 'device': device}) + + logging.debug('setting control %(control)s of device %(device)s to %(value)s' % { + 'control': control, 'device': device, 'value': value}) + + subprocess.call('v4l2-ctl -d %(device)s --set-ctrl %(control)s=%(value)s' % { + 'device': device, 'control': control, 'value': value}, shell=True) + + +def _list_ctrls(device): + output = subprocess.call('v4l2-ctl -d %(device)s --list-ctrls' % { + 'device': device}, shell=True) + + controls = {} + for line in output: + if not line: + continue + + match = re.match('^\s*(\w+)\s+\(\w+\)\s+\:\s*(.+)', line) + if not match: + continue + + (control, properties) = match.groups() + properties = dict([v.split('=') for v in properties.split(' ')]) + controls[control] = properties + + return controls