def list_resolutions(device): import motionctl global _resolutions_cache device = utils.make_str(device) if device in _resolutions_cache: return _resolutions_cache[device] logging.debug('listing resolutions of device %(device)s...' % {'device': device}) resolutions = set() output = '' started = time.time() cmd = 'v4l2-ctl -d %(device)s --list-formats-ext | grep -vi stepwise | grep -oE "[0-9]+x[0-9]+" || true' % { 'device': pipes.quote(device) } p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, bufsize=1) fd = p.stdout.fileno() fl = fcntl.fcntl(fd, fcntl.F_GETFL) fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) while True: try: data = p.stdout.read(1024) if not data: break except IOError: data = '' time.sleep(0.01) output += data if len(output) > 10240: logging.warn('v4l2-ctl command returned more than 10k of output') break if time.time() - started > _V4L2_TIMEOUT: logging.warn('v4l2-ctl command ran for more than %s seconds' % _V4L2_TIMEOUT) break try: # try to kill the v4l2-ctl subprocess p.kill() except: pass # nevermind for pair in output.split('\n'): pair = pair.strip() if not pair: continue width, height = pair.split('x') width = int(width) height = int(height) if (width, height) in resolutions: continue # duplicate resolution if width < 96 or height < 96: # some reasonable minimal values continue if not motionctl.resolution_is_valid(width, height): continue resolutions.add((width, height)) logging.debug( 'found resolution %(width)sx%(height)s for device %(device)s' % { 'device': device, 'width': width, 'height': height }) if not resolutions: logging.debug( 'no resolutions found for device %(device)s, using common values' % {'device': 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 return resolutions
def list_resolutions(device): import motionctl global _resolutions_cache device = utils.make_str(device) if device in _resolutions_cache: return _resolutions_cache[device] logging.debug('listing resolutions of device %(device)s...' % {'device': device}) resolutions = set() output = '' started = time.time() cmd = 'v4l2-ctl -d %(device)s --list-formats-ext | grep -vi stepwise | grep -oE "[0-9]+x[0-9]+" || true' % { 'device': pipes.quote(device)} p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, bufsize=1) fd = p.stdout.fileno() fl = fcntl.fcntl(fd, fcntl.F_GETFL) fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) while True: try: data = p.stdout.read(1024) if not data: break except IOError: data = '' time.sleep(0.01) output += data if len(output) > 10240: logging.warn('v4l2-ctl command returned more than 10k of output') break if time.time() - started > _V4L2_TIMEOUT: logging.warn('v4l2-ctl command ran for more than %s seconds' % _V4L2_TIMEOUT) break try: # try to kill the v4l2-ctl subprocess p.kill() except: pass # nevermind for pair in output.split('\n'): pair = pair.strip() if not pair: continue width, height = pair.split('x') width = int(width) height = int(height) if (width, height) in resolutions: continue # duplicate resolution if width < 96 or height < 96: # some reasonable minimal values continue if not motionctl.resolution_is_valid(width, height): continue resolutions.add((width, height)) logging.debug('found resolution %(width)sx%(height)s for device %(device)s' % { 'device': device, 'width': width, 'height': height}) if not resolutions: logging.debug('no resolutions found for device %(device)s, using common values' % {'device': 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 return resolutions