原創 LittleProgrammer2S 2018-08-24 13:52
1. 前言
前段時間調試了一個uvc攝像頭,這裏做下記錄。硬件平臺爲mt6735,軟件平臺爲android 5.0
2. 底層配置
UVC全稱是usb video class,一種usb視頻規範。所有遵循uvc協議的攝像頭都不需要安裝額外的驅動,只需要一個通用驅動即可。Linux內核已經集成了uvc驅動,代碼路徑是kernel-3.10/drivers/media/usb/uvc/
2.1 打開配置
Linux內核需要打開以下配置來支持uvc設備
CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_VIDEO_DEV=y
CONFIG_VIDEO_V4L2=y
CONFIG_VIDEOBUF2_CORE=y
CONFIG_VIDEOBUF2_MEMOPS=y
CONFIG_VIDEOBUF2_VMALLOC=y
CONFIG_MEDIA_USB_SUPPORT=y
CONFIG_USB_VIDEO_CLASS=y
MTK平臺還需要額外打開otg配置
CONFIG_USB_MTK_OTG=y
CONFIG_USB_MTK_HDRC=y
CONFIG_USB_MTK_HDRC_HCD=y
插入攝像頭,如果生成了/dev/video0設備節點,則證明uvc攝像頭已經加載成功了。成功生成驅動節點後還需要爲它添加權限
2.2 添加權限
在uevent.rc中加入
/dev/video0 0666 root root
在system_app.te中加入
allow system_app video_device:chr_file { read write open getattr };
2.3 Debug
如果沒有出現/dev/video0節點,需要先判斷是否枚舉成功。在shell終端cat相關的節點查詢
cat /sys/kernel/debug/usb/devices
如果該攝像頭枚舉成功,則能找到對應的設備信息
T: Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=1 Spd=480 MxCh=1
D: Ver=2.00 Cls=00(>ifc) Sub=00 Prot=00 MxPS=64 #Cfgs=1
P: Vendor=18EC ProdID=3399 Rev=0.00
S: Manufacturer=ARKMICRO
S: Product=USB PC CAMERA
如果枚舉成功則需要判斷當前的usb攝像頭是不是遵循uvc協議的攝像頭。將usb攝像頭插到PC上(ubuntu操作系統),通過”lsusb”命令查找是否有視頻類接口信息
lsusb -d 18ec:3399 -v | grep "14 Video"
如果該攝像頭遵循UVC協議,則會輸出以下類似信息
bFunctionClass 14 Video
bInterfaceClass 14 Video
bInterfaceClass 14 Video
bInterfaceClass 14 Video
其中18ec:3399是攝像頭的vid和pid,而14 video代表uvc規範
2.4 幾個比較有用的調試命令
打開/關閉linux uvc driver log
echo 0xffff > /sys/module/uvcvideo/parameters/trace //打開
echo 0 > /sys/module/uvcvideo/parameters/trace //關閉
獲取詳細的usb設備描述符
lsusb -d 18ec:3399 –v
3. 上層應用
v4l2 - Video for Linux 2,是Linux內核中關於視頻設備的內核驅動框架,爲上層的訪問底層的視頻設備提供了統一的接口。同時是針對uvc免驅usb設備的編程框架,主要用於採集usb攝像頭等。
MTK標準的Camera並沒有採用v4l2框架,所以需要在jni層實現基本的v4l2視頻採集流程。
3.1 操作流程
在v4l2編程中,一般使用ioctl函數來對設備進行操作:
extern int ioctl (int __fd, unsigned long int __request, …) __THROW;
__fd:設備的ID,例如用open函數打開/dev/video0後返回的cameraFd;
__request:具體的命令標誌符。
在進行V4L2開發中,一般會用到以下的命令標誌符:
VIDIOC_REQBUFS:分配內存
VIDIOC_QUERYBUF:把VIDIOC_REQBUFS中分配的數據緩存轉換