v4l2 FIELD 的理解

本文深入探讨了视频传输中的顺序式和交错式,包括阴极射线电视机的工作原理、field的概念、帧的组合方式以及不同field顺序的应用场景。通过解析V4L2_FIELD_*参数,帮助开发者理解并正确实现视频流的传输。

我们要区分video为 顺序式和交错式: 数序式video顺序的传输video image所有的行,而交错式video则把一个video划分成两个fields,分别保存video image的奇数行和偶数行,被称作奇数field和偶数field.  阴极射线电视机需要交替的显示行来组成一个完整的帧,交替的时延需要我们交替的传输奇数field和偶数field. 这个奇怪的技术的引用是因为:在刷新率接近电影时,图片会消退的过快。使用field可以避免使用double buffer以及额外的带宽需求。

首先要明确camera并不是在同一时间曝光一帧,camera通过许多fields来传输这些帧的,这些field是在不同瞬间拍照。屏幕上的一个对象因此会在两个field之间产生动画效果。这种情况下需要识别哪一帧更老一点,也称作“瞬间序”

当驱动通过fields 提供或者接收images,应用应该知道如何通过这些fields组合成帧,通过划分为top bottom field, “空间序”: top field的第一行是帧的第一行, bottom field的第一行是帧的第二行。

然而因为field是一个跟着一个拍的,争论帧是由top还是bottom开始的是没意义的,任何两个相邻的top bottom field, 或者 bottom top field都可以组成一个有效的帧。

与直觉相反top field不一定是older field, older filed是否包含top 或者bottom lines是由video标准决定的. 因此要区分瞬间序和空间序。下面的图会给出清晰的解释。

所有的video capture和out devices必须汇报当前的field顺序。 一些驱动可能允许选择不同的序,end应用可以在调用VIDIOC_S_FMT前初始化struct v4l2_pix_format的 field成员。否则可以使用V4L2_FIELD_ANY

下面列出了可能的field类型

V4L2_FIELD_ANY 0 Application 可以请求使用这个参数,如果V4L2_FIELD_NONE, V4L2_FIELD_TOP, V4L2_FIELD_BOTTOM V4L2_FIELD_INTERLACE 中任何一个格式都支持.驱动选择使用哪一个格式依赖于硬件能力,以及请求的image尺寸,驱动选择一个然后返回这个格式。struct_buffer的field成员不可以为V4L2_FIELD_ANY. 
V4L2_FIELD_NONE 1 
 Images是顺序式格式,驱动可以指定这种order,当驱动无法区分V4L2_FIELD_TOP和V4L2_FIELD_BOTTOM 
V4L2_FIELD_TOP 2 
 Images仅仅包含top field 
V4L2_FIELD_BOTTOM 3 
 Images仅仅包含bottom field. 应用可能希望防止设备捕获interlaced的图片,因为这种图片会在运动物体周围产生毛状特效 
V4L2_FIELD_INTERLACED 4 Images包含top和bottom field, 隔行交替,fields的瞬间序依赖于当前video的标准。M/NTSC首先传输bottom field, 其他的则先传输top field 
V4L2_FIELD_SEQ_TB 5 
 Images包含top和bottom field, top field的行首先存放在memory中,然后紧跟着bottom field的行。 Fields一直以瞬间序存储,较老的放在内存前面。Images的尺寸和帧相关,而不是field
 
V4L2_FIELD_SEQ_BT 6 Images包含top和bottom field, bottom field的行首先存放在memory中,然后紧跟着top field的行。 Fields一直以瞬间序存储,较老的放在内存前面。Images的尺寸和帧相关,而不是field 
V4L2_FIELD_ALTERATE 7  一个帧的两个field分别放在不同的buffer, 按照瞬间序,也就是说老的一个是第一个。driver或者应用指明field的奇偶性(奇偶性:当前的field是top 还是bottom field). 任何两个连续的field构成一个frame,是否两个field是连续的,不需要drop掉他们,可以通过v4l2_buffer中的sequence 成员判定。Images的尺寸和frame而不是fields相关
 
