美文网首页
Android Camera 无法正常获取插值支持的分辨率

Android Camera 无法正常获取插值支持的分辨率

作者: 宇辰妈咪 | 来源:发表于2020-04-17 14:19 被阅读0次

      最近公司开发的一款型号客户要求相机拍照分辨率最大支持到3600万像素,相机模组硬件支持的最大分辨率为400万,驱动工程师通过插值算法实现支持最大3600万像素。APP是采用高通SDM450 9.0平台的SnapdragonCamera应用实现,前期实现正常没问题。

    后来因为要实现视频水印和分段录像功能更换camera应用框架后,新框架采用Mediacodec+OpenGL方式实现,获取的camera对象方式如下:

    import android.hardware.Camera;mCamera = Camera.open(mCameraId); 

    final Camera.Parameters params = mCamera.getParameters();

    List<Size> supported = params.getSupportedPictureSizes();                                                                                                                          


    通过此种方式获取系统支持的照片尺寸发现最高只能支持到400万,插值的方式支持的方式这里获取不到了。原来SnapdragonCamera获取camera对象是通过CameraProxy接口封装后获取,这是他们的差异。

    谷歌从Android4.4版本之后的camera开始引入了CameraProxy和4.0版本的设计差距还是很大的,4.0版本以前的camera在是camera 主activity中直接调用camera hal层的的接口(如android.hardware.camera.open(), android.hardware.camera.setPreviewDisplay(),android.hardware.camera..startPreview()等)与camera device通信。Android4.4版本camera app对camera device的访问又封装了一次,对camera device的访问必须经过camera manager接口,camera manager接口定义了camera基本操作,这样便于控制和管理camera device。此次修改APP架构没有采用CameraProxy类,直接通过Android 4.0版本以前的方式来直接调用 camera hal层的接口。

    这样的话需要分析引入新的封装机制后与直接调用hal层打开camera的区别之处。首先来了解下camera相关的接口。

    1.CameraManager接口:提供的访问camera设备基本的操作,实现类必须调用CameraManager.cameraOpen获取CameraManager.CameraProxy接口对象来控制camera,实现CameraManager接口的类必须拥有一个独立于主线程的线程来实现对camera的操作,CameraManager接口也包装回调函数

    2.CameraProxy接口,封装在CameraManager接口之内,接收对camera操作请求,发送消息到camer handle。所有对camera的操作都经由改接口,进行异步处理

    3. AndroidCameraManagerImpl类,该类实现了CameraManager接口,与camera framework层接口直接通信,起到camera app 与camera framework对话中介的作用。

    4.AndroidCameraProxyImpl类,AndroidCameraManagerImpl内部类,实现CameraManager.CameraProxy接口,CameraProxy已经介绍过了就是控制对camera的访问,AndroidCameraProxyImpl类实现了具体的操作。

    5. CameraManagerFactory类,这个类的实现很简单,看到Factory,会想到软件设计中的工厂模式,这里就是封装了创建CameraManager对象的细节

    6. CameraHolder类,看名字就可以看出这个类的基本功能了,就用来保存camera实力对象的,用在不同的module之间快速切换。

    以上是Android 4.4之后camera app对camera framework层接口封装的介绍。下面我们来看camera初始化过程。时序图如下;

    通过跟踪代码发现封装CameraProxy代理最终打开camera获取camera对象的方式与上面代码实现方式的区别之处:

    最终打开camera是通过cameraholder类调用AndroidCameraManagerImpl.java中的 public CameraManager.CameraProxy cameraOpen(

            Handler handler, int cameraId, CameraOpenErrorCallback callback)方式打开camera:

    case OPEN_CAMERA:

    try {

    Method openMethod = Class.forName("android.hardware.Camera").getMethod( "openLegacy", int.class, int.class);

    mCamera = (android.hardware.Camera) openMethod.invoke( null, msg.arg1, CAMERA_HAL_API_VERSION_1_0); }

    catch (Exception e) {

    /* Retry with open if openLegacy doesn't exist/fails */ Log.v(TAG, "openLegacy failed due to " + e.getMessage() + ", using open instead");

    mCamera = android.hardware.Camera.open(msg.arg1); }


    尝试采用此种方式获取camera对象后,重新通过以下代码打印log,发现底层插值算法支持的高分辨率最大到3600万像素都可以打印出来。

     List<Size> supported = params.getSupportedPictureSizes();

    for(Size size:supported){

    Log.i(TAG, "Camera support size.width="+size.width+",size.height="+size.height);

    }

    至此就解决了新框架无法获取插值算法支持的分辨率的问题。


    相关文章

      网友评论

          本文标题:Android Camera 无法正常获取插值支持的分辨率

          本文链接:https://www.haomeiwen.com/subject/yiwevhtx.html