Skip to content

Commit

Permalink
Merge pull request #36 from tiagocoutinho/vivid-tests
Browse files Browse the repository at this point in the history
Add video tests for vivid
  • Loading branch information
tiagocoutinho authored Aug 29, 2024
2 parents 1cdbc41 + a1291a0 commit 9ed094a
Show file tree
Hide file tree
Showing 7 changed files with 284 additions and 133 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
default_language_version:
python: python3.10
python: python3.12
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
Expand Down
35 changes: 24 additions & 11 deletions docs/develop.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,24 +36,37 @@ $ python -m linuxpy.codegen.cli

## Running tests

Some video tests will only run with a properly configured `vivid` driver.
First make sure your user belongs to `input` and `video` groups (create those
groups if they don't exist):

```console
$ sudo modprobe vivid n_devs=1 vid_cap_nr=190 vid_out_nr=191 meta_cap_nr=192 meta_out_nr=193
$ sudo addgroup input
$ sudo addgroup video
$ sudo addgroup led
$ sudo adduser $USER input
$ sudo adduser $USER video
```

Additionally the user which runs the tests will need read/write access to
`/dev/video190`, `/dev/video191`, `/dev/video192` and `/dev/video193`.
On most systems this can be achieved by adding the user to the `video` group:
(reboot if necessary for those changes to take effect)

```console
$ sudo addgroup $USER video
Change the udev rules so these groups have access to the devices used by tests:

Create a new rules file (ex: `/etc/udev/rules.d/80-device.rules`):

```
KERNEL=="event[0-9]*", SUBSYSTEM=="input", GROUP="input", MODE:="0660"
KERNEL=="uinput", SUBSYSTEM=="misc", GROUP="input", MODE:="0660"
SUBSYSTEM=="video4linux", MODE:="0666"
KERNEL=="uleds", GROUP="input", MODE:="0660"
SUBSYSTEM=="leds", ACTION=="add", RUN+="/bin/chmod -R g=u,o=u /sys%p"
SUBSYSTEM=="leds", ACTION=="change", ENV{TRIGGER}!="none", RUN+="/bin/chmod -R g=u,o=u /sys%p"
```

Some input tests require the user which runs the tests to have read/write
access to `/dev/uinput`.
On most systems this can be achieved by adding the user to the `input` group:
Finally, make sure all kernel modules are installed:

```console
$ sudo addgroup $USER input
$ sudo modprobe uinput
$ sudo modprobe uleds
$ sudo modprobe -r vivid
$ sudo modprobe vivid n_devs=1 vid_cap_nr=190 vid_out_nr=191 meta_cap_nr=192 meta_out_nr=193
```
52 changes: 26 additions & 26 deletions linuxpy/codegen/video.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,32 +67,32 @@
# STD macros are too complicated to auto generate
class StandardID(enum.IntFlag):
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 # BTSC
V4L2_STD_NTSC_M_JP = 0x00002000 # EIA-J
V4L2_STD_NTSC_443 = 0x00004000
V4L2_STD_NTSC_M_KR = 0x00008000 # FM A2
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
PAL_B = 0x00000001
PAL_B1 = 0x00000002
PAL_G = 0x00000004
PAL_H = 0x00000008
PAL_I = 0x00000010
PAL_D = 0x00000020
PAL_D1 = 0x00000040
PAL_K = 0x00000080
PAL_M = 0x00000100
PAL_N = 0x00000200
PAL_Nc = 0x00000400
PAL_60 = 0x00000800
NTSC_M = 0x00001000 # BTSC
NTSC_M_JP = 0x00002000 # EIA-J
NTSC_443 = 0x00004000
NTSC_M_KR = 0x00008000 # FM A2
SECAM_B = 0x00010000
SECAM_D = 0x00020000
SECAM_G = 0x00040000
SECAM_H = 0x00080000
SECAM_K = 0x00100000
SECAM_K1 = 0x00200000
SECAM_L = 0x00400000
SECAM_LC = 0x00800000
ATSC_8_VSB = 0x01000000
ATSC_16_VSB = 0x02000000
{iocs_body}"""

Expand Down
52 changes: 16 additions & 36 deletions linuxpy/video/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -569,8 +569,8 @@ def set_selection(fd, buffer_type, target, rectangle):
def get_selection(
fd,
buffer_type: BufferType,
target: SelectionTarget = SelectionTarget.CROP_DEFAULT,
):
target: SelectionTarget = SelectionTarget.CROP,
) -> Rect:
sel = raw.v4l2_selection()
sel.type = buffer_type
sel.target = target
Expand All @@ -594,31 +594,18 @@ def get_control(fd, id):


CTRL_TYPE_CTYPE_STRUCT = {
ControlType.AREA: raw.v4l2_area,
# ControlType.AREA: raw.v4l2_area,
}


def _struct_for_ctrl_type(ctrl_type):
ctrl_type = ControlType(ctrl_type).name.lower()
name = f"v4l2_ctrl_{ctrl_type}"
return getattr(raw, name)


def _field_for_control(control):
has_payload = ControlFlag.HAS_PAYLOAD in ControlFlag(control.flags)
if has_payload:
if control.type == ControlType.INTEGER:
return "p_s32"
elif control.type == ControlType.INTEGER64:
return "p_s64"
elif control.type == ControlType.STRING:
return "string"
else:
ctrl_name = ControlType(control.type).name.lower()
return f"p_{ctrl_name}"
if control.type == ControlType.INTEGER64:
return "value64"
return "value"
try:
return getattr(raw, name)
except AttributeError:
name = f"v4l2_{ctrl_type}"
return getattr(raw, name)


def get_ctrl_type_struct(ctrl_type):
Expand Down Expand Up @@ -703,13 +690,13 @@ def _prepare_write_controls_values(control: raw.v4l2_query_ext_ctrl, value: obje
else:
array_type = CTRL_TYPE_CTYPE_ARRAY.get(control.type)
raw_control.size = control.elem_size * control.elems
field = _field_for_control(control)
# a struct: assume value is proper raw struct
if array_type is None:
value = ctypes.pointer(value)
else:
value = convert_to_ctypes_array(value, control.nr_of_dims, array_type)
setattr(raw_control, field, value)
ptr = ctypes.cast(value, ctypes.c_void_p)
raw_control.ptr = ptr
else:
if control.type == ControlType.INTEGER64:
raw_control.value64 = value
Expand Down Expand Up @@ -818,20 +805,20 @@ def set_output(fd, index: int):
ioctl(fd, IOC.S_OUTPUT, index)


def get_std(fd):
def get_std(fd) -> StandardID:
out = ctypes.c_uint64()
ioctl(fd, IOC.G_STD, out)
return out.value
return StandardID(out.value)


def set_std(fd, std):
ioctl(fd, IOC.S_STD, std)


def query_std(fd):
def query_std(fd) -> StandardID:
out = ctypes.c_uint64()
ioctl(fd, IOC.QUERYSTD, out)
return out.value
return StandardID(out.value)


# Helpers
Expand Down Expand Up @@ -986,13 +973,13 @@ def get_output(self):
def set_output(self, index: int):
return set_output(self.fileno(), index)

def get_std(self):
def get_std(self) -> StandardID:
return get_std(self.fileno())

def set_std(self, std):
return set_std(self.fileno(), std)

def query_std(self):
def query_std(self) -> StandardID:
return query_std(self.fileno())


Expand Down Expand Up @@ -1067,13 +1054,6 @@ def __setattr__(self, key, value):
self._init_if_needed()
self[key] = value

def __delattr__(self, key):
self._init_if_needed()
try:
del self[key]
except KeyError as error:
raise AttributeError(key) from error

def __missing__(self, key):
self._init_if_needed()
for v in self.values():
Expand Down
52 changes: 26 additions & 26 deletions linuxpy/video/raw.py
Original file line number Diff line number Diff line change
Expand Up @@ -4038,32 +4038,32 @@ class v4l2_subdev_client_capability(Struct):


class StandardID(enum.IntFlag):
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 # BTSC
V4L2_STD_NTSC_M_JP = 0x00002000 # EIA-J
V4L2_STD_NTSC_443 = 0x00004000
V4L2_STD_NTSC_M_KR = 0x00008000 # FM A2
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
PAL_B = 0x00000001
PAL_B1 = 0x00000002
PAL_G = 0x00000004
PAL_H = 0x00000008
PAL_I = 0x00000010
PAL_D = 0x00000020
PAL_D1 = 0x00000040
PAL_K = 0x00000080
PAL_M = 0x00000100
PAL_N = 0x00000200
PAL_Nc = 0x00000400
PAL_60 = 0x00000800
NTSC_M = 0x00001000 # BTSC
NTSC_M_JP = 0x00002000 # EIA-J
NTSC_443 = 0x00004000
NTSC_M_KR = 0x00008000 # FM A2
SECAM_B = 0x00010000
SECAM_D = 0x00020000
SECAM_G = 0x00040000
SECAM_H = 0x00080000
SECAM_K = 0x00100000
SECAM_K1 = 0x00200000
SECAM_L = 0x00400000
SECAM_LC = 0x00800000
ATSC_8_VSB = 0x01000000
ATSC_16_VSB = 0x02000000


class IOC(enum.IntEnum):
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Source = "https://github.com/tiagocoutinho/linuxpy"
[project.optional-dependencies]
dev = [
"build>=0.10.0",
"gevent>=21",
"twine>=4.0.2",
"ward>=0.68.0b0",
"ward-coverage>=0.3.0",
Expand Down
Loading

0 comments on commit 9ed094a

Please sign in to comment.