Python: v4l2-ctl-Parameter mit subprocess setzen und verifizieren

English Deutsch

Der folgende Code verwendet das ausführbare Programm v4l2-ctl, um v4l2-Parameter wie exposure_absolute zu setzen und auszulesen. Er bietet auch die Möglichkeit, einen Parameter zu setzen und zu überprüfen, ob er korrekt gesetzt wurde.

v4l2_set_params.py
def v4l2_set_parameters_once(params, device="/dev/video0"):
    """
    Given a dict of parameters:
    {
        "exposure_auto": 1,
        "exposure_absolute": 10,
    }
    this function sets those parameters using the v4l2-ctl command line executable
    """
    set_ctrl_str = ",".join([f"{k}={v}" for k,v in params.items()]) # expsosure_absolute=400,exposure_auto=1
    subprocess.check_output(["v4l2-ctl", "-d", device, f"--set-ctrl={set_ctrl_str}"])

def v4l2_get_parameters(params, device="/dev/video0"):
    """
    Query a bunch of v4l2 parameters.
    params is a list like
    [
        "exposure_auto",
        "exposure_absolute"
    ]

    Returns a dict of values:
    {
        "exposure_auto": 1,
        "exposure_absolute": 10,
    }
    """
    get_ctrl_str = ",".join([f"{k}" for k in params])
    out = subprocess.check_output(["v4l2-ctl", "-d", device, f"--get-ctrl={get_ctrl_str}"])
    out = out.decode("utf-8")
    result = {}
    for line in out.split("\n"):
        # Zeile sollte so aussehen: "exposure_auto: 1"
        if ":" not in line:
            continue
        k, _, v = line.partition(":")
        result[k.strip()] = v.strip()
    return result

def v4l2_set_params_until_effective(params, device="/dev/video0"):
    """
    Set V4L2 params and check if they have been set correctly.
    If V4L2 does not confirm the parameters correctly, they will be set again until they have an effect

    params is a dict like {
        "exposure_auto": 1,
        "exposure_absolute": 10,
    }
    """
    while True:
        v4l2_set_parameters_once(params, device=device)
        result = v4l2_get_parameters(params.keys(), device=device)
        # Prüfen, ob abgefragte Parameter mit gesetzten Parametern übereinstimmen
        had_any_mismatch = False
        for k, v in params.items():
            if k not in result:
                raise ValueError(f"Could not query {k}")
            # Hinweis: Werte von v4l2 sind immer Strings. Daher müssen wir als Strings vergleichen
            if str(result.get(k)) != str(v):
                print(f"Abweichung bei {k} = {result.get(k)} aber sollte {v} sein")
                had_any_mismatch = True
        # Prüfen, ob es eine Abweichung gab
        if not had_any_mismatch:
            return

Verwendungsbeispiel:

v4l2_usage_example.py
v4l2_set_params_until_effective({
    "exposure_auto": 1,
    "exposure_absolute": 1000,
})

Check out similar posts by category: Audio/Video, Linux, OpenCV, Python