diff --git a/utils/mc-print.py b/utils/mc-print.py index 4621387..a35b201 100755 --- a/utils/mc-print.py +++ b/utils/mc-print.py @@ -201,7 +201,15 @@ def print_pads(ent, subdev, videodev, only_graph: bool, print_supported): def print_entity(ent, only_graph: bool, print_supported): - print(ent.name, ent.interface.dev_path if ent.interface else '') + print(f'Entity {ent.id}: \'{ent.name}\', Function: {ent.function.name}', end='') + if ent.interface: + print(f', Interface: {ent.interface.intf_type.name}', end='') + if ent.interface.dev_path: + print(f', Path: {ent.interface.dev_path}') + else: + print() + else: + print() if ent.interface and ent.interface.is_subdev: subdev = v4l2.SubDevice(ent.interface.dev_path) @@ -252,6 +260,9 @@ def main(): flatten = lambda t: [item for sublist in t for item in sublist] + print(f'Driver: {md.driver}, Model: {md.model}, Bus info: {md.bus_info}') + print() + printed = set() while len(print_queue) > 0: diff --git a/v4l2/enums.py b/v4l2/enums.py new file mode 100644 index 0000000..d348d09 --- /dev/null +++ b/v4l2/enums.py @@ -0,0 +1,68 @@ +from enum import Enum, IntFlag + +import v4l2.uapi + +__all__ = [ 'MediaEntityFunction', 'MediaLinkFlag', 'MediaPadFlag', 'MediaInterfaceType' ] + +class MediaEntityFunction(Enum): + UNKNOWN = v4l2.uapi.MEDIA_ENT_F_UNKNOWN + V4L2_SUBDEV_UNKNOWN = v4l2.uapi.MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN + DTV_DEMOD = v4l2.uapi.MEDIA_ENT_F_DTV_DEMOD + TS_DEMUX = v4l2.uapi.MEDIA_ENT_F_TS_DEMUX + DTV_CA = v4l2.uapi.MEDIA_ENT_F_DTV_CA + DTV_NET_DECAP = v4l2.uapi.MEDIA_ENT_F_DTV_NET_DECAP + IO_V4L = v4l2.uapi.MEDIA_ENT_F_IO_V4L + IO_DTV = v4l2.uapi.MEDIA_ENT_F_IO_DTV + IO_VBI = v4l2.uapi.MEDIA_ENT_F_IO_VBI + IO_SWRADIO = v4l2.uapi.MEDIA_ENT_F_IO_SWRADIO + CAM_SENSOR = v4l2.uapi.MEDIA_ENT_F_CAM_SENSOR + FLASH = v4l2.uapi.MEDIA_ENT_F_FLASH + LENS = v4l2.uapi.MEDIA_ENT_F_LENS + TUNER = v4l2.uapi.MEDIA_ENT_F_TUNER + IF_VID_DECODER = v4l2.uapi.MEDIA_ENT_F_IF_VID_DECODER + IF_AUD_DECODER = v4l2.uapi.MEDIA_ENT_F_IF_AUD_DECODER + AUDIO_CAPTURE = v4l2.uapi.MEDIA_ENT_F_AUDIO_CAPTURE + AUDIO_PLAYBACK = v4l2.uapi.MEDIA_ENT_F_AUDIO_PLAYBACK + AUDIO_MIXER = v4l2.uapi.MEDIA_ENT_F_AUDIO_MIXER + PROC_VIDEO_COMPOSER = v4l2.uapi.MEDIA_ENT_F_PROC_VIDEO_COMPOSER + PROC_VIDEO_PIXEL_FORMATTER = v4l2.uapi.MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER + PROC_VIDEO_PIXEL_ENC_CONV = v4l2.uapi.MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV + PROC_VIDEO_LUT = v4l2.uapi.MEDIA_ENT_F_PROC_VIDEO_LUT + PROC_VIDEO_SCALER = v4l2.uapi.MEDIA_ENT_F_PROC_VIDEO_SCALER + PROC_VIDEO_STATISTICS = v4l2.uapi.MEDIA_ENT_F_PROC_VIDEO_STATISTICS + PROC_VIDEO_ENCODER = v4l2.uapi.MEDIA_ENT_F_PROC_VIDEO_ENCODER + PROC_VIDEO_DECODER = v4l2.uapi.MEDIA_ENT_F_PROC_VIDEO_DECODER + PROC_VIDEO_ISP = v4l2.uapi.MEDIA_ENT_F_PROC_VIDEO_ISP + VID_MUX = v4l2.uapi.MEDIA_ENT_F_VID_MUX + VID_IF_BRIDGE = v4l2.uapi.MEDIA_ENT_F_VID_IF_BRIDGE + ATV_DECODER = v4l2.uapi.MEDIA_ENT_F_ATV_DECODER + DV_DECODER = v4l2.uapi.MEDIA_ENT_F_DV_DECODER + DV_ENCODER = v4l2.uapi.MEDIA_ENT_F_DV_ENCODER + +class MediaLinkFlag(IntFlag): + ENABLED = v4l2.uapi.MEDIA_LNK_FL_ENABLED + IMMUTABLE = v4l2.uapi.MEDIA_LNK_FL_IMMUTABLE + DYNAMIC = v4l2.uapi.MEDIA_LNK_FL_DYNAMIC + +class MediaPadFlag(IntFlag): + SINK = v4l2.uapi.MEDIA_PAD_FL_SINK + SOURCE = v4l2.uapi.MEDIA_PAD_FL_SOURCE + MUST_CONNECT = v4l2.uapi.MEDIA_PAD_FL_MUST_CONNECT + INTERNAL = v4l2.uapi.MEDIA_PAD_FL_INTERNAL + +class MediaInterfaceType(Enum): + DVB_FE = v4l2.uapi.MEDIA_INTF_T_DVB_FE + DVB_DEMUX = v4l2.uapi.MEDIA_INTF_T_DVB_DEMUX + DVB_DVR = v4l2.uapi.MEDIA_INTF_T_DVB_DVR + DVB_CA = v4l2.uapi.MEDIA_INTF_T_DVB_CA + DVB_NET = v4l2.uapi.MEDIA_INTF_T_DVB_NET + V4L_VIDEO = v4l2.uapi.MEDIA_INTF_T_V4L_VIDEO + V4L_VBI = v4l2.uapi.MEDIA_INTF_T_V4L_VBI + V4L_RADIO = v4l2.uapi.MEDIA_INTF_T_V4L_RADIO + V4L_SUBDEV = v4l2.uapi.MEDIA_INTF_T_V4L_SUBDEV + V4L_SWRADIO = v4l2.uapi.MEDIA_INTF_T_V4L_SWRADIO + V4L_TOUCH = v4l2.uapi.MEDIA_INTF_T_V4L_TOUCH + ALSA_BASE = v4l2.uapi.MEDIA_INTF_T_ALSA_BASE + ALSA_PCM_CAPTURE = v4l2.uapi.MEDIA_INTF_T_ALSA_PCM_CAPTURE + ALSA_PCM_PLAYBACK = v4l2.uapi.MEDIA_INTF_T_ALSA_PCM_PLAYBACK + ALSA_CONTROL = v4l2.uapi.MEDIA_INTF_T_ALSA_CONTROL diff --git a/v4l2/media.py b/v4l2/media.py index deeb51f..c4d1d83 100644 --- a/v4l2/media.py +++ b/v4l2/media.py @@ -1,6 +1,5 @@ from __future__ import annotations -from enum import IntFlag import ctypes import fcntl import weakref @@ -9,6 +8,7 @@ import fnmatch import v4l2.uapi from .helpers import filepath_for_major_minor +from .enums import MediaEntityFunction, MediaLinkFlag, MediaPadFlag, MediaInterfaceType __all__ = [ 'MediaObject', 'MediaEntity', 'MediaInterface', 'MediaPad', 'MediaLink', @@ -41,7 +41,7 @@ def __init__(self, md, media_entity: v4l2.uapi.media_v2_entity) -> None: super().__init__(md, media_entity.id) self.media_entity = media_entity self.name = media_entity.name.decode('ascii') - self.function = media_entity.function + self.function = MediaEntityFunction(media_entity.function) self.flags = media_entity.flags self.pads: list['MediaPad'] = None # type: ignore self.interface: 'MediaInterface' = None # type: ignore @@ -81,6 +81,7 @@ def __init__(self, md, media_iface: v4l2.uapi.media_v2_interface) -> None: self.media_iface = media_iface self.majorminor = (self.media_iface.unnamed_1.devnode.major, self.media_iface.unnamed_1.devnode.minor) self.dev_path = filepath_for_major_minor(*self.majorminor) + self.intf_type = MediaInterfaceType(self.media_iface.intf_type) def _finalize(self): # pylint: disable=useless-parent-delegation super()._finalize() @@ -190,6 +191,7 @@ def __init__(self, name: str, key: str = 'path') -> None: key = 'path' self.fd = os.open(name, os.O_RDWR | os.O_NONBLOCK) + self.__read_device_info() self.__read_topology() weakref.finalize(self, os.close, self.fd) @@ -220,6 +222,26 @@ def get_device_info(self): fcntl.ioctl(self.fd, v4l2.uapi.MEDIA_IOC_DEVICE_INFO, mdi, True) return mdi + @staticmethod + def __decode_kernel_version(v: int): + a = (v >> 16) & 0xff + b = (v >> 8) & 0xff + c = v & 0xff + return (a, b, c) + + def __read_device_info(self): + mdi = v4l2.uapi.media_device_info() + fcntl.ioctl(self.fd, v4l2.uapi.MEDIA_IOC_DEVICE_INFO, mdi, True) + + self.driver = mdi.driver.decode() + self.model = mdi.model.decode() + self.serial = mdi.serial.decode() + self.bus_info = mdi.bus_info.decode() + self.media_version = MediaDevice.__decode_kernel_version(mdi.media_version) + self.hw_revision = mdi.hw_revision + self.driver_version = MediaDevice.__decode_kernel_version(mdi.driver_version) + + def __read_topology(self): topology = v4l2.uapi.media_v2_topology() @@ -272,14 +294,3 @@ def find_entity(self, name): if fnmatch.fnmatch(e.name, name): return e return None - -class MediaLinkFlag(IntFlag): - ENABLED = v4l2.uapi.MEDIA_LNK_FL_ENABLED - IMMUTABLE = v4l2.uapi.MEDIA_LNK_FL_IMMUTABLE - DYNAMIC = v4l2.uapi.MEDIA_LNK_FL_DYNAMIC - -class MediaPadFlag(IntFlag): - SINK = v4l2.uapi.MEDIA_PAD_FL_SINK - SOURCE = v4l2.uapi.MEDIA_PAD_FL_SOURCE - MUST_CONNECT = v4l2.uapi.MEDIA_PAD_FL_MUST_CONNECT - INTERNAL = v4l2.uapi.MEDIA_PAD_FL_INTERNAL