Android USB Camera(1) : 調試記錄

本文记录了在Android 5.0平台下,使用MT6735硬件调试UVC(USB Video Class)摄像头的过程。主要涉及底层配置,包括打开设备配置、权限设置及调试命令,以及上层应用开发,利用V4L2框架进行视频采集。针对MJPEG格式,文章详细介绍了在JNI层插入Huffman表以解码图像,并在Java层显示解码后的图像。
摘要由CSDN通过智能技术生成

原創 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中分配的數據緩存轉換

Android USB OTG (On-The-Go) 允许设备通过USB连接外部设备,例如摄像头,扩展其功能。以下是一个简单的示例,展示如何在Android应用中使用OTG连接并访问外置摄像头: 首先,你需要在AndroidManifest.xml文件中添加相应的权限,并启用调试模式: ```xml <uses-feature android:name="android.hardware.usb.host" android:required="true" /> <uses-permission android:name="android.permission.USB_PERMISSION" /> <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" android:resource="@xml/accessory_filter" /> ``` 然后创建一个USBDeviceConnectionListener,用于监听USB设备的连接和断开: ```java private class UsbCameraConnectionListener implements UsbManager.UsbDeviceConnectionListener { @Override public void onConnected(UsbDevice device) { // 连接摄像头后处理 UsbCamera camera = new UsbCamera(device); try { camera.open(); } catch (IOException e) { Log.e(TAG, "Error opening camera", e); } } @Override public void onDisconnected(UsbDevice device) { // 断开摄像头时清理资源 if (camera != null) { camera.close(); camera = null; } } @Override public void onError(UsbDevice device, int error) { // 错误处理 Log.e(TAG, "Error with USB device: " + error); } } ``` 接着,在你的Activity中初始化UsbManager,并设置监听器: ```java private final static String TAG = "YourApp"; ... UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE); usbManager.requestPermission(this, accessory.getDevice(), new String[] { "your_accessory_vendor_id", "your_accessory_product_id" }); usbManager.connectAccessory(accessory, connectionListener); ``` 最后,记得在onCreate()方法中检查是否有可用的USB设备,并启动相应的服务来读取相机数据。 这是一个基本的框架,实际操作中需要处理更多的细节,如错误处理、相机参数调整等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

seiyaaa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值