diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f206288..2ba7cf3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: - python-version: [3.7, 3.8, 3.9, "3.10", "3.11"] + python-version: [3.9, "3.10", "3.11", "3.12"] steps: - name: Checkout @@ -31,7 +31,7 @@ jobs: - name: Linting tests run: | black --check --diff v4l2py tests examples - ruff check --diff --format=github --show-files . + ruff check --diff --output-format=github --show-files . - name: Build package run: | python -m build diff --git a/README.md b/README.md index c3a2301..818ad2b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # v4l2py +**Since version 3.0 this project is now a shim for `linuxpy.video`** + +**Please consider using [linuxpy](https/github.com/tiagocoutinho/linuxpy) directly.** + [![V4L2py][pypi-version]](https://pypi.python.org/pypi/v4l2py) [![Python Versions][pypi-python-versions]](https://pypi.python.org/pypi/v4l2py) ![License][license] diff --git a/pyproject.toml b/pyproject.toml index 6d6f352..3a44539 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ license = {text = "GPL-3.0-or-later"} authors = [ { name = "Jose Tiago Macara Coutinho", email = "coutinhotiago@gmail.com" } ] -requires-python = ">=3.7" +requires-python = ">=3.9" classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", @@ -13,15 +13,14 @@ classifiers = [ "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Topic :: Multimedia :: Video", "Topic :: Multimedia :: Video :: Capture", ] -dependencies = [] +dependencies = ["linuxpy>=0.9.0"] dynamic = ["version", "readme"] [project.urls] diff --git a/tests/test_device.py b/tests/test_device.py index b3d45c2..a7e3d09 100644 --- a/tests/test_device.py +++ b/tests/test_device.py @@ -4,7 +4,8 @@ # Copyright (c) 2021 Tiago Coutinho # Distributed under the GPLv3 license. See LICENSE for more info. -from contextlib import ExitStack +import os +from contextlib import ExitStack, contextmanager from errno import EINVAL from inspect import isgenerator from math import isclose @@ -62,11 +63,11 @@ def __init__(self, filename="/dev/video39"): def __enter__(self): self.stack = ExitStack() - ioctl = mock.patch("v4l2py.device.fcntl.ioctl", self.ioctl) - opener = mock.patch("v4l2py.io.open", self.open) - mmap = mock.patch("v4l2py.device.mmap.mmap", self.mmap) - select = mock.patch("v4l2py.io.IO.select", self.select) - blocking = mock.patch("v4l2py.device.os.get_blocking", self.get_blocking) + ioctl = mock.patch("linuxpy.ioctl.fcntl.ioctl", self.ioctl) + opener = mock.patch("linuxpy.io.open", self.open) + mmap = mock.patch("linuxpy.video.device.mmap.mmap", self.mmap) + select = mock.patch("linuxpy.io.IO.select", self.select) + blocking = mock.patch("linuxpy.device.os.get_blocking", self.get_blocking) self.stack.enter_context(ioctl) self.stack.enter_context(opener) self.stack.enter_context(mmap) @@ -99,37 +100,38 @@ def ioctl(self, fd, ioc, arg): # noqa: C901 if arg.index > 0: raise OSError(EINVAL, "ups!") arg.name = self.input0_name - arg.type = raw.V4L2_INPUT_TYPE_CAMERA + arg.type = raw.InputType.CAMERA elif isinstance(arg, raw.v4l2_query_ext_ctrl): if arg.index > 0: raise OSError(EINVAL, "ups!") arg.name = b"brightness" - arg.type = raw.V4L2_CTRL_TYPE_INTEGER + arg.type = raw.CtrlType.INTEGER arg.id = 9963776 elif isinstance(arg, raw.v4l2_capability): arg.driver = self.driver arg.card = self.card arg.bus_info = self.bus_info arg.version = self.version + arg.capabilities = raw.Capability.STREAMING | raw.Capability.VIDEO_CAPTURE elif isinstance(arg, raw.v4l2_format): - if ioc == raw.VIDIOC_G_FMT: + if ioc == raw.IOC.G_FMT: arg.fmt.pix.width = 640 arg.fmt.pix.height = 480 - arg.fmt.pix.pixelformat = raw.V4L2_PIX_FMT_RGB24 + arg.fmt.pix.pixelformat = raw.PixelFormat.RGB24 elif isinstance(arg, raw.v4l2_buffer): - if ioc == raw.VIDIOC_QUERYBUF: + if ioc == raw.IOC.QUERYBUF: pass - elif ioc == raw.VIDIOC_DQBUF: + elif ioc == raw.IOC.DQBUF: arg.index = 0 arg.bytesused = len(self.frame) arg.sequence = 123 arg.timestamp.secs = 123 arg.timestamp.usecs = 456789 - elif ioc == raw.VIDIOC_STREAMON: - assert arg.value == raw.V4L2_BUF_TYPE_VIDEO_CAPTURE + elif ioc == raw.IOC.STREAMON: + assert arg.value == raw.BufType.VIDEO_CAPTURE self.video_capture_state = "ON" - elif ioc == raw.VIDIOC_STREAMOFF: - assert arg.value == raw.V4L2_BUF_TYPE_VIDEO_CAPTURE + elif ioc == raw.IOC.STREAMOFF: + assert arg.value == raw.BufType.VIDEO_CAPTURE self.video_capture_state = "OFF" return 0 @@ -137,7 +139,7 @@ def mmap(self, fd, length, offset): assert self.fd == fd return MemoryMap(self) - def select(self, readers, writers, other): + def select(self, readers, writers, other, timeout=None): assert readers[0].fileno() == self.fd return readers, writers, other @@ -165,6 +167,18 @@ def assert_frame(frame, camera): assert numpy.all(frame.array == numpy.frombuffer(camera.frame, dtype="u1")) +@contextmanager +def video_files(paths=("/dev/video99")): + with mock.patch("linuxpy.device.pathlib.Path.glob") as glob: + expected_files = list(paths) + glob.return_value = expected_files + with mock.patch("linuxpy.device.pathlib.Path.is_char_device") as is_char_device: + is_char_device.return_value = True + with mock.patch("linuxpy.device.os.access") as access: + access.return_value = os.R_OK | os.W_OK + yield paths + + @test("device number") def _( filename=each("/dev/video0", "/dev/video1", "/dev/video999"), @@ -175,10 +189,7 @@ def _( @test("video files") def _(): - with mock.patch("v4l2py.device.pathlib.Path.glob") as glob: - expected_files = ["/dev/video0", "/dev/video55"] - glob.return_value = expected_files - + with video_files(["/dev/video0", "/dev/video55"]) as expected_files: assert list(iter_video_files()) == expected_files @@ -186,9 +197,7 @@ def _(): def _(): assert isgenerator(iter_devices()) - with mock.patch("v4l2py.device.pathlib.Path.glob") as glob: - expected_files = ["/dev/video0", "/dev/video55"] - glob.return_value = expected_files + with video_files(["/dev/video0", "/dev/video55"]) as expected_files: devices = list(iter_devices()) assert len(devices) == 2 for device in devices: diff --git a/v4l2py/__init__.py b/v4l2py/__init__.py index 3b9e515..75691cf 100644 --- a/v4l2py/__init__.py +++ b/v4l2py/__init__.py @@ -6,6 +6,8 @@ # ruff: noqa: F401 +import warnings + from .device import ( Device, Frame, @@ -19,4 +21,8 @@ ) from .io import IO, GeventIO -__version__ = "2.3.0" +__version__ = "3.0.0" + +warnings.warn( + "v4l2py is no longer being maintained. Please consider using linuxpy.video instead" +) diff --git a/v4l2py/device.py b/v4l2py/device.py index a897317..524d240 100644 --- a/v4l2py/device.py +++ b/v4l2py/device.py @@ -4,1591 +4,7 @@ # Copyright (c) 2021 Tiago Coutinho # Distributed under the GPLv3 license. See LICENSE for more info. -import asyncio -import collections -import copy -import ctypes -import enum -import errno -import fcntl -import fractions -import logging -import mmap -import os -import pathlib -import typing -from io import IOBase -from collections import UserDict +# ruff: noqa: F401, F403 -from . import raw -from .io import IO, fopen - -log = logging.getLogger(__name__) -log_ioctl = log.getChild("ioctl") -log_mmap = log.getChild("mmap") - - -class V4L2Error(Exception): - pass - - -def _enum(name, prefix, klass=enum.IntEnum): - return klass( - name, - ( - (name.replace(prefix, ""), getattr(raw, name)) - for name in dir(raw) - if name.startswith(prefix) - ), - ) - - -Capability = _enum("Capability", "V4L2_CAP_", klass=enum.IntFlag) -PixelFormat = _enum("PixelFormat", "V4L2_PIX_FMT_") -BufferType = _enum("BufferType", "V4L2_BUF_TYPE_") -BufferFlag = _enum("BufferFlag", "V4L2_BUF_FLAG_", klass=enum.IntFlag) -Memory = _enum("Memory", "V4L2_MEMORY_") -ImageFormatFlag = _enum("ImageFormatFlag", "V4L2_FMT_FLAG_", klass=enum.IntFlag) -Field = _enum("Field", "V4L2_FIELD_") -FrameSizeType = _enum("FrameSizeType", "V4L2_FRMSIZE_TYPE_") -FrameIntervalType = _enum("FrameIntervalType", "V4L2_FRMIVAL_TYPE_") -IOC = _enum("IOC", "VIDIOC_", klass=enum.Enum) -InputStatus = _enum("InputStatus", "V4L2_IN_ST_", klass=enum.IntFlag) -InputType = _enum("InputType", "V4L2_INPUT_TYPE_") -InputCapabilities = _enum("InputCapabilities", "V4L2_IN_CAP_", klass=enum.IntFlag) -ControlClass = _enum("ControlClass", "V4L2_CTRL_CLASS_") -ControlType = _enum("ControlType", "V4L2_CTRL_TYPE_") -ControlID = _enum("ControlID", "V4L2_CID_") -ControlFlag = _enum("ControlFlag", "V4L2_CTRL_FLAG_") -SelectionTarget = _enum("SelectionTarget", "V4L2_SEL_TGT_") -Priority = _enum("Priority", "V4L2_PRIORITY_") -TimeCode = _enum("TimeCode", "V4L2_TC_TYPE_") -TimeFlag = _enum("TimeFlag", "V4L2_TC_FLAG_", klass=enum.IntFlag) - - -def human_pixel_format(ifmt): - return "".join(map(chr, ((ifmt >> i) & 0xFF for i in range(0, 4 * 8, 8)))) - - -PixelFormat.human_str = lambda self: human_pixel_format(self.value) - - -Info = collections.namedtuple( - "Info", - "driver card bus_info version capabilities device_capabilities " - "crop_capabilities buffers formats frame_sizes inputs controls", -) - -ImageFormat = collections.namedtuple( - "ImageFormat", "type description flags pixel_format" -) - -Format = collections.namedtuple("Format", "width height pixel_format") - -CropCapability = collections.namedtuple( - "CropCapability", "type bounds defrect pixel_aspect" -) - -Rect = collections.namedtuple("Rect", "left top width height") - -Size = collections.namedtuple("Size", "width height") - -FrameType = collections.namedtuple( - "FrameType", "type pixel_format width height min_fps max_fps step_fps" -) - -Input = collections.namedtuple( - "InputType", "index name type audioset tuner std status capabilities" -) - - -INFO_REPR = """\ -driver = {info.driver} -card = {info.card} -bus = {info.bus_info} -version = {info.version} -capabilities = {capabilities} -device_capabilities = {device_capabilities} -buffers = {buffers} -""" - - -def ioctl(fd, request, arg): - log_ioctl.debug("%s, request=%s, arg=%s", fd, request.name, arg) - return fcntl.ioctl(fd, request.value, arg) - - -def mem_map(fd, length, offset): - log_mmap.debug("%s, length=%d, offset=%d", fd, length, offset) - return mmap.mmap(fd, length, offset=offset) - - -def flag_items(flag): - return [item for item in type(flag) if item in flag] - - -def Info_repr(info): - dcaps = "|".join(cap.name for cap in flag_items(info.device_capabilities)) - caps = "|".join(cap.name for cap in flag_items(info.capabilities)) - buffers = "|".join(buff.name for buff in info.buffers) - return INFO_REPR.format( - info=info, capabilities=caps, device_capabilities=dcaps, buffers=buffers - ) - - -Info.__repr__ = Info_repr - - -def raw_crop_caps_to_crop_caps(stream_type, crop): - return CropCapability( - type=stream_type, - bounds=Rect( - crop.bounds.left, - crop.bounds.top, - crop.bounds.width, - crop.bounds.height, - ), - defrect=Rect( - crop.defrect.left, - crop.defrect.top, - crop.defrect.width, - crop.defrect.height, - ), - pixel_aspect=crop.pixelaspect.numerator / crop.pixelaspect.denominator, - ) - - -CropCapability.from_raw = raw_crop_caps_to_crop_caps - - -def iter_read(fd, ioc, indexed_struct, start=0, stop=128, step=1, ignore_einval=False): - for index in range(start, stop, step): - indexed_struct.index = index - try: - ioctl(fd, ioc, indexed_struct) - yield indexed_struct - except OSError as error: - if error.errno == errno.EINVAL: - if ignore_einval: - continue - else: - break - else: - raise - - -def frame_sizes(fd, pixel_formats): - def get_frame_intervals(fmt, w, h): - value = raw.v4l2_frmivalenum() - value.pixel_format = fmt - value.width = w - value.height = h - res = [] - for val in iter_read(fd, IOC.ENUM_FRAMEINTERVALS, value): - # values come in frame interval (fps = 1/interval) - try: - ftype = FrameIntervalType(val.type) - except ValueError: - break - if ftype == FrameIntervalType.DISCRETE: - min_fps = max_fps = step_fps = fractions.Fraction( - val.discrete.denominator / val.discrete.numerator - ) - else: - if val.stepwise.min.numerator == 0: - min_fps = 0 - else: - min_fps = fractions.Fraction( - val.stepwise.min.denominator, val.stepwise.min.numerator - ) - if val.stepwise.max.numerator == 0: - max_fps = 0 - else: - max_fps = fractions.Fraction( - val.stepwise.max.denominator, val.stepwise.max.numerator - ) - if val.stepwise.step.numerator == 0: - step_fps = 0 - else: - step_fps = fractions.Fraction( - val.stepwise.step.denominator, val.stepwise.step.numerator - ) - res.append( - FrameType( - type=ftype, - pixel_format=fmt, - width=w, - height=h, - min_fps=min_fps, - max_fps=max_fps, - step_fps=step_fps, - ) - ) - return res - - size = raw.v4l2_frmsizeenum() - sizes = [] - for pixel_format in pixel_formats: - size.pixel_format = pixel_format - size.index = 0 - while True: - try: - ioctl(fd, IOC.ENUM_FRAMESIZES, size) - except OSError: - break - if size.type == FrameSizeType.DISCRETE: - sizes += get_frame_intervals( - pixel_format, size.discrete.width, size.discrete.height - ) - size.index += 1 - return sizes - - -def read_capabilities(fd): - caps = raw.v4l2_capability() - ioctl(fd, IOC.QUERYCAP, caps) - return caps - - -def iter_read_formats(fd, type): - format = raw.v4l2_fmtdesc() - format.type = type - pixel_formats = set(PixelFormat) - for fmt in iter_read(fd, IOC.ENUM_FMT, format): - pixel_fmt = fmt.pixelformat - if pixel_fmt not in pixel_formats: - log.warning( - "ignored unknown pixel format %s (%d)", - human_pixel_format(pixel_fmt), - pixel_fmt, - ) - continue - image_format = ImageFormat( - type=type, - flags=ImageFormatFlag(fmt.flags), - description=fmt.description.decode(), - pixel_format=PixelFormat(pixel_fmt), - ) - yield image_format - - -def iter_read_inputs(fd): - input = raw.v4l2_input() - for inp in iter_read(fd, IOC.ENUMINPUT, input): - input_type = Input( - index=inp.index, - name=inp.name.decode(), - type=InputType(inp.type), - audioset=inp.audioset, - tuner=inp.tuner, - std=inp.std, - status=InputStatus(inp.status), - capabilities=InputCapabilities(inp.capabilities), - ) - yield input_type - - -def iter_read_controls(fd): - ctrl = raw.v4l2_query_ext_ctrl() - nxt = ControlFlag.NEXT_CTRL | ControlFlag.NEXT_COMPOUND - ctrl.id = nxt - for ctrl_ext in iter_read(fd, IOC.QUERY_EXT_CTRL, ctrl): - if not (ctrl_ext.flags & ControlFlag.DISABLED) and not ( - ctrl_ext.type == ControlType.CTRL_CLASS - ): - yield copy.deepcopy(ctrl_ext) - ctrl_ext.id |= nxt - - -def iter_read_menu(fd, ctrl): - qmenu = raw.v4l2_querymenu() - qmenu.id = ctrl.id - for menu in iter_read( - fd, - IOC.QUERYMENU, - qmenu, - start=ctrl._info.minimum, - stop=ctrl._info.maximum + 1, - step=ctrl._info.step, - ignore_einval=True, - ): - yield copy.deepcopy(menu) - - -def read_info(fd): - caps = read_capabilities(fd) - version_tuple = ( - (caps.version & 0xFF0000) >> 16, - (caps.version & 0x00FF00) >> 8, - (caps.version & 0x0000FF), - ) - version_str = ".".join(map(str, version_tuple)) - device_capabilities = Capability(caps.device_caps) - buffers = [typ for typ in BufferType if Capability[typ.name] in device_capabilities] - - img_fmt_stream_types = { - BufferType.VIDEO_CAPTURE, - BufferType.VIDEO_CAPTURE_MPLANE, - BufferType.VIDEO_OUTPUT, - BufferType.VIDEO_OUTPUT_MPLANE, - BufferType.VIDEO_OVERLAY, - } & set(buffers) - - image_formats = [] - pixel_formats = set() - for stream_type in img_fmt_stream_types: - for image_format in iter_read_formats(fd, stream_type): - image_formats.append(image_format) - pixel_formats.add(image_format.pixel_format) - - crop = raw.v4l2_cropcap() - crop_stream_types = { - BufferType.VIDEO_CAPTURE, - BufferType.VIDEO_OUTPUT, - BufferType.VIDEO_OVERLAY, - } & set(buffers) - crop_caps = [] - for stream_type in crop_stream_types: - crop.type = stream_type - try: - ioctl(fd, IOC.CROPCAP, crop) - except OSError: - continue - crop_cap = CropCapability.from_raw(stream_type, crop) - crop_caps.append(crop_cap) - - return Info( - driver=caps.driver.decode(), - card=caps.card.decode(), - bus_info=caps.bus_info.decode(), - version=version_str, - capabilities=Capability(caps.capabilities), - device_capabilities=device_capabilities, - crop_capabilities=crop_caps, - buffers=buffers, - formats=image_formats, - frame_sizes=frame_sizes(fd, pixel_formats), - inputs=list(iter_read_inputs(fd)), - controls=list(iter_read_controls(fd)), - ) - - -def query_buffer( - fd, buffer_type: BufferType, memory: Memory, index: int -) -> raw.v4l2_buffer: - buff = raw.v4l2_buffer() - buff.type = buffer_type - buff.memory = memory - buff.index = index - buff.reserved = 0 - ioctl(fd, IOC.QUERYBUF, buff) - return buff - - -def enqueue_buffer( - fd, buffer_type: BufferType, memory: Memory, index: int -) -> raw.v4l2_buffer: - buff = raw.v4l2_buffer() - buff.type = buffer_type - buff.memory = memory - buff.index = index - buff.reserved = 0 - ioctl(fd, IOC.QBUF, buff) - return buff - - -def dequeue_buffer(fd, buffer_type: BufferType, memory: Memory) -> raw.v4l2_buffer: - buff = raw.v4l2_buffer() - buff.type = buffer_type - buff.memory = memory - buff.index = 0 - buff.reserved = 0 - ioctl(fd, IOC.DQBUF, buff) - return buff - - -def request_buffers( - fd, buffer_type: BufferType, memory: Memory, count: int -) -> raw.v4l2_requestbuffers: - req = raw.v4l2_requestbuffers() - req.type = buffer_type - req.memory = memory - req.count = count - ioctl(fd, IOC.REQBUFS, req) - if not req.count: - raise IOError("Not enough buffer memory") - return req - - -def free_buffers( - fd, buffer_type: BufferType, memory: Memory -) -> raw.v4l2_requestbuffers: - req = raw.v4l2_requestbuffers() - req.type = buffer_type - req.memory = memory - req.count = 0 - ioctl(fd, IOC.REQBUFS, req) - return req - - -def set_format( - fd, buffer_type: BufferType, width: int, height: int, pixel_format: str = "MJPG" -): - f = raw.v4l2_format() - if isinstance(pixel_format, str): - pixel_format = raw.v4l2_fourcc(*pixel_format.upper()) - f.type = buffer_type - f.fmt.pix.pixelformat = pixel_format - f.fmt.pix.field = Field.ANY - f.fmt.pix.width = width - f.fmt.pix.height = height - f.fmt.pix.bytesperline = 0 - f.fmt.pix.sizeimage = 0 - return ioctl(fd, IOC.S_FMT, f) - - -def get_raw_format(fd, buffer_type): - fmt = raw.v4l2_format() - fmt.type = buffer_type - ioctl(fd, IOC.G_FMT, fmt) - return fmt - - -def get_format(fd, buffer_type): - f = get_raw_format(fd, buffer_type) - return Format( - width=f.fmt.pix.width, - height=f.fmt.pix.height, - pixel_format=PixelFormat(f.fmt.pix.pixelformat), - ) - - -def get_parm(fd, buffer_type): - p = raw.v4l2_streamparm() - p.type = buffer_type - ioctl(fd, IOC.G_PARM, p) - return p - - -def set_fps(fd, buffer_type, fps): - # v4l2 fraction is u32 - max_denominator = int(min(2**32, 2**32 / fps)) - p = raw.v4l2_streamparm() - p.type = buffer_type - fps = fractions.Fraction(fps).limit_denominator(max_denominator) - if buffer_type == BufferType.VIDEO_CAPTURE: - p.parm.capture.timeperframe.numerator = fps.denominator - p.parm.capture.timeperframe.denominator = fps.numerator - elif buffer_type == BufferType.VIDEO_OUTPUT: - p.parm.output.timeperframe.numerator = fps.denominator - p.parm.output.timeperframe.denominator = fps.numerator - else: - raise ValueError(f"Unsupported buffer type {buffer_type!r}") - return ioctl(fd, IOC.S_PARM, p) - - -def get_fps(fd, buffer_type): - p = get_parm(fd, buffer_type) - if buffer_type == BufferType.VIDEO_CAPTURE: - parm = p.parm.capture - elif buffer_type == BufferType.VIDEO_OUTPUT: - parm = p.parm.output - else: - raise ValueError(f"Unsupported buffer type {buffer_type!r}") - return fractions.Fraction( - parm.timeperframe.denominator, parm.timeperframe.numerator - ) - - -def stream_on(fd, buffer_type): - btype = raw.v4l2_buf_type(buffer_type) - return ioctl(fd, IOC.STREAMON, btype) - - -def stream_off(fd, buffer_type): - btype = raw.v4l2_buf_type(buffer_type) - return ioctl(fd, IOC.STREAMOFF, btype) - - -def set_selection(fd, buffer_type, rectangles): - sel = raw.v4l2_selection() - sel.type = buffer_type - sel.target = raw.V4L2_SEL_TGT_CROP - sel.rectangles = len(rectangles) - rects = (raw.v4l2_ext_rect * sel.rectangles)() - - for i in range(sel.rectangles): - rects[i].r.left = rectangles[i].left - rects[i].r.top = rectangles[i].top - rects[i].r.width = rectangles[i].width - rects[i].r.height = rectangles[i].height - - sel.pr = ctypes.cast(ctypes.pointer(rects), ctypes.POINTER(raw.v4l2_ext_rect)) - ioctl(fd, IOC.S_SELECTION, sel) - - -def get_selection( - fd, - buffer_type: BufferType, - target: SelectionTarget = SelectionTarget.CROP_DEFAULT, - max_nb: int = 128, -): - sel = raw.v4l2_selection() - sel.type = buffer_type - sel.target = target - sel.rectangles = max_nb - rects = (raw.v4l2_ext_rect * sel.rectangles)() - sel.pr = ctypes.cast(ctypes.pointer(rects), ctypes.POINTER(raw.v4l2_ext_rect)) - ioctl(fd, IOC.G_SELECTION, sel) - if sel.rectangles == 0: - return Rect( - left=sel.r.left, top=sel.r.top, width=sel.r.width, height=sel.r.height - ) - else: - return [ - Rect( - left=rects[i].r.left, - top=rects[i].r.top, - width=rects[i].r.width, - height=rects[i].r.height, - ) - for i in range(sel.rectangles) - ] - - -def get_control(fd, id): - control = raw.v4l2_control(id) - ioctl(fd, IOC.G_CTRL, control) - return control.value - - -def set_control(fd, id, value): - control = raw.v4l2_control(id, value) - ioctl(fd, IOC.S_CTRL, control) - - -def get_priority(fd) -> Priority: - priority = raw.enum() - ioctl(fd, IOC.G_PRIORITY, priority) - return Priority(priority.value) - - -def set_priority(fd, priority: Priority): - priority = raw.enum(priority.value) - ioctl(fd, IOC.S_PRIORITY, priority) - - -# Helpers - - -def create_buffer(fd, buffer_type: BufferType, memory: Memory) -> raw.v4l2_buffer: - """request + query buffers""" - buffers = create_buffers(fd, buffer_type, memory, 1) - return buffers[0] - - -def create_buffers( - fd, buffer_type: BufferType, memory: Memory, count: int -) -> typing.List[raw.v4l2_buffer]: - """request + query buffers""" - request_buffers(fd, buffer_type, memory, count) - return [query_buffer(fd, buffer_type, memory, index) for index in range(count)] - - -def mmap_from_buffer(fd, buff: raw.v4l2_buffer) -> mmap.mmap: - return mem_map(fd, buff.length, offset=buff.m.offset) - - -def create_mmap_buffers( - fd, buffer_type: BufferType, memory: Memory, count: int -) -> typing.List[mmap.mmap]: - """create buffers + mmap_from_buffer""" - return [ - mmap_from_buffer(fd, buff) - for buff in create_buffers(fd, buffer_type, memory, count) - ] - - -def create_mmap_buffer(fd, buffer_type: BufferType, memory: Memory) -> mmap.mmap: - return create_mmap_buffers(fd, buffer_type, memory, 1) - - -def enqueue_buffers( - fd, buffer_type: BufferType, memory: Memory, count: int -) -> typing.List[raw.v4l2_buffer]: - return [enqueue_buffer(fd, buffer_type, memory, index) for index in range(count)] - - -class ReentrantContextManager: - def __init__(self): - self._context_level = 0 - - def __enter__(self): - if not self._context_level: - self.open() - self._context_level += 1 - return self - - def __exit__(self, *exc): - self._context_level -= 1 - if not self._context_level: - self.close() - - -class Device(ReentrantContextManager): - def __init__(self, name_or_file, read_write=True, io=IO, legacy_controls=False): - super().__init__() - self.info = None - self.controls = None - self.io = io - if isinstance(name_or_file, (str, pathlib.Path)): - filename = pathlib.Path(name_or_file) - self._read_write = read_write - self._fobj = None - elif isinstance(name_or_file, IOBase): - filename = pathlib.Path(name_or_file.name) - self._read_write = "+" in name_or_file.mode - self._fobj = name_or_file - # this object context manager won't close the file anymore - self._context_level += 1 - self._init() - else: - raise TypeError( - f"name_or_file must be str or a file-like object, not {name_or_file.__class__.__name__}" - ) - self.log = log.getChild(filename.stem) - self.filename = filename - self.index = device_number(filename) - self.legacy_controls = legacy_controls - - def __repr__(self): - return f"<{type(self).__name__} name={self.filename}, closed={self.closed}>" - - def __iter__(self): - with VideoCapture(self) as stream: - yield from stream - - async def __aiter__(self): - with VideoCapture(self) as stream: - async for frame in stream: - yield frame - - @classmethod - def from_id(cls, did: int, **kwargs): - return cls("/dev/video{}".format(did), **kwargs) - - def _init(self): - self.info = read_info(self.fileno()) - if self.legacy_controls: - self.controls = LegacyControls.from_device(self) - else: - self.controls = Controls.from_device(self) - - def open(self): - if not self._fobj: - self.log.info("opening %s", self.filename) - self._fobj = self.io.open(self.filename, self._read_write) - self._init() - self.log.info("opened %s (%s)", self.filename, self.info.card) - - def close(self): - if not self.closed: - self.log.info("closing %s (%s)", self.filename, self.info.card) - self._fobj.close() - self._fobj = None - self.log.info("closed %s (%s)", self.filename, self.info.card) - - def fileno(self): - return self._fobj.fileno() - - @property - def closed(self): - return self._fobj is None or self._fobj.closed - - @property - def is_blocking(self): - return os.get_blocking(self.fileno()) - - def query_buffer(self, buffer_type, memory, index): - return query_buffer(self.fileno(), buffer_type, memory, index) - - def enqueue_buffer( - self, buffer_type: BufferType, memory: Memory, index: int - ) -> raw.v4l2_buffer: - return enqueue_buffer(self.fileno(), buffer_type, memory, index) - - def dequeue_buffer( - self, buffer_type: BufferType, memory: Memory - ) -> raw.v4l2_buffer: - return dequeue_buffer(self.fileno(), buffer_type, memory) - - def request_buffers(self, buffer_type, memory, size): - return request_buffers(self.fileno(), buffer_type, memory, size) - - def create_buffers( - self, buffer_type: BufferType, memory: Memory, count: int - ) -> typing.List[raw.v4l2_buffer]: - return create_buffers(self.fileno(), buffer_type, memory, count) - - def free_buffers(self, buffer_type, memory): - return free_buffers(self.fileno(), buffer_type, memory) - - def enqueue_buffers( - self, buffer_type: BufferType, memory: Memory, count: int - ) -> typing.List[raw.v4l2_buffer]: - return enqueue_buffers(self.fileno(), buffer_type, memory, count) - - def set_format( - self, - buffer_type: BufferType, - width: int, - height: int, - pixel_format: str = "MJPG", - ): - return set_format( - self.fileno(), buffer_type, width, height, pixel_format=pixel_format - ) - - def get_format(self, buffer_type): - return get_format(self.fileno(), buffer_type) - - def set_fps(self, buffer_type, fps): - return set_fps(self.fileno(), buffer_type, fps) - - def get_fps(self, buffer_type): - return get_fps(self.fileno(), buffer_type) - - def set_selection(self, buffer_type, rectangles): - return set_selection(self.fileno(), buffer_type, rectangles) - - def get_selection(self, buffer_type, target): - return get_selection(self.fileno(), buffer_type, target) - - def get_priority(self) -> Priority: - return get_priority(self.fileno()) - - def set_priority(self, priority: Priority): - set_priority(self.fileno(), priority) - - def stream_on(self, buffer_type): - self.log.info("Starting %r stream...", buffer_type.name) - stream_on(self.fileno(), buffer_type) - self.log.info("%r stream ON", buffer_type.name) - - def stream_off(self, buffer_type): - self.log.info("Stoping %r stream...", buffer_type.name) - stream_off(self.fileno(), buffer_type) - self.log.info("%r stream OFF", buffer_type.name) - - def write(self, data: bytes) -> None: - self._fobj.write(data) - - -class Controls(dict): - @classmethod - def from_device(cls, device): - ctrl_type_map = { - ControlType.BOOLEAN: BooleanControl, - ControlType.INTEGER: IntegerControl, - ControlType.INTEGER64: Integer64Control, - ControlType.MENU: MenuControl, - ControlType.INTEGER_MENU: MenuControl, - ControlType.U8: U8Control, - ControlType.U16: U16Control, - ControlType.U32: U32Control, - } - ctrl_dict = dict() - - for ctrl in device.info.controls: - ctrl_type = ControlType(ctrl.type) - ctrl_class = ctrl_type_map.get(ctrl_type, GenericControl) - ctrl_dict[ctrl.id] = ctrl_class(device, ctrl) - - return cls(ctrl_dict) - - def __getattr__(self, key): - try: - return self[key] - except KeyError: - pass - raise AttributeError( - f"'{self.__class__.__name__}' object has no attribute '{key}'" - ) - - def __setattr__(self, key, value): - self[key] = value - - def __delattr__(self, key): - try: - del self[key] - except KeyError: - raise AttributeError(key) - - def __missing__(self, key): - for v in self.values(): - if isinstance(v, BaseControl) and (v.config_name == key): - return v - raise KeyError(key) - - def used_classes(self): - return {v.control_class for v in self.values() if isinstance(v, BaseControl)} - - def with_class(self, control_class): - if isinstance(control_class, ControlClass): - pass - elif isinstance(control_class, str): - cl = [c for c in ControlClass if c.name == control_class.upper()] - if len(cl) != 1: - raise ValueError(f"{control_class} is no valid ControlClass") - control_class = cl[0] - else: - raise TypeError( - f"control_class expected as ControlClass or str, not {control_class.__class__.__name__}" - ) - - for v in self.values(): - if isinstance(v, BaseControl) and (v.control_class == control_class): - yield v - - def set_to_default(self): - for v in self.values(): - if not isinstance(v, BaseControl): - continue - - try: - v.set_to_default() - except AttributeError: - pass - - def set_clipping(self, clipping: bool) -> None: - for v in self.values(): - if isinstance(v, BaseNumericControl): - v.clipping = clipping - - -class LegacyControls(Controls): - @classmethod - def from_device(cls, device): - ctrl_dict = dict() - for ctrl in device.info.controls: - ctrl_dict[ctrl.id] = LegacyControl(device, ctrl) - return cls(ctrl_dict) - - -class BaseControl: - def __init__(self, device, info): - self.device = device - self._info = info - self.id = self._info.id - self.name = self._info.name.decode() - self._config_name = None - self.control_class = ControlClass(raw.V4L2_CTRL_ID2CLASS(self.id)) - self.type = ControlType(self._info.type) - - try: - self.standard = ControlID(self.id) - except ValueError: - self.standard = None - - def __repr__(self): - repr = f"{self.config_name}" - - addrepr = self._get_repr() - addrepr = addrepr.strip() - if addrepr: - repr += f" {addrepr}" - - flags = [ - flag.name.lower() - for flag in ControlFlag - if ((self._info.flags & flag) == flag) - ] - if flags: - repr += " flags=" + ",".join(flags) - - return f"<{type(self).__name__} {repr}>" - - def _get_repr(self) -> str: - return "" - - def _get_control(self): - value = get_control(self.device, self.id) - return value - - def _set_control(self, value): - if not self.is_writeable: - reasons = [] - if self.is_flagged_read_only: - reasons.append("read-only") - if self.is_flagged_inactive: - reasons.append("inactive") - if self.is_flagged_disabled: - reasons.append("disabled") - if self.is_flagged_grabbed: - reasons.append("grabbed") - raise AttributeError( - f"{self.__class__.__name__} {self.config_name} is not writeable: {', '.join(reasons)}" - ) - set_control(self.device, self.id, value) - - @property - def config_name(self) -> str: - if self._config_name is None: - res = self.name.lower() - for r in ("(", ")"): - res = res.replace(r, "") - for r in (", ", " "): - res = res.replace(r, "_") - self._config_name = res - return self._config_name - - @property - def is_flagged_disabled(self) -> bool: - return (self._info.flags & ControlFlag.DISABLED) == ControlFlag.DISABLED - - @property - def is_flagged_grabbed(self) -> bool: - return (self._info.flags & ControlFlag.GRABBED) == ControlFlag.GRABBED - - @property - def is_flagged_read_only(self) -> bool: - return (self._info.flags & ControlFlag.READ_ONLY) == ControlFlag.READ_ONLY - - @property - def is_flagged_update(self) -> bool: - return (self._info.flags & ControlFlag.UPDATE) == ControlFlag.UPDATE - - @property - def is_flagged_inactive(self) -> bool: - return (self._info.flags & ControlFlag.INACTIVE) == ControlFlag.INACTIVE - - @property - def is_flagged_slider(self) -> bool: - return (self._info.flags & ControlFlag.SLIDER) == ControlFlag.SLIDER - - @property - def is_flagged_write_only(self) -> bool: - return (self._info.flags & ControlFlag.WRITE_ONLY) == ControlFlag.WRITE_ONLY - - @property - def is_flagged_volatile(self) -> bool: - return (self._info.flags & ControlFlag.VOLATILE) == ControlFlag.VOLATILE - - @property - def is_flagged_has_payload(self) -> bool: - return (self._info.flags & ControlFlag.HAS_PAYLOAD) == ControlFlag.HAS_PAYLOAD - - @property - def is_flagged_execute_on_write(self) -> bool: - return ( - self._info.flags & ControlFlag.EXECUTE_ON_WRITE - ) == ControlFlag.EXECUTE_ON_WRITE - - @property - def is_flagged_modify_layout(self) -> bool: - return ( - self._info.flags & ControlFlag.MODIFY_LAYOUT - ) == ControlFlag.MODIFY_LAYOUT - - @property - def is_flagged_dynamic_array(self) -> bool: - return ( - self._info.flags & ControlFlag.DYNAMIC_ARRAY - ) == ControlFlag.DYNAMIC_ARRAY - - @property - def is_writeable(self) -> bool: - return not ( - self.is_flagged_read_only - or self.is_flagged_inactive - or self.is_flagged_disabled - or self.is_flagged_grabbed - ) - - -class BaseMonoControl(BaseControl): - def _get_repr(self) -> str: - repr = f" default={self.default}" - if not self.is_flagged_write_only: - repr += f" value={self.value}" - return repr - - def _convert_read(self, value): - return value - - @property - def default(self): - return self._convert_read(self._info.default_value) - - @property - def value(self): - if not self.is_flagged_write_only: - v = self._get_control() - return self._convert_read(v) - else: - return None - - def _convert_write(self, value): - return value - - def _mangle_write(self, value): - return value - - @value.setter - def value(self, value): - v = self._convert_write(value) - v = self._mangle_write(v) - self._set_control(v) - - def set_to_default(self): - self.value = self.default - - -class GenericControl(BaseMonoControl): - pass - - -class BaseNumericControl(BaseMonoControl): - lower_bound = -(2**31) - upper_bound = 2**31 - 1 - - def __init__(self, device, info, clipping=True): - super().__init__(device, info) - self.minimum = self._info.minimum - self.maximum = self._info.maximum - self.step = self._info.step - self.clipping = clipping - - if self.minimum < self.lower_bound: - raise RuntimeWarning( - f"Control {self.config_name}'s claimed minimum value {self.minimum} exceeds lower bound of {self.__class__.__name__}" - ) - if self.maximum > self.upper_bound: - raise RuntimeWarning( - f"Control {self.config_name}'s claimed maximum value {self.maximum} exceeds upper bound of {self.__class__.__name__}" - ) - - def _get_repr(self) -> str: - repr = f" min={self.minimum} max={self.maximum} step={self.step}" - repr += super()._get_repr() - return repr - - def _convert_read(self, value): - return int(value) - - def _convert_write(self, value): - if isinstance(value, int): - return value - else: - try: - v = int(value) - except Exception: - pass - else: - return v - raise ValueError( - f"Failed to coerce {value.__class__.__name__} '{value}' to int" - ) - - def _mangle_write(self, value): - if self.clipping: - if value < self.minimum: - return self.minimum - elif value > self.maximum: - return self.maximum - else: - if value < self.minimum: - raise ValueError( - f"Control {self.config_name}: {value} exceeds allowed minimum {self.minimum}" - ) - elif value > self.maximum: - raise ValueError( - f"Control {self.config_name}: {value} exceeds allowed maximum {self.maximum}" - ) - return value - - def increase(self, steps: int = 1): - self.value += steps * self.step - - def decrease(self, steps: int = 1): - self.value -= steps * self.step - - def set_to_minimum(self): - self.value = self.minimum - - def set_to_maximum(self): - self.value = self.maximum - - -class IntegerControl(BaseNumericControl): - lower_bound = -(2**31) - upper_bound = 2**31 - 1 - - -class Integer64Control(BaseNumericControl): - lower_bound = -(2**63) - upper_bound = 2**63 - 1 - - -class U8Control(BaseNumericControl): - lower_bound = 0 - upper_bound = 2**8 - - -class U16Control(BaseNumericControl): - lower_bound = 0 - upper_bound = 2**16 - - -class U32Control(BaseNumericControl): - lower_bound = 0 - upper_bound = 2**32 - - -class BooleanControl(BaseMonoControl): - _true = ["true", "1", "yes", "on", "enable"] - _false = ["false", "0", "no", "off", "disable"] - - def _convert_read(self, value): - return bool(value) - - def _convert_write(self, value): - if isinstance(value, bool): - return value - elif isinstance(value, str): - if value in self._true: - return True - elif value in self._false: - return False - else: - try: - v = bool(value) - except Exception: - pass - else: - return v - raise ValueError( - f"Failed to coerce {value.__class__.__name__} '{value}' to bool" - ) - - -class MenuControl(BaseMonoControl, UserDict): - def __init__(self, device, info): - BaseControl.__init__(self, device, info) - UserDict.__init__(self) - - if self.type == ControlType.MENU: - self.data = { - item.index: item.name.decode() - for item in iter_read_menu(self.device._fobj, self) - } - elif self.type == ControlType.INTEGER_MENU: - self.data = { - item.index: int(item.name) - for item in iter_read_menu(self.device._fobj, self) - } - else: - raise TypeError( - f"MenuControl only supports control types MENU or INTEGER_MENU, but not {self.type.name}" - ) - - def _convert_write(self, value): - return int(value) - - -class ButtonControl(BaseControl): - def push(self): - self._set_control(1) - - -class BaseCompoundControl(BaseControl): - def __init__(self, device, info): - raise NotImplementedError() - - -class LegacyMenuItem: - def __init__(self, item: raw.v4l2_querymenu): - self.item = item - self.index = item.index - self.name = item.name.decode() - - def __repr__(self) -> str: - return f"<{type(self).__name__} index={self.index} name={self.name}>" - - -class LegacyControl(BaseNumericControl): - def __init__(self, device, info): - super().__init__(device, info) - - self.info = self._info - if self.type == ControlType.MENU: - self.menu = { - menu.index: LegacyMenuItem(menu) - for menu in iter_read_menu(self.device._fobj, self) - } - else: - self.menu = {} - - def _get_repr(self) -> str: - repr = f"type={self.type.name.lower()}" - repr += super()._get_repr() - return repr - - @property - def is_writeonly(self) -> bool: - return self.is_flagged_write_only - - @property - def is_readonly(self) -> bool: - return self.is_flagged_read_only - - @property - def is_inactive(self) -> bool: - return self.is_flagged_inactive - - @property - def is_grabbed(self) -> bool: - return self.is_flagged_grabbed - - @property - def is_disabled(self) -> bool: - return self.is_flagged_disabled - - def increase(self, steps: int = 1): - self.value += steps * self.step - - def decrease(self, steps: int = 1): - self.value -= steps * self.step - - -class DeviceHelper: - def __init__(self, device: Device): - super().__init__() - self.device = device - - -class BufferManager(DeviceHelper): - def __init__(self, device: Device, buffer_type: BufferType, size: int = 2): - super().__init__(device) - self.type = buffer_type - self.size = size - self.buffers = None - self.name = type(self).__name__ - - def formats(self): - formats = self.device.info.formats - return [fmt for fmt in formats if fmt.type == self.type] - - def crop_capabilities(self): - crop_capabilities = self.device.info.crop_capabilities - return [crop for crop in crop_capabilities if crop.type == self.type] - - def query_buffer(self, memory, index): - return self.device.query_buffer(self.type, memory, index) - - def enqueue_buffer(self, memory: Memory, index: int) -> raw.v4l2_buffer: - return self.device.enqueue_buffer(self.type, memory, index) - - def dequeue_buffer(self, memory: Memory) -> raw.v4l2_buffer: - return self.device.dequeue_buffer(self.type, memory) - - def enqueue_buffers(self, memory: Memory) -> typing.List[raw.v4l2_buffer]: - return self.device.enqueue_buffers(self.type, memory, self.size) - - def free_buffers(self, memory: Memory): - result = self.device.free_buffers(self.type, memory) - self.buffers = None - return result - - def create_buffers(self, memory: Memory): - if self.buffers: - raise V4L2Error("buffers already requested. free first") - self.buffers = self.device.create_buffers(self.type, memory, self.size) - return self.buffers - - def set_format(self, width, height, pixel_format="MJPG"): - return self.device.set_format(self.type, width, height, pixel_format) - - def get_format(self): - return self.device.get_format(self.type) - - def set_fps(self, fps): - return self.device.set_fps(self.type, fps) - - def get_fps(self): - return self.device.get_fps(self.type) - - def set_selection(self, rectangles): - return self.device.set_selection(self.type, rectangles) - - def get_selection(self): - return self.device.get_selection(self.type) - - def stream_on(self): - self.device.stream_on(self.type) - - def stream_off(self): - self.device.stream_off(self.type) - - start = stream_on - stop = stream_off - - def write(self, data: bytes) -> None: - self.device.write(data) - - -class Frame: - __slots__ = ["format", "buff", "data"] - - def __init__(self, data: bytes, buff: raw.v4l2_buffer, format: Format): - self.format = format - self.buff = buff - self.data = data - - def __bytes__(self): - return self.data - - def __len__(self): - return len(self.data) - - def __getitem__(self, index): - return self.data[index] - - def __repr__(self) -> str: - return ( - f"<{type(self).__name__} width={self.width}, height={self.height}, " - f"format={self.pixel_format.name}, frame_nb={self.frame_nb}, timestamp={self.timestamp}>" - ) - - @property - def width(self): - return self.format.width - - @property - def height(self): - return self.format.height - - @property - def nbytes(self): - return self.buff.bytesused - - @property - def pixel_format(self): - return PixelFormat(self.format.pixel_format) - - @property - def index(self): - return self.buff.index - - @property - def type(self): - return BufferType(self.buff.type) - - @property - def flags(self): - return BufferFlag(self.buff.flags) - - @property - def timestamp(self): - return self.buff.timestamp.secs + self.buff.timestamp.usecs * 1e-6 - - @property - def frame_nb(self): - return self.buff.sequence - - @property - def memory(self): - return Memory(self.buff.memory) - - @property - def time_type(self): - if BufferFlag.TIMECODE in self.flags: - return TimeCode(self.buff.timecode.type) - - @property - def time_flags(self): - if BufferFlag.TIMECODE in self.flags: - return TimeFlag(self.buff.timecode.flags) - - @property - def time_frame(self): - if BufferFlag.TIMECODE in self.flags: - return self.buff.timecode.frames - - @property - def array(self): - import numpy - - return numpy.frombuffer(bytes(self), dtype="u1") - - -class VideoCapture(BufferManager): - def __init__(self, device: Device, size: int = 2): - super().__init__(device, BufferType.VIDEO_CAPTURE, size) - self.buffer = None - - def __enter__(self): - self.open() - return self - - def __exit__(self, *exc): - self.close() - - def __iter__(self): - yield from self.buffer - - async def __aiter__(self): - async for frame in self.buffer: - yield frame - - def open(self): - if self.buffer is None: - self.device.log.info("Preparing for video capture...") - self.buffer = MemoryMap(self) - self.buffer.open() - self.stream_on() - self.device.log.info("Video capture started!") - - def close(self): - if self.buffer: - self.device.log.info("Closing video capture...") - self.stream_off() - self.buffer.close() - self.buffer = None - self.device.log.info("Video capture closed") - - -class MemoryMap(ReentrantContextManager): - def __init__(self, buffer_manager: BufferManager): - super().__init__() - self.buffer_manager = buffer_manager - self.buffers = None - self.reader = QueueReader(buffer_manager, Memory.MMAP) - - @property - def device(self) -> Device: - return self.buffer_manager.device - - def __iter__(self): - while True: - yield self.read() - - async def __aiter__(self): - device = self.device.fileno() - loop = asyncio.get_event_loop() - event = asyncio.Event() - frame = None - - def cb(): - nonlocal frame - frame = self.raw_read() - event.set() - - loop.add_reader(device, cb) - try: - while True: - await event.wait() - event.clear() - yield frame - frame = None - finally: - loop.remove_reader(device) - - def open(self): - if self.buffers is None: - self.device.log.info("Reserving buffers...") - fd = self.device.fileno() - buffers = self.buffer_manager.create_buffers(Memory.MMAP) - self.buffers = [mmap_from_buffer(fd, buff) for buff in buffers] - self.buffer_manager.enqueue_buffers(Memory.MMAP) - self.format = self.buffer_manager.get_format() - self.buffer_manager.device.log.info("Buffers reserved") - - def close(self): - if self.buffers: - self.device.log.info("Freeing buffers...") - for mem in self.buffers: - mem.close() - self.buffer_manager.free_buffers(Memory.MMAP) - self.buffers = None - self.format = None - self.device.log.info("Buffers freed") - - def raw_grab(self): - with self.reader as buff: - return self.buffers[buff.index][: buff.bytesused], buff - - def raw_read(self): - data, buff = self.raw_grab() - return Frame(data, buff, self.format) - - def wait_read(self): - device = self.device - if device.io.select is not None: - device.io.select((device,), (), ()) - return self.raw_read() - - def read(self): - # first time we check what mode device was opened (blocking vs non-blocking) - # if file was opened with O_NONBLOCK: DQBUF will not block until a buffer - # is available for read. So we need to do it here - if self.device.is_blocking: - self.read = self.raw_read - else: - self.read = self.wait_read - return self.read() - - -class QueueReader: - def __init__(self, buffer_manager: BufferManager, memory: Memory): - self.buffer_manager = buffer_manager - self.memory = memory - self.index = None - - def __enter__(self): - # get next buffer that has some data in it - buffer = self.buffer_manager.dequeue_buffer(self.memory) - self.index = buffer.index - return buffer - - def __exit__(self, *exc): - self.buffer_manager.enqueue_buffer(self.memory, self.index) - self.index = None - - -class VideoOutput(BufferManager): - def __init__(self, device: Device, size: int = 2): - super().__init__(device, BufferType.VIDEO_OUTPUT, size) - self.buffer = None - - -def device_number(path): - num = "" - for c in str(path)[::-1]: - if c.isdigit(): - num = c + num - else: - break - return int(num) if num else None - - -def iter_video_files(path="/dev"): - path = pathlib.Path(path) - return sorted(path.glob("video*")) - - -def iter_devices(path="/dev", **kwargs): - return (Device(name, **kwargs) for name in iter_video_files(path=path)) - - -def iter_video_capture_files(path="/dev"): - def filt(filename): - with fopen(filename) as fobj: - caps = read_capabilities(fobj.fileno()) - return Capability.VIDEO_CAPTURE in Capability(caps.device_caps) - - return filter(filt, iter_video_files(path)) - - -def iter_video_capture_devices(path="/dev", **kwargs): - return (Device(name, **kwargs) for name in iter_video_capture_files(path)) +from linuxpy.device import device_number +from linuxpy.video.device import * diff --git a/v4l2py/io.py b/v4l2py/io.py index 6d4fb29..95ad3d7 100644 --- a/v4l2py/io.py +++ b/v4l2py/io.py @@ -4,37 +4,6 @@ # Copyright (c) 2021 Tiago Coutinho # Distributed under the GPLv3 license. See LICENSE for more info. -import functools -import os -import select +# ruff: noqa: F403 - -def fopen(path, rw=False, blocking=False): - kwargs = {"buffering": 0} - if not blocking: - - def opener(path, flags): - return os.open(path, flags | os.O_NONBLOCK) - - kwargs["opener"] = opener - return open(path, "rb+" if rw else "rb", **kwargs) - - -class IO: - open = functools.partial(fopen, blocking=False) - select = select.select - - -class GeventIO: - @staticmethod - def open(path, rw=False): - mode = "rb+" if rw else "rb" - import gevent.fileobject - - return gevent.fileobject.FileObject(path, mode, buffering=0) - - @staticmethod - def select(*args, **kwargs): - import gevent.select - - return gevent.select.select(*args, **kwargs) +from linuxpy.io import * diff --git a/v4l2py/raw.py b/v4l2py/raw.py index 8eb1db0..f47bf0c 100644 --- a/v4l2py/raw.py +++ b/v4l2py/raw.py @@ -4,2160 +4,6 @@ # Copyright (c) 2021 Tiago Coutinho # Distributed under the GPLv3 license. See LICENSE for more info. -import ctypes +# ruff: noqa: F403 -_IOC_NRBITS = 8 -_IOC_TYPEBITS = 8 -_IOC_SIZEBITS = 14 -_IOC_DIRBITS = 2 - -_IOC_NRSHIFT = 0 -_IOC_TYPESHIFT = _IOC_NRSHIFT + _IOC_NRBITS -_IOC_SIZESHIFT = _IOC_TYPESHIFT + _IOC_TYPEBITS -_IOC_DIRSHIFT = _IOC_SIZESHIFT + _IOC_SIZEBITS - -_IOC_NONE = 0 -_IOC_WRITE = 1 -_IOC_READ = 2 - - -def _IOC(dir_, type_, nr, size): - return ( - ctypes.c_int32(dir_ << _IOC_DIRSHIFT).value - | ctypes.c_int32(ord(type_) << _IOC_TYPESHIFT).value - | ctypes.c_int32(nr << _IOC_NRSHIFT).value - | ctypes.c_int32(size << _IOC_SIZESHIFT).value - ) - - -def _IOC_TYPECHECK(t): - return ctypes.sizeof(t) - - -def _IO(type_, nr): - return _IOC(_IOC_NONE, type_, nr, 0) - - -def _IOW(type_, nr, size): - return _IOC(_IOC_WRITE, type_, nr, _IOC_TYPECHECK(size)) - - -def _IOR(type_, nr, size): - return _IOC(_IOC_READ, type_, nr, _IOC_TYPECHECK(size)) - - -def _IOWR(type_, nr, size): - return _IOC(_IOC_READ | _IOC_WRITE, type_, nr, _IOC_TYPECHECK(size)) - - -# -# type alias -# - -enum = ctypes.c_uint -c_int = ctypes.c_int - - -# -# time -# - - -class timeval(ctypes.Structure): - _fields_ = [ - ("secs", ctypes.c_long), - ("usecs", ctypes.c_long), - ] - - -# -# v4l2 -# - - -VIDEO_MAX_FRAME = 32 - - -VID_TYPE_CAPTURE = 1 -VID_TYPE_TUNER = 2 -VID_TYPE_TELETEXT = 4 -VID_TYPE_OVERLAY = 8 -VID_TYPE_CHROMAKEY = 16 -VID_TYPE_CLIPPING = 32 -VID_TYPE_FRAMERAM = 64 -VID_TYPE_SCALES = 128 -VID_TYPE_MONOCHROME = 256 -VID_TYPE_SUBCAPTURE = 512 -VID_TYPE_MPEG_DECODER = 1024 -VID_TYPE_MPEG_ENCODER = 2048 -VID_TYPE_MJPEG_DECODER = 4096 -VID_TYPE_MJPEG_ENCODER = 8192 - - -def v4l2_fourcc(a, b, c, d): - return ord(a) | (ord(b) << 8) | (ord(c) << 16) | (ord(d) << 24) - - -def v4l2_fourcc2str(fourcc): - a = chr(fourcc & 0xFF) - b = chr((fourcc >> 8) & 0xFF) - c = chr((fourcc >> 16) & 0xFF) - d = chr((fourcc >> 24) & 0xFF) - return "".join([a, b, c, d]) - - -v4l2_field = enum -( - V4L2_FIELD_ANY, - V4L2_FIELD_NONE, - V4L2_FIELD_TOP, - V4L2_FIELD_BOTTOM, - V4L2_FIELD_INTERLACED, - V4L2_FIELD_SEQ_TB, - V4L2_FIELD_SEQ_BT, - V4L2_FIELD_ALTERNATE, - V4L2_FIELD_INTERLACED_TB, - V4L2_FIELD_INTERLACED_BT, -) = range(10) - - -def V4L2_FIELD_HAS_TOP(field): - return ( - field == V4L2_FIELD_TOP - or field == V4L2_FIELD_INTERLACED - or field == V4L2_FIELD_INTERLACED_TB - or field == V4L2_FIELD_INTERLACED_BT - or field == V4L2_FIELD_SEQ_TB - or field == V4L2_FIELD_SEQ_BT - ) - - -def V4L2_FIELD_HAS_BOTTOM(field): - return ( - field == V4L2_FIELD_BOTTOM - or field == V4L2_FIELD_INTERLACED - or field == V4L2_FIELD_INTERLACED_TB - or field == V4L2_FIELD_INTERLACED_BT - or field == V4L2_FIELD_SEQ_TB - or field == V4L2_FIELD_SEQ_BT - ) - - -def V4L2_FIELD_HAS_BOTH(field): - return ( - field == V4L2_FIELD_INTERLACED - or field == V4L2_FIELD_INTERLACED_TB - or field == V4L2_FIELD_INTERLACED_BT - or field == V4L2_FIELD_SEQ_TB - or field == V4L2_FIELD_SEQ_BT - ) - - -v4l2_buf_type = enum -( - V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_BUF_TYPE_VIDEO_OUTPUT, - V4L2_BUF_TYPE_VIDEO_OVERLAY, - V4L2_BUF_TYPE_VBI_CAPTURE, - V4L2_BUF_TYPE_VBI_OUTPUT, - V4L2_BUF_TYPE_SLICED_VBI_CAPTURE, - V4L2_BUF_TYPE_SLICED_VBI_OUTPUT, - V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY, - V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, - V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, - V4L2_BUF_TYPE_SDR_CAPTURE, - V4L2_BUF_TYPE_SDR_OUTPUT, - V4L2_BUF_TYPE_META_CAPTURE, -) = range(1, 14) - - -v4l2_ctrl_type = enum -( - V4L2_CTRL_TYPE_INTEGER, - V4L2_CTRL_TYPE_BOOLEAN, - V4L2_CTRL_TYPE_MENU, - V4L2_CTRL_TYPE_BUTTON, - V4L2_CTRL_TYPE_INTEGER64, - V4L2_CTRL_TYPE_CTRL_CLASS, - V4L2_CTRL_TYPE_STRING, - V4L2_CTRL_TYPE_BITMASK, - V4L2_CTRL_TYPE_INTEGER_MENU, -) = range(1, 10) - - -# Compound types are >= 0x0100 -V4L2_CTRL_COMPOUND_TYPES = 0x0100 -V4L2_CTRL_TYPE_U8 = 0x0100 -V4L2_CTRL_TYPE_U16 = 0x0101 -V4L2_CTRL_TYPE_U32 = 0x0102 -V4L2_CTRL_TYPE_AREA = 0x0106 -V4L2_CTRL_TYPE_HDR10_CLL_INFO = 0x0110 -V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY = 0x0111 -V4L2_CTRL_TYPE_H264_SPS = 0x0200 -V4L2_CTRL_TYPE_H264_PPS = 0x0201 -V4L2_CTRL_TYPE_H264_SCALING_MATRIX = 0x0202 -V4L2_CTRL_TYPE_H264_SLICE_PARAMS = 0x0203 -V4L2_CTRL_TYPE_H264_DECODE_PARAMS = 0x0204 -V4L2_CTRL_TYPE_H264_PRED_WEIGHTS = 0x0205 -V4L2_CTRL_TYPE_FWHT_PARAMS = 0x0220 -V4L2_CTRL_TYPE_VP8_FRAME = 0x0240 -V4L2_CTRL_TYPE_MPEG2_QUANTISATION = 0x0250 -V4L2_CTRL_TYPE_MPEG2_SEQUENCE = 0x0251 -V4L2_CTRL_TYPE_MPEG2_PICTURE = 0x0252 -V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR = 0x0260 -V4L2_CTRL_TYPE_VP9_FRAME = 0x0261 -V4L2_CTRL_TYPE_HEVC_SPS = 0x0270 -V4L2_CTRL_TYPE_HEVC_PPS = 0x0271 -V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS = 0x0272 -V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX = 0x0273 -V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS = 0x0274 - -v4l2_tuner_type = enum -( - V4L2_TUNER_RADIO, - V4L2_TUNER_ANALOG_TV, - V4L2_TUNER_DIGITAL_TV, -) = range(1, 4) - - -v4l2_memory = enum -( - V4L2_MEMORY_MMAP, - V4L2_MEMORY_USERPTR, - V4L2_MEMORY_OVERLAY, - V4L2_MEMORY_DMABUF, -) = range(1, 5) - - -v4l2_colorspace = enum -( - # Default colorspace, i.e. let the driver figure it out. - # Can only be used with video capture. - V4L2_COLORSPACE_DEFAULT, - # SMPTE 170M: used for broadcast NTSC/PAL SDTV - V4L2_COLORSPACE_SMPTE170M, - # Obsolete pre-1998 SMPTE 240M HDTV standard, superseded by Rec 709 - V4L2_COLORSPACE_SMPTE240M, - # Rec.709: used for HDTV - V4L2_COLORSPACE_REC709, - # Deprecated, do not use. No driver will ever return this. This was - # based on a misunderstanding of the bt878 datasheet. - V4L2_COLORSPACE_BT878, - # NTSC 1953 colorspace. This only makes sense when dealing with - # really, really old NTSC recordings. Superseded by SMPTE 170M. - V4L2_COLORSPACE_470_SYSTEM_M, - # EBU Tech 3213 PAL/SECAM colorspace. This only makes sense when - # dealing with really old PAL/SECAM recordings. Superseded by - # SMPTE 170M. - V4L2_COLORSPACE_470_SYSTEM_BG, - # Effectively shorthand for V4L2_COLORSPACE_SRGB, V4L2_YCBCR_ENC_601 - # and V4L2_QUANTIZATION_FULL_RANGE. To be used for (Motion-)JPEG. - V4L2_COLORSPACE_JPEG, - # For RGB colorspaces such as produces by most webcams. - V4L2_COLORSPACE_SRGB, - # AdobeRGB colorspace - V4L2_COLORSPACE_ADOBERGB, - # BT.2020 colorspace, used for UHDTV. - V4L2_COLORSPACE_BT2020, - # Raw colorspace: for RAW unprocessed images - V4L2_COLORSPACE_RAW, - # DCI-P3 colorspace, used by cinema projectors - V4L2_COLORSPACE_DCI_P3, -) = range(0, 13) - - -v4l2_priority = enum -( - V4L2_PRIORITY_UNSET, - V4L2_PRIORITY_BACKGROUND, - V4L2_PRIORITY_INTERACTIVE, - V4L2_PRIORITY_RECORD, - V4L2_PRIORITY_DEFAULT, -) = list(range(0, 4)) + [2] - - -class v4l2_rect(ctypes.Structure): - _fields_ = [ - ("left", ctypes.c_int32), - ("top", ctypes.c_int32), - ("width", ctypes.c_int32), - ("height", ctypes.c_int32), - ] - - -class v4l2_ext_rect(ctypes.Structure): - _fields_ = [ - ("r", v4l2_rect), - ("reserved", ctypes.c_int32 * 4), - ] - - -class v4l2_fract(ctypes.Structure): - _fields_ = [ - ("numerator", ctypes.c_uint32), - ("denominator", ctypes.c_uint32), - ] - - -# -# Driver capabilities -# - - -class v4l2_capability(ctypes.Structure): - _fields_ = [ - ("driver", ctypes.c_char * 16), - ("card", ctypes.c_char * 32), - ("bus_info", ctypes.c_char * 32), - ("version", ctypes.c_uint32), - ("capabilities", ctypes.c_uint32), - ("device_caps", ctypes.c_uint32), - ("reserved", ctypes.c_uint32 * 3), - ] - - -# -# Values for 'capabilities' field -# -V4L2_CAP_VIDEO_CAPTURE = 0x00000001 # Is a video capture device -V4L2_CAP_VIDEO_OUTPUT = 0x00000002 # Is a video output device -V4L2_CAP_VIDEO_OVERLAY = 0x00000004 # Can do video overlay -V4L2_CAP_VBI_CAPTURE = 0x00000010 # Is a raw VBI capture device -V4L2_CAP_VBI_OUTPUT = 0x00000020 # Is a raw VBI output device -V4L2_CAP_SLICED_VBI_CAPTURE = 0x00000040 # Is a sliced VBI capture device -V4L2_CAP_SLICED_VBI_OUTPUT = 0x00000080 # Is a sliced VBI output device -V4L2_CAP_RDS_CAPTURE = 0x00000100 # RDS data capture -V4L2_CAP_VIDEO_OUTPUT_OVERLAY = 0x00000200 # Can do video output overlay -V4L2_CAP_HW_FREQ_SEEK = 0x00000400 # Can do hardware frequency seek -V4L2_CAP_RDS_OUTPUT = 0x00000800 # Is an RDS encoder -V4L2_CAP_VIDEO_CAPTURE_MPLANE = ( - 0x00001000 # Is a video capture device that supports multiplanar formats -) -V4L2_CAP_VIDEO_OUTPUT_MPLANE = ( - 0x00002000 # Is a video output device that supports multiplanar formats -) -V4L2_CAP_VIDEO_M2M_MPLANE = ( - 0x00004000 # Is a video mem-to-mem device that supports multiplanar formats -) -V4L2_CAP_VIDEO_M2M = 0x00008000 # Is a video mem-to-mem device -V4L2_CAP_TUNER = 0x00010000 # has a tuner -V4L2_CAP_AUDIO = 0x00020000 # has audio support -V4L2_CAP_RADIO = 0x00040000 # is a radio device -V4L2_CAP_MODULATOR = 0x00080000 # has a modulator -V4L2_CAP_SDR_CAPTURE = 0x00100000 # Is a SDR capture device -V4L2_CAP_EXT_PIX_FORMAT = 0x00200000 # Supports the extended pixel format -V4L2_CAP_SDR_OUTPUT = 0x00400000 # Is a SDR output device -V4L2_CAP_META_CAPTURE = 0x00800000 # Is a metadata capture device -V4L2_CAP_READWRITE = 0x01000000 # read/write systemcalls -V4L2_CAP_ASYNCIO = 0x02000000 # async I/O -V4L2_CAP_STREAMING = 0x04000000 # streaming I/O ioctls -V4L2_CAP_TOUCH = 0x10000000 # Is a touch device -V4L2_CAP_DEVICE_CAPS = 0x80000000 # sets device capabilities field - - -# -# Video image format -# - - -class v4l2_pix_format(ctypes.Structure): - _fields_ = [ - ("width", ctypes.c_uint32), - ("height", ctypes.c_uint32), - ("pixelformat", ctypes.c_uint32), - ("field", v4l2_field), - ("bytesperline", ctypes.c_uint32), - ("sizeimage", ctypes.c_uint32), - ("colorspace", v4l2_colorspace), - ("priv", ctypes.c_uint32), - ] - - -# RGB formats -V4L2_PIX_FMT_RGB332 = v4l2_fourcc("R", "G", "B", "1") -V4L2_PIX_FMT_ARGB444 = v4l2_fourcc("A", "R", "1", "2") -V4L2_PIX_FMT_XRGB444 = v4l2_fourcc("X", "R", "1", "2") -V4L2_PIX_FMT_RGBA444 = v4l2_fourcc("R", "A", "1", "2") -V4L2_PIX_FMT_RGBX444 = v4l2_fourcc("R", "X", "1", "2") -V4L2_PIX_FMT_ABGR444 = v4l2_fourcc("A", "B", "1", "2") -V4L2_PIX_FMT_XBGR444 = v4l2_fourcc("X", "B", "1", "2") -V4L2_PIX_FMT_BGRA444 = v4l2_fourcc("B", "A", "1", "2") -V4L2_PIX_FMT_BGRX444 = v4l2_fourcc("B", "X", "1", "2") - -V4L2_PIX_FMT_ARGB555 = v4l2_fourcc("A", "R", "1", "5") -V4L2_PIX_FMT_XRGB555 = v4l2_fourcc("X", "R", "1", "5") -V4L2_PIX_FMT_RGBA555 = v4l2_fourcc("R", "A", "1", "5") -V4L2_PIX_FMT_RGBX555 = v4l2_fourcc("R", "X", "1", "5") -V4L2_PIX_FMT_ABGR555 = v4l2_fourcc("A", "B", "1", "5") -V4L2_PIX_FMT_XBGR555 = v4l2_fourcc("X", "B", "1", "5") -V4L2_PIX_FMT_BGRA555 = v4l2_fourcc("B", "A", "1", "5") -V4L2_PIX_FMT_BGRX555 = v4l2_fourcc("B", "X", "1", "5") - -V4L2_PIX_FMT_RGB565 = v4l2_fourcc("R", "G", "B", "P") -V4L2_PIX_FMT_RGB565X = v4l2_fourcc("R", "G", "B", "R") -V4L2_PIX_FMT_BGR24 = v4l2_fourcc("B", "G", "R", "3") -V4L2_PIX_FMT_RGB24 = v4l2_fourcc("R", "G", "B", "3") -V4L2_PIX_FMT_BGR666 = v4l2_fourcc("B", "G", "R", "H") -V4L2_PIX_FMT_ABGR32 = v4l2_fourcc("A", "R", "2", "4") -V4L2_PIX_FMT_XBGR32 = v4l2_fourcc("X", "R", "2", "4") -V4L2_PIX_FMT_BGRA32 = v4l2_fourcc("R", "A", "2", "4") -V4L2_PIX_FMT_BGRX32 = v4l2_fourcc("R", "X", "2", "4") -V4L2_PIX_FMT_RGBA32 = v4l2_fourcc("A", "B", "2", "4") -V4L2_PIX_FMT_RGBX32 = v4l2_fourcc("X", "B", "2", "4") -V4L2_PIX_FMT_ARGB32 = v4l2_fourcc("B", "A", "2", "4") -V4L2_PIX_FMT_XRGB32 = v4l2_fourcc("B", "X", "2", "4") - -# Deprecated RGB formats -V4L2_PIX_FMT_RGB444 = v4l2_fourcc("R", "4", "4", "4") -V4L2_PIX_FMT_RGB555 = v4l2_fourcc("R", "G", "B", "O") -V4L2_PIX_FMT_RGB555X = v4l2_fourcc("R", "G", "B", "Q") -V4L2_PIX_FMT_BGR32 = v4l2_fourcc("B", "G", "R", "4") -V4L2_PIX_FMT_RGB32 = v4l2_fourcc("R", "G", "B", "4") - -# Grey formats -V4L2_PIX_FMT_GREY = v4l2_fourcc("G", "R", "E", "Y") -V4L2_PIX_FMT_Y04 = v4l2_fourcc("Y", "0", "4", " ") -V4L2_PIX_FMT_Y06 = v4l2_fourcc("Y", "0", "6", " ") -V4L2_PIX_FMT_Y10 = v4l2_fourcc("Y", "1", "0", " ") -V4L2_PIX_FMT_Y12 = v4l2_fourcc("Y", "1", "2", " ") -V4L2_PIX_FMT_Y16 = v4l2_fourcc("Y", "1", "6", " ") -V4L2_PIX_FMT_Y32 = v4l2_fourcc("Y", "3", "2", " ") - -# Palette formats -V4L2_PIX_FMT_PAL8 = v4l2_fourcc("P", "A", "L", "8") - -# Luminance+Chrominance formats -V4L2_PIX_FMT_YVU410 = v4l2_fourcc("Y", "V", "U", "9") -V4L2_PIX_FMT_YVU420 = v4l2_fourcc("Y", "V", "1", "2") -V4L2_PIX_FMT_YUYV = v4l2_fourcc("Y", "U", "Y", "V") -V4L2_PIX_FMT_YYUV = v4l2_fourcc("Y", "Y", "U", "V") -V4L2_PIX_FMT_YVYU = v4l2_fourcc("Y", "V", "Y", "U") -V4L2_PIX_FMT_UYVY = v4l2_fourcc("U", "Y", "V", "Y") -V4L2_PIX_FMT_VYUY = v4l2_fourcc("V", "Y", "U", "Y") -V4L2_PIX_FMT_YUV422P = v4l2_fourcc("4", "2", "2", "P") -V4L2_PIX_FMT_YUV411P = v4l2_fourcc("4", "1", "1", "P") -V4L2_PIX_FMT_Y41P = v4l2_fourcc("Y", "4", "1", "P") -V4L2_PIX_FMT_YUV444 = v4l2_fourcc("Y", "4", "4", "4") -V4L2_PIX_FMT_YUV555 = v4l2_fourcc("Y", "U", "V", "O") -V4L2_PIX_FMT_YUV565 = v4l2_fourcc("Y", "U", "V", "P") -V4L2_PIX_FMT_YUV32 = v4l2_fourcc("Y", "U", "V", "4") -V4L2_PIX_FMT_YUV410 = v4l2_fourcc("Y", "U", "V", "9") -V4L2_PIX_FMT_YUV420 = v4l2_fourcc("Y", "U", "1", "2") -V4L2_PIX_FMT_HI240 = v4l2_fourcc("H", "I", "2", "4") -V4L2_PIX_FMT_HM12 = v4l2_fourcc("H", "M", "1", "2") - -# two planes -- one Y, one Cr + Cb interleaved -V4L2_PIX_FMT_NV12 = v4l2_fourcc("N", "V", "1", "2") -V4L2_PIX_FMT_NV21 = v4l2_fourcc("N", "V", "2", "1") -V4L2_PIX_FMT_NV16 = v4l2_fourcc("N", "V", "1", "6") -V4L2_PIX_FMT_NV61 = v4l2_fourcc("N", "V", "6", "1") - -# Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm -V4L2_PIX_FMT_SBGGR8 = v4l2_fourcc("B", "A", "8", "1") -V4L2_PIX_FMT_SGBRG8 = v4l2_fourcc("G", "B", "R", "G") -V4L2_PIX_FMT_SGRBG8 = v4l2_fourcc("G", "R", "B", "G") -V4L2_PIX_FMT_SRGGB8 = v4l2_fourcc("R", "G", "G", "B") -V4L2_PIX_FMT_SBGGR10 = v4l2_fourcc("B", "G", "1", "0") -V4L2_PIX_FMT_SGBRG10 = v4l2_fourcc("G", "B", "1", "0") -V4L2_PIX_FMT_SGRBG10 = v4l2_fourcc("B", "A", "1", "0") -V4L2_PIX_FMT_SRGGB10 = v4l2_fourcc("R", "G", "1", "0") -V4L2_PIX_FMT_SGRBG10DPCM8 = v4l2_fourcc("B", "D", "1", "0") -V4L2_PIX_FMT_SBGGR16 = v4l2_fourcc("B", "Y", "R", "2") - -# compressed formats -V4L2_PIX_FMT_MJPEG = v4l2_fourcc("M", "J", "P", "G") -V4L2_PIX_FMT_JPEG = v4l2_fourcc("J", "P", "E", "G") -V4L2_PIX_FMT_DV = v4l2_fourcc("d", "v", "s", "d") -V4L2_PIX_FMT_MPEG = v4l2_fourcc("M", "P", "E", "G") -V4L2_PIX_FMT_MPG1 = v4l2_fourcc("M", "P", "G", "1") -V4L2_PIX_FMT_MPG2 = v4l2_fourcc("M", "P", "G", "2") -V4L2_PIX_FMT_MPEG2_SLICE = v4l2_fourcc("M", "G", "2", "S") -V4L2_PIX_FMT_MPG4 = v4l2_fourcc("M", "P", "G", "4") -V4L2_PIX_FMT_H263 = v4l2_fourcc("H", "2", "6", "3") -V4L2_PIX_FMT_H264 = v4l2_fourcc("H", "2", "6", "4") -V4L2_PIX_FMT_H264_NO_SC = v4l2_fourcc("A", "V", "C", "1") -V4L2_PIX_FMT_H264_MVC = v4l2_fourcc("M", "2", "6", "4") -V4L2_PIX_FMT_H265 = v4l2_fourcc("H", "2", "6", "5") -V4L2_PIX_FMT_XVID = v4l2_fourcc("X", "V", "I", "D") -V4L2_PIX_FMT_VC1_ANNEX_G = v4l2_fourcc("V", "C", "1", "G") -V4L2_PIX_FMT_VC1_ANNEX_L = v4l2_fourcc("V", "C", "1", "L") -V4L2_PIX_FMT_VP8 = v4l2_fourcc("V", "P", "8", "0") -V4L2_PIX_FMT_VP9 = v4l2_fourcc("V", "P", "9", "0") -V4L2_PIX_FMT_HEVC = v4l2_fourcc("H", "E", "V", "C") -V4L2_PIX_FMT_FWHT = v4l2_fourcc("F", "W", "H", "T") - -# Vendor-specific formats -V4L2_PIX_FMT_CPIA1 = v4l2_fourcc("C", "P", "I", "A") -V4L2_PIX_FMT_WNVA = v4l2_fourcc("W", "N", "V", "A") -V4L2_PIX_FMT_SN9C10X = v4l2_fourcc("S", "9", "1", "0") -V4L2_PIX_FMT_SN9C20X_I420 = v4l2_fourcc("S", "9", "2", "0") -V4L2_PIX_FMT_PWC1 = v4l2_fourcc("P", "W", "C", "1") -V4L2_PIX_FMT_PWC2 = v4l2_fourcc("P", "W", "C", "2") -V4L2_PIX_FMT_ET61X251 = v4l2_fourcc("E", "6", "2", "5") -V4L2_PIX_FMT_SPCA501 = v4l2_fourcc("S", "5", "0", "1") -V4L2_PIX_FMT_SPCA505 = v4l2_fourcc("S", "5", "0", "5") -V4L2_PIX_FMT_SPCA508 = v4l2_fourcc("S", "5", "0", "8") -V4L2_PIX_FMT_SPCA561 = v4l2_fourcc("S", "5", "6", "1") -V4L2_PIX_FMT_PAC207 = v4l2_fourcc("P", "2", "0", "7") -V4L2_PIX_FMT_MR97310A = v4l2_fourcc("M", "3", "1", "0") -V4L2_PIX_FMT_SN9C2028 = v4l2_fourcc("S", "O", "N", "X") -V4L2_PIX_FMT_SQ905C = v4l2_fourcc("9", "0", "5", "C") -V4L2_PIX_FMT_PJPG = v4l2_fourcc("P", "J", "P", "G") -V4L2_PIX_FMT_OV511 = v4l2_fourcc("O", "5", "1", "1") -V4L2_PIX_FMT_OV518 = v4l2_fourcc("O", "5", "1", "8") -V4L2_PIX_FMT_STV0680 = v4l2_fourcc("S", "6", "8", "0") - - -# -# Format enumeration -# - - -class v4l2_fmtdesc(ctypes.Structure): - _fields_ = [ - ("index", ctypes.c_uint32), - ("type", ctypes.c_int), - ("flags", ctypes.c_uint32), - ("description", ctypes.c_char * 32), - ("pixelformat", ctypes.c_uint32), - ("reserved", ctypes.c_uint32 * 4), - ] - - -V4L2_FMT_FLAG_COMPRESSED = 0x0001 -V4L2_FMT_FLAG_EMULATED = 0x0002 - - -# -# Experimental frame size and frame rate enumeration -# - -v4l2_frmsizetypes = enum -( - V4L2_FRMSIZE_TYPE_DISCRETE, - V4L2_FRMSIZE_TYPE_CONTINUOUS, - V4L2_FRMSIZE_TYPE_STEPWISE, -) = range(1, 4) - - -class v4l2_frmsize_discrete(ctypes.Structure): - _fields_ = [ - ("width", ctypes.c_uint32), - ("height", ctypes.c_uint32), - ] - - -class v4l2_frmsize_stepwise(ctypes.Structure): - _fields_ = [ - ("min_width", ctypes.c_uint32), - ("max_width", ctypes.c_uint32), - ("step_width", ctypes.c_uint32), - ("min_height", ctypes.c_uint32), - ("max_height", ctypes.c_uint32), - ("step_height", ctypes.c_uint32), - ] - - -class v4l2_frmsizeenum(ctypes.Structure): - class _u(ctypes.Union): - _fields_ = [ - ("discrete", v4l2_frmsize_discrete), - ("stepwise", v4l2_frmsize_stepwise), - ] - - _fields_ = [ - ("index", ctypes.c_uint32), - ("pixel_format", ctypes.c_uint32), - ("type", ctypes.c_uint32), - ("_u", _u), - ("reserved", ctypes.c_uint32 * 2), - ] - - _anonymous_ = ("_u",) - - -# -# Frame rate enumeration -# - -v4l2_frmivaltypes = enum -( - V4L2_FRMIVAL_TYPE_DISCRETE, - V4L2_FRMIVAL_TYPE_CONTINUOUS, - V4L2_FRMIVAL_TYPE_STEPWISE, -) = range(1, 4) - - -class v4l2_frmival_stepwise(ctypes.Structure): - _fields_ = [ - ("min", v4l2_fract), - ("max", v4l2_fract), - ("step", v4l2_fract), - ] - - -class v4l2_frmivalenum(ctypes.Structure): - class _u(ctypes.Union): - _fields_ = [ - ("discrete", v4l2_fract), - ("stepwise", v4l2_frmival_stepwise), - ] - - _fields_ = [ - ("index", ctypes.c_uint32), - ("pixel_format", ctypes.c_uint32), - ("width", ctypes.c_uint32), - ("height", ctypes.c_uint32), - ("type", ctypes.c_uint32), - ("_u", _u), - ("reserved", ctypes.c_uint32 * 2), - ] - - _anonymous_ = ("_u",) - - -# -# Timecode -# - - -class v4l2_timecode(ctypes.Structure): - _fields_ = [ - ("type", ctypes.c_uint32), - ("flags", ctypes.c_uint32), - ("frames", ctypes.c_uint8), - ("seconds", ctypes.c_uint8), - ("minutes", ctypes.c_uint8), - ("hours", ctypes.c_uint8), - ("userbits", ctypes.c_uint8 * 4), - ] - - -V4L2_TC_TYPE_24FPS = 1 -V4L2_TC_TYPE_25FPS = 2 -V4L2_TC_TYPE_30FPS = 3 -V4L2_TC_TYPE_50FPS = 4 -V4L2_TC_TYPE_60FPS = 5 - -V4L2_TC_FLAG_DROPFRAME = 0x0001 -V4L2_TC_FLAG_COLORFRAME = 0x0002 -V4L2_TC_USERBITS_field = 0x000C -V4L2_TC_USERBITS_USERDEFINED = 0x0000 -V4L2_TC_USERBITS_8BITCHARS = 0x0008 - - -class v4l2_jpegcompression(ctypes.Structure): - _fields_ = [ - ("quality", ctypes.c_int), - ("APPn", ctypes.c_int), - ("APP_len", ctypes.c_int), - ("APP_data", ctypes.c_char * 60), - ("COM_len", ctypes.c_int), - ("COM_data", ctypes.c_char * 60), - ("jpeg_markers", ctypes.c_uint32), - ] - - -V4L2_JPEG_MARKER_DHT = 1 << 3 -V4L2_JPEG_MARKER_DQT = 1 << 4 -V4L2_JPEG_MARKER_DRI = 1 << 5 -V4L2_JPEG_MARKER_COM = 1 << 6 -V4L2_JPEG_MARKER_APP = 1 << 7 - - -# -# Memory-mapping buffers -# - - -class v4l2_requestbuffers(ctypes.Structure): - _fields_ = [ - ("count", ctypes.c_uint32), - ("type", v4l2_buf_type), - ("memory", v4l2_memory), - ("reserved", ctypes.c_uint32 * 2), - ] - - -class v4l2_buffer(ctypes.Structure): - class _u(ctypes.Union): - _fields_ = [ - ("offset", ctypes.c_uint32), # V4L2_MEMORY_MMAP - ("userptr", ctypes.c_ulong), # V4L2_MEMORY_USERPTR - # TODO: ("planes", ctypes.POINTER(v4l2_plane)), - ("fd", ctypes.c_int), # V4L2_MEMORY_DMABUF - ] - - _fields_ = [ - ("index", ctypes.c_uint32), - ("type", v4l2_buf_type), - ("bytesused", ctypes.c_uint32), - ("flags", ctypes.c_uint32), - ("field", v4l2_field), - ("timestamp", timeval), - ("timecode", v4l2_timecode), - ("sequence", ctypes.c_uint32), - ("memory", v4l2_memory), - ("m", _u), - ("length", ctypes.c_uint32), - ("reserved2", ctypes.c_uint32), - ("request_fd", ctypes.c_uint32), # V4L2_BUF_FLAG_REQUEST_FD - ] - - -V4L2_BUF_FLAG_TIMESTAMP_UNKNOWN = 0x00000000 -V4L2_BUF_FLAG_MAPPED = 0x0001 -V4L2_BUF_FLAG_QUEUED = 0x0002 -V4L2_BUF_FLAG_DONE = 0x0004 -V4L2_BUF_FLAG_KEYFRAME = 0x0008 -V4L2_BUF_FLAG_PFRAME = 0x0010 -V4L2_BUF_FLAG_BFRAME = 0x0020 -V4L2_BUF_FLAG_TIMECODE = 0x0100 -V4L2_BUF_FLAG_PREPARED = 0x400 -V4L2_BUF_FLAG_NO_CACHE_INVALIDATE = 0x800 -V4L2_BUF_FLAG_NO_CACHE_CLEAN = 0x1000 -V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF = 0x200 -V4L2_BUF_FLAG_LAST = 0x100000 -V4L2_BUF_FLAG_REQUEST_FD = 0x800000 -V4L2_BUF_FLAG_TIMESTAMP_MASK = 0xE000 -V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC = 0x2000 -V4L2_BUF_FLAG_TIMESTAMP_COPY = 0x4000 -V4L2_BUF_FLAG_TSTAMP_SRC_MASK = 0x70000 -V4L2_BUF_FLAG_TSTAMP_SRC_EOF = 0x0 -V4L2_BUF_FLAG_TSTAMP_SRC_SOE = 0x10000 - - -# -# Overlay preview -# - - -class v4l2_framebuffer(ctypes.Structure): - _fields_ = [ - ("capability", ctypes.c_uint32), - ("flags", ctypes.c_uint32), - ("base", ctypes.c_void_p), - ("fmt", v4l2_pix_format), - ] - - -V4L2_FBUF_CAP_EXTERNOVERLAY = 0x0001 -V4L2_FBUF_CAP_CHROMAKEY = 0x0002 -V4L2_FBUF_CAP_LIST_CLIPPING = 0x0004 -V4L2_FBUF_CAP_BITMAP_CLIPPING = 0x0008 -V4L2_FBUF_CAP_LOCAL_ALPHA = 0x0010 -V4L2_FBUF_CAP_GLOBAL_ALPHA = 0x0020 -V4L2_FBUF_CAP_LOCAL_INV_ALPHA = 0x0040 -V4L2_FBUF_CAP_SRC_CHROMAKEY = 0x0080 - -V4L2_FBUF_FLAG_PRIMARY = 0x0001 -V4L2_FBUF_FLAG_OVERLAY = 0x0002 -V4L2_FBUF_FLAG_CHROMAKEY = 0x0004 -V4L2_FBUF_FLAG_LOCAL_ALPHA = 0x0008 -V4L2_FBUF_FLAG_GLOBAL_ALPHA = 0x0010 -V4L2_FBUF_FLAG_LOCAL_INV_ALPHA = 0x0020 -V4L2_FBUF_FLAG_SRC_CHROMAKEY = 0x0040 - - -class v4l2_clip(ctypes.Structure): - pass - - -v4l2_clip._fields_ = [ - ("c", v4l2_rect), - ("next", ctypes.POINTER(v4l2_clip)), -] - - -class v4l2_window(ctypes.Structure): - _fields_ = [ - ("w", v4l2_rect), - ("field", v4l2_field), - ("chromakey", ctypes.c_uint32), - ("clips", ctypes.POINTER(v4l2_clip)), - ("clipcount", ctypes.c_uint32), - ("bitmap", ctypes.c_void_p), - ("global_alpha", ctypes.c_uint8), - ] - - -# -# Capture parameters -# - - -class v4l2_captureparm(ctypes.Structure): - _fields_ = [ - ("capability", ctypes.c_uint32), - ("capturemode", ctypes.c_uint32), - ("timeperframe", v4l2_fract), - ("extendedmode", ctypes.c_uint32), - ("readbuffers", ctypes.c_uint32), - ("reserved", ctypes.c_uint32 * 4), - ] - - -V4L2_MODE_HIGHQUALITY = 0x0001 -V4L2_CAP_TIMEPERFRAME = 0x1000 - - -class v4l2_outputparm(ctypes.Structure): - _fields_ = [ - ("capability", ctypes.c_uint32), - ("outputmode", ctypes.c_uint32), - ("timeperframe", v4l2_fract), - ("extendedmode", ctypes.c_uint32), - ("writebuffers", ctypes.c_uint32), - ("reserved", ctypes.c_uint32 * 4), - ] - - -# -# Input image cropping -# - - -class v4l2_cropcap(ctypes.Structure): - _fields_ = [ - ("type", v4l2_buf_type), - ("bounds", v4l2_rect), - ("defrect", v4l2_rect), - ("pixelaspect", v4l2_fract), - ] - - -class v4l2_crop(ctypes.Structure): - _fields_ = [ - ("type", ctypes.c_int), - ("c", v4l2_rect), - ] - - -# Selection interface definitions from 'v4l2-common.h' - -# Selection TARGET -V4L2_SEL_TGT_CROP = 0x0000 -V4L2_SEL_TGT_CROP_DEFAULT = 0x0001 -V4L2_SEL_TGT_CROP_BOUNDS = 0x0002 -V4L2_SEL_TGT_NATIVE_SIZE = 0x0003 -V4L2_SEL_TGT_COMPOSE = 0x0100 -V4L2_SEL_TGT_COMPOSE_DEFAULT = 0x0101 -V4L2_SEL_TGT_COMPOSE_BOUNDS = 0x0102 -V4L2_SEL_TGT_COMPOSE_PADDED = 0x0103 - -# Selection flags -V4L2_SEL_FLAG_GE = 1 << 0 -V4L2_SEL_FLAG_LE = 1 << 1 -V4L2_SEL_FLAG_KEEP_CONFIG = 1 << 2 - - -class v4l2_selection(ctypes.Structure): - class _u(ctypes.Union): - _fields_ = [ - ("reserved", ctypes.c_uint32 * 8), - ("pr", ctypes.POINTER(v4l2_ext_rect)), - ] - - _anonymous_ = ("u",) - _fields_ = [ - ("type", v4l2_buf_type), - ("target", ctypes.c_uint32), - ("flags", ctypes.c_uint32), - ("r", v4l2_rect), - ("rectangles", ctypes.c_uint32), - ("u", _u), - ] - - -# -# Analog video standard -# - -v4l2_std_id = ctypes.c_uint64 - - -V4L2_STD_PAL_B = 0x00000001 -V4L2_STD_PAL_B1 = 0x00000002 -V4L2_STD_PAL_G = 0x00000004 -V4L2_STD_PAL_H = 0x00000008 -V4L2_STD_PAL_I = 0x00000010 -V4L2_STD_PAL_D = 0x00000020 -V4L2_STD_PAL_D1 = 0x00000040 -V4L2_STD_PAL_K = 0x00000080 - -V4L2_STD_PAL_M = 0x00000100 -V4L2_STD_PAL_N = 0x00000200 -V4L2_STD_PAL_Nc = 0x00000400 -V4L2_STD_PAL_60 = 0x00000800 - -V4L2_STD_NTSC_M = 0x00001000 -V4L2_STD_NTSC_M_JP = 0x00002000 -V4L2_STD_NTSC_443 = 0x00004000 -V4L2_STD_NTSC_M_KR = 0x00008000 - -V4L2_STD_SECAM_B = 0x00010000 -V4L2_STD_SECAM_D = 0x00020000 -V4L2_STD_SECAM_G = 0x00040000 -V4L2_STD_SECAM_H = 0x00080000 -V4L2_STD_SECAM_K = 0x00100000 -V4L2_STD_SECAM_K1 = 0x00200000 -V4L2_STD_SECAM_L = 0x00400000 -V4L2_STD_SECAM_LC = 0x00800000 - -V4L2_STD_ATSC_8_VSB = 0x01000000 -V4L2_STD_ATSC_16_VSB = 0x02000000 - - -# some common needed stuff -V4L2_STD_PAL_BG = V4L2_STD_PAL_B | V4L2_STD_PAL_B1 | V4L2_STD_PAL_G -V4L2_STD_PAL_DK = V4L2_STD_PAL_D | V4L2_STD_PAL_D1 | V4L2_STD_PAL_K -V4L2_STD_PAL = V4L2_STD_PAL_BG | V4L2_STD_PAL_DK | V4L2_STD_PAL_H | V4L2_STD_PAL_I -V4L2_STD_NTSC = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_M_KR -V4L2_STD_SECAM_DK = V4L2_STD_SECAM_D | V4L2_STD_SECAM_K | V4L2_STD_SECAM_K1 -V4L2_STD_SECAM = ( - V4L2_STD_SECAM_B - | V4L2_STD_SECAM_G - | V4L2_STD_SECAM_H - | V4L2_STD_SECAM_DK - | V4L2_STD_SECAM_L - | V4L2_STD_SECAM_LC -) - -V4L2_STD_525_60 = V4L2_STD_PAL_M | V4L2_STD_PAL_60 | V4L2_STD_NTSC | V4L2_STD_NTSC_443 -V4L2_STD_625_50 = V4L2_STD_PAL | V4L2_STD_PAL_N | V4L2_STD_PAL_Nc | V4L2_STD_SECAM -V4L2_STD_ATSC = V4L2_STD_ATSC_8_VSB | V4L2_STD_ATSC_16_VSB - -V4L2_STD_UNKNOWN = 0 -V4L2_STD_ALL = V4L2_STD_525_60 | V4L2_STD_625_50 - -# some merged standards -V4L2_STD_MN = V4L2_STD_PAL_M | V4L2_STD_PAL_N | V4L2_STD_PAL_Nc | V4L2_STD_NTSC -V4L2_STD_B = V4L2_STD_PAL_B | V4L2_STD_PAL_B1 | V4L2_STD_SECAM_B -V4L2_STD_GH = V4L2_STD_PAL_G | V4L2_STD_PAL_H | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H -V4L2_STD_DK = V4L2_STD_PAL_DK | V4L2_STD_SECAM_DK - - -class v4l2_standard(ctypes.Structure): - _fields_ = [ - ("index", ctypes.c_uint32), - ("id", v4l2_std_id), - ("name", ctypes.c_char * 24), - ("frameperiod", v4l2_fract), - ("framelines", ctypes.c_uint32), - ("reserved", ctypes.c_uint32 * 4), - ] - - -# -# Video timings dv preset -# - - -class v4l2_dv_preset(ctypes.Structure): - _fields_ = [("preset", ctypes.c_uint32), ("reserved", ctypes.c_uint32 * 4)] - - -# -# DV preset enumeration -# - - -class v4l2_dv_enum_preset(ctypes.Structure): - _fields_ = [ - ("index", ctypes.c_uint32), - ("preset", ctypes.c_uint32), - ("name", ctypes.c_char * 32), - ("width", ctypes.c_uint32), - ("height", ctypes.c_uint32), - ("reserved", ctypes.c_uint32 * 4), - ] - - -# -# DV preset values -# - -V4L2_DV_INVALID = 0 -V4L2_DV_480P59_94 = 1 -V4L2_DV_576P50 = 2 -V4L2_DV_720P24 = 3 -V4L2_DV_720P25 = 4 -V4L2_DV_720P30 = 5 -V4L2_DV_720P50 = 6 -V4L2_DV_720P59_94 = 7 -V4L2_DV_720P60 = 8 -V4L2_DV_1080I29_97 = 9 -V4L2_DV_1080I30 = 10 -V4L2_DV_1080I25 = 11 -V4L2_DV_1080I50 = 12 -V4L2_DV_1080I60 = 13 -V4L2_DV_1080P24 = 14 -V4L2_DV_1080P25 = 15 -V4L2_DV_1080P30 = 16 -V4L2_DV_1080P50 = 17 -V4L2_DV_1080P60 = 18 - - -# -# DV BT timings -# - - -class v4l2_bt_timings(ctypes.Structure): - _fields_ = [ - ("width", ctypes.c_uint32), - ("height", ctypes.c_uint32), - ("interlaced", ctypes.c_uint32), - ("polarities", ctypes.c_uint32), - ("pixelclock", ctypes.c_uint64), - ("hfrontporch", ctypes.c_uint32), - ("hsync", ctypes.c_uint32), - ("hbackporch", ctypes.c_uint32), - ("vfrontporch", ctypes.c_uint32), - ("vsync", ctypes.c_uint32), - ("vbackporch", ctypes.c_uint32), - ("il_vfrontporch", ctypes.c_uint32), - ("il_vsync", ctypes.c_uint32), - ("il_vbackporch", ctypes.c_uint32), - ("reserved", ctypes.c_uint32 * 16), - ] - - _pack_ = True - - -# Interlaced or progressive format -V4L2_DV_PROGRESSIVE = 0 -V4L2_DV_INTERLACED = 1 - -# Polarities. If bit is not set, it is assumed to be negative polarity -V4L2_DV_VSYNC_POS_POL = 0x00000001 -V4L2_DV_HSYNC_POS_POL = 0x00000002 - - -class v4l2_dv_timings(ctypes.Structure): - class _u(ctypes.Union): - _fields_ = [ - ("bt", v4l2_bt_timings), - ("reserved", ctypes.c_uint32 * 32), - ] - - _fields_ = [ - ("type", ctypes.c_uint32), - ("_u", _u), - ] - - _anonymous_ = ("_u",) - _pack_ = True - - -# Values for the type field -V4L2_DV_BT_656_1120 = 0 - - -# -# Video inputs -# - - -class v4l2_input(ctypes.Structure): - _fields_ = [ - ("index", ctypes.c_uint32), - ("name", ctypes.c_char * 32), - ("type", ctypes.c_uint32), - ("audioset", ctypes.c_uint32), - ("tuner", ctypes.c_uint32), - ("std", v4l2_std_id), - ("status", ctypes.c_uint32), - ("capabilities", ctypes.c_uint32), - ("reserved", ctypes.c_uint32 * 3), - ] - - -V4L2_INPUT_TYPE_TUNER = 1 -V4L2_INPUT_TYPE_CAMERA = 2 -V4L2_INPUT_TYPE_TOUCH = 3 - -V4L2_IN_ST_NO_POWER = 0x00000001 -V4L2_IN_ST_NO_SIGNAL = 0x00000002 -V4L2_IN_ST_NO_COLOR = 0x00000004 - -V4L2_IN_ST_HFLIP = 0x00000010 -V4L2_IN_ST_VFLIP = 0x00000020 - -V4L2_IN_ST_NO_H_LOCK = 0x00000100 -V4L2_IN_ST_COLOR_KILL = 0x00000200 - -V4L2_IN_ST_NO_SYNC = 0x00010000 -V4L2_IN_ST_NO_EQU = 0x00020000 -V4L2_IN_ST_NO_CARRIER = 0x00040000 - -V4L2_IN_ST_MACROVISION = 0x01000000 -V4L2_IN_ST_NO_ACCESS = 0x02000000 -V4L2_IN_ST_VTR = 0x04000000 - -V4L2_IN_CAP_PRESETS = 0x00000001 -V4L2_IN_CAP_CUSTOM_TIMINGS = 0x00000002 -V4L2_IN_CAP_STD = 0x00000004 -V4L2_IN_CAP_NATIVE_SIZE = 0x00000008 - -# -# Video outputs -# - - -class v4l2_output(ctypes.Structure): - _fields_ = [ - ("index", ctypes.c_uint32), - ("name", ctypes.c_char * 32), - ("type", ctypes.c_uint32), - ("audioset", ctypes.c_uint32), - ("modulator", ctypes.c_uint32), - ("std", v4l2_std_id), - ("reserved", ctypes.c_uint32 * 4), - ] - - -V4L2_OUTPUT_TYPE_MODULATOR = 1 -V4L2_OUTPUT_TYPE_ANALOG = 2 -V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY = 3 - -V4L2_OUT_CAP_PRESETS = 0x00000001 -V4L2_OUT_CAP_CUSTOM_TIMINGS = 0x00000002 -V4L2_OUT_CAP_STD = 0x00000004 - -# -# Controls -# - - -class v4l2_control(ctypes.Structure): - _fields_ = [ - ("id", ctypes.c_uint32), - ("value", ctypes.c_int32), - ] - - -class v4l2_ext_control(ctypes.Structure): - class _u(ctypes.Union): - _fields_ = [ - ("value", ctypes.c_int32), - ("value64", ctypes.c_int64), - ("string", ctypes.POINTER(ctypes.c_char)), - ("p_u8", ctypes.POINTER(ctypes.c_uint8)), - ("p_u16", ctypes.POINTER(ctypes.c_uint16)), - ("p_u32", ctypes.POINTER(ctypes.c_uint32)), - ("reserved", ctypes.c_void_p), - ] - - _fields_ = [ - ("id", ctypes.c_uint32), - ("size", ctypes.c_uint32), - ("reserved2", ctypes.c_uint32 * 1), - ("_u", _u), - ] - - _anonymous_ = ("_u",) - _pack_ = True - - -class v4l2_ext_controls(ctypes.Structure): - _fields_ = [ - ("ctrl_class", ctypes.c_uint32), - ("count", ctypes.c_uint32), - ("error_idx", ctypes.c_uint32), - ("reserved", ctypes.c_uint32 * 2), - ("controls", ctypes.POINTER(v4l2_ext_control)), - ] - - -V4L2_CTRL_CLASS_USER = 0x00980000 # Old-style 'user' controls -V4L2_CTRL_CLASS_MPEG = ( - 0x00990000 # Stateful codec controls (..._CODEC in v4l2-controls.h) -) -V4L2_CTRL_CLASS_CAMERA = 0x009A0000 # Camera class controls -V4L2_CTRL_CLASS_FM_TX = 0x009B0000 # FM Modulator controls -V4L2_CTRL_CLASS_FLASH = 0x009C0000 # Camera flash controls -V4L2_CTRL_CLASS_JPEG = 0x009D0000 # JPEG-compression controls -V4L2_CTRL_CLASS_IMAGE_SOURCE = 0x009E0000 # Image source controls -V4L2_CTRL_CLASS_IMAGE_PROC = 0x009F0000 # Image processing controls -V4L2_CTRL_CLASS_DV = 0x00A00000 # Digital Video controls -V4L2_CTRL_CLASS_FM_RX = 0x00A10000 # FM Receiver controls -V4L2_CTRL_CLASS_RF_TUNER = 0x00A20000 # RF tuner controls -V4L2_CTRL_CLASS_DETECT = 0x00A30000 # Detection controls -V4L2_CTRL_CLASS_CODEC_STATELESS = 0x00A40000 # Stateless codecs controls -V4L2_CTRL_CLASS_COLORIMETRY = 0x00A50000 # Colorimetry controls - - -def V4L2_CTRL_ID_MASK(): - return 0x0FFFFFFF - - -def V4L2_CTRL_ID2CLASS(id_): - return id_ & 0x0FFF0000 # unsigned long - - -def V4L2_CTRL_DRIVER_PRIV(id_): - return (id_ & 0xFFFF) >= 0x1000 - - -class v4l2_queryctrl(ctypes.Structure): - _fields_ = [ - ("id", ctypes.c_uint32), - ("type", v4l2_ctrl_type), - ("name", ctypes.c_char * 32), - ("minimum", ctypes.c_int32), - ("maximum", ctypes.c_int32), - ("step", ctypes.c_int32), - ("default_value", ctypes.c_int32), - ("flags", ctypes.c_uint32), - ("reserved", ctypes.c_uint32 * 2), - ] - - -V4L2_CTRL_MAX_DIMS = 4 - - -class v4l2_query_ext_ctrl(ctypes.Structure): - _fields_ = [ - ("id", ctypes.c_uint32), - ("type", v4l2_ctrl_type), - ("name", ctypes.c_char * 32), - ("minimum", ctypes.c_int64), - ("maximum", ctypes.c_int64), - ("step", ctypes.c_uint64), - ("default_value", ctypes.c_int64), - ("flags", ctypes.c_uint32), - ("elem_size", ctypes.c_uint32), - ("elems", ctypes.c_uint32), - ("nr_of_dims", ctypes.c_uint32), - ("dims", ctypes.c_uint32 * V4L2_CTRL_MAX_DIMS), - ("reserved", ctypes.c_uint32 * 32), - ] - - -class v4l2_querymenu(ctypes.Structure): - _fields_ = [ - ("id", ctypes.c_uint32), - ("index", ctypes.c_uint32), - ("name", ctypes.c_char * 32), - ("reserved", ctypes.c_uint32), - ] - - -NONE = 0x0000 -V4L2_CTRL_FLAG_DISABLED = 0x0001 -V4L2_CTRL_FLAG_GRABBED = 0x0002 -V4L2_CTRL_FLAG_READ_ONLY = 0x0004 -V4L2_CTRL_FLAG_UPDATE = 0x0008 -V4L2_CTRL_FLAG_INACTIVE = 0x0010 -V4L2_CTRL_FLAG_SLIDER = 0x0020 -V4L2_CTRL_FLAG_WRITE_ONLY = 0x0040 -V4L2_CTRL_FLAG_VOLATILE = 0x0080 -V4L2_CTRL_FLAG_HAS_PAYLOAD = 0x0100 -V4L2_CTRL_FLAG_EXECUTE_ON_WRITE = 0x0200 -V4L2_CTRL_FLAG_MODIFY_LAYOUT = 0x0400 -V4L2_CTRL_FLAG_DYNAMIC_ARRAY = 0x0800 -V4L2_CTRL_FLAG_NEXT_CTRL = 0x80000000 -V4L2_CTRL_FLAG_NEXT_COMPOUND = 0x40000000 - -V4L2_CID_BASE = V4L2_CTRL_CLASS_USER | 0x900 -V4L2_CID_USER_BASE = V4L2_CID_BASE -V4L2_CID_PRIVATE_BASE = 0x08000000 - -V4L2_CID_USER_CLASS = V4L2_CTRL_CLASS_USER | 1 -V4L2_CID_BRIGHTNESS = V4L2_CID_BASE + 0 -V4L2_CID_CONTRAST = V4L2_CID_BASE + 1 -V4L2_CID_SATURATION = V4L2_CID_BASE + 2 -V4L2_CID_HUE = V4L2_CID_BASE + 3 -V4L2_CID_AUDIO_VOLUME = V4L2_CID_BASE + 5 -V4L2_CID_AUDIO_BALANCE = V4L2_CID_BASE + 6 -V4L2_CID_AUDIO_BASS = V4L2_CID_BASE + 7 -V4L2_CID_AUDIO_TREBLE = V4L2_CID_BASE + 8 -V4L2_CID_AUDIO_MUTE = V4L2_CID_BASE + 9 -V4L2_CID_AUDIO_LOUDNESS = V4L2_CID_BASE + 10 -V4L2_CID_BLACK_LEVEL = V4L2_CID_BASE + 11 # Deprecated -V4L2_CID_AUTO_WHITE_BALANCE = V4L2_CID_BASE + 12 -V4L2_CID_DO_WHITE_BALANCE = V4L2_CID_BASE + 13 -V4L2_CID_RED_BALANCE = V4L2_CID_BASE + 14 -V4L2_CID_BLUE_BALANCE = V4L2_CID_BASE + 15 -V4L2_CID_GAMMA = V4L2_CID_BASE + 16 -V4L2_CID_WHITENESS = V4L2_CID_GAMMA # Deprecated -V4L2_CID_EXPOSURE = V4L2_CID_BASE + 17 -V4L2_CID_AUTOGAIN = V4L2_CID_BASE + 18 -V4L2_CID_GAIN = V4L2_CID_BASE + 19 -V4L2_CID_HFLIP = V4L2_CID_BASE + 20 -V4L2_CID_VFLIP = V4L2_CID_BASE + 21 - -# Deprecated; use V4L2_CID_PAN_RESET and V4L2_CID_TILT_RESET -V4L2_CID_HCENTER = V4L2_CID_BASE + 22 -V4L2_CID_VCENTER = V4L2_CID_BASE + 23 - -V4L2_CID_POWER_LINE_FREQUENCY = V4L2_CID_BASE + 24 - -v4l2_power_line_frequency = enum -( - V4L2_CID_POWER_LINE_FREQUENCY_DISABLED, - V4L2_CID_POWER_LINE_FREQUENCY_50HZ, - V4L2_CID_POWER_LINE_FREQUENCY_60HZ, -) = range(3) - -V4L2_CID_HUE_AUTO = V4L2_CID_BASE + 25 -V4L2_CID_WHITE_BALANCE_TEMPERATURE = V4L2_CID_BASE + 26 -V4L2_CID_SHARPNESS = V4L2_CID_BASE + 27 -V4L2_CID_BACKLIGHT_COMPENSATION = V4L2_CID_BASE + 28 -V4L2_CID_CHROMA_AGC = V4L2_CID_BASE + 29 -V4L2_CID_COLOR_KILLER = V4L2_CID_BASE + 30 -V4L2_CID_COLORFX = V4L2_CID_BASE + 31 - -v4l2_colorfx = enum -( - V4L2_COLORFX_NONE, - V4L2_COLORFX_BW, - V4L2_COLORFX_SEPIA, -) = range(3) - -V4L2_CID_AUTOBRIGHTNESS = V4L2_CID_BASE + 32 -V4L2_CID_BAND_STOP_FILTER = V4L2_CID_BASE + 33 - -V4L2_CID_ROTATE = V4L2_CID_BASE + 34 -V4L2_CID_BG_COLOR = V4L2_CID_BASE + 35 -V4L2_CID_LASTP1 = V4L2_CID_BASE + 36 - -V4L2_CID_MPEG_BASE = V4L2_CTRL_CLASS_MPEG | 0x900 -V4L2_CID_MPEG_CLASS = V4L2_CTRL_CLASS_MPEG | 1 - -# MPEG streams -V4L2_CID_MPEG_STREAM_TYPE = V4L2_CID_MPEG_BASE + 0 - -v4l2_mpeg_stream_type = enum -( - V4L2_MPEG_STREAM_TYPE_MPEG2_PS, - V4L2_MPEG_STREAM_TYPE_MPEG2_TS, - V4L2_MPEG_STREAM_TYPE_MPEG1_SS, - V4L2_MPEG_STREAM_TYPE_MPEG2_DVD, - V4L2_MPEG_STREAM_TYPE_MPEG1_VCD, - V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD, -) = range(6) - -V4L2_CID_MPEG_STREAM_PID_PMT = V4L2_CID_MPEG_BASE + 1 -V4L2_CID_MPEG_STREAM_PID_AUDIO = V4L2_CID_MPEG_BASE + 2 -V4L2_CID_MPEG_STREAM_PID_VIDEO = V4L2_CID_MPEG_BASE + 3 -V4L2_CID_MPEG_STREAM_PID_PCR = V4L2_CID_MPEG_BASE + 4 -V4L2_CID_MPEG_STREAM_PES_ID_AUDIO = V4L2_CID_MPEG_BASE + 5 -V4L2_CID_MPEG_STREAM_PES_ID_VIDEO = V4L2_CID_MPEG_BASE + 6 -V4L2_CID_MPEG_STREAM_VBI_FMT = V4L2_CID_MPEG_BASE + 7 - -v4l2_mpeg_stream_vbi_fmt = enum -( - V4L2_MPEG_STREAM_VBI_FMT_NONE, - V4L2_MPEG_STREAM_VBI_FMT_IVTV, -) = range(2) - -V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ = V4L2_CID_MPEG_BASE + 100 - -v4l2_mpeg_audio_sampling_freq = enum -( - V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100, - V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000, - V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000, -) = range(3) - -V4L2_CID_MPEG_AUDIO_ENCODING = V4L2_CID_MPEG_BASE + 101 - -v4l2_mpeg_audio_encoding = enum -( - V4L2_MPEG_AUDIO_ENCODING_LAYER_1, - V4L2_MPEG_AUDIO_ENCODING_LAYER_2, - V4L2_MPEG_AUDIO_ENCODING_LAYER_3, - V4L2_MPEG_AUDIO_ENCODING_AAC, - V4L2_MPEG_AUDIO_ENCODING_AC3, -) = range(5) - -V4L2_CID_MPEG_AUDIO_L1_BITRATE = V4L2_CID_MPEG_BASE + 102 - -v4l2_mpeg_audio_l1_bitrate = enum -( - V4L2_MPEG_AUDIO_L1_BITRATE_32K, - V4L2_MPEG_AUDIO_L1_BITRATE_64K, - V4L2_MPEG_AUDIO_L1_BITRATE_96K, - V4L2_MPEG_AUDIO_L1_BITRATE_128K, - V4L2_MPEG_AUDIO_L1_BITRATE_160K, - V4L2_MPEG_AUDIO_L1_BITRATE_192K, - V4L2_MPEG_AUDIO_L1_BITRATE_224K, - V4L2_MPEG_AUDIO_L1_BITRATE_256K, - V4L2_MPEG_AUDIO_L1_BITRATE_288K, - V4L2_MPEG_AUDIO_L1_BITRATE_320K, - V4L2_MPEG_AUDIO_L1_BITRATE_352K, - V4L2_MPEG_AUDIO_L1_BITRATE_384K, - V4L2_MPEG_AUDIO_L1_BITRATE_416K, - V4L2_MPEG_AUDIO_L1_BITRATE_448K, -) = range(14) - -V4L2_CID_MPEG_AUDIO_L2_BITRATE = V4L2_CID_MPEG_BASE + 103 - -v4l2_mpeg_audio_l2_bitrate = enum -( - V4L2_MPEG_AUDIO_L2_BITRATE_32K, - V4L2_MPEG_AUDIO_L2_BITRATE_48K, - V4L2_MPEG_AUDIO_L2_BITRATE_56K, - V4L2_MPEG_AUDIO_L2_BITRATE_64K, - V4L2_MPEG_AUDIO_L2_BITRATE_80K, - V4L2_MPEG_AUDIO_L2_BITRATE_96K, - V4L2_MPEG_AUDIO_L2_BITRATE_112K, - V4L2_MPEG_AUDIO_L2_BITRATE_128K, - V4L2_MPEG_AUDIO_L2_BITRATE_160K, - V4L2_MPEG_AUDIO_L2_BITRATE_192K, - V4L2_MPEG_AUDIO_L2_BITRATE_224K, - V4L2_MPEG_AUDIO_L2_BITRATE_256K, - V4L2_MPEG_AUDIO_L2_BITRATE_320K, - V4L2_MPEG_AUDIO_L2_BITRATE_384K, -) = range(14) - -V4L2_CID_MPEG_AUDIO_L3_BITRATE = V4L2_CID_MPEG_BASE + 104 - -v4l2_mpeg_audio_l3_bitrate = enum -( - V4L2_MPEG_AUDIO_L3_BITRATE_32K, - V4L2_MPEG_AUDIO_L3_BITRATE_40K, - V4L2_MPEG_AUDIO_L3_BITRATE_48K, - V4L2_MPEG_AUDIO_L3_BITRATE_56K, - V4L2_MPEG_AUDIO_L3_BITRATE_64K, - V4L2_MPEG_AUDIO_L3_BITRATE_80K, - V4L2_MPEG_AUDIO_L3_BITRATE_96K, - V4L2_MPEG_AUDIO_L3_BITRATE_112K, - V4L2_MPEG_AUDIO_L3_BITRATE_128K, - V4L2_MPEG_AUDIO_L3_BITRATE_160K, - V4L2_MPEG_AUDIO_L3_BITRATE_192K, - V4L2_MPEG_AUDIO_L3_BITRATE_224K, - V4L2_MPEG_AUDIO_L3_BITRATE_256K, - V4L2_MPEG_AUDIO_L3_BITRATE_320K, -) = range(14) - -V4L2_CID_MPEG_AUDIO_MODE = V4L2_CID_MPEG_BASE + 105 - -v4l2_mpeg_audio_mode = enum -( - V4L2_MPEG_AUDIO_MODE_STEREO, - V4L2_MPEG_AUDIO_MODE_JOINT_STEREO, - V4L2_MPEG_AUDIO_MODE_DUAL, - V4L2_MPEG_AUDIO_MODE_MONO, -) = range(4) - -V4L2_CID_MPEG_AUDIO_MODE_EXTENSION = V4L2_CID_MPEG_BASE + 106 - -v4l2_mpeg_audio_mode_extension = enum -( - V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4, - V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8, - V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12, - V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16, -) = range(4) - -V4L2_CID_MPEG_AUDIO_EMPHASIS = V4L2_CID_MPEG_BASE + 107 - -v4l2_mpeg_audio_emphasis = enum -( - V4L2_MPEG_AUDIO_EMPHASIS_NONE, - V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS, - V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17, -) = range(3) - -V4L2_CID_MPEG_AUDIO_CRC = V4L2_CID_MPEG_BASE + 108 - -v4l2_mpeg_audio_crc = enum -( - V4L2_MPEG_AUDIO_CRC_NONE, - V4L2_MPEG_AUDIO_CRC_CRC16, -) = range(2) - -V4L2_CID_MPEG_AUDIO_MUTE = V4L2_CID_MPEG_BASE + 109 -V4L2_CID_MPEG_AUDIO_AAC_BITRATE = V4L2_CID_MPEG_BASE + 110 -V4L2_CID_MPEG_AUDIO_AC3_BITRATE = V4L2_CID_MPEG_BASE + 111 - -v4l2_mpeg_audio_ac3_bitrate = enum -( - V4L2_MPEG_AUDIO_AC3_BITRATE_32K, - V4L2_MPEG_AUDIO_AC3_BITRATE_40K, - V4L2_MPEG_AUDIO_AC3_BITRATE_48K, - V4L2_MPEG_AUDIO_AC3_BITRATE_56K, - V4L2_MPEG_AUDIO_AC3_BITRATE_64K, - V4L2_MPEG_AUDIO_AC3_BITRATE_80K, - V4L2_MPEG_AUDIO_AC3_BITRATE_96K, - V4L2_MPEG_AUDIO_AC3_BITRATE_112K, - V4L2_MPEG_AUDIO_AC3_BITRATE_128K, - V4L2_MPEG_AUDIO_AC3_BITRATE_160K, - V4L2_MPEG_AUDIO_AC3_BITRATE_192K, - V4L2_MPEG_AUDIO_AC3_BITRATE_224K, - V4L2_MPEG_AUDIO_AC3_BITRATE_256K, - V4L2_MPEG_AUDIO_AC3_BITRATE_320K, - V4L2_MPEG_AUDIO_AC3_BITRATE_384K, - V4L2_MPEG_AUDIO_AC3_BITRATE_448K, - V4L2_MPEG_AUDIO_AC3_BITRATE_512K, - V4L2_MPEG_AUDIO_AC3_BITRATE_576K, - V4L2_MPEG_AUDIO_AC3_BITRATE_640K, -) = range(19) - -V4L2_CID_MPEG_VIDEO_ENCODING = V4L2_CID_MPEG_BASE + 200 - -v4l2_mpeg_video_encoding = enum -( - V4L2_MPEG_VIDEO_ENCODING_MPEG_1, - V4L2_MPEG_VIDEO_ENCODING_MPEG_2, - V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, -) = range(3) - -V4L2_CID_MPEG_VIDEO_ASPECT = V4L2_CID_MPEG_BASE + 201 - -v4l2_mpeg_video_aspect = enum -( - V4L2_MPEG_VIDEO_ASPECT_1x1, - V4L2_MPEG_VIDEO_ASPECT_4x3, - V4L2_MPEG_VIDEO_ASPECT_16x9, - V4L2_MPEG_VIDEO_ASPECT_221x100, -) = range(4) - -V4L2_CID_MPEG_VIDEO_B_FRAMES = V4L2_CID_MPEG_BASE + 202 -V4L2_CID_MPEG_VIDEO_GOP_SIZE = V4L2_CID_MPEG_BASE + 203 -V4L2_CID_MPEG_VIDEO_GOP_CLOSURE = V4L2_CID_MPEG_BASE + 204 -V4L2_CID_MPEG_VIDEO_PULLDOWN = V4L2_CID_MPEG_BASE + 205 -V4L2_CID_MPEG_VIDEO_BITRATE_MODE = V4L2_CID_MPEG_BASE + 206 - -v4l2_mpeg_video_bitrate_mode = enum -( - V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, - V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, -) = range(2) - -V4L2_CID_MPEG_VIDEO_BITRATE = V4L2_CID_MPEG_BASE + 207 -V4L2_CID_MPEG_VIDEO_BITRATE_PEAK = V4L2_CID_MPEG_BASE + 208 -V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION = V4L2_CID_MPEG_BASE + 209 -V4L2_CID_MPEG_VIDEO_MUTE = V4L2_CID_MPEG_BASE + 210 -V4L2_CID_MPEG_VIDEO_MUTE_YUV = V4L2_CID_MPEG_BASE + 211 - -V4L2_CID_MPEG_CX2341X_BASE = V4L2_CTRL_CLASS_MPEG | 0x1000 -V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE = V4L2_CID_MPEG_CX2341X_BASE + 0 - -v4l2_mpeg_cx2341x_video_spatial_filter_mode = enum -( - V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL, - V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO, -) = range(2) - -V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER = V4L2_CID_MPEG_CX2341X_BASE + 1 -V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE = V4L2_CID_MPEG_CX2341X_BASE + 2 - -v4l2_mpeg_cx2341x_video_luma_spatial_filter_type = enum -( - V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF, - V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR, - V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_VERT, - V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE, - V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE, -) = range(5) - -V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE = V4L2_CID_MPEG_CX2341X_BASE + 3 - -v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type = enum -( - V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF, - V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR, -) = range(2) - -V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE = V4L2_CID_MPEG_CX2341X_BASE + 4 - -v4l2_mpeg_cx2341x_video_temporal_filter_mode = enum -( - V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL, - V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO, -) = range(2) - -V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER = V4L2_CID_MPEG_CX2341X_BASE + 5 -V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE = V4L2_CID_MPEG_CX2341X_BASE + 6 - -v4l2_mpeg_cx2341x_video_median_filter_type = enum -( - V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF, - V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR, - V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_VERT, - V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT, - V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG, -) = range(5) - -V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM = V4L2_CID_MPEG_CX2341X_BASE + 7 -V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP = V4L2_CID_MPEG_CX2341X_BASE + 8 -V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM = V4L2_CID_MPEG_CX2341X_BASE + 9 -V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP = V4L2_CID_MPEG_CX2341X_BASE + 10 -V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS = V4L2_CID_MPEG_CX2341X_BASE + 11 - -V4L2_CID_CAMERA_CLASS_BASE = V4L2_CTRL_CLASS_CAMERA | 0x900 -V4L2_CID_CAMERA_CLASS = V4L2_CTRL_CLASS_CAMERA | 1 - -V4L2_CID_EXPOSURE_AUTO = V4L2_CID_CAMERA_CLASS_BASE + 1 - -v4l2_exposure_auto_type = enum -( - V4L2_EXPOSURE_AUTO, - V4L2_EXPOSURE_MANUAL, - V4L2_EXPOSURE_SHUTTER_PRIORITY, - V4L2_EXPOSURE_APERTURE_PRIORITY, -) = range(4) - -V4L2_CID_EXPOSURE_ABSOLUTE = V4L2_CID_CAMERA_CLASS_BASE + 2 -V4L2_CID_EXPOSURE_AUTO_PRIORITY = V4L2_CID_CAMERA_CLASS_BASE + 3 - -V4L2_CID_PAN_RELATIVE = V4L2_CID_CAMERA_CLASS_BASE + 4 -V4L2_CID_TILT_RELATIVE = V4L2_CID_CAMERA_CLASS_BASE + 5 -V4L2_CID_PAN_RESET = V4L2_CID_CAMERA_CLASS_BASE + 6 -V4L2_CID_TILT_RESET = V4L2_CID_CAMERA_CLASS_BASE + 7 - -V4L2_CID_PAN_ABSOLUTE = V4L2_CID_CAMERA_CLASS_BASE + 8 -V4L2_CID_TILT_ABSOLUTE = V4L2_CID_CAMERA_CLASS_BASE + 9 - -V4L2_CID_FOCUS_ABSOLUTE = V4L2_CID_CAMERA_CLASS_BASE + 10 -V4L2_CID_FOCUS_RELATIVE = V4L2_CID_CAMERA_CLASS_BASE + 11 -V4L2_CID_FOCUS_AUTO = V4L2_CID_CAMERA_CLASS_BASE + 12 - -V4L2_CID_ZOOM_ABSOLUTE = V4L2_CID_CAMERA_CLASS_BASE + 13 -V4L2_CID_ZOOM_RELATIVE = V4L2_CID_CAMERA_CLASS_BASE + 14 -V4L2_CID_ZOOM_CONTINUOUS = V4L2_CID_CAMERA_CLASS_BASE + 15 - -V4L2_CID_PRIVACY = V4L2_CID_CAMERA_CLASS_BASE + 16 - -V4L2_CID_FM_TX_CLASS_BASE = V4L2_CTRL_CLASS_FM_TX | 0x900 -V4L2_CID_FM_TX_CLASS = V4L2_CTRL_CLASS_FM_TX | 1 - -V4L2_CID_RDS_TX_DEVIATION = V4L2_CID_FM_TX_CLASS_BASE + 1 -V4L2_CID_RDS_TX_PI = V4L2_CID_FM_TX_CLASS_BASE + 2 -V4L2_CID_RDS_TX_PTY = V4L2_CID_FM_TX_CLASS_BASE + 3 -V4L2_CID_RDS_TX_PS_NAME = V4L2_CID_FM_TX_CLASS_BASE + 5 -V4L2_CID_RDS_TX_RADIO_TEXT = V4L2_CID_FM_TX_CLASS_BASE + 6 - -V4L2_CID_AUDIO_LIMITER_ENABLED = V4L2_CID_FM_TX_CLASS_BASE + 64 -V4L2_CID_AUDIO_LIMITER_RELEASE_TIME = V4L2_CID_FM_TX_CLASS_BASE + 65 -V4L2_CID_AUDIO_LIMITER_DEVIATION = V4L2_CID_FM_TX_CLASS_BASE + 66 - -V4L2_CID_AUDIO_COMPRESSION_ENABLED = V4L2_CID_FM_TX_CLASS_BASE + 80 -V4L2_CID_AUDIO_COMPRESSION_GAIN = V4L2_CID_FM_TX_CLASS_BASE + 81 -V4L2_CID_AUDIO_COMPRESSION_THRESHOLD = V4L2_CID_FM_TX_CLASS_BASE + 82 -V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME = V4L2_CID_FM_TX_CLASS_BASE + 83 -V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME = V4L2_CID_FM_TX_CLASS_BASE + 84 - -V4L2_CID_PILOT_TONE_ENABLED = V4L2_CID_FM_TX_CLASS_BASE + 96 -V4L2_CID_PILOT_TONE_DEVIATION = V4L2_CID_FM_TX_CLASS_BASE + 97 -V4L2_CID_PILOT_TONE_FREQUENCY = V4L2_CID_FM_TX_CLASS_BASE + 98 - -V4L2_CID_TUNE_PREEMPHASIS = V4L2_CID_FM_TX_CLASS_BASE + 112 - -v4l2_preemphasis = enum -( - V4L2_PREEMPHASIS_DISABLED, - V4L2_PREEMPHASIS_50_uS, - V4L2_PREEMPHASIS_75_uS, -) = range(3) - -V4L2_CID_TUNE_POWER_LEVEL = V4L2_CID_FM_TX_CLASS_BASE + 113 -V4L2_CID_TUNE_ANTENNA_CAPACITOR = V4L2_CID_FM_TX_CLASS_BASE + 114 - - -# Image source controls - -V4L2_CID_IMAGE_SOURCE_CLASS_BASE = V4L2_CTRL_CLASS_IMAGE_SOURCE | 0x900 -V4L2_CID_IMAGE_SOURCE_CLASS = V4L2_CTRL_CLASS_IMAGE_SOURCE | 1 - -V4L2_CID_VBLANK = V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 1 -V4L2_CID_HBLANK = V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 2 -V4L2_CID_ANALOGUE_GAIN = V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 3 -V4L2_CID_TEST_PATTERN_RED = V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 4 -V4L2_CID_TEST_PATTERN_GREENR = V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 5 -V4L2_CID_TEST_PATTERN_BLUE = V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 6 -V4L2_CID_TEST_PATTERN_GREENB = V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 7 -V4L2_CID_UNIT_CELL_SIZE = V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 8 - -# Image processing controls - -V4L2_CID_IMAGE_PROC_CLASS_BASE = V4L2_CTRL_CLASS_IMAGE_PROC | 0x900 -V4L2_CID_IMAGE_PROC_CLASS = V4L2_CTRL_CLASS_IMAGE_PROC | 1 - -V4L2_CID_LINK_FREQ = V4L2_CID_IMAGE_PROC_CLASS_BASE + 1 -V4L2_CID_PIXEL_RATE = V4L2_CID_IMAGE_PROC_CLASS_BASE + 2 -V4L2_CID_TEST_PATTERN = V4L2_CID_IMAGE_PROC_CLASS_BASE + 3 -V4L2_CID_DEINTERLACING_MODE = V4L2_CID_IMAGE_PROC_CLASS_BASE + 4 -V4L2_CID_DIGITAL_GAIN = V4L2_CID_IMAGE_PROC_CLASS_BASE + 5 - - -# -# Tuning -# - - -class v4l2_tuner(ctypes.Structure): - _fields_ = [ - ("index", ctypes.c_uint32), - ("name", ctypes.c_char * 32), - ("type", v4l2_tuner_type), - ("capability", ctypes.c_uint32), - ("rangelow", ctypes.c_uint32), - ("rangehigh", ctypes.c_uint32), - ("rxsubchans", ctypes.c_uint32), - ("audmode", ctypes.c_uint32), - ("signal", ctypes.c_int32), - ("afc", ctypes.c_int32), - ("reserved", ctypes.c_uint32 * 4), - ] - - -class v4l2_modulator(ctypes.Structure): - _fields_ = [ - ("index", ctypes.c_uint32), - ("name", ctypes.c_char * 32), - ("capability", ctypes.c_uint32), - ("rangelow", ctypes.c_uint32), - ("rangehigh", ctypes.c_uint32), - ("txsubchans", ctypes.c_uint32), - ("reserved", ctypes.c_uint32 * 4), - ] - - -V4L2_TUNER_CAP_LOW = 0x0001 -V4L2_TUNER_CAP_NORM = 0x0002 -V4L2_TUNER_CAP_STEREO = 0x0010 -V4L2_TUNER_CAP_LANG2 = 0x0020 -V4L2_TUNER_CAP_SAP = 0x0020 -V4L2_TUNER_CAP_LANG1 = 0x0040 -V4L2_TUNER_CAP_RDS = 0x0080 - -V4L2_TUNER_SUB_MONO = 0x0001 -V4L2_TUNER_SUB_STEREO = 0x0002 -V4L2_TUNER_SUB_LANG2 = 0x0004 -V4L2_TUNER_SUB_SAP = 0x0004 -V4L2_TUNER_SUB_LANG1 = 0x0008 -V4L2_TUNER_SUB_RDS = 0x0010 - -V4L2_TUNER_MODE_MONO = 0x0000 -V4L2_TUNER_MODE_STEREO = 0x0001 -V4L2_TUNER_MODE_LANG2 = 0x0002 -V4L2_TUNER_MODE_SAP = 0x0002 -V4L2_TUNER_MODE_LANG1 = 0x0003 -V4L2_TUNER_MODE_LANG1_LANG2 = 0x0004 - - -class v4l2_frequency(ctypes.Structure): - _fields_ = [ - ("tuner", ctypes.c_uint32), - ("type", v4l2_tuner_type), - ("frequency", ctypes.c_uint32), - ("reserved", ctypes.c_uint32 * 8), - ] - - -class v4l2_hw_freq_seek(ctypes.Structure): - _fields_ = [ - ("tuner", ctypes.c_uint32), - ("type", v4l2_tuner_type), - ("seek_upward", ctypes.c_uint32), - ("wrap_around", ctypes.c_uint32), - ("reserved", ctypes.c_uint32 * 8), - ] - - -# -# RDS -# - - -class v4l2_rds_data(ctypes.Structure): - _fields_ = [ - ("lsb", ctypes.c_char), - ("msb", ctypes.c_char), - ("block", ctypes.c_char), - ] - - _pack_ = True - - -V4L2_RDS_BLOCK_MSK = 0x7 -V4L2_RDS_BLOCK_A = 0 -V4L2_RDS_BLOCK_B = 1 -V4L2_RDS_BLOCK_C = 2 -V4L2_RDS_BLOCK_D = 3 -V4L2_RDS_BLOCK_C_ALT = 4 -V4L2_RDS_BLOCK_INVALID = 7 - -V4L2_RDS_BLOCK_CORRECTED = 0x40 -V4L2_RDS_BLOCK_ERROR = 0x80 - - -# -# Audio -# - - -class v4l2_audio(ctypes.Structure): - _fields_ = [ - ("index", ctypes.c_uint32), - ("name", ctypes.c_char * 32), - ("capability", ctypes.c_uint32), - ("mode", ctypes.c_uint32), - ("reserved", ctypes.c_uint32 * 2), - ] - - -V4L2_AUDCAP_STEREO = 0x00001 -V4L2_AUDCAP_AVL = 0x00002 - -V4L2_AUDMODE_AVL = 0x00001 - - -class v4l2_audioout(ctypes.Structure): - _fields_ = [ - ("index", ctypes.c_uint32), - ("name", ctypes.c_char * 32), - ("capability", ctypes.c_uint32), - ("mode", ctypes.c_uint32), - ("reserved", ctypes.c_uint32 * 2), - ] - - -# -# Mpeg services (experimental) -# - -V4L2_ENC_IDX_FRAME_I = 0 -V4L2_ENC_IDX_FRAME_P = 1 -V4L2_ENC_IDX_FRAME_B = 2 -V4L2_ENC_IDX_FRAME_MASK = 0xF - - -class v4l2_enc_idx_entry(ctypes.Structure): - _fields_ = [ - ("offset", ctypes.c_uint64), - ("pts", ctypes.c_uint64), - ("length", ctypes.c_uint32), - ("flags", ctypes.c_uint32), - ("reserved", ctypes.c_uint32 * 2), - ] - - -V4L2_ENC_IDX_ENTRIES = 64 - - -class v4l2_enc_idx(ctypes.Structure): - _fields_ = [ - ("entries", ctypes.c_uint32), - ("entries_cap", ctypes.c_uint32), - ("reserved", ctypes.c_uint32 * 4), - ("entry", v4l2_enc_idx_entry * V4L2_ENC_IDX_ENTRIES), - ] - - -V4L2_ENC_CMD_START = 0 -V4L2_ENC_CMD_STOP = 1 -V4L2_ENC_CMD_PAUSE = 2 -V4L2_ENC_CMD_RESUME = 3 - -V4L2_ENC_CMD_STOP_AT_GOP_END = 1 << 0 - - -class v4l2_encoder_cmd(ctypes.Structure): - class _u(ctypes.Union): - class _s(ctypes.Structure): - _fields_ = [ - ("data", ctypes.c_uint32 * 8), - ] - - _fields_ = [ - ("raw", _s), - ] - - _fields_ = [ - ("cmd", ctypes.c_uint32), - ("flags", ctypes.c_uint32), - ("_u", _u), - ] - - _anonymous_ = ("_u",) - - -# -# Data services (VBI) -# - - -class v4l2_vbi_format(ctypes.Structure): - _fields_ = [ - ("sampling_rate", ctypes.c_uint32), - ("offset", ctypes.c_uint32), - ("samples_per_line", ctypes.c_uint32), - ("sample_format", ctypes.c_uint32), - ("start", ctypes.c_int32 * 2), - ("count", ctypes.c_uint32 * 2), - ("flags", ctypes.c_uint32), - ("reserved", ctypes.c_uint32 * 2), - ] - - -V4L2_VBI_UNSYNC = 1 << 0 -V4L2_VBI_INTERLACED = 1 << 1 - - -class v4l2_sliced_vbi_format(ctypes.Structure): - _fields_ = [ - ("service_set", ctypes.c_uint16), - ("service_lines", ctypes.c_uint16 * 2 * 24), - ("io_size", ctypes.c_uint32), - ("reserved", ctypes.c_uint32 * 2), - ] - - -V4L2_SLICED_TELETEXT_B = 0x0001 -V4L2_SLICED_VPS = 0x0400 -V4L2_SLICED_CAPTION_525 = 0x1000 -V4L2_SLICED_WSS_625 = 0x4000 -V4L2_SLICED_VBI_525 = V4L2_SLICED_CAPTION_525 -V4L2_SLICED_VBI_625 = V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625 - - -class v4l2_sliced_vbi_cap(ctypes.Structure): - _fields_ = [ - ("service_set", ctypes.c_uint16), - ("service_lines", ctypes.c_uint16 * 2 * 24), - ("type", v4l2_buf_type), - ("reserved", ctypes.c_uint32 * 3), - ] - - -class v4l2_sliced_vbi_data(ctypes.Structure): - _fields_ = [ - ("id", ctypes.c_uint32), - ("field", ctypes.c_uint32), - ("line", ctypes.c_uint32), - ("reserved", ctypes.c_uint32), - ("data", ctypes.c_char * 48), - ] - - -# -# Sliced VBI data inserted into MPEG Streams -# - - -V4L2_MPEG_VBI_IVTV_TELETEXT_B = 1 -V4L2_MPEG_VBI_IVTV_CAPTION_525 = 4 -V4L2_MPEG_VBI_IVTV_WSS_625 = 5 -V4L2_MPEG_VBI_IVTV_VPS = 7 - - -class v4l2_mpeg_vbi_itv0_line(ctypes.Structure): - _fields_ = [ - ("id", ctypes.c_char), - ("data", ctypes.c_char * 42), - ] - - _pack_ = True - - -class v4l2_mpeg_vbi_itv0(ctypes.Structure): - _fields_ = [ - ("linemask", ctypes.c_uint32 * 2), # how to define __le32 in ctypes? - ("line", v4l2_mpeg_vbi_itv0_line * 35), - ] - - _pack_ = True - - -class v4l2_mpeg_vbi_ITV0(ctypes.Structure): - _fields_ = [ - ("line", v4l2_mpeg_vbi_itv0_line * 36), - ] - - _pack_ = True - - -V4L2_MPEG_VBI_IVTV_MAGIC0 = "itv0" -V4L2_MPEG_VBI_IVTV_MAGIC1 = "ITV0" - - -class v4l2_mpeg_vbi_fmt_ivtv(ctypes.Structure): - class _u(ctypes.Union): - _fields_ = [ - ("itv0", v4l2_mpeg_vbi_itv0), - ("ITV0", v4l2_mpeg_vbi_ITV0), - ] - - _fields_ = [("magic", ctypes.c_char * 4), ("_u", _u)] - - _anonymous_ = ("_u",) - _pack_ = True - - -# -# Aggregate structures -# - - -class v4l2_format(ctypes.Structure): - class _u(ctypes.Union): - _fields_ = [ - ("pix", v4l2_pix_format), - ("win", v4l2_window), - ("vbi", v4l2_vbi_format), - ("sliced", v4l2_sliced_vbi_format), - ("raw_data", ctypes.c_char * 200), - ] - - _fields_ = [ - ("type", v4l2_buf_type), - ("fmt", _u), - ] - - -class v4l2_streamparm(ctypes.Structure): - class _u(ctypes.Union): - _fields_ = [ - ("capture", v4l2_captureparm), - ("output", v4l2_outputparm), - ("raw_data", ctypes.c_char * 200), - ] - - _fields_ = [("type", v4l2_buf_type), ("parm", _u)] - - -# -# Advanced debugging -# - -V4L2_CHIP_MATCH_HOST = 0 -V4L2_CHIP_MATCH_I2C_DRIVER = 1 -V4L2_CHIP_MATCH_I2C_ADDR = 2 -V4L2_CHIP_MATCH_AC97 = 3 - - -class v4l2_dbg_match(ctypes.Structure): - class _u(ctypes.Union): - _fields_ = [ - ("addr", ctypes.c_uint32), - ("name", ctypes.c_char * 32), - ] - - _fields_ = [ - ("type", ctypes.c_uint32), - ("_u", _u), - ] - - _anonymous_ = ("_u",) - _pack_ = True - - -class v4l2_dbg_register(ctypes.Structure): - _fields_ = [ - ("match", v4l2_dbg_match), - ("size", ctypes.c_uint32), - ("reg", ctypes.c_uint64), - ("val", ctypes.c_uint64), - ] - - _pack_ = True - - -class v4l2_dbg_chip_ident(ctypes.Structure): - _fields_ = [ - ("match", v4l2_dbg_match), - ("ident", ctypes.c_uint32), - ("revision", ctypes.c_uint32), - ] - - _pack_ = True - - -# -# ioctl codes for video devices -# - -VIDIOC_QUERYCAP = _IOR("V", 0, v4l2_capability) -VIDIOC_RESERVED = _IO("V", 1) -VIDIOC_ENUM_FMT = _IOWR("V", 2, v4l2_fmtdesc) -VIDIOC_G_FMT = _IOWR("V", 4, v4l2_format) -VIDIOC_S_FMT = _IOWR("V", 5, v4l2_format) -VIDIOC_REQBUFS = _IOWR("V", 8, v4l2_requestbuffers) -VIDIOC_QUERYBUF = _IOWR("V", 9, v4l2_buffer) -VIDIOC_G_FBUF = _IOR("V", 10, v4l2_framebuffer) -VIDIOC_S_FBUF = _IOW("V", 11, v4l2_framebuffer) -VIDIOC_OVERLAY = _IOW("V", 14, ctypes.c_int) -VIDIOC_QBUF = _IOWR("V", 15, v4l2_buffer) -VIDIOC_DQBUF = _IOWR("V", 17, v4l2_buffer) -VIDIOC_STREAMON = _IOW("V", 18, ctypes.c_int) -VIDIOC_STREAMOFF = _IOW("V", 19, ctypes.c_int) -VIDIOC_G_PARM = _IOWR("V", 21, v4l2_streamparm) -VIDIOC_S_PARM = _IOWR("V", 22, v4l2_streamparm) -VIDIOC_G_STD = _IOR("V", 23, v4l2_std_id) -VIDIOC_S_STD = _IOW("V", 24, v4l2_std_id) -VIDIOC_ENUMSTD = _IOWR("V", 25, v4l2_standard) -VIDIOC_ENUMINPUT = _IOWR("V", 26, v4l2_input) -VIDIOC_G_CTRL = _IOWR("V", 27, v4l2_control) -VIDIOC_S_CTRL = _IOWR("V", 28, v4l2_control) -VIDIOC_G_TUNER = _IOWR("V", 29, v4l2_tuner) -VIDIOC_S_TUNER = _IOW("V", 30, v4l2_tuner) -VIDIOC_G_AUDIO = _IOR("V", 33, v4l2_audio) -VIDIOC_S_AUDIO = _IOW("V", 34, v4l2_audio) -VIDIOC_QUERYCTRL = _IOWR("V", 36, v4l2_queryctrl) -VIDIOC_QUERYMENU = _IOWR("V", 37, v4l2_querymenu) -VIDIOC_G_INPUT = _IOR("V", 38, ctypes.c_int) -VIDIOC_S_INPUT = _IOWR("V", 39, ctypes.c_int) -VIDIOC_G_OUTPUT = _IOR("V", 46, ctypes.c_int) -VIDIOC_S_OUTPUT = _IOWR("V", 47, ctypes.c_int) -VIDIOC_ENUMOUTPUT = _IOWR("V", 48, v4l2_output) -VIDIOC_G_AUDOUT = _IOR("V", 49, v4l2_audioout) -VIDIOC_S_AUDOUT = _IOW("V", 50, v4l2_audioout) -VIDIOC_G_MODULATOR = _IOWR("V", 54, v4l2_modulator) -VIDIOC_S_MODULATOR = _IOW("V", 55, v4l2_modulator) -VIDIOC_G_FREQUENCY = _IOWR("V", 56, v4l2_frequency) -VIDIOC_S_FREQUENCY = _IOW("V", 57, v4l2_frequency) -VIDIOC_CROPCAP = _IOWR("V", 58, v4l2_cropcap) -VIDIOC_G_CROP = _IOWR("V", 59, v4l2_crop) -VIDIOC_S_CROP = _IOW("V", 60, v4l2_crop) -VIDIOC_G_JPEGCOMP = _IOR("V", 61, v4l2_jpegcompression) -VIDIOC_S_JPEGCOMP = _IOW("V", 62, v4l2_jpegcompression) -VIDIOC_QUERYSTD = _IOR("V", 63, v4l2_std_id) -VIDIOC_TRY_FMT = _IOWR("V", 64, v4l2_format) -VIDIOC_ENUMAUDIO = _IOWR("V", 65, v4l2_audio) -VIDIOC_ENUMAUDOUT = _IOWR("V", 66, v4l2_audioout) -VIDIOC_G_PRIORITY = _IOR("V", 67, v4l2_priority) -VIDIOC_S_PRIORITY = _IOW("V", 68, v4l2_priority) -VIDIOC_G_SLICED_VBI_CAP = _IOWR("V", 69, v4l2_sliced_vbi_cap) -VIDIOC_LOG_STATUS = _IO("V", 70) -VIDIOC_G_EXT_CTRLS = _IOWR("V", 71, v4l2_ext_controls) -VIDIOC_S_EXT_CTRLS = _IOWR("V", 72, v4l2_ext_controls) -VIDIOC_TRY_EXT_CTRLS = _IOWR("V", 73, v4l2_ext_controls) - -VIDIOC_ENUM_FRAMESIZES = _IOWR("V", 74, v4l2_frmsizeenum) -VIDIOC_ENUM_FRAMEINTERVALS = _IOWR("V", 75, v4l2_frmivalenum) -VIDIOC_G_ENC_INDEX = _IOR("V", 76, v4l2_enc_idx) -VIDIOC_ENCODER_CMD = _IOWR("V", 77, v4l2_encoder_cmd) -VIDIOC_TRY_ENCODER_CMD = _IOWR("V", 78, v4l2_encoder_cmd) - -VIDIOC_DBG_S_REGISTER = _IOW("V", 79, v4l2_dbg_register) -VIDIOC_DBG_G_REGISTER = _IOWR("V", 80, v4l2_dbg_register) - -VIDIOC_DBG_G_CHIP_IDENT = _IOWR("V", 81, v4l2_dbg_chip_ident) - -VIDIOC_S_HW_FREQ_SEEK = _IOW("V", 82, v4l2_hw_freq_seek) -VIDIOC_ENUM_DV_PRESETS = _IOWR("V", 83, v4l2_dv_enum_preset) -VIDIOC_S_DV_PRESET = _IOWR("V", 84, v4l2_dv_preset) -VIDIOC_G_DV_PRESET = _IOWR("V", 85, v4l2_dv_preset) -VIDIOC_QUERY_DV_PRESET = _IOR("V", 86, v4l2_dv_preset) -VIDIOC_S_DV_TIMINGS = _IOWR("V", 87, v4l2_dv_timings) -VIDIOC_G_DV_TIMINGS = _IOWR("V", 88, v4l2_dv_timings) - -VIDIOC_G_SELECTION = _IOWR("V", 94, v4l2_selection) -VIDIOC_S_SELECTION = _IOWR("V", 95, v4l2_selection) - -VIDIOC_OVERLAY_OLD = _IOWR("V", 14, ctypes.c_int) -VIDIOC_S_PARM_OLD = _IOW("V", 22, v4l2_streamparm) -VIDIOC_S_CTRL_OLD = _IOW("V", 28, v4l2_control) -VIDIOC_G_AUDIO_OLD = _IOWR("V", 33, v4l2_audio) -VIDIOC_G_AUDOUT_OLD = _IOWR("V", 49, v4l2_audioout) -VIDIOC_CROPCAP_OLD = _IOR("V", 58, v4l2_cropcap) - -VIDIOC_QUERY_EXT_CTRL = _IOWR("V", 103, v4l2_query_ext_ctrl) - -BASE_VIDIOC_PRIVATE = 192 +from linuxpy.video.raw import *