Camera2 API AutoFocus with Samsung S5

后端 未结 4 699
一生所求
一生所求 2020-12-28 21:30

I\'m working with the new Camera2 API on a Samsung S5. The supported hardware level this device is reporting is LEGACY, which is fine.

However, I canno

相关标签:
4条回答
  • 2020-12-28 21:54

    I experience the same issue with a Galaxy Note 4 running Android 5.1.1 - while the same code works fine on a variety of other Android devices. There have been reports of similar issues with Galaxy-S4/S5/S6.

    http://developer.samsung.com/forum/board/thread/view.do?boardName=SDK&messageId=289824&startId=zzzzz~ https://www.youtube.com/watch?v=lnMoYZwVaFM

    So to anwer you question: This is most likely a bug in Samsung's implementation of the Camera-2 implementation - which seems to be of very low quality, unfourtunately.

    0 讨论(0)
  • 2020-12-28 22:02

    I branched form google's Camera2Basic example and changed it to use CaptureRequest.CONTROL_AF_MODE_AUTO instead of CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE

    You can take the project from git and test it - https://github.com/pinhassi/android-Camera2Basic

    Or just add this to Camera2BasicFragment:

    private static final long LOCK_FOCUS_DELAY_ON_FOCUSED = 5000;
    private static final long LOCK_FOCUS_DELAY_ON_UNFOCUSED = 1000;
    
    private Integer mLastAfState = null;
    private Handler mUiHandler = new Handler(); // UI handler
    private Runnable mLockAutoFocusRunnable = new Runnable() {
    
        @Override
        public void run() {
            lockAutoFocus();
        }
    };
    
    
    public void lockAutoFocus() {
        try {
            // This is how to tell the camera to lock focus.
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
            CaptureRequest captureRequest = mPreviewRequestBuilder.build();
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, null); // prevent CONTROL_AF_TRIGGER_START from calling over and over again
            mCaptureSession.capture(captureRequest, mCaptureCallback, mBackgroundHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }
    
    
    /**
     *
     * @return
     */
    private float getMinimumFocusDistance() {
        if (mCameraId == null)
            return 0;
    
        Float minimumLens = null;
        try {
            CameraManager manager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
            CameraCharacteristics c = manager.getCameraCharacteristics(mCameraId);
            minimumLens = c.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE);
        } catch (Exception e) {
            Log.e(TAG, "isHardwareLevelSupported Error", e);
        }
        if (minimumLens != null)
            return minimumLens;
        return 0;
    }
    
    /**
     *
     * @return
     */
    private boolean isAutoFocusSupported() {
        return  isHardwareLevelSupported(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) || getMinimumFocusDistance() > 0;
    }
    
    // Returns true if the device supports the required hardware level, or better.
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private boolean isHardwareLevelSupported(int requiredLevel) {
        boolean res = false;
        if (mCameraId == null)
            return res;
        try {
            CameraManager manager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
            CameraCharacteristics cameraCharacteristics = manager.getCameraCharacteristics(mCameraId);
    
            int deviceLevel = cameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
            switch (deviceLevel) {
                case CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3:
                    Log.d(TAG, "Camera support level: INFO_SUPPORTED_HARDWARE_LEVEL_3");
                    break;
                case CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL:
                    Log.d(TAG, "Camera support level: INFO_SUPPORTED_HARDWARE_LEVEL_FULL");
                    break;
                case CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY:
                    Log.d(TAG, "Camera support level: INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY");
                    break;
                case CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED:
                    Log.d(TAG, "Camera support level: INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED");
                    break;
                default:
                    Log.d(TAG, "Unknown INFO_SUPPORTED_HARDWARE_LEVEL: " + deviceLevel);
                    break;
            }
    
    
            if (deviceLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
                res = requiredLevel == deviceLevel;
            } else {
                // deviceLevel is not LEGACY, can use numerical sort
                res = requiredLevel <= deviceLevel;
            }
    
        } catch (Exception e) {
            Log.e(TAG, "isHardwareLevelSupported Error", e);
        }
        return res;
    }
    

    Then, add to STATE_PREVIEW block:

            case STATE_PREVIEW: {
    
                // We have nothing to do when the camera preview is working normally.
                // TODO: handle auto focus
                Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
                if (afState != null && !afState.equals(mLastAfState)) {
                    switch (afState) {
                        case CaptureResult.CONTROL_AF_STATE_INACTIVE:
                            Log.d(TAG, "CaptureResult.CONTROL_AF_STATE_INACTIVE");
                            lockAutoFocus();
                            break;
                        case CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN:
                            Log.d(TAG, "CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN");
                            break;
                        case CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED:
                            Log.d(TAG, "CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED");
                            mUiHandler.removeCallbacks(mLockAutoFocusRunnable);
                            mUiHandler.postDelayed(mLockAutoFocusRunnable, LOCK_FOCUS_DELAY_ON_FOCUSED);
                            break;
                        case CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
                            mUiHandler.removeCallbacks(mLockAutoFocusRunnable);
                            mUiHandler.postDelayed(mLockAutoFocusRunnable, LOCK_FOCUS_DELAY_ON_UNFOCUSED);
                            Log.d(TAG, "CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED");
                            break;
                        case CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED:
                            mUiHandler.removeCallbacks(mLockAutoFocusRunnable);
                            //mUiHandler.postDelayed(mLockAutoFocusRunnable, LOCK_FOCUS_DELAY_ON_UNFOCUSED);
                            Log.d(TAG, "CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED");
                            break;
                        case CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN:
                            Log.d(TAG, "CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN");
                            break;
                        case CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED:
                            mUiHandler.removeCallbacks(mLockAutoFocusRunnable);
                            //mUiHandler.postDelayed(mLockAutoFocusRunnable, LOCK_FOCUS_DELAY_ON_FOCUSED);
                            Log.d(TAG, "CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED");
                            break;
                    }
                }
                mLastAfState = afState;
                break;
            }
    

    And replace all occurrences of:

    mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                                                CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
    

    With:

    if (isAutoFocusSupported())
                                    mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                                            CaptureRequest.CONTROL_AF_MODE_AUTO);
                                else
                                    mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                                            CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
    
    0 讨论(0)
  • 2020-12-28 22:17

    The Samsung S5 with autofocus returned INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY, which means it does not support Camera2 api.

    I have the below filter for using camera in my application.

    if (Build.VERSION.SDK_INT >= 21 &amp;&amp; isDeviceCompatibleOfCamera2()) {
     // Use camera2
    } else {
     // Use old camera
    }
    
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
     public boolean isDeviceCompatibleOfCamera2() {
     try {
        CameraManager manager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
        String backCameraId = manager.getCameraIdList()[0];
        CameraCharacteristics backCameraInfo = manager.getCameraCharacteristics(backCameraId);
    
        int level = backCameraInfo.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
        return level == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL;
    
        } catch (CameraAccessException e) {
         ETLog.d(TAG, &quot;Device not compatible of camera2 api&quot; + e);
        }
        return false;
     }
    
    0 讨论(0)
  • 2020-12-28 22:18

    I think the issue is with your setRepeatingRequest. As far as I know, CaptureRequest.CONTROL_AF_MODE_AUTO should only cause an autofocus to occur once, but setRepeatingRequest will send continuous requests. Try using capture instead:

    previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO);
    previewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_START);
    
    state = STATE_PREVIEW;
    
    try {
    mCaptureSession.capture(mPreviewRequestBuilder.build(), mPreCaptureCallback, mBackgroundHandler);
    } catch (Exception e) {e.printStackTrace();}
    
    0 讨论(0)
提交回复
热议问题