android camera2配置流程
阿新 • • 發佈:2019-01-26
更新camera配置通過CameraAgent.CameraProxy.applySettings()實現
在camera_API1中
AndroidCameraAgentImpl.java
public boolean applySettings(CameraSettings settings) {
return applySettingsHelper(settings, AndroidCameraStateHolder.CAMERA_IDLE |
AndroidCameraStateHolder.CAMERA_UNLOCKED);
}
CameraAgent.java
protected boolean applySettingsHelper(CameraSettings settings,
final int statesToAwait) {
if (settings == null) {
Log.v(TAG, "null argument in applySettings()");
return false;
}
if (!getCapabilities().supports(settings)) {
Log.w(TAG, "Unsupported settings in applySettings()" );
return false;
}
final CameraSettings copyOfSettings = settings.copy();
getDispatchThread().runJob(new Runnable() {
@Override
public void run() {
getCameraState().waitForStates(statesToAwait);
getCameraHandler().obtainMessage(CameraActions.APPLY_SETTINGS, copyOfSettings)
.sendToTarget();
}});
return true;
}
camera的配置會儲存在CameraSettings,然後通過settings.copy()將它映象出一份,通過CameraActions.APPLY_SETTINGS訊息傳送給
AndroidCameraAgentImpl去接收,
case CameraActions.APPLY_SETTINGS: {
Parameters parameters = mParameterCache.getBlocking();
CameraSettings settings = (CameraSettings) msg.obj;
applySettingsToParameters(settings, parameters);
mCamera.setParameters(parameters);
mParameterCache.invalidate();
break;
}
通過applySettingsToParameters(settings, parameters);進行處理最後通過mCamera.setParameters(parameters);來使它生效。
在最新的camea_API2中,流程會有所不同,具體看如下
AndroidCamera2AgentImpl.java
@Override
public boolean applySettings(CameraSettings settings) {
if (settings == null) {
Log.w(TAG, "null parameters in applySettings()");
return false;
}
if (!(settings instanceof AndroidCamera2Settings)) {
Log.e(TAG, "Provided settings not compatible with the backing framework API");
return false;
}
// Wait for any state that isn't OPENED
//這裡和API1中一樣呼叫CameraAgent的applySettingsHelper函式
if (applySettingsHelper(settings, ~AndroidCamera2StateHolder.CAMERA_UNOPENED)) {
mLastSettings = settings;
return true;
}
return false;
}
case CameraActions.APPLY_SETTINGS: {
AndroidCamera2Settings settings = (AndroidCamera2Settings) msg.obj;
applyToRequest(settings);
break;
}
private void applyToRequest(AndroidCamera2Settings settings) {
// TODO: If invoked when in PREVIEW_READY state, a new preview size will not take effect
//將配置資訊儲存到Camera2RequestSettingsSet的mDictionary中
mPersistentSettings.union(settings.getRequestSettings());
mPreviewSize = settings.getCurrentPreviewSize();
mPhotoSize = settings.getCurrentPhotoSize();
if (mCameraState.getState() >= AndroidCamera2StateHolder.CAMERA_PREVIEW_ACTIVE) {
// If we're already previewing, reflect most settings immediately
try {
//通過這裡將mDictionary中的配置寫入camera硬體中
mSession.setRepeatingRequest(
mPersistentSettings.createRequest(mCamera,
CameraDevice.TEMPLATE_PREVIEW, mPreviewSurface),
/*listener*/mCameraResultStateCallback, /*handler*/this);
} catch (CameraAccessException ex) {
Log.e(TAG, "Failed to apply updated request settings", ex);
}
} else if (mCameraState.getState() < AndroidCamera2StateHolder.CAMERA_PREVIEW_READY) {
// If we're already ready to preview, this doesn't regress our state
changeState(AndroidCamera2StateHolder.CAMERA_CONFIGURED);
}
}
Camera2RequestSettingsSet.java
//mPersistentSettings.createRequest函式如下
public CaptureRequest createRequest(CameraDevice camera, int template, Surface... targets)
throws CameraAccessException {
if (camera == null) {
throw new NullPointerException("Tried to create request using null CameraDevice");
}
//建立CaptureRequest.Builder
Builder reqBuilder = camera.createCaptureRequest(template);
//將儲存在mDictionary中的camera配置資訊儲存到reqBuilder內的CameraMetadataNative中,
//CameraMetadataNative最後會通過JNI方法CameraMetadata_writeValues更新資料
for (Key<?> key : mDictionary.keySet()) {
setRequestFieldIfNonNull(reqBuilder, key);
}
for (Surface target : targets) {
if (target == null) {
throw new NullPointerException("Tried to add null Surface as request target");
}
reqBuilder.addTarget(target);
}
return reqBuilder.build();
}
到此java層的基本流程就告一段落。可以通過adb shell dumpsys media.camera檢視camera配置。