我是靠谱客的博主 机智巨人,最近开发中收集的这篇文章主要介绍android平台多路摄像头实现方式的简析,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

采用Camera API2 HAL3架构,android P和Q的初始化预览流程无异。

流程大概为CameraManager.openCamera打开摄像头设备回调onOpened方法得到CameraDevice,通过CameraDevice创建CaptureRequest预览请求,设置Surface容器同时创建CameraCaptureSession会话,从而实现视频预览。

多路摄像头应用MIPI CSI2架构,通过MIPI CSI2接口结合N4芯片达到多路视频显示的目的。
实现多路摄像头需要对Camera框架进行了适配,通过MIPI虚拟通道,每个通道对应一个虚拟cameraID,从cameraID-8开始+1,前后左右分别对应8,9,10,11分别对应虚拟通道1,2,3,4,cameraID-12则为打开四路通道的对应Id(后续看需求,可用于四路视频的录制)。camlitehal层处理camera相关的驱动操作,camera配置文件在device/…/camera_config.xml(区别于device/…/manifest.xml),并不是安装传统的打开设备节点legecy/0,legecy/1的方式打开)

最终会调用到mtkcam的hal层和驱动层来操控摄像头sensor和isp。
N4摄像头sensor处理源码路径:

n4_yuv kernel-4.9/drivers/misc/mediatek/imgsensor/src/common/v1

mtkcam部分目录为vendor/mediatek/proprietary/hardware/mtkcam/,按照mtkcam进行扩展实现对camera多路以及单路摄像头的预览。

客户端预览多路摄像头流程

可开启线程池,打开不同cameraId的摄像头,多任务实现多摄像头的同时预览。

    public static final String FRONT_CAMERA_ID = "8";
    public static final String BACK_CAMERA_ID = "9";
    public static final String LEFT_CAMERA_ID = "10";
    public static final String RIGHT_CAMERA_ID = "11";
    
/** 打开摄像头 openCamera**/
   CameraManager manager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
   manager.openCamera(mCameraId, mDeviceStateCallback, mBgHandler);
   
private final CameraDevice.StateCallback mDeviceStateCallback = new CameraDevice.StateCallback() {
        @Override
        public void onOpened(CameraDevice cameraDevice) {
            mCameraDevice = cameraDevice;
            startPreview();
        }

        @Override
        public void onDisconnected(CameraDevice cameraDevice) {
            cameraDevice.close();
        }

        @Override
        public void onError(CameraDevice cameraDevice, int error) {
            cameraDevice.close();
        }
    };
/** startPreview 视频预览**/
        mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
        
        Surface surface = mSurfaceView.getHolder().getSurface();
                        mPreviewBuilder.addTarget(surface);


        mCameraDevice.createCaptureSession(Collections.singletonList(surface), mSessionStateCallback, null);
private CameraCaptureSession.StateCallback mSessionStateCallback = new CameraCaptureSession.StateCallback() {
                        @Override
                        public void onConfigured(CameraCaptureSession cameraCaptureSession) {
                            mPreviewSession = cameraCaptureSession;
                            updatePreview();
                        }

                        @Override
                        public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
       cameraCaptureSession.close();
                            mPreviewSession = null;
                        }
                    }
/** updatePreview **/
        mPreviewRequest = mPreviewBuilder.build();
            mPreviewBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);   mPreviewSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback, mBgHandler);

private CameraCaptureSession.CaptureCallback mCaptureCallback = new CameraCaptureSession.CaptureCallback() {
        @Override
        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
            //result为预览视频的结果,以此获取摄像头预览画面信息
        }
    };

openSession流程(MTK)

CameraDeviceClient frameworks/av/services/camera/libcameraservice/common

Camera3Device frameworks/av/services/camera/libcameraservice/device3

CameraProviderManager openSession frameworksavservicescameralibcameraservicecommon

openSession方法调用findDeviceInfoLockedmDevices中获取匹配cameraId的Device
android 从camhallite 的hal层中加载获取cameraId,

hardware::Return CameraProviderManager::ProviderInfo::cameraDeviceStatusChange

cameraDeviceStatusChange方法将CameraDevice添加到mDevices中,接着通过
deviceInfo3->mInterface->open的流程打开摄像头设备

之后在源码中CameraDevice实现类:

vendor/mediatek/proprietary/hardware/mtkcam/main/hal/device/3.x/device/CameraDevice3Impl.cpp
vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/device/3.x/device/CameraDevice3SessionImpl.cpp
vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/devicemgr/CameraDeviceManagerBase.cpp

详细见博客介绍:Camera Hal3 Open/Close

之后根据操作打开n4则去切换mipi,打开cvbs单路摄像头则去打开/dev/video10节点。

传统方式openSession(google原生方式)

CameraDevice
源码地址:hardwareinterfacescameradevice3.2defaultCameraDevice.cpp

CameraModule
源码地址:hardwareinterfacescameracommon1.0defaultCameraModule.cpp

QCamera2Factory
源码地址:hardwareqcomcameraqcamera2QCamera2Factory.cpp

QCamera3HardwareInterface hardwareqcomcameraqcamera2hal3QCamera3HWI.cpp

mm_camera_interface.c hardwareqcomcameraqcamera2stackmm-camera-interfacesrc

mm_camera.c hardwareqcomcameraqcamera2stackmm-camera-interfacesrcmm_camera.c

mtkcam mtk Camera Half分析

CameraId获取流程

CameraProviderManager mInterface->getCameraIdList

ICameraProvider获取 hardware/interfaces/camera/provider/2.4/
再从hal层 camhal3lite获取

camhal3lite通过mipivcWrapper.cpp 对mipi端口进行操控vendor/mediatek/proprietary/hardware/mtkcam/drv/src/mipivc/mipivcWrapper.cpp

最后

以上就是机智巨人为你收集整理的android平台多路摄像头实现方式的简析的全部内容,希望文章能够帮你解决android平台多路摄像头实现方式的简析所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(48)

评论列表共有 0 条评论

立即
投稿
返回
顶部