Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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