Программирование ARM Устройства Video4Linux Mon, October 27 2025  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.


Устройства Video4Linux Печать
Добавил(а) microsin   

[2.1. Введение]

Драйверы V4L2 имеют тенденцию становиться все более сложными из-за сложности аппаратуры: большинство устройств имеют несколько микросхем (IC), экспортируют несколько узлов устройства (device nodes) в /dev, и также создают non-V4L2 устройства, такие как DVB, ALSA, FB, I2C и устройства ввода (IR).

В особенности тот факт, что драйверы V4L2 должны настраивать поддержку IC для мультиплексирования/кодирования/декодирования потоков звука/видео, еще больше усложняют задачу реализации драйвера. Обычно эти IC подключены к драйверу основного моста (main bridge driver) через одну или несколько шин I2C, но могут использоваться и другие шины. Такие устройства называются 'sub-devices'.

Долгое время фреймворк ограничивался структурой video_device для создания узлов V4L устройств и video_buf для обработки видео-буферов (отметим, что в данном документе фреймворк video_buf не обсуждается). Это означало, что все драйверы должны были выполнять настройку экземпляров устройств и подключение к самим sub-устройствам. Что-то из этого довольно сложно сделать правильно, и многие драйверы никогда не делали это правильно.

Есть также много общего кода, который никогда не мог бы быть переработан из-за отсутствия фреймворка. Таким образом, этот фреймворк устанавливает основные строительные блоки, которые нужны всем драйверам, и эта же структура должна значительно упростить рефакторинг общего кода в служебные функции, общие для всех драйверов.

Хорошим примером, на который следует обратить внимание в качестве ссылки, является исходник v4l2-pci-skeleton.c, доступный в samples/v4l/. Он является скелетным драйвером для карты захвата PCI и демонстрирует, как использовать фреймворк драйверов V4L2. Его можно использовать в качестве шаблона для реального драйвера видеозахвата PCI.

[2.2. Структура драйвера V4L]

Все драйвера имеют следующую структуру:

1. Структура для каждого экземпляра устройства (device instance), в которой содержится его состояние (device state).
2. Способ инициализации и управления экземплярами sub-устройств (sub-device instances, при их наличии).
3. Создание узлов устройств (V4L2 device nodes: /dev/videoX, /dev/vbiX и /dev/radioX), и отслеживание специфических данных device-node.
4. Структуры, специфичные для файловых операций, содержащие данные о файловых операциях (filehandle instances).
5. Обработка видеобуфера.

Грубая схема, как это выглядит:

device instances
  |
  +-sub-device instances
  |
  \-V4L2 device nodes
      |
      \-filehandle instances

[2.3. Структура фреймворка V4L2]

Фреймворк очень похож на структуру драйвера: в нем есть структура v4l2_device для данных экземпляра устройства, структура v4l2_subdev для ссылки на экземпляры sub-устройств, структура video_device для хранения данных V4L2 device node и структура v4l2_fh для отслеживания экземпляров дескрипторов файлов (filehandle instances).

В фреймворк V4L2 также опционально интегрируется фреймворк media. Если драйвер установил поле mdev структуры v4l2_device, то sub-устройства и video nodes будут автоматически отображаться как сущности в фреймворке media.

struct v4l2_device {
struct device *dev;
struct media_device *mdev;
struct list_head subdevs;
spinlock_t lock;
char name[36];
void (*notify)(struct v4l2_subdev *sd, unsigned int notification, void *arg);
struct v4l2_ctrl_handler *ctrl_handler;
struct v4l2_prio_state prio;
struct kref ref;
void (*release)(struct v4l2_device *v4l2_dev); };

Описание полей v4l2_device:

dev указатель на структуру device.

mdev указатель на структуру media_device, он может быть NULL.

subdevs используется для отслеживания зарегистрированных sub-устройств.

lock блокировка этой структуры. Может также использоваться драйвером, если эта структура встроена в более крупную структуру.

name уникальное имя устройства, по умолчанию имя драйвера + bus ID.

notify Операция оповещения, вызываемая некоторыми sub-устройствами.

ctrl_handler Обработчик управления. Может быть NULL.

prio состояние приоритета устройства.

ref отслеживание ссылок на эту структуру.

release функция освобождения, когда счетчик ref достигает 0.

Общее описание. Каждый экземпляр устройства V4L2 должен создать структуру v4l2_device, либо отдельную, либо встроенную в более крупную структуру. Она позволяет упростить доступ к sub-устройствам (см. v4l2-subdev.h) и предоставляет базовую поддержку V4L2 на уровне устройства.

Замечания:

1. dev->driver_data указывает на эту структуру.
2. Поле dev может быть NULL если здесь нет родительского устройства.

[2.4. Внутреннее представление video-устройства]

Реальные узлы устройств (device nodes) в директории /dev создаются с использование структуры video_device (v4l2-dev.h). Эта структура может быть либо выделена динамически, либо встроена в более крупную структуру.

Заголовочный файл v4l2-dev.h может быть расположен в следующих каталогах (в зависимости от версии операционной системы).

Для SDK LuckFox:

~/luckfox-pico/sysdrv/source/kernel/include/media/

Для Ubuntu 24.04.3 LTS:

/usr/src/linux-hwe-6.14-headers-6.14.0-33/include/media/

Структуры video_device в файлах v4l2-dev.h SDK LuckFox и Ubuntu linux-hwe-6.14-headers-6.14.0-33 почти совпадают, за исключением того, что для поля name в LuckFox выделено меньше памяти (32 байта вместо 64), и в Ubuntu есть 2 дополнительные зарезервированные поля ANDROID_KABI_RESERVE(1) и ANDROID_KABI_RESERVE(2).

Структура video_device из v4l2-dev.h SDK LuckFox:

