简介
uvc_app实现了完整的uvc device的功能,包括配置、预览、切换、事件及指令响应等,通过采集摄像头的数据,通过MJPG编码或者H264编码通过ISOC模式传输。
使用方法
- 使能uvcapp:make menuconfig,选择enable uvcapp或在buildroot对应产品defconfig中添加BR2_PACKAGEUVCAPP=y
- 确认uvc_config.sh:确认usb设备配置,目前支持uvc和rndis复合。
- 执行uvcconfig.sh,若需要使用复合设备如rndis,执行uvcconfig.sh rndis
- 执行uvc_app默认将摄像头数据通过uvc传输
源码说明
代码demo目录:external/uvc_app
# uvc_app代码流程:
Main.c:main() //初始化传入的长宽,运行模式flag等参数,申请buffer
drm_open/drm_alloc/drm_handle_to_fd
->uvc_control_run(flags) //运行uvc控制接口,默认LOOP_ONCE,循环等待uvc驱动切换设置完成
->uvc_control.c:uevent_monitor_run //uvc事件监听线程启动,循环监听video4linux(v4l2)是否接入事件
->video_uevent //解析是否为add video接入事件,
->uvc_control_signal 识别到add video,通知uvc control线程,find_video设置为true;
->uvc_control_thread //创建并启动uvc control线程,循环判断uvc 是否连接
->check_uvc_video_id // 检测uvc 是否连接,通过循环读取cat /sys/class/video4linux/video%d/name,识别是否有名称带usb或gadget的uvc节点
->add_uvc_video //启动uvc连接
->uvc_video.cpp:uvc_video_id_add // 第一次进入初始化结构体uvc_video,启动uvc_gadget线程
->uvc_gadget_pthread_create //启动uvc_gadget线程
->uvc-gadget.c:uvc_gadget_main //运行main,初始化uvc_device结构体,配置uvc各参数:名称 长宽 传输格式,速度,io模式配置等,打开uvc device,初始化event
->uvc_open //ioctl控制驱动启动uvc设备
->uvc_events_init //根据传入fcc配置初始化uvc device相关event注册,接下来循环处理事件和数据
while循环
->uvc_events_process //v4l2事件处理函数
->uvc_events_process_setup //处理host请求的UVC_EVENT_SETUP事件
->v4l2_stop_capturing
->uvc_events_process_data -> uvc_events_process_control_data// 处理host请求的UVC_EVENT_DATA事件->像曝光、白平衡,亮度,对比度,等等
->uvc_handle_streamon_event//处理host请求的UVC_EVENT_STREAMON事件,视频流传输启动
->uvc_control.c:uvc_control_init //将获取的宽高信息等传入
->uvc_encode_init
->mpi_enc.c:mpi_enc_cmd_config_mjpg //配置为MPP_VIDEO_CodingMJPEG编码类型,格式为MPP_FMT_YUV420SP( NV12、NV21)
->mpi_enc.c:mpi_enc_test_init
->test_ctx_init
->mpp_create //mpp接口
->mpp_init /mpp接口
->test_mpp_setup// 编码配置与计算相关
->uvc-gadget.c:uvc_video_process//在uvc 视频流开启的情况下,主要对v4l2 buffer队列的qbuffer和dqbuffer响应处理
->while(1) { ...
uvc_read_camera_buffer //循环将相机原始数据编码后信息写到uvc buffer队列
}
->uvc_encode.cpp:uvc_encode_process //按格式编码处理函数
(->mpi_enc.c:mpi_enc_test_run // mjpeg格式下先调用该函数编码)
->uvc_video.cpp:uvc_buffer_write
->_uvc_buffer_write//数据的格式转换部分
->uvc_buffer_push_back(&v->uvc->read, buffer);//将转换后的数据push到read队列,后续传输给host
代码简单流程分析到此,总结如下:uvc 模组端运行步骤:
1.usb uvc与AP端需要连接并配置ready,代码可通过循环读取cat /sys/class/video4linux/video%d/name,识别是否有名称带usb或gadget的uvc节点;
2.运行uvc_control_run,启动uvc_control线程来初始化uvc相关服务与事件监听处理接口;
3.uvc_read_camera_buffer ,循环读取相机数据按设置格式编码转换后传入uvc buffer队列供host端处理。
三部同事整理的旧版video demo流程如下,与uvc_app主流程一致: