Video4Linux2 part 5b: format negotiation

开发者福利!热门AI工具限时免费用 购周边即赠Coding Plan Lite,Claude Code、Cursor等20+工具畅享,效率翻倍! 阅读详情

This article is a continuation of the irregular LWN series on writing videodrivers for Linux. The introductory article describes theseries and contains pointers to the previous articles. In the last episode, we looked at how the Video4Linux2 API describes video formats: image sizes andthe representation of pixels within them. This article will complete thediscussion by describing the process of coming to an agreement with anapplication on an actual video format supported by the hardware.

As we saw in the previous article, there are many ways of representingimage data in memory. There is probably no video device on the marketwhich can handle all of the formats understood by the Video4Linuxinterface. Drivers are not expected to support formats not understood bythe underlying hardware; in fact, performing format conversions within thekernel is explicitly frowned upon. So the driver must make it possible forthe application to select a format which works with the hardware.

The first step is to simply allow the application to query the supportedformats. The VIDIOC_ENUM_FMT ioctl() is provided for thepurpose; within the driver this command turns into a call to this callback(if a video capture device is being queried):

 

    int (*vidioc_enum_fmt_cap)(struct file *file, void *private_data,

			       struct v4l2_fmtdesc *f);

This callback will ask a video capture device to describe one of itsformats. The application will pass in a v4l2_fmtdesc structure:

 

    struct v4l2_fmtdesc

    {

	__u32		    index;

	enum v4l2_buf_type  type;

	__u32               flags;

	__u8		    description[32];

	__u32		    pixelformat;

	__u32		    reserved[4];

    };

The application will set the index and type fields.index is a simple integer used to identify a format; like theother indexes used by V4L2, this one starts at zero and increases to themaximum number of formats supported. An application can enumerate all ofthe supported formats by incrementing the index value until the driverreturns EINVAL. The type field describes the data streamtype; it will be V4L2_BUF_TYPE_VIDEO_CAPTURE for a video capture(camera or tuner) device.

If the index corresponds to a supported format, the driver shouldfill in the rest of the structure. The pixelformat field shouldbe the fourcc code describing the video representation anddescription a short textual description of the format. The onlydefined value for the flags field isV4L2_FMT_FLAG_COMPRESSED, which indicates a compressed videoformat.

The above callback is for video capture devices; it will only be calledwhen type is V4L2_BUF_TYPE_VIDEO_CAPTURE. TheVIDIOC_ENUM_FMT call will be split out into different callbacksdepending on the type field:

 

    /* V4L2_BUF_TYPE_VIDEO_OUTPUT */

    int (*vidioc_enum_fmt_video_output)(file, private_date, f);



    /* V4L2_BUF_TYPE_VIDEO_OVERLAY */

    int (*vidioc_enum_fmt_overlay)(file, private_date, f);



    /* V4L2_BUF_TYPE_VBI_CAPTURE */

    int (*vidioc_enum_fmt_vbi)(file, private_date, f);



    /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */ */

    int (*vidioc_enum_fmt_vbi_capture)(file, private_date, f);



    /* V4L2_BUF_TYPE_VBI_OUTPUT */

    /* V4L2_BUF_TYPE_SLICED_VBI_OUTPUT */

    int (*vidioc_enum_fmt_vbi_output)(file, private_date, f);



    /* V4L2_BUF_TYPE_VIDEO_PRIVATE */

    int (*vidioc_enum_fmt_type_private)(file, private_date, f);

The argument types are the same for all of these calls. It's worth noting that drivers can support special buffer types with codesstarting with V4L2_BUF_TYPE_PRIVATE, but that would clearlyrequire a special understanding on the application side.For the purposes of this article, we will focus on video capture and outputdevices; the other types of video devices will be examined in futureinstallments.

The application can find out how the hardware is currently configured withthe VIDIOC_G_FMT call. The argument passed in this case is av4l2_format structure:

 

    struct v4l2_format

    {

	enum v4l2_buf_type type;

	union

	{

		struct v4l2_pix_format		pix;

		struct v4l2_window		win;

		struct v4l2_vbi_format		vbi;

		struct v4l2_sliced_vbi_format	sliced;

		__u8	raw_data[200];

	} fmt;

    };

Once again, type describes the buffer type; the V4L2 layer willsplit this call into one of several driver callbacks depending on thattype. For video capture devices, the callback is:

 

    int (*vidioc_g_fmt_cap)(struct file *file, void *private_data,

    			    struct v4l2_format *f);

For video capture (and output) devices, the pix field of the unionis of interest. This is the v4l2_pix_format structure seen in theprevious installment; the driver should fill in that structure with thecurrent hardware settings and return. This call should not normally failunless something is seriously wrong with the hardware.

The other callbacks are:

    int (*vidioc_s_fmt_overlay)(file, private_data, f);

    int (*vidioc_s_fmt_video_output)(file, private_data, f);

    int (*vidioc_s_fmt_vbi)(file, private_data, f);

    int (*vidioc_s_fmt_vbi_output)(file, private_data, f);

    int (*vidioc_s_fmt_vbi_capture)(file, private_data, f);

    int (*vidioc_s_fmt_type_private)(file, private_data, f);

The vidioc_s_fmt_video_output() callback uses the samepix field in the same way as capture interfaces do.

Most applications will eventually want to configure the hardware to providea format which works for their purpose. There are two interfaces providedfor changing video formats. The first of these is theVIDIOC_TRY_FMT call, which, within a V4L2 driver, turns into oneof these callbacks:

 

    int (*vidioc_try_fmt_cap)(struct file *file, void *private_data,

			      struct v4l2_format *f);

    int (*vidioc_try_fmt_video_output)(struct file *file, void *private_data,

			      	       struct v4l2_format *f);

    /* And so on for the other buffer types */

To handle this call,the driver should look at the requested video format and decide whetherthat format can be supported by the hardware or not. If the applicationhas requested something impossible, the driver should return-EINVAL. So, for example, a fourcc code describing an unsupportedformat or a request for interlaced video on a progressive-only device wouldfail. On the other hand, the driver can adjust size fields to match animage size supported by the hardware; normal practice is to adjust sizesdownward if need be. So a driver for a device which only handlesVGA-resolution images would change the width and heightparameters accordingly and return success. The v4l2_formatstructure will be copied back to user space after the call; the drivershould update the structure to reflect any changed parameters so theapplication can see what it is really getting.

The VIDIOC_TRY_FMT handlers are optional for drivers, but omittingthis functionality is not recommended. If provided, this function iscallable at any time, even if the device is currently operating. It shouldnot make any changes to the actual hardware operating parameters; itis just a way for the application to find out what is possible.

When the application wants to change the hardware's format for real, itdoes a VIDIOC_S_FMT call, which arrives at the driver in thisform:

 

    int (*vidioc_s_fmt_cap)(struct file *file, void *private_data,

    			    struct v4l2_format *f);

    int (*vidioc_s_fmt_video_output)(struct file *file, void *private_data,

    			             struct v4l2_format *f);

Unlike VIDIOC_TRY_FMT, this call cannot be made at arbitrarytimes. If the hardware is currently operating, or if it has streamingbuffers allocated (a topic for yet another future installment), changingthe format could lead to no end of mayhem. Consider what happens, forexample, if the new format is larger than the buffers which are currentlyin use. So the driver should always ensure that the hardware is idle andfail the request (with -EBUSY) if not.

A format change should be atomic - it should change all of the parametersto match the request or none of them. Once again, image size parameterscan be adjusted by the driver if need be. The usual form of thesecallbacks is something like this:

 

    int my_s_fmt_cap(struct file *file, void *private, 

                     struct v4l2_format *f)

    {

	struct mydev *dev = (struct mydev *) private;

	int ret;



	if (hardware_busy(mydev))

	    return -EBUSY;

	ret = my_try_fmt_cap(file, private, f);

	if (ret != 0)

	    return ret;

	return tweak_hardware(mydev, &f->fmt.pix);

    }

Using the VIDIOC_TRY_FMT handler avoids duplication of code andgets rid of any excuse for not implementing that handler in the firstplace. If the "try" function succeeds, the resulting format is known towork and can be programmed directly into the hardware.

There are a number of other calls which influence how video I/O is done.Future articles will look at some of them. Support for setting formats isenough to enable applications to start transferring images, however, andthat is what the purpose of all this structure is in the end. So the nextarticle, hopefully to come after a shorter delay than happened this timearound, will get into support for reading and writing video data.


hostapd.conf配置文档 ##### hostapd configuration file ############################################## # Empty lines and lines starting with # are ignored # AP netdevice name (without 'ap' postfix, i.e., wlan0 uses wl 阅读详情

相关推荐

cs188Inference in Bayes Nets(贝叶斯网络的推理)

cs188Inference in Bayes Nets贝叶斯网络的推理Question1(3 points):Bayes Net StructureQuestion2(1 points):Bayes Net ProbabilitiesQuestion 3(5 points):Join FactorsQuestion44 points):EliminateQuestion54 points):NormalizeQuestion 6(4 points):Variable EliminationQuesti

weixin_46582817的博客 1648

总结:关于使用ffmpeg video4linux2 打开usb摄像头流的失败过程排查

在ubuntu下,虽然使用opencv能够能够打开usb摄像头视频流,但项目中用的 ffmpeg作为解码工具。 网上搜索到使用代码: ............................... AVInputFormat *inputFmt = av_find_input_format("video4linux2"); ............................... av

halowell的专栏 8779

保姆级教程:在Ubuntu 22.04上用Conda搞定nuPlan数据集环境(Python 3.9 + PyTorch)

本文提供了一份详细的Ubuntu 22.04环境下使用Conda配置nuPlan自动驾驶数据集的保姆级教程,涵盖Python 3.9安装、Conda环境管理、PyTorch配置及数据集可视化验证等关键步骤,帮助开发者高效搭建开发环境。

weixin_29061997的博客 223

linux播放视频接口,V4L2(video 4 linux 2)视频采集接口使用说明

可以支持多种设备,它可以有以下几种接口:1. 视频采集接口(video capture interface):这种应用的设备可以是高频头或者摄像头.V4L2的最初设计就是应用于这种功能的.2. 视频输出接口(video output interface):可以驱动计算机的外围视频图像设备--像可以输出电视信号格式的设备.3. 直接传输视频接口(video overlay interface):它的...

weixin_33558958的博客 2279

Linux日常使用技巧(一)

Linux日常使用技巧(一)

IT菜鸟 9288

Linux 定时任务管理:cron 高级用法

本文系统介绍 Linux Cron 的核心用法与实战技巧,涵盖定时任务配置、时间表达式、环境变量设置、条件执行及日志记录等高级功能。通过数据库备份、日志清理、系统监控等典型案例,结合调试方法与最佳实践,帮助用户高效实现自动化运维。适用于服务器维护、数据同步等场景,提升系统管理效率。

qq_37124515的博客 76

linux 权限 指令与权限(重启之后)

1.将含有目标字符串的行过滤出来2.可以与管道文件连用3.过滤出进程过滤出所有进程过滤出指定进程4.过滤出目录下的特定代码(字符串)与所在的行数查找的字符串有空格,建议用双引号5.将包含目标字符串的行漏掉,将其他的过滤出6.—i 忽略指定字符串的大小写7. 5.6.组合使用。

2401_86976959的博客 172

Linux 中安装 Redis 5

Linux中,先以root用户通过apt安装Redis,默认端口6379,仅限本地访问。为实现跨主机访问,需修改配置文件将绑定IP从127.0.0.1改为0.0.0.0,并关闭保护模式(protected-mode no)。完成后重启服务,使用redis-cli连接即可。操作简便,适合学习与测试环境。

sdm070427的博客 221

Linux文件查看与编辑:cat、less、tail、vim快速入门

零基础入门 Linux 文件查看与编辑:一文吃透 cat、less、tail、vim 四大命令。从真实排障场景出发,讲解语法、参数、实战示例与预期输出,附工具选型对比表、tail -f 与 tail -F 的区别(inode 原理)、vim 模式速查与最佳实践

m0_66083353的博客 465

Linux dmesg 工业边缘实战:内核日志过滤、持久化与故障定位

本文围绕 Linux dmesg 在工业边缘节点上的应用,介绍内核日志基础用法、时间/级别/子系统过滤、硬件/OOM/网络/USB/panic 排障、journald 与 syslog 持久化、实时监测和 sysctl 配合,适合网关与边缘设备日常运维。