/**
* struct video_device - Структура для создания V4L2 device nodes
* и управления ими.
*
* @entity: &struct media_entity
* @intf_devnode: указатель на &struct media_intf_devnode
* @pipe: &struct media_pipeline
* @fops: указатель на &struct v4l2_file_operations для video device
* @device_caps: device capabilities, как они используются в v4l2_capabilities
* @dev: &struct device (адрес структуры устройства) для video device
* @cdev: символьное устройство (character device)
* @v4l2_dev: указатель на родительское устройство (&struct v4l2_device parent)
* @dev_parent: указатель на &struct device parent
* @ctrl_handler: дескриптор управления, связанный с этим device node.
* Может быть NULL.
* @queue: &struct vb2_queue, связанная с этим device node. Может быть NULL.
* @prio: указатель на &struct v4l2_prio_state с состоянием приоритета устройства
* (Priority state). Если NULL, то будет использоваться v4l2_dev->prio.
* @name: имя video-устройства
* @vfl_type: тип V4L device, как определено в &enum vfl_devnode_type
* @vfl_dir: приемник V4L, передатчик или m2m
* @minor: device node 'minor'. Установлено в -1, если при регистрации была ошибка
* @num: номер video device node
* @flags: флаги video-устройства. Используйте bitops для установки/очистки/проверки
* flags. Содержат набор &enum v4l2_video_device_flags.
* @index: атрибут для дифференциации нескольких индексов на одном физическом устройстве
* @fh_lock: блокировка для всех v4l2_fh
* @fh_list: список &struct v4l2_fh
* @dev_debug: внутренние флаги отладки устройства, не для использования драйверами
* @tvnorms: поддерживаемые нормы tv
*
* @release: video device release() callback
* @ioctl_ops: указатель на &struct v4l2_ioctl_ops with ioctl callbacks
*
* @valid_ioctls: bitmap с допустимыми ioctls для этого устройства
* @lock: указатель на &struct mutex serialization lock
*
* .. замечание::
* Только установлен @dev_parent, если нельзя вывести из @v4l2_dev.
*/
struct video_device {
#if defined(CONFIG_MEDIA_CONTROLLER)
struct media_entity entity;
struct media_intf_devnode *intf_devnode;
struct media_pipeline pipe;
#endif
const struct v4l2_file_operations *fops;

u32 device_caps;

/* sysfs */
struct device dev;
struct cdev *cdev;

struct v4l2_device *v4l2_dev;
struct device *dev_parent;

struct v4l2_ctrl_handler *ctrl_handler;

struct vb2_queue *queue;

struct v4l2_prio_state *prio;

/* Информация устройства */
char name[64];
enum vfl_devnode_type vfl_type;
enum vfl_devnode_direction vfl_dir;
int minor; u16 num;
unsigned long flags;
int index;

/* Дескрипторы файлов V4L2 */
spinlock_t fh_lock;
struct list_head fh_list;

int dev_debug;

v4l2_std_id tvnorms;

/* Функции обратного вызова (callbacks) */
void (*release)(struct video_device *vdev);
const struct v4l2_ioctl_ops *ioctl_ops;
DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE);

struct mutex *lock; };

Для динамического выделения используйте video_device_alloc():

struct video_device *vdev = video_device_alloc();

if (vdev == NULL)
return -ENOMEM;
vdev->release = video_device_release;

Если вы встраиваете экземпляр video_device в более крупную структуру, то должны установить release() на вашу собственную функцию:

struct video_device *vdev = &my_vdev->vdev;
vdev->release = my_vdev_release;

Функция обратного вызова release() должна быть установлена и она вызывается, когда вышел последний пользователь video-устройства.

Функция обратно вызова по умолчанию video_device_release() просто вызывает kfree для освобождения выделенной памяти.

Существует также функция video_device_release_empty(), которая ничего не делает (она пустая) и должна использоваться, если структура встроена, и при ее освобождении делать нечего не надо.

Вы также должны установить следующие поля video_device:

video_device->v4l2_dev: должно быть установлено в родительское устройство (v4l2_device parent).

video_device->name: установите в что-то описательное и уникальное.

video_device->vfl_dir: установите это в VFL_DIR_RX для устройства захвата (VFL_DIR_RX имеет значение 0, так что это уже нормальное готовое значение по умолчанию), в VFL_DIR_TX для устройств вывода и VFL_DIR_M2M для устройств mem2mem (кодек).

video_device->fops: установите в структуру v4l2_file_operations.

video_device->ioctl_ops: если вы используете v4l2_ioctl_ops для упрощения обслуживания ioctl (настоятельно рекомендуется использовать это, что может стать обязательным в будущем!), то установите это в вашу структуры v4l2_ioctl_ops. Поля video_device->vfl_type и video_device->vfl_dir используются для запрета операций, которые не соответствуют комбинации type/dir. Например, операции VBI запрещены для non-VBI nodes, и операции вывода запрещены для устройства захвата (capture device). Это делает возможным предоставление только одной структуры v4l2_ioctl_ops и для vbi, и для video nodes.

Аббревиатура VBI расшифровывается как Vertical Blanking Interval, т. е. импульс вертикальной синхронизации видеосигнала. Термины VBI и non-VBI в контексте фреймворка V4L2 относятся к разным способам захвата и обработки видео данных. Вот их основные различия:

Аспект VBI Non-VBI (основной видеосигнал)
Что представляет Данные в "гасящем импульсе" (интервале между кадрами) Основное изображение (видеокадр)
Тип данных Служебные данные: телетекст, скрытые субтитры, телемагазин Пиксели основного видеоизображения
API V4L2 V4L2_BUF_TYPE_VBI_CAPTURE / V4L2_BUF_TYPE_VBI_OUTPUT V4L2_BUF_TYPE_VIDEO_CAPTURE / V4L2_BUF_TYPE_VIDEO_OUTPUT
Флаги возможностей V4L2_CAP_VBI_CAPTURE / V4L2_CAP_VBI_OUTPUT V4L2_CAP_VIDEO_CAPTURE / V4L2_CAP_VIDEO_OUTPUT
Устройства в /dev /dev/vbiX (младшие номера 224-255) /dev/videoX (младшие номера 0-63)

[Практическое использование]

На практике VBI-данные можно получать не только через специальные устройства /dev/vbiX, но и через основные видеоустройства /dev/videoX. Для этого в драйвере должен быть установлен флаг V4L2_CAP_VBI_CAPTURE, а приложению нужно использовать тип буфера V4L2_BUF_TYPE_VBI_CAPTURE при вызове VIDIOC_S_FMT для установки формата.

Для проверки возможностей устройства, включая поддержку VBI, используйте утилиту v4l2-compliance.

video_device->lock: оставьте в значении leave to NULL, если хотите выполнить всю блокировку в драйвере. В противном случае вы даете этому полю указатель на структуру mutex_lock, и перед файловой операцией video_device->unlocked_ioctl эта блокировка будет взята и впоследствии освобождена ядром. Подробности см. в следующей секции.

video_device->queue: указатель на структуру vb2_queue связанную с этим device node. Если queue не NULL и queue->lock не NULL, то используется queue->lock для очередей ioctls (VIDIOC_REQBUFS, CREATE_BUFS, QBUF, DQBUF, QUERYBUF, PREPARE_BUF, STREAMON and STREAMOFF) вместо поля lock, показанного выше. Таким образом, фреймворку очередей vb2 не придется ждать других ioctls. Этот указатель на очередь также используются вспомогательными функциями vb2 для проверки владения очередью (т. е. разрешен ли вызов filehandle для выполнения операции).