V4L2_FIELD_INTERLACED_TB 8 
 Images 包含top和bottom field, 每行交替, top field在前面。top field首先传送 
 
V4L2_FIELD_INTERLACED_BT 9 Images 包含top和bottom field, 每行交替, bottom field在前面。bottom field首先传送 
 

Field Order, Top Field First Transmitted

Field Order, Bottom Field First Transmitted


<think>好的,用户现在想了解在RK3588平上如何配置使用V4L2_FIELD_INTERLACED,特别是与csi2_hw时钟设置相关的内容。我需要结合之前的回答用户提供的引用来构建一个清晰的指南。 首先,我需要回顾用户之前的问题,关于RK3588的mipi0_csi2_hw的PCLK_CSI_HOST_0时钟配置,之前的回答详细介绍了设备树配置、内核驱动以及调试方法。现在用户转向视频捕获的场序配置,这涉及V4L2框架,特别是V4L2_FIELD_INTERLACED的使用。 用户提供的引用包括V4L2_FIELD相关的宏定义、色彩空间、内存映射以及场序的择。尤其是引用45解释了V4L2_FIELD_INTERLACED的应用场景不同标准下的场序差异。用户可能在使用RK3588的CSI2接口时遇到了隔行视频采集的问题,需要正确配置场序以确保视频数据正确处理。 我需要分步骤解答:首先,理解V4L2_FIELD_INTERLACED的作用;接着,在RK3588的设备树中配置CSI2硬件以支持隔行扫描;然后,在内核驱动中设置相应的V4L2格式;最后,调试验证配置是否正确。 需要注意的是,用户提到csi2_hw时钟设置,这可能与视频数据传输的时序有关,需要确保时钟配置与传感器的隔行输出同步。引用中的时钟配置指南应作为基础,结合场序设置,确保整体配置的一致性。 另外,用户可能在实际应用中遇到了图像撕裂或场序错误的问题,需要提供常见问题的解决方法,例如检查场序是否匹配、时钟同步问题等。同时,用户可能需要示例代码来参考如何在应用层设置V4L2格式,包括场序的择。 最后,要确保回答结构清晰,步骤明确,涵盖设备树、驱动配置、应用层设置调试方法,并附上相关问题帮助用户进一步排查问题。</think>### RK3588 V4L2_FIELD_INTERLACED配置与CSI2时钟协同指南 --- #### **一、V4L2_FIELD_INTERLACED核心概念** 1. **场序定义** `V4L2_FIELD_INTERLACED`表示**隔行扫描模式**,视频帧由两个交替的场(TOPBOTTOM)组成,通过`v4l2_pix_format.field`字段配置[^4]。RK3588的MIPI CSI-2控制器需与Sensor场序严格同步。 2. **RK3588适配要点** - CSI2硬件需支持**行交错模式**(Line Interleaved) - 时钟配置必须满足**场同步时序**(如NTSC/PAL标准差异)[^5] - 内存映射需处理**双场数据分离**(DMA缓冲区管理) --- #### **二、设备树(DTS)协同配置** 1. **CSI2硬件层配置** ```dts &csi2_hw { status = "okay"; /* 时钟与场序关联配置 */ assigned-clocks = <&cru CLK_CSI2_HOST0>; assigned-clock-parents = <&cru NPLL>; // 推荐视频专用PLL assigned-clock-rates = <297000000>; // 匹配1080i@60Hz需求 rockchip,csi2-field-order = "interlaced_bt"; // 指定场序模式 }; ``` - `assigned-clock-rates`需根据**场频**计算: $$ 频率 = (垂直分辨率 \times 场数) \times 帧率 $$ 例如:1080i@60Hz = (540 lines \times 2 fields) \times 60 = 64.8MHz → 实际需考虑消隐区后配置297MHz[^1] 2. **MIPI PHY参数** ```dts &csi2_dphy_hw { status = "okay"; // 场同步时序参数 rockchip,hs-clk-rate = <800000000>; rockchip,field-sync-code = <0x8B>; // BT.656场同步码 }; ``` --- #### **三、V4L2驱动层实现** 1. **格式协商流程** ```c // 应用层设置隔行格式 struct v4l2_format fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, .fmt.pix = { .width = 1920, .height = 1080, .pixelformat = V4L2_PIX_FMT_YUYV, .field = V4L2_FIELD_INTERLACED_BT, // 指定场序类型 .colorspace = V4L2_COLORSPACE_SMPTE170M // NTSC标准[^2] } }; ioctl(fd, VIDIOC_S_FMT, &fmt); ``` 2. **驱动层场序处理** ```c // drivers/media/platform/rockchip/cif/capture.c static int rkcif_csi2_start_streaming(struct rkcif_device *dev) { /* 校验场序模式 */ if (dev->fmt.field == V4L2_FIELD_INTERLACED) { writel(CSI2_FIELD_MODE_INTERLACED, dev->base_addr + CSI2_CTRL_REG); // 配置场同步中断 writel(CSI2_INT_FIELD_SYNC, dev->base_addr + CSI2_INT_EN); } /* 启动DMA双场缓冲区 */ rkcif_alloc_dma_buf(dev, 2); // 为TOP/BOTTOM场分配独立缓冲区 } ``` --- #### **四、时钟与场序同步要点** 1. **PCLK配置规则** | 视频标准 | 场频 | 典型PCLK | 对应PLL | |-----------|---------|------------|-----------| | NTSC 60i | 59.94Hz | 74.25MHz | NPLL | | PAL 50i | 50Hz | 54MHz | CPLL | | 1080i@30 | 29.97Hz | 148.5MHz | GPLL | 2. **分频系数计算** $$ DIV = \frac{PLL\_rate}{PCLK\_rate} $$ 例如:NPLL=1188MHz → 1080i@60Hz需要: $$ DIV = 1188 / 297 = 4 → 寄存器写入0x03 (N-1) $$ 对应DTS配置: ```dts assigned-clock-rates = <297000000>; ``` --- #### **五、调试与问题排查** 1. **场序状态验证** ```shell # 查看当前video节点格式 v4l2-ctl --get-fmt-video # 期望输出: # Width/Height : 1920/1080 # Pixel Format : 'YUYV' # Field : Interlaced ``` 2. **时序异常分析** - **图像撕裂**:检查`v4l2_pix_format.field`与Sensor实际输出是否一致[^4] - **场序颠倒**:切换`V4L2_FIELD_INTERLACED_BT`/`V4L2_FIELD_INTERLACED_TB`[^5] - **时钟抖动**:使用示波器测量PCLK与VSYNC相位关系 3. **寄存器级调试** ```shell # 读取CSI2控制寄存器 io -4 0xFD5C0000 # CSI2_CTRL_REG地址 # BIT[3:2] = 10 表示隔行模式 # BIT[5] = 1 表示场同步锁定 ``` --- #### **六、典型应用场景配置** ```c // 完整捕获流程示例 struct v4l2_requestbuffers req = { .count = 4, .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, .memory = V4L2_MEMORY_MMAP // 内存映射[^3] }; ioctl(fd, VIDIOC_REQBUFS, &req); // 映射双场缓冲区 for (i=0; i<req.count; i++) { struct v4l2_buffer buf = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, .memory = V4L2_MEMORY_MMAP, .index = i }; ioctl(fd, VIDIOC_QUERYBUF, &buf); buffers[i].start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset); ioctl(fd, VIDIOC_QBUF, &buf); // 入队缓冲区 } ``` --- ### 相关问题 1. 如何通过v4l2-ctl工具动态切换隔行/逐行模式? 2. RK3588 CSI2的场同步中断机制如何实现双场分离? 3. 在UYVY格式下隔行视频的DMA缓冲区管理有何特殊要求?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值