Android UCV 同时打开多路摄像头

Android UVC 同时打开多路摄像头
前言
硬件环境
效果图
注意问题
代码分析(摄像头的打开步骤)
1.找到摄像头设备
打开摄像头
项目地址
前言
做项目用到了多路摄像头,但是原生固件最多支持两路同时打开(cameraID 0和1),又不想对固件修改,所以打算采用uvc方式打开多路USB摄像头。找了几篇博客,以及github上的项目,down下来发现存在各种各样的问题(编译问题,打开多路问题)。从这个角度出发,打算把自己的过程以及代码分享出来。

硬件环境
硬件环境:
rk3399,rk3288,展讯9853
Logitech摄像头两个,WCH双目摄像头两个,一共六个镜头

效果图
六路,厉害了haha


注意问题
ndk版本一定要注意,否者会出现打不开的问题,笔者之前配置的android-ndk-r16b,怎么搞也不行,结果改成android-ndk-r14b就ok了,这点要注意一下

代码分析(摄像头的打开步骤)
1.找到摄像头设备
USBMonitor/usb设备控制类
主要的能力:usb设备节点(设备信息)的获取,对USB设备操作的广播监听(设备的连接与断开,usb权限请求的监听)
当我们点击demo中视频预览区域会弹出当前camera设备的列表,列表数据就是由它得来,需要注意得地方是dialog这里做了一个Camera设备的筛选

public void updateDevices() {
//        mUSBMonitor.dumpDevices();
        final List<DeviceFilter> filter = DeviceFilter.getDeviceFilters(getActivity(), R.xml.device_filter);
        mDeviceListAdapter = new DeviceListAdapter(getActivity(), mUSBMonitor.getDeviceList(filter.get(0)));
        mSpinner.setAdapter(mDeviceListAdapter);
    }

mUSBMonitor对象就是在MainActivity中初始化的那个,根据device_filter(class = 239)生成一个筛选器,至于为什么根据这个筛选我也不是很清楚,不过debug看来,确实camera数据的class = 239


这样就筛选出了想要的Camera数据

打开摄像头
关键类 AbstractUVCCameraHandler,UVCCamera
UVCCamera负责jni驱动的调用,可以看作是android APi 的“Camera”类,具有打开,释放,调焦等功能
AbstractUVCCameraHandler负责控制UVCCamera,一些状态回调,数据回调,录制视频文件的编码等
它有一个内部线程类“CameraThread”很重要,主要方法都在这里面,但是蛋疼的是并没有看懂异步处理的核心用意,还是菜啊,望指正
打开逻辑很简单的,具体流程如下:
1.点击想要打开的设备节点,进行权限检查

if (item instanceof UsbDevice) {
                    mUSBMonitor.requestPermission((UsbDevice)item);//获取设备信息,并检查打开此设备的权限
                    ((CameraDialogParent)getActivity()).onDialogResult(false);
                }

2.这个设备是否有打开权限,有的话直接打开,没有的话去请求,请求成功了直接打开

if (mUsbManager.hasPermission(device)) {
                    // 如果应用已经拥有权限,请调用onConnect
                    processConnect(device);
                } else {
                    try {
                        //未经许可请求
                        mUsbManager.requestPermission(device, mPermissionIntent);
                    } catch (final Exception e) {
                        // 它似乎在Android 5.1.x的GALAXY系统中生成一个名为android.permission.sec.MDM_APP_MGMT的未知异常
                        Log.w(TAG, e);
                        processCancel(device);
                        result = true;
                    }
                }

3.假设已经有权限了,直接进到打开摄像头方法里面

private final void processConnect(final UsbDevice device) {
        if (destroyed) return;
        updatePermission(device, true);
        mAsyncHandler.post(new Runnable() {
            @Override
            public void run() {
                if (DEBUG) Log.v(TAG, "processConnect:device=" + device);
                UsbControlBlock ctrlBlock;
                final boolean createNew;
                ctrlBlock = mCtrlBlocks.get(device);
                if (ctrlBlock == null) {
                    ctrlBlock = new UsbControlBlock(USBMonitor.this, device);//封装了一个模块数据
                    mCtrlBlocks.put(device, ctrlBlock);
                    createNew = true;
                } else {
                    createNew = false;
                }
                if (mOnDeviceConnectListener != null) {
                    mOnDeviceConnectListener.onConnect(device, ctrlBlock, createNew);
                }
            }
        });
    }

主要就是封装了一个UsbControlBlock(设备数据),还有一些是第一次打开还是反复打开的逻辑,缓存逻辑

4.回调给了MainActivity,记得前面说的“AbstractUVCCameraHandler负责控制UVCCamera”,没错,就是要用mHandlerFirst来控制打开camera

 mHandlerFirst.open(ctrlBlock);//打开摄像机
                final SurfaceTexture st = mUVCCameraViewFirst.getSurfaceTexture();
                mHandlerFirst.startPreview(new Surface(st));

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mCaptureButtonFirst.setVisibility(View.VISIBLE);
                    }
                });

最终调用到了UVCCamera内的nativeConnect 方法,调用jni连接摄像头

到这里相机就打开了,要注意的是数据回调这部分我对源码修改了一下。

嗯,就是这些,还是挺简单的,代码会后续优化

项目地址
原项目地址(是真的牛,不过我下载编译后有些问题):
https://github.com/saki4510t/UVCCamera
我做了一些修改的项目地址:
https://github.com/yyfd2013zy/UvcCameraDemo
————————————————
版权声明:本文为CSDN博主「加非盐」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yyfd2013/article/details/85321175

发布了36 篇原创文章 · 获赞 162 · 访问量 62万+

猜你喜欢

转载自blog.csdn.net/qq_19004627/article/details/103255915