video_device->prio: отслеживает приоритеты. Используется для реализации VIDIOC_G_PRIORITY и VIDIOC_S_PRIORITY. Если оставить в NULL, то будет использоваться структура v4l2_prio_state в v4l2_device. Если вы хотите иметь отдельное состояние приоритета для (группы) узлов устройств, вы можете указать полем prio на свою собственную структуру v4l2_prio_ state.

video_device->dev_parent: это значение устанавливается только в том случае, если v4l2_device было зарегистрировано с NULL в качестве структуры родительского устройства. Это происходит только в тех случаях, когда одно аппаратное устройство имеет несколько устройств PCI, которые все используют одно и то же ядро v4l2_device.

Примером этого является драйвер cx88: одна коренная структура v4l2_device, но это использует как raw video PCI device (cx8800), так и MPEG PCI device (cx8802). Поскольку v4l2_device не может быть одновременно связано с двумя устройствами PCI, то оно устанавливается без родительского устройства. Но когда инициализируется структура video_device, вы знаете, какое родительское устройство PCI использовать, и поэтому вы устанавливаете dev_device в корректное устройство PCI.

Если вы используете v4l2_ioctl_ops, то должны установить video_device->unlocked_ioctl в video_ioctl2() своей структуры v4l2_file_operations.

В некоторых случаях вы захотите сказать ядру, что функция, указанная в вашем v4l2_ioctl_ ops, должна игнорироваться. Отметить такие ioctls можно, вызвав эту функцию до вызова video_ register_device():

v4l2_disable_ioctl (vdev, cmd);

Это обычно необходимо, если на основе внешних факторов (например какая карта используется) вы хотите отключить определенные функции в v4l2_ioctl_ops без необходимости создавать новую структуру.

Структура v4l2_file_operations это подмножество file_operations. Основное отличие заключается в том, что аргумент inode опущен, поскольку он никогда не используется.

Если необходима интеграция с фреймворком media, то вы должны инициализировать структуру media_entity, встроенную в структуру video_device (поле entity) путем вызова media_entity_pads_init():

struct media_pad *pad = &my_vdev->pad;
int err;
err = media_entity_pads_init(&vdev->entity, 1, pad);

Массив pad-ов должен быть предварительно инициализирован. Здесь не надо вручную устанавливать поля типа struct media_entity и имени name.

Ссылка на entity будет автоматически захвачена/освобождена, когда video-устройство открывается/закрывается.

2.4.1. ioctls и блокировка

Ядро V4L предоставляет опциональные службы блокировки (locking services). Основная служба это поле lock в структуре video_device, которое является указателем на мьютекс. Если вы установили этот указатель, то он будет использоваться unlocked_ioctl для сериализации всех ioctls.

Если вы используете фреймворк videobuf2, то здесь есть вторая блокировка, которую вы можете установить: video_device->queue->lock. Если она установлена, то будет использоваться вместо video_device->lock для сериализации всех поставленных в очередь ioctls (см. предыдущую секцию для полного списка этих ioctls).

videobuf2 — это фреймворк внутри ядра Linux, который предоставляет унифицированную систему управления буферами для подсистемы V4L2.

[Основное назначение]

Videobuf2 абстрагирует работу с буферами видео данных, предоставляя единый API для:

- Выделения памяти
- Управления буферами
- Синхронизации между пользовательским пространством и ядром
- Поддержки различных моделей ввода-вывода

[Типы буферов (Memory Types)]

Videobuf2 поддерживает несколько моделей памяти:

1. V4L2_MEMORY_MMAP

// Буферы выделяются в ядре, отображаются в пользовательское пространство
struct vb2_queue q = {
.memory = V4L2_MEMORY_MMAP,
.ops = &my_vb2_ops, };

2. V4L2_MEMORY_USERPTR

// Пользовательское пространство предоставляет указатели на память
struct v4l2_buffer buf = {
.memory = V4L2_MEMORY_USERPTR,
.m.userptr = (unsigned long)user_buffer, };

3. V4L2_MEMORY_DMABUF

// Используются DMA-буферы (Direct Memory Access)
struct v4l2_buffer buf = {
.memory = V4L2_MEMORY_DMABUF,
.m.fd = dmabuf_fd, };

[Архитектура и компоненты]

Основные структуры:

struct vb2_queue          // Очередь буферов
struct vb2_buffer         // Буфер данных
struct vb2_ops            // Операции драйвера
struct vb2_mem_ops        // Операции с памятью

Типичная инициализация в драйвере:

static const struct vb2_ops my_vb2_ops = {
.queue_setup = my_queue_setup,
.buf_prepare = my_buf_prepare,
.buf_queue = my_buf_queue,
.start_streaming = my_start_streaming,
.stop_streaming = my_stop_streaming,
.wait_prepare = vb2_ops_wait_prepare,
.wait_finish = vb2_ops_wait_finish, };

static int my_video_open(struct file *file) {
struct my_device *dev = video_drvdata(file);

dev->vb2_queue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
dev->vb2_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
dev->vb2_queue.ops = &my_vb2_ops;
dev->vb2_queue.mem_ops = &vb2_dma_contig_memops;
dev->vb2_queue.drv_priv = dev;

return vb2_queue_init(&dev->vb2_queue); }

[Поток данных]

Для захвата видео (Capture):

1. QBUF → Буфер ставится в очередь драйвера
2. DQBUF → Заполненный буфер возвращается пользователю
3. STREAMON → Начало потока данных

Для вывода видео (Output):

1. QBUF → Буфер с данными для вывода
2. DQBUF → Освобожденный буфер возвращается
3. STREAMON → Начало вывода

[Преимущества использования videobuf2]

- Стандартизация: единый подход для всех V4L2 драйверов
- Производительность: оптимизированные операции с памятью
- Безопасность: проверка корректности операций
- Поддержка Zero-copy: через DMABUF и MMAP

[Практическое использование]

Драйверы, использующие videobuf2, обычно реализуют:

- Обработчики операций vb2_ops
- Callback-и для управления потоком данных
- Поддержку различных форматов пикселей

Videobuf2 значительно упрощает разработку V4L2 драйверов, беря на себя сложные аспекты управления памятью и синхронизации, позволяя разработчику сосредоточиться на специфичной для устройства логике.

Преимущество использования другой блокировки для очередей ioctls заключается в том, что для некоторых драйверов (в частности драйверов USB) определенные команды, такие как настройка управления, могут занимать много времени, поэтому вы захотите использовать отдельную блокировку буферных очередей ioctls. Таким образом, ваш VIDIOC_DQBUF не останавливается, потому что драйвер занят изменением к примеру, экспозиции web-камеры.