ZenovaEdgeOS的博客 313

第 02 天:Linux 权限、inode、目录项与链接

本文系统梳理了Linux多用户权限模型,重点解析文件权限、inode与目录项关系、硬链接与软链接差异,并结合网络服务配置、日志、静态资源及Unix Domain Socket场景,阐明权限排错的关键点。强调删除依赖父目录写权、访问需逐级穿过目录、软硬链接本质区别等核心概念,提出“Permission denied”需综合路径、用户、策略等证据排查,为运维与开发提供实用指导。

2502_91577682的博客 153

Linux 文件系统

特性硬链接软链接inode号和源文件相同全新独立inode跨分区不支持支持链接目录用户不能创建,系统..是硬链接支持删除源文件硬链接仍然可用变成无效悬空链接本质多个目录项指向同一个inode保存路径字符串的独立文件。

Diopeng_out的博客 212

编译Linux man中文手册manpages-zh

【代码】编译Linux man中文手册manpages-zh。

haierccc的博客 213

ARM64 Linux 6.10 内核驱动(15):devm_*为什么能自动释放

devm_* 自动释放依赖 struct device 上的 devres_head 链表,每条记录含 release 函数和数据。申请时通过 devres_add 将资源记账,释放时 devres_release_all 按 LIFO 顺序调用 release 并 kfree 节点。关键在于:资源申请与记账绑定,解绑时统一清理,无需手动管理,确保失败路径或卸载时无泄漏。

T1mzhou的博客 284

Linux2)——权限

root用户:不受权限约束,可以做任意操作,提示符#普通用户:权限受限,提示符$命令:su 用户名功能:切换用户三类访问者:u - user:文件拥有者g - group:所属用户组o - others:其他用户a - all:代表u+g+o所有用户。

BIII__的博客 135

Nginx 多 Worker 进程监听同一端口场景下 Linux 内核 Socket 创建管理与请求寻址机制

每个 Worker 进程独立创建监听 Socket:在开启选项的场景下,每个 Worker 进程都会独立调用socket()系统调用,创建属于自己的监听 Socket,而不是继承 Master 进程的 Socket 文件描述符;所有 Worker 进程的 Socket 都设置 SO_REUSEPORT 选项:在执行bind()系统调用之前,每个 Worker 进程都会调用系统调用,为自己的监听 Socket,设置端口重用选项;内核通过函数完成端口绑定冲突检测:在执行bind()系统调用时,内核会通过。

binqian的专栏 104

Linux --线程同步与互斥

某些类,只应该具有一个对象(实例)。比如服务器加载几百 GB 数据到内存,需要一个单例类来管理。本文从售票 bug线程互斥:用 mutex 保护临界区,理解ticket--非原子的本质;线程同步:用条件变量 + while 判断,实现线程间的顺序协作;生产者消费者模型:用阻塞队列/环形队列 + 信号量,解耦生产与消费;线程池:用日志模块 + 单例 + 任务队列,实现高效的线程复用;线程安全与可重入:理解两者的联系与区别;死锁:掌握四个必要条件和避免方法;STL 与智能指针:明确标准库的线程安全边界。

2501_94405739的博客 143

Re:Linux 系统篇(三十二):库的制作与原理Chapter3:动态链接深度解析 —— .so 为什么能被多进程共享?PIC、GOT 与虚拟内存的联动

本文深入解析动态链接与共享库机制,结合ELF格式、进程地址空间与页表原理,揭示.so文件如何实现多进程共享:通过虚拟地址独立、物理内存复用,配合位置无关代码(PIC)与全局偏移表(GOT),实现高效加载与延迟绑定。对比静态链接的冗余问题,动态链接显著节省磁盘与内存资源,构建起从源码到运行的完整链路。

mogreat的博客 546

Linux 库制作与原理

这份文档讲解Linux下的制作、使用,ELF目标文件格式、编译链接、程序加载、虚拟地址空间、动态链接原理,配套gcc选项、Makefile示例、调试命令。

Diopeng_out的博客 314
上一篇: Video4Linux2 part 5a: colors and formats
下一篇: Video4Linux2 part 6b: Streaming I/O
kickxxx
博客等级 码龄16年 586粉丝 174原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值