NV12摄像头
功能说明
新加入NV12格式的编码支持
1 | /* A.6. Video Class-Specific VS Interface Descriptor Subtypes */ |
- 根据协议分析,NV12 依然属于UVC_VS_FORMAT_UNCOMPRESSED
- 需要通过guidFormat来判断
模块结构
略
数据结构
在UVC协议中的数据结构
%%{init: {'theme':'default'}}%% classDiagram Descriptor --> VideoControl Descriptor --> VideoStream VideoStream --> InputHeader VideoStream --> OutputHeader VideoStream --> Format Format --> FormatYUV Format --> FormatMJPEG VideoStream --> Frame Frame --> FrameYUV Frame --> FrameMJPEG class Format{ getFrame(uint32_t); getId(); getType(); getFrameNum(); setFrameNum(uint8_t); } class FormatYUV{ getFrame(uint32_t); getId(); getType(); getFrameNum(); setFrameNum(uint8_t); +getGuid(); } class FormatMJPEG{ getFrame(uint32_t); getId(); getType(); getFrameNum(); setFrameNum(uint8_t); }
- 之前没有对YUV格式做细致的区分,实际上以前我们支持的YUV仅仅时YUY2一种
- 新增一个接口getGuid 获取细分的格式
编解码器的数据结构
%%{init: {'theme':'default'}}%% classDiagram class X264Encoder{ +m_fmt X264Encoder(); getSize(); encode(); +init(); +setFmt(); } class MppEncoder{ +m_fmt MppEncoder(); getVideoInitSPS(); init(); putFrameData(); getSize(); encode(); +setFmt(); } coder --|> H264Encoder coder --|> X264Encoder coder --|> MppEncoder
- H264作为服务端解码工具,添加自动识别格式的代码逻辑
- X264合Mpp作为客户端编码工具,需要添加针对多种格式的支持(目前仅YUY2 NV12)
- 考虑到兼容性问题,这里不修改已有函数,新增两个设置函数,新增两个私有成员变量
协议中的guidFormat字段
1 | struct uvc_format_uncompressed { |
格式 | guidFormat | 对应X264编码 | 对应MPP编码 |
---|---|---|---|
YUYV | 32595559-0000-0010-8000-00aa00389b71 | X264_CSP_I422 | MPP_FMT_YUV422_YUYV |
NV12 | 3231564e-0000-0010-8000-00aa00389b71 | X264_CSP_NV12 | MPP_FMT_YUV420SP |
- 很明显取guidFormat的前4位作为ASCII码 正好对应英文缩写
执行流程
类 | 新增字段 | 默认值 | 关联函数 |
---|---|---|---|
H264Coder | m_fmt | AV_PIX_FMT_YUYV422 | decode |
X264Encoder | m_fmt | X264_CSP_I422 | setFmt、X264Encoder、init |
MppEncoder | m_fmt | MPP_FMT_YUV422_YUYV | setFmt、init |
针对 X264Encoder/MppEncoder
- 新增加m_fmt函数 进行编码格式的保存
- 根据 guidFormat 获取到的guid,针对X264Encoder/MppEncoder 调用setFmt来设置格式,然后调用init进行初始化操作
- init取代直接使用固定值的方式,根据初m_fmt来进行参数设置
针对H264Coder
- 构造函数中,取消第二个AVFrame 的内存申请
- decode 中取消强制转码为 AV_PIX_FMT_YUYV422 的操作,采用原始编码
1 | /* Colorspace type */ |
- 这是x264.h的头文件
- x86下 原逻辑中的X264_CSP_I422 在NV12编码中,需要替换为X264_CSP_NV12
- arm下 MPP_FMT_YUV422_YUYV 修改为 MPP_FMT_YUV420SP
arm 需要根据NV12编码修改下面的地方
1 | MppFrameFormat KsType2Mpp(uint32_t type) |
- 问题 因为Mpp编码几乎是复制了原来的老代码,引入了一组不必要的enum定义进行二次转换,这里需要统一修改下保持和x86下的一致性
- 本文作者: crazyboy
- 本文链接: http://crazyboy.www.crazyboy.info/blog/blog/2022/12/20/kylin/usb/redir/kylinusbredir3/code_nv12/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!