Конечно, вы можете всегда делать всю блокировку самостоятельно, оставив оба указателя lock в состоянии NULL.

В случае videobuf2 вам понадобится реализовать две функции обратного вызова wait_prepare() и wait_finish() для разблокировки/блокировки, если это применимо. Если вы используете указатель queue->lock, то можете использовать вспомогательные функции vb2_ops_wait_prepare() и vb2_ops_wait_finish().

Реализация hotplug disconnect также должна принимать блокировку от video_device перед вызовом v4l2_device_disconnect. Если вы также используете video_device->queue->lock, то должны сначала заблокировать video_device->queue->lock, а затем video_device->lock. Таким способом вы можете быть уверены, что при вызове вами v4l2_device_disconnect() не будет выполняться ioctl.

2.4.2. Регистрация video-устройства

Затем вы регистрируете video устройство вызовом video_register_device(). Это создаст для вас символьное устройство (character device).

err = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
if (err) {
video_device_release(vdev); /* или kfree(my_vdev); */
return err; }

Если родительское устройство v4l2_device имеет поле mdev, отличное от NULL, объект видеоустройства будет автоматически зарегистрирован на устройстве media.

От аргумента type зависит, какое устройство регистрируется. Существуют следующие типы:

vfl_devnode_type Имя устройства Использование
VFL_TYPE_VIDEO /dev/videoX Для видеоустройств ввода/вывода (video input/output devices)
VFL_TYPE_VBI /dev/vbiX Для данных, передаваемых во время кадрового синхроимпульса/гашения (vertical blank data, например субтитры, телетекст)
VFL_TYPE_RADIO /dev/radioX Для радиоприемников (radio tuners)
VFL_TYPE_SUBDEV /dev/v4l-subdevX Для V4L2 subdevices
VFL_TYPE_SDR /dev/swradioX Для радиоприемников Software Defined Radio (SDR)
VFL_TYPE_TOUCH /dev/v4l-touchX Для датчиков касания (touch sensors)

Последний аргумент дает вам определенный контроль над используемым номером device node (т. е. значением X в имени videoX). Обычно вы передадите -1, чтобы позволить фреймворку v4l2 взять первое свободное число. Но иногда пользователи хотят выбрать определенный номер узла. Обычно драйверы позволяют пользователю выбрать определенный номер узла с помощью опции модуля драйвера. Затем этот номер передается этой функции, и video_register_device попытается выбрать этот номер узла устройства (device node). Если этот номер уже занят, то будет выбран следующий свободный номер device node, и в лог ядра будет послано предупреждающее сообщение (warning kernel log).

Другой вариант похожего случая использования - когда драйвер создает несколько устройств. Тогда может оказаться полезным разместить различные устройства в отдельных диапазонах. Например, устройства видеозахвата (video capture devices) начинаются с 0, а устройства видеовывода (video output devices) начинаются с 16. Таким образом, вы можете использовать последний аргумент, чтобы указать минимальный номер device node, и фреймворк v4l2 попытается выбрать первое свободное число, которое равно или больше переданного вами значения. Если попытка окажется неудачной, то он просто выберет первый свободный номер.

Поскольку в этом случае вас не волнует предупреждение о невозможности выбора указанного device node, вы можете вызвать вместо этого функцию video_register_device_no_warn().

Каждый раз при создании device node также создаются для вас некоторые атрибуты. Если вы заглянете в каталог /sys/class/video4linux, то увидите устройства. Перейдите например в каталог video0, и вы увидите атрибуты name, dev_debug, index и другие.

~$ cd /sys/class/video4linux/video0
/sys/class/video4linux/video0$ ls -1
dev
dev_debug
device
index
name
power
subsystem
uevent

Атрибут name это поле name в структуре video_device. Атрибут dev_debug может использоваться для разрешения отладки ядра. Более подробную информацию об этом см. в следующей секции.

Атрибут index это индекс device node: для каждого вызова video_register_device() индекс просто увеличивается на 1. Первое video device node, которое вы регистрируете, всегда начинается с индекса 0.

Пользователи могут установить правила udev, которые используют атрибут index для создания причудливых имен устройств (например, 'mpegX' для узлов устройств видеозахвата MPEG).

После того, как устройство было успешно зарегистрировано, вы затем можете использовать эти поля:

video_device->vfl_type: тип устройства, переданный в video_register_device().
video_device->minor: назначенный устройству minor-номер.
video_device->num: номер device node (т. е. X в videoX).
video_device->index: номер индекса устройства.

Если регистрация потерпела неудачу, то вам нужно вызвать video_device_release() для освобождения выделенной структуры video_device, или освобождения вашей собственной структуры, если video_device было в неё встроено. Функция обратного вызова vdev->release() никогда не будет вызвана, если регистрация была неудачной, и вы никогда не должны пытаться отменить регистрацию устройства, если его регистрация была неудачной.

2.4.3. video device debugging

Атрибут dev_debug, который создается для любого устройства video, vbi, radio или swradio в /sys/class/video4linux/< devX>/, позволит вам разрешить использование лога файловых операций.

Это маска бит, в которой могут быть установлены следующие биты:

Маска Описание
0x01 Лог имени ioctl и кода ошибки. В лог попадают VIDIOC_(D)QBUF ioctls только если также установлен бит 0x08.
0x02 Лог аргументов имени ioctl и кода ошибки. В лог попадают VIDIOC_(D)QBUF ioctls только если также установлен бит 0x08.
0x04 Лог файловых операций open, release, read, write, mmap и get_unmapped_area. Операции чтения и записи подадут в лог только если также установлен бит 0x08.
0x08 Лог файловых операций чтения и записи, а также VIDIOC_QBUF и VIDIOC_DQBUF ioctl-ы.
0x10 Лог операции опроса файла (poll file operation).
0x20 Лог ошибки и сообщений в операциях управления.

2.4.4. Video device cleanup

Когда должны быть удалены video device nodes, либо во время выгрузки драйвера, либо из-за того, что устройство USB было отключено, вы должны отменить его регистрацию вызовом:

video_unregister_device() (vdev);

Это удалит device nodes из sysfs (заставит udev удалить их из /dev).

После возврата из video_unregister_device() не могут больше произойти новые открытия очищенного устройства. Однако в случае устройств USB некоторые приложения все еще могут держать открытыми одно из этих device nodes. Поэтому после unregister все файловые операции (кроме release, конечно) также возвратят ошибку.

Когда выйдет последний пользователь video device node, вызывается функция обратного вызова vdev->release(), и здесь вы можете выполнить финальную очистку.

Не забудьте очистить объект media, связанный с video device, если он был инициализирован:

media_entity_cleanup (&vdev->entity);

Это может быть сделано из функции обратного вызова release.

