赞
踩
目前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的值。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。