Android Camera API 1打开相机失败

        目前Camera API 1使用的比较少了,一般代码如下。遇到的问题是camera1接口无法打开相机,cam2接口打开正常。最后排查结果是 sensor的 frameRate 配置不对。

    Camera camera;
    CameraPreview mPreview;

    @SuppressLint("MissingPermission")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.cam_1_layout);

        mPreview = findViewById(R.id.camera_1_preview);
        try {
            camera = Camera.open(0);
            mPreview.setCamera(camera);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    private Camera mCamera;

    public CameraPreview(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CameraPreview(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public CameraPreview(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    public void setCamera(Camera camera) {
        mCamera = camera;
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        // 相机预览尺寸变化时,调整相机参数
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setPreviewSize(width, height);
            mCamera.setParameters(parameters);
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // 停止相机预览并释放资源
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }

    log显示是  Camera.open(0); 时异常,预览分辨率不对导致。跟踪代码,Cam初始化时

CameraService::connectHelper 函数中执行 client->initialize,client 对应到不同api创建不同的对象。api1下的Camera2Client::initialize 流程中有 mParameters.initialize 步骤,在 Parameters::initialize 中执行 getFilteredSizes 进行过滤操作

    //过滤预览size
    res = getFilteredSizes(maxPreviewSize, &availablePreviewSizes);
    if (res != OK) return res;
    res = getFilteredSizes(videoSizeUpperBound, &availableVideoSizes);
    if (res != OK) return res;


status_t Parameters::getFilteredSizes(Size limit, Vector<Size> *sizes) {
    if (info == NULL) {
        ALOGE("%s: Static metadata is not initialized", __FUNCTION__);
        return NO_INIT;
    }
    if (sizes == NULL) {
        ALOGE("%s: Input size is null", __FUNCTION__);
        return BAD_VALUE;
    }
    sizes->clear();
    Vector<StreamConfiguration> scs = getStreamConfigurations();
    for (size_t i=0; i < scs.size(); i++) {
        const StreamConfiguration &sc = scs[i];
        if (sc.isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT &&
                sc.format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
                sc.width <= limit.width && sc.height <= limit.height) {
            int64_t minFrameDuration = getMinFrameDurationNs(
                    {sc.width, sc.height}, HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
            if (minFrameDuration > MAX_PREVIEW_RECORD_DURATION_NS) {
                // Filter slow sizes from preview/record
                continue;
            }
            sizes->push({sc.width, sc.height});
        }
    }
    if (sizes->isEmpty()) {
        ALOGE("generated preview size list is empty!!");
        return BAD_VALUE;
    }
    return OK;
}

这里获取 sensor 配置支持的 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS 数值,与平台默认 MAX_PREVIEW_RECORD_DURATION_NS 值比较。这里比较是每一帧的时间,单位是ns,值越大,说明帧率越低。MAX_PREVIEW_RECORD_DURATION_NS 由系统默认设置,一般平台帧率30,MAX_PREVIEW_RECORD_DURATION_NS  = 1/30 * 1000 000 000 (ns)。sensor 配置帧率一般在 sensor.xml 中,标签是 <frameRate> ,根据不同SIZE会配置不同frameRate的值。

相关推荐

  1. Android Camera API 1打开相机失败

    2024-04-10 06:14:04       33 阅读
  2. cpp-stub 打桩失败

    2024-04-10 06:14:04       61 阅读
  3. Android EDLA项目 5G热点打开失败分析

    2024-04-10 06:14:04       24 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-10 06:14:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-10 06:14:04       101 阅读
  3. 在Django里面运行非项目文件

    2024-04-10 06:14:04       82 阅读
  4. Python语言-面向对象

    2024-04-10 06:14:04       91 阅读

热门阅读

  1. Hadoop简介

    2024-04-10 06:14:04       35 阅读
  2. 数据仓库理论与实战

    2024-04-10 06:14:04       29 阅读
  3. 高并发环境下的实现与优化策略

    2024-04-10 06:14:04       42 阅读
  4. 百度机器学习算法春招一二三面面经

    2024-04-10 06:14:04       33 阅读
  5. 基于Flask测试深度学习模型预测

    2024-04-10 06:14:04       40 阅读
  6. Vscode使用教程

    2024-04-10 06:14:04       34 阅读
  7. 【hive】单节点搭建hadoop和hive

    2024-04-10 06:14:04       32 阅读
  8. Hadoop 源码中使用ServiceLoader

    2024-04-10 06:14:04       39 阅读
  9. vscode 关键字记录

    2024-04-10 06:14:04       31 阅读
  10. Ajax、Fetch、Axios三者的区别

    2024-04-10 06:14:04       41 阅读
  11. 在 Vue 3 中使用 Axios 发送 POST 请求

    2024-04-10 06:14:04       37 阅读