下面列出了android.hardware.camera2.CaptureResult#CONTROL_AF_STATE_FOCUSED_LOCKED 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private boolean isAFAcceptable(TotalCaptureResultProxy metadata)
{
Integer afState = metadata.get(CaptureResult.CONTROL_AF_STATE);
if (afState == null)
{
return true;
} else
{
switch (afState)
{
case CaptureResult.CONTROL_AF_STATE_INACTIVE:
case CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED:
case CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
case CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED:
case CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED:
return true;
default:
return false;
}
}
}
/**
* Convert reported camera2 AF state to OneCamera AutoFocusState.
*/
public static OneCamera.AutoFocusState stateFromCamera2State(int state)
{
switch (state)
{
case CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN:
return OneCamera.AutoFocusState.ACTIVE_SCAN;
case CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN:
return OneCamera.AutoFocusState.PASSIVE_SCAN;
case CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED:
return OneCamera.AutoFocusState.PASSIVE_FOCUSED;
case CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED:
return OneCamera.AutoFocusState.ACTIVE_FOCUSED;
case CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED:
return OneCamera.AutoFocusState.PASSIVE_UNFOCUSED;
case CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
return OneCamera.AutoFocusState.ACTIVE_UNFOCUSED;
default:
return OneCamera.AutoFocusState.INACTIVE;
}
}
/**
* Utility function: converts CaptureResult.CONTROL_AF_STATE to String.
*/
private static String controlAFStateToString(int controlAFState)
{
switch (controlAFState)
{
case CaptureResult.CONTROL_AF_STATE_INACTIVE:
return "inactive";
case CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN:
return "passive_scan";
case CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED:
return "passive_focused";
case CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN:
return "active_scan";
case CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED:
return "focus_locked";
case CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
return "not_focus_locked";
case CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED:
return "passive_unfocused";
default:
return "unknown";
}
}
private void process(CaptureResult result) {
Integer state = result.get(CaptureResult.CONTROL_AF_STATE);
if (null == state) {
return;
}
Log.d(TAG, "process: CONTROL_AF_STATE: " + state);
if (state == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED || state == CaptureResult
.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) {
Log.d(TAG, "process: start normal preview");
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest
.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.FLASH_MODE_OFF);
startPreview();
}
}
/**
* Auto-Focus の状態を文字列に変換します。
*
* @param afState Auto Focus の状態
* @return 文字列
*/
static String debugAFState(Integer afState) {
if (afState == null) {
return "NULL";
}
switch (afState) {
default:
return "UNKNOWN";
case CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN:
return "CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN";
case CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED:
return "CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED";
case CaptureResult.CONTROL_AF_STATE_INACTIVE:
return "CaptureResult.CONTROL_AF_STATE_INACTIVE";
case CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
return "CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED";
case CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED:
return "CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED";
case CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN:
return "CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN";
case CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED:
return "CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED";
}
}
@Override
public void onCaptureResult(CaptureResult result, boolean isCompleted) {
Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
boolean isAfReady = afState == null
|| afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED
|| afState == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
if (isAfReady) {
nextState(mAutoExposureState);
}
}
@Override
public void onCaptureResult(CaptureResult result, boolean isCompleted) {
Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
if (DEBUG) {
Log.d(TAG, "afState: " + Camera2Helper.debugAFState(afState) + " isCompleted: " + isCompleted);
}
boolean isAfReady = afState == null
|| afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED
|| afState == CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED
|| afState == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
boolean timeout = (System.currentTimeMillis() - mStartTime) > 5000;
if (isAfReady || timeout) {
nextState(mAutoExposureState);
}
}
@Override
public void monitorControlStates(CaptureResult result) {
Integer afStateMaybe = result.get(CaptureResult.CONTROL_AF_STATE);
if (afStateMaybe != null) {
int afState = afStateMaybe;
// Since we handle both partial and total results for multiple frames here, we
// might get the final callbacks for an earlier frame after receiving one or
// more that correspond to the next one. To prevent our data from oscillating,
// we never consider AF states that are older than the last one we've seen.
if (result.getFrameNumber() > mLastAfFrameNumber) {
boolean afStateChanged = afState != mLastAfState;
mLastAfState = afState;
mLastAfFrameNumber = result.getFrameNumber();
switch (afState) {
case CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN:
case CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED:
case CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED: {
if (afStateChanged && mPassiveAfCallback != null) {
// A CameraAFMoveCallback is attached. If we just started to
// scan, the motor is moving; otherwise, it has settled.
mPassiveAfCallback.onAutoFocusMoving(
afState == CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN,
mCameraProxy);
}
break;
}
case CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED:
case CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED: {
// This check must be made regardless of whether the focus state has
// changed recently to avoid infinite waiting during autoFocus()
// when the algorithm has already either converged or failed to.
if (mOneshotAfCallback != null) {
// A call to autoFocus() was just made to request a focus lock.
// Notify the caller that the lens is now indefinitely fixed,
// and report whether the image we're stuck with is in focus.
mOneshotAfCallback.onAutoFocus(
afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED,
mCameraProxy);
mOneshotAfCallback = null;
}
break;
}
}
}
}
Integer aeStateMaybe = result.get(CaptureResult.CONTROL_AE_STATE);
if (aeStateMaybe != null) {
int aeState = aeStateMaybe;
// Since we handle both partial and total results for multiple frames here, we
// might get the final callbacks for an earlier frame after receiving one or
// more that correspond to the next one. To prevent our data from oscillating,
// we never consider AE states that are older than the last one we've seen.
if (result.getFrameNumber() > mLastAeFrameNumber) {
mCurrentAeState = aeStateMaybe;
mLastAeFrameNumber = result.getFrameNumber();
switch (aeState) {
case CaptureResult.CONTROL_AE_STATE_CONVERGED:
case CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED:
case CaptureResult.CONTROL_AE_STATE_LOCKED: {
// This check must be made regardless of whether the exposure state
// has changed recently to avoid infinite waiting during
// takePicture() when the algorithm has already converged.
if (mOneshotCaptureCallback != null) {
// A call to takePicture() was just made, and autoexposure
// converged so it's time to initiate the capture!
mCaptureReader.setOnImageAvailableListener(
/*listener*/mOneshotCaptureCallback,
/*handler*/Camera2Handler.this);
try {
mSession.capture(
mPersistentSettings.createRequest(mCamera,
CameraDevice.TEMPLATE_STILL_CAPTURE,
mCaptureReader.getSurface()),
/*callback*/mOneshotCaptureCallback,
/*handler*/Camera2Handler.this);
} catch (CameraAccessException ex) {
Log.e(TAG, "Unable to initiate capture", ex);
} finally {
mOneshotCaptureCallback = null;
}
}
break;
}
}
}
}
}
/**
* Invoke every time we get a new CaptureResult via
* {@link CameraDevice.CaptureCallback#onCaptureCompleted}.
*
* <p>This function is responsible for dispatching updates via the
* {@link AutoFocusStateListener} so without calling this on a regular basis, no
* AF changes will be observed.</p>
*
* @param result CaptureResult
*/
public synchronized void onCaptureCompleted(CaptureResult result) {
/**
* Work-around for b/11269834
* Although these should never-ever happen, harden for ship
*/
if (result == null) {
Log.w(TAG, "onCaptureCompleted - missing result, skipping AF update");
return;
}
Key<Integer> keyAfState = CaptureResult.CONTROL_AF_STATE;
if (keyAfState == null) {
Log.e(TAG, "onCaptureCompleted - missing android.control.afState key, " +
"skipping AF update");
return;
}
Key<Integer> keyAfMode = CaptureResult.CONTROL_AF_MODE;
if (keyAfMode == null) {
Log.e(TAG, "onCaptureCompleted - missing android.control.afMode key, " +
"skipping AF update");
return;
}
Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
Integer afMode = result.get(CaptureResult.CONTROL_AF_MODE);
/**
* Work-around for b/11238865
* This is a HAL bug as these fields should be there always.
*/
if (afState == null) {
Log.w(TAG, "onCaptureCompleted - missing android.control.afState !");
return;
} else if (afMode == null) {
Log.w(TAG, "onCaptureCompleted - missing android.control.afMode !");
return;
}
if (DEBUG_LOGGING) Log.d(TAG, "onCaptureCompleted - new AF mode = " + afMode +
" new AF state = " + afState);
if (mLastAfState == afState && afMode == mLastAfMode) {
// Same AF state as last time, nothing else needs to be done.
return;
}
if (VERBOSE_LOGGING) Log.v(TAG, "onCaptureCompleted - new AF mode = " + afMode +
" new AF state = " + afState);
mLastAfState = afState;
mLastAfMode = afMode;
switch (afState) {
case CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED:
mListener.onAutoFocusSuccess(result, /*locked*/true);
endTraceAsync();
break;
case CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
mListener.onAutoFocusFail(result, /*locked*/true);
endTraceAsync();
break;
case CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED:
mListener.onAutoFocusSuccess(result, /*locked*/false);
break;
case CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED:
mListener.onAutoFocusFail(result, /*locked*/false);
break;
case CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN:
mListener.onAutoFocusScan(result);
break;
case CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN:
mListener.onAutoFocusScan(result);
break;
case CaptureResult.CONTROL_AF_STATE_INACTIVE:
mListener.onAutoFocusInactive(result);
break;
}
}
private void process(CaptureResult result) {
synchronized (mCameraStateLock) {
switch (mState) {
case STATE_PREVIEW: {
// We have nothing to do when the camera preview is running normally.
break;
}
case STATE_WAITING_FOR_3A_CONVERGENCE: {
boolean readyToCapture = true;
if (!mNoAFRun) {
Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
if (afState == null) {
break;
}
// If auto-focus has reached locked state, we are ready to capture
readyToCapture =
(afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED ||
afState == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
}
// If we are running on an non-legacy device, we should also wait until
// auto-exposure and auto-white-balance have converged as well before
// taking a picture.
if (!isLegacyLocked()) {
Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
Integer awbState = result.get(CaptureResult.CONTROL_AWB_STATE);
if (aeState == null || awbState == null) {
break;
}
readyToCapture = readyToCapture &&
aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED &&
awbState == CaptureResult.CONTROL_AWB_STATE_CONVERGED;
}
// If we haven't finished the pre-capture sequence but have hit our maximum
// wait timeout, too bad! Begin capture anyway.
if (!readyToCapture && hitTimeoutLocked()) {
Log.w(TAG, "Timed out waiting for pre-capture sequence to complete.");
readyToCapture = true;
}
if (readyToCapture && mPendingUserCaptures > 0) {
// Capture once for each user tap of the "Picture" button.
while (mPendingUserCaptures > 0) {
captureStillPictureLocked();
mPendingUserCaptures--;
}
// After this, the camera will go back to the normal state of preview.
mState = STATE_PREVIEW;
}
}
}
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void setupJPEGCaptureListener() {
mCaptureCallback = new CameraCaptureSession.CaptureCallback() {
private void process(CaptureResult result) {
switch (mState) {
case STATE_PREVIEW: {
// We have nothing to do when the camera preview is working normally.
break;
}
case STATE_WAITING_LOCK: {
int afState = result.get(CaptureResult.CONTROL_AF_STATE);
if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState ||
CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) {
// CONTROL_AE_STATE can be null on some devices
Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
if (aeState == null ||
aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
mState = STATE_WAITING_NON_PRECAPTURE;
captureStillPicture();
} else {
runPrecaptureSequence();
}
}
break;
}
case STATE_WAITING_PRECAPTURE: {
// CONTROL_AE_STATE can be null on some devices
Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
if (aeState == null ||
aeState == CaptureResult.CONTROL_AE_STATE_PRECAPTURE ||
aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) {
mState = STATE_WAITING_NON_PRECAPTURE;
}
break;
}
case STATE_WAITING_NON_PRECAPTURE: {
// CONTROL_AE_STATE can be null on some devices
Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
if (aeState == null || aeState != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) {
mState = STATE_PICTURE_TAKEN;
captureStillPicture();
}
break;
}
}
}
};
}