2.4.5. helper-функции

Есть несколько вспомогательных функций:

● Для приватных данных файла и video_device

Вы можете установить/получить приватные данные драйвера в структуре video_device с помощью:

video_get_drvdata (vdev);
video_set_drvdata (vdev);

Обратите внимание, что вы можете безопасно вызвать video_set_drvdata() перед вызовом video_register_device().

И функция:

video_devdata (struct file *file);

.. возвратит video_device, принадлежащее структуре file.

Функция video_devdata() комбинирует video_get_drvdata() с video_devdata():

video_drvdata (struct file *file);

Вы можете перейти от структуры video_device к структуре v4l2_device с помощью:

struct v4l2_device *v4l2_dev = vdev->v4l2_dev;

● Для имени device node

video_device node kernel name может быть получено с помощью:

video_device_node_name (vdev);

Это имя используется в качестве hint инструментами userspace, такими как udev. Эта функция должна использоваться везде, где это возможно, вместо доступа к полям video_device::num и video_device::minor.

2.4.6. Функции и структуры данных video_device

enum vfl_devnode_type

Тип V4L2 device node.

Содержит значения:

VFL_TYPE_VIDEO Для устройств ввода/вывода video.
VFL_TYPE_VBI Для данных кадрового синхроимпульса (т. е. субтитров, телетекста).
VFL_TYPE_RADIO Для радиоприемников.
VFL_TYPE_SUBDEV Для V4L2 subdevices.
VFL_TYPE_SDR Для радиоприемников Software Defined Radio.
VFL_TYPE_TOUCH Для датчиков касания.
VFL_TYPE_MAX Количество типов VFL, должно быть последним в перечислении.

enum vfl_devnode_direction

Идентифицирует, чему соответствует структура video_device - приемнику, передатчику или устройству память-память.

Содержит константы:

VFL_DIR_RX Устройство является приемником.
VFL_DIR_TX Устройство является передатчиком.
VFL_DIR_M2M Устройство является перекодировщиком память-память.

Замечание: игнорируется, если enum vfl_devnode_type равно VFL_TYPE_SUBDEV.

enum v4l2_video_device_flags

Флаги, используемые структурой video_device.

Содержит константы:

V4L2_FL_REGISTERED Показывает, что структура video_device зарегистрирована. Драйверы могут очистить этот флаг, если они хотят заблокировать любой будущий доступ к устройству. Этот флаг очищается вызовом video_unregister_device.
V4L2_FL_USES_V4L2_FH Показывает, что file->private_data указывает на структуру v4l2_fh. Этот флаг устанавливается ядром, когда вызывается v4l2_fh_init(). Все драйвера должны это использовать.
V4L2_FL_QUIRK_INVERTED_CROP Некоторые старые драйверы M2M некорректно используют g/s_crop/cropcap: переставлены crop и compose. Если этот флаг установлен, то выбор целей переставляется в g/s_crop/cropcap функций модуля v4l2-ioctl.c. Это позволяет таким драйверам корректно реализовать selection API, но старое crop API все еще будет работать так, как ожидалось, для сохранения обратной совместимости. Для новых драйверов никогда не устанавливайте этот флаг.
V4L2_FL_SUBDEV_RO_DEVNODE Показывает, что video device node зарегистрировано в режиме только для чтения (read-only mode). Этот флаг применяется только к device nodes, зарегистрированным для sub-devices, он устанавливается ядром, когда sub-devices device nodes регистрируются вызовом v4l2_device_register_ro_subdev_nodes() и используется обработчик sub-device ioctl для ограничения доступа к некоторым вызовам ioctl.

struct v4l2_prio_state

Хранит состояния приоритета.

Определение:

struct v4l2_prio_state {
atomic_t prios[4]; };

Члены структуры:

prios массив элементов для сохранения приоритетов.

Замечание: размер массива prios соответствует количеству типов приоритета, определенных перечислением v4l2_priority.

void v4l2_prio_init(struct v4l2_prio_state *global)

Инициализирует структуру v4l2_prio_state.

Параметры:

struct v4l2_prio_state *global Указатель на структуру v4l2_prio_state.

int v4l2_prio_change(struct v4l2_prio_state *global,
                     enum v4l2_priority *local,
                     enum v4l2_priority new)

Меняет приоритет v4l2 file handler.

Параметры:

struct v4l2_prio_state *global Указатель на структуру v4l2_prio_state device node.

enum v4l2_priority *local Указатель на желаемый приоритет, как определено перечислением v4l2_priority.

enum v4l2_priority new Запрошенный тип приоритета, как определено перечислением v4l2_priority.

Замечание: эта функция должна использоваться только ядром V4L2.

void v4l2_prio_open(struct v4l2_prio_state *global,
                    enum v4l2_priority *local)

Реализует логику приоритета для открытия file handler.

Параметры:

struct v4l2_prio_state *global Указатель на структуру v4l2_prio_state device node.

enum v4l2_priority *local Указатель на желаемый приоритет, как определено перечислением v4l2_priority.

Замечание: эта функция должна использоваться только ядром V4L2.

void v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority local)

Реализует логику приоритета для закрытия file handler.

Параметры:

struct v4l2_prio_state *global Указатель на структуру v4l2_prio_state device node.

enum v4l2_priority local Приоритет для освобождения, как определено перечислением v4l2_priority.

Замечание: эта функция должна использоваться только ядром V4L2.

enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)

Возвратит максимальный приоритет, как сохранено в массиве global.

Параметры:

struct v4l2_prio_state *global Указатель на структуру v4l2_prio_state device node.

Замечание: эта функция должна использоваться только ядром V4L2.

int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority local)

Реализует логику приоритета для закрытия file handler.

Параметры:

struct v4l2_prio_state *global Указатель на структуру v4l2_prio_state device node.

enum v4l2_priority local Желаемый приоритет, как определено перечислением v4l2_priority local.

Замечание: эта функция должна использоваться только ядром V4L2.

struct v4l2_file_operations

Операции файловой системы, используемые устройством V4L2.

Определение:

struct v4l2_file_operations {
struct module *owner;
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
__poll_t (*poll) (struct file *, struct poll_table_struct *);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
#ifdef CONFIG_COMPAT;
long (*compat_ioctl32) (struct file *, unsigned int, unsigned long);
#endif;
unsigned long (*get_unmapped_area) (struct file *,
unsigned long,
unsigned long,
unsigned long,
unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct file *);
int (*release) (struct file *); };

Поля структуры:

owner Указатель на структуру module.

read Операции, необходимые для реализации системного вызова чтения (read() syscall).

write Операции, необходимые для реализации системного вызова записи (write() syscall).

poll Операции, необходимые для реализации poll() syscall.

unlocked_ioctl Операции, необходимые для реализации ioctl() syscall.

compat_ioctl32 Операции, необходимые для реализации ioctl() syscall специального случая, когда Kernel использует 64-разрядные инструкции, но userspace использует 32 бита.

get_unmapped_area Вызывается mmap() syscall, используется когда %!CONFIG_MMU.

mmap Операции, необходимые для реализации mmap() syscall.

open Операции, необходимые для реализации open() syscall.

release Операции, необходимые для реализации release() syscall.

Замечание: эти операции используются для реализации структуры файловых операций (fs struct file_operations) на драйверах V4L2. Ядро V4L2 переопределяет операции fs с некоторой дополнительной логикой, необходимой для подсистемы.

struct video_device

Эта структура используется для создания и обслуживания узлов видеоустройств systemfs (V4L2 device nodes).

struct video_device {
#if defined(CONFIG_MEDIA_CONTROLLER);
struct media_entity entity;
struct media_intf_devnode *intf_devnode;
struct media_pipeline pipe;
#endif;
const struct v4l2_file_operations *fops;
u32 device_caps;
struct device dev;
struct cdev *cdev;
struct v4l2_device *v4l2_dev;
struct device *dev_parent;
struct v4l2_ctrl_handler *ctrl_handler;
struct vb2_queue *queue;
struct v4l2_prio_state *prio;
char name[64];
enum vfl_devnode_type vfl_type;
enum vfl_devnode_direction vfl_dir;
int minor;
u16 num;
unsigned long flags;
int index;
spinlock_t fh_lock;
struct list_head fh_list;
int dev_debug;
v4l2_std_id tvnorms;
void (*release)(struct video_device *vdev);
const struct v4l2_ioctl_ops *ioctl_ops;
unsigned long valid_ioctls[BITS_TO_LONGS(BASE_VIDIOC_PRIVATE)];
struct mutex *lock; };

Поля структуры:

entity Структура media_entity, в V4L2 используется для интеграции устройства в Media Controller Framework — подсистему для управления сложными мультимедийными устройствами.

intf_devnode Указатель на структуру struct media_intf_devnode, служит для представления интерфейса устройства (device node) в рамках Media Controller — подсистемы Linux, предназначенной для управления сложными мультимедийными аппаратными конвейерами.

pipe Структура media_pipeline, используется для представления и управления конвейером обработки медиаданных — набором соединенных сущностей (entities), через которые поток данных проходит от источника к приемнику. Этот механизм обеспечивает целостность и предсказуемость сложных аппаратных конфигураций во время передачи данных.

fops Указатель на структуру v4l2_file_operations для video-устройства. Это набор callback-функций, которые драйвер устройства должен реализовать для обработки операций с файловым дескриптором (например, open, release, ioctl). Эта структура связывает системные вызовы с конкретной логикой драйвера.

device_caps Возможности устройства (capabilities), как они используются в v4l2_capabilities. Это поле в структуре struct v4l2_capability в V4L2, которое появилось в ядре Linux 3.1 для решения проблемы смешивания возможностей устройства и драйвера. Поле device_caps содержит только аппаратные возможности устройства, в отличие от основного поля capabilities, которое может включать как аппаратные возможности, так и возможности, предоставляемые драйвером.

dev Структура device для видео-устройства, используется для связи V4L2-устройства с общей моделью устройств Linux (Linux Device Model). Поле device обеспечивает интеграцию V4L2-устройства в системную иерархию устройств, предоставляя информацию о родительском устройстве и позволяя работать с системными ресурсами.

cdev Указатель на структуру символьного устройства, используется для связи V4L2-устройства с подсистемой символьных устройств (character devices) ядра Linux. Поле cdev представляет V4L2-устройство как символьное устройство в ядре, обеспечивая базовую функциональность для операций с файлами и взаимодействия с пространством пользователя.

v4l2_dev Указатель на структуру v4l2_device, это одно из самых важных полей, которое связывает конкретное видеоустройство с родительской структурой V4L2-устройства. Поле v4l2_dev устанавливает связь "родитель-потомок" между видеоустройством и общим V4L2-устройством, которое может содержать несколько отдельных видеоустройств.

dev_parent Указатель на структуру device родительского устройства.

ctrl_handler Дескриптор управления (control handler), связанный с этим узлом устройства (device node). Может быть NULL. Используется для управления контролами (настройками) V4L2-устройства, такими как яркость, контрастность, насыщенность, громкость и другие параметры. Поле ctrl_handler связывает видеоустройство с обработчиком контролов, который управляет всеми настройками устройства и предоставляет к ним единый интерфейс доступа.

queue Структура vb2_queue, связанная с этим device node. Может быть NULL. Используется для связи видеоустройства с очередью буферов, которая управляет процессом захвата или вывода видео данных через механизм videobuf2 (V4L2 videobuffer2 API). Обеспечивает централизованное управление буферами, обработку операций с буферами, разделение блокировок.

prio Указатель на структуру v4l2_prio_state с состоянием приоритета устройства (Priority state). Если NULL, то используется v4l2_dev->prio. Используется для управления приоритетами доступа к устройству, когда несколько процессов пытаются использовать одно видеоустройство одновременно. Поле prio реализует механизм приоритетного доступа, который определяет, какой процесс получит управление устройством при конкурирующих попытках открытия.

name Имя видеоустройства, используется для хранения человеко-читаемого имени видеоустройства, которое отображается в системах отладки, логировании и пользовательских интерфейсах. Поле name содержит понятное имя устройства, которое помогает идентифицировать его среди других видеоустройств в системе.

vfl_type Тип видеоустройства (V4L device type), как это определено перечислением vfl_devnode_type. Определяет тип видеоустройства в системе V4L2 и указывает, к какому классу устройств оно принадлежит.

vfl_dir Направление, в котором пересылаются видеоданные: V4L receiver, transmitter или m2m. Определяет тип видеоустройства в системе V4L2. Это поле играет ключевую роль в классификации устройств и определяет их поведение в системе.

minor Хранит младший номер (minor number) устройства в системе. Этот номер используется для идентификации конкретного экземпляра устройства в рамках одного типа V4L2-устройств. Устанавливается в -1, если регистрация была неудачной. Поле minor определяет уникальный идентификатор устройства, который вместе со старшим номером (major number) формирует полный номер устройства в системе Linux.

num Номер video device node, используется как альтернативный идентификатор устройства, но в современных ядрах Linux это поле в значительной степени устарело и не используется по своему первоначальному назначению. Сейчас поле практически не используется или дублирует значение minor.

flags Флаги видеоустройства. Используйте bitops для установки/очистки/проверки флагов. Содержит набор значений из перечисления v4l2_video_device_flags. Используется для хранения флагов состояния и настроек видеоустройства. Эти флаги управляют различными аспектами поведения устройства и его взаимодействия с системой: состояние устройства (зарегистрировано, доступно и т.д.), поведение драйвера при операциях ввода/вывода, поддерживаемые функции устройства, настройки доступа и синхронизации.

index Атрибут для дифференцирования нескольких индексов на одном физическом устройстве. Используется для указания желаемого номера устройства при его регистрации. Это поле позволяет драйверу запросить конкретный номер для устройства (например, /dev/video0, /dev/video1 и т.д.). Поле index служит для: запроса конкретного minor номера устройства, гарантированного порядка нумерации устройств, создания предсказуемых device node имен.

fh_lock Блокировка для всех файловых дескрипторов v4l2_fh (file handles), используется для синхронизации доступа к списку файловых дескрипторов, связанных с видеоустройством. Поле fh_lock защищает: список открытых файловых дескрипторов устройства, операции добавления/удаления file handles, доступ к общим ресурсам устройства из нескольких file handles.

fh_list Список структур v4l2_fh, используется для хранения списка всех открытых файловых дескрипторов (file handles), связанных с данным видеоустройством. Это позволяет ядру отслеживать, какие процессы или потоки в данный момент работают с устройством, и эффективно управлять уведомлениями о событиях.

dev_debug Внутренние флаги отладки устройства, не для использования драйверами. Используется для включения отладочного вывода в ядре, связанного с обработкой IOCTL-команд конкретного видеоустройства. Отладочную информацию можно активировать через sysfs, записав значение в файл dev_debug для нужного видеоустройства.

tvnorms Используется для указания поддерживаемых телевизионных стандартов устройством. Это поле особенно важно для TV-тюнеров, capture cards и других устройств, работающих с аналоговым видео. Поле tvnorms содержит битовую маску поддерживаемых телевизионных стандартов, таких как PAL, NTSC, SECAM и их варианты.

release Функция обратного вызова освобождения устройства (callback). Вызывается при окончательном освобождении видеоустройства. Это критически важная функция для корректного управления памятью и ресурсами. Функция release обеспечивает правильное освобождение всех ресурсов, связанных с видеоустройством, когда последняя ссылка на устройство удаляется из системы.

ioctl_ops Указатель на структуру v4l2_ioctl_ops с функциями обратного вызова интерфейса управления ввода/вывода (ioctl callbacks). Содержит указатель на таблицу обработчиков IOCTL-команд V4L2. Это одно из самых важных полей, которое определяет функциональность видеоустройства. Поле ioctl_ops связывает V4L2 IOCTL-команды с конкретными функциями-обработчиками в драйвере. Это основной механизм, через который приложения взаимодействуют с видеоустройством.

valid_ioctls Представляет собой битовую маску, которая используется для отслеживания допустимых операций ввода-вывода (ioctl), поддерживаемых конкретным видеоустройством. Это внутренний механизм V4L2 фреймворка для управления доступными командами.

lock Указатель на структуру mutex для блокировки сериализации. Используется для синхронизации доступа к устройству между различными операциями и потоками. Это важный механизм защиты от race conditions в многопоточных средах. Поле lock обеспечивает взаимное исключение (mutual exclusion) для: синхронизации операций IOCTL между собой, защиты внутреннего состояния устройства, координации доступа из нескольких файловых дескрипторов, предотвращения конфликтов между разными операциями.

Замечание: устанавливаем dev_parent только в том случае, если это невозможно вывести из v4l2_dev.

media_entity_to_video_device (__entity)

Возвращает встроенный в него объект структруры video_device из объекта структуры media_entity.

Параметры:

__entity указатель на структуру media_entity, может быть NULL.

to_video_device (cd)

Возвращает встроенный в него объект структруры video_device из объекта структуры device.

Параметры:

cd указатель на структуру device.

int __video_register_device (struct video_device *vdev,
                             enum vfl_devnode_type type,
                             int nr,
                             int warn_if_nr_in_use,
                             struct module *owner)

Регистрирует устройства video4linux.

Параметры:

struct video_device *vdev Указатель на структуру video_device для регистрации.

enum vfl_devnode_type type Тип регистрируемого устройства, как это определено перечислением vfl_devnode_type.

int nr Желаемый номер device node: 0 == /dev/video0, 1 == /dev/video1, ..., -1 == первый свободный.

int warn_if_nr_in_use Предупреждает, если желаемый номер device node был уже использован и вместо него был выбран другой номер устройства.

struct module *owner

Модуль, который владеет video device node.

Описание:

Код регистрации назначает minor-номера и номера device node, основываясь на запрошенном типе и регистрирует новый new device с ядром системы (kernel). Эта функция подразумевает, что структура video_device была обнулена, когда выделялась в памяти, и не содержит никакой устаревшей даты.

Будет возвращена ошибка, если нет свободного minor-номера или не может быть найден номер device node, или если была неудачной регистрация device node.

В случае успеха возвратит 0.

Замечание: подразумевается, что эта функция используется только внутри ядра V4L2. Драйверы должны использовать video_register_device() или video_register_device_no_warn().

int video_register_device (struct video_device *vdev,
                           enum vfl_devnode_type type,
                           int nr)

Регистрирует устройства video4linux.

Параметры:

struct video_device *vdev Структура video_device для регистрации.

enum vfl_devnode_type type Тип регистрируемого устройства, как это определено перечислением vfl_devnode_type.

int nr Желаемый номер device node: 0 == /dev/video0, 1 == /dev/video1, ..., -1 == первый свободный.

Описание:

Внутри вызывается __video_register_device(), для подробностей см. её документацию.

Замечание: если video_register_device потерпела неудачу, то release() callback структуры video_device не вызывается, так что вызывающий код отвечает за освобождение любых данных. Обычно это означает, что в случае отказа вы должны вызвать video_device_release().

int video_register_device_no_warn (struct video_device *vdev,
                                   enum vfl_devnode_type type,
                                   int nr)

Регистрирует устройства video4linux.

Параметры:

struct video_device *vdev Указатель на структуру video_device для регистрации.

enum vfl_devnode_type type Тип регистрируемого устройства, как это определено перечислением vfl_devnode_type.

int nr Желаемый номер device node: 0 == /dev/video0, 1 == /dev/video1, ..., -1 == первый свободный.

Описание:

Эта функция идентична video_register_device() с тем исключением, что не выдается warning, если желаемый номер device node уже использовался. Внутри вызывается __video_register_device(), для подробностей см. её документацию.

Замечание: если video_register_device потерпела неудачу, то release() callback структуры video_device не вызывается, так что вызывающий код отвечает за освобождение любых данных. Обычно это означает, что в случае отказа вы должны вызвать video_device_release().

void video_unregister_device(struct video_device *vdev)

Отменяет регистрацию video-устройств.

Параметры:

struct video_device *vdev Указатель на структуру video_device.

Описание:

Ничего не делает, если vdev == NULL или если video_is_registered() возвратила false.

struct video_device *video_device_alloc(void)

Вспомогательная функция для выделение памяти структуры video_device.

Описание:

Возвратит NULL, если ENOMEM или в случае успеха указатель на структуру video_device.

void video_device_release(struct video_device *vdev)

Вспомогательная функция для освобождения структуры video_device.

Параметры:

struct video_device *vdev Указатель на структуру video_device.

Описание:

Может также использоваться для video_device->release().

void video_device_release_empty(struct video_device *vdev)

Вспомогательная функция для реализации обратного вызова video_device->release().

Параметры:

struct video_device *vdev Указатель на структуру video_device.

Описание:

Эта функция освобождения ничего не делает. Она должна использоваться, когда video_device является глобальной статической структурой.

Замечание: наличие статической video_device в лучшем случае является сомнительной историей.

void v4l2_disable_ioctl(struct video_device *vdev, unsigned int cmd)

Отметит, что данная команда не реализована. Не должна использоваться блокировка ядра.

Параметры:

struct video_device *vdev Указатель на структуру video_device.

unsigned int cmd Команда ioctl.

Описание:

Эта функция позволяет драйверам предоставтить только одну структуру v4l2_ioctl_ops, но запретить ioctl-ы на основе определенной карты, которая фактически найдена.

Замечание: это должно быть вызвано перед video_register_device. См. также комментарии для determine_valid_ioctls().

void *video_get_drvdata(struct video_device *vdev)

Получает приватные данные из структуры video_device.

Параметры:

struct video_device *vdev Указатель на структуру video_device.

Описание:

Возвратит указатель на приватные данные.

void video_set_drvdata(struct video_device *vdev, void *data)

Установит приватные данные из структуры video_device.

Параметры:

struct video_device *vdev Указатель на структуру video_device.

void *data Указатель на приватные данные.

struct video_device *video_devdata(struct file *file)

Извлечет структуру video_device из структуры file.

Параметры:

struct file *file Указатель на структуру file.

void *video_drvdata(struct file *file)

Извлечет приватные данные из структуры video_device, используя структуру file.

Параметры:

struct file *file Указатель на структуру file.

Описание:

Эта функция комбинирует обе функции video_get_drvdata() и video_devdata(), поскольку это часто используется.

const char *video_device_node_name(struct video_device *vdev)

Возвратит имя видеоустройства.

Параметры:

struct video_device *vdev Указатель на структуру video_device.

Описание:

Возвратит строку имени устройства.

int video_is_registered(struct video_device *vdev)

Возвратит true, если структура video_device зарегистрирована.

Параметры:

struct video_device *vdev Указатель на структуру video_device.

struct dentry *v4l2_debugfs_root(void)

Возвратит dentry верхнего уровня директории "v4l2" debugfs.

Описание:

Если эта директория пока не существует, то она будет создана.

int video_device_pipeline_start(struct video_device *vdev,
                                struct media_pipeline *pipe)

Пометит конвейер как потоковый.

Параметры:

struct video_device *vdev Указатель на структуру начального video_device.

struct media_pipeline *pipe Media конвейер для назначения всем объектам в конвейере.

Описание:

Пометит все объекты, подключенные к указанному видеоустройству через разрешенные ссылки, напрямую или косвенно, как потоковые. Данный обхект конвейера назначается каждой pad в конвейере и сохраняется в поле media_pad pipe.

Вызовы этой функции могут быть вложенными, в этом случае для остановки потоковой передачи потребуется одинаковое количество вызовов video_device_pipeline_stop (). Указатель конвейера должен быть идентичным для всех вложенных вызовов video_device_pipeline_start().

Видеустройство должно содержать одну pad.

Это обертка удобства над media_pipeline_start().

int __video_device_pipeline_start(struct video_device *vdev, struct media_pipeline *pipe)

Помечает конвейер как потоковый.

Параметры:

struct video_device *vdev Указатель на структуру начального video_device.

struct media_pipeline *pipe Media конвейер для назначения всем объектам в конвейере.

Замечание: это неблокирующая версия функции video_device_pipeline_start().

Видеустройство должно содержать одну pad.

Это обертка удобства над __media_pipeline_start().

void video_device_pipeline_stop(struct video_device *vdev)

Пометит конвейер как не потоковый.

Параметры:

struct video_device *vdev Указатель на структуру начального video_device.

Описание:

Пометит все объекты, подключенные к данному видеоустройству через разрешенные ссылки, прямо или косвенно, как не потоковые. Для поля media_pad pipe устанавливается значение NULL.

Если было сделано несколько вызовов media_pipeline_start(), то требуется одинаковое количество вызовов этой функции, чтобы пометить конвейер как не потоковый.

Видеустройство должно содержать одну pad.

Это обертка удобства над media_pipeline_stop().

void __video_device_pipeline_stop(struct video_device *vdev)

Пометит конвейер как не потоковый.

Параметры:

struct video_device *vdev Указатель на структуру начального video_device.

Замечание: это не блокирующая версия media_pipeline_stop().

Видеустройство должно содержать одну pad.

int video_device_pipeline_alloc_start(struct video_device *vdev)

Пометит конвейер как потоковый.

Параметры:

struct video_device *vdev Указатель на структуру начального video_device.

Описание:

Функция video_device_pipeline_alloc_start() аналогична video_device_pipeline_start(), но вместо работы над данным конвейером функция будет использовать существующий конвейер, если видеоустройство уже является частью конвейера, или выделять новый конвейер.

Количество вызовов video_device_pipeline_alloc_start() должно совпадать с количеством вызовов video_device_pipeline_stop().

struct media_pipeline *video_device_pipeline(struct video_device *vdev)

Получение медиа-конвейера, частью которого является видеоустройство.

Параметры:

struct video_device *vdev Указатель на структуру video_device.

Описание:

Эта функция возвратит media конвейер, с которым ассоциировано это видеоустройство при построении конвейера с помощью video_device_pipeline_start(). Указатель остается действительным до вызова функции video_device_pipeline_stop().

Видеустройство должно содержать одну pad.

Это обертка удобства над media_entity_pipeline().

Возвращаемое значение: media_pipeline, частью которого является видеоустройство, или NULL, если видеоустройство не является частью какого-либо конвейера.

[Ссылки]

1. Video4Linux devices.

 

 

Добавить комментарий


Защитный код
Обновить

Top of Page