骁龙相机是高通开发的一个测试系统摄像头的demo,代码完善,功能强大。可以配合Camera驱动进行功能联调。
很多逻辑代码在CaptureModule.java里。
CaptureModule有8000多行,包罗万象。
涉及到界面显示要结合CaptureUI.java 一起来实现。
CaptureActivity持有了 CaptureModule 和 CaptureUI 。
以上是主要的引用关系。
CameraActivity 中调用了以下代码
case ModuleSwitcher.CAPTURE_MODULE_INDEX:
if(mCaptureModule == null) {
mCaptureModule = new CaptureModule();
//核心代码!!!
mCaptureModule.init(this, mCameraCaptureModuleRootView);
} else {
mCaptureModule.reinit();
}
mCurrentModule = mCaptureModule;
mCameraCaptureModuleRootView.setVisibility(View.VISIBLE);
Log.e("CameraActity"," setModuleFromIndex =================== CAPTURE_MODULE_INDEX");
break;
CaptureModule 里初始化代码:
@Override
public void init(CameraActivity activity, View parent) {
mActivity = activity;
mRootView = parent;
mSettingsManager = SettingsManager.getInstance();
mSettingsManager.createCaptureModule(this);
mSettingsManager.registerListener(this);
if (mSettingsManager.mIsHasOneCamera) {
CURRENT_ID = 0;
} else {
if (isBackCameraId()) {
CURRENT_ID = BACK_MODE;
} else {
CURRENT_ID = FRONT_MODE;
}
}
mSettingsManager.init();
mFirstPreviewLoaded = false;
Log.d(TAG, "init");
for (int i = 0; i < MAX_NUM_CAM; i++) {
mCameraOpened[i] = false;
mTakingPicture[i] = false;
}
for (int i = 0; i < MAX_NUM_CAM; i++) {
mState[i] = STATE_PREVIEW;
}
SceneModule module;
for (int i = 0; i < mSelectableModes.length + 2; i++) {
module = new SceneModule();
module.mode = CameraMode.values()[i];
mSceneCameraIds.add(module);
}
mPostProcessor = new PostProcessor(mActivity, this);
mFrameProcessor = new FrameProcessor(mActivity, this);
mContentResolver = mActivity.getContentResolver();
initModeByIntent();
initCameraIds();
mUI = new CaptureUI(activity, this, parent);
mUI.initializeControlByIntent();
mFocusStateListener = new FocusStateListener(mUI);
mLocationManager = new LocationManager(mActivity, this);
}
通过以下代码初始化CaptureUI
mUI = new CaptureUI(activity, this, parent);
mUI.initializeControlByIntent();
介绍一个核心操作来,了解是如何切换拍照模式的。
首先,通过CaptureUI ,来对组件赋予监听回调。
mFlashButton = (FlashToggleButton) mRootView.findViewById(R.id.flash_button);
mModeSelectLayout = (RecyclerView) mRootView.findViewById(R.id.mode_select_layout);
mModeSelectLayout.setLayoutManager(new LinearLayoutManager(mActivity,
LinearLayoutManager.HORIZONTAL, false));
mCameraModeAdapter = new Camera2ModeAdapter(mModule.getCameraModeList());
//设置单击回调
mCameraModeAdapter.setOnItemClickListener(mModule.getModeItemClickListener());
mModeSelectLayout.setAdapter(mCameraModeAdapter);
mSettingsIcon = (ImageView) mRootView.findViewById(R.id.settings);
mSettingsIcon.setImageResource(R.drawable.settings);
mSettingsIcon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openSettingsMenu();
}
});
对应CaptureModule的处理。
public OnItemClickListener getModeItemClickListener() {
return new OnItemClickListener() {
@Override
public int onItemClick(int mode) {
if (showLog) Log.e(TAG, "mode >>> " + mode);
if (!getCameraModeSwitcherAllowed()) {
return -1;
}
if (mode == CameraMode.VIDEO.ordinal()) {
videoCameraId = -1;
videoType = VIDEO_DEFAULT;
} else {
if (mode == CameraMode.MACRO.ordinal() || mode == CameraMode.NIGHT.ordinal()) {
videoCameraId = -1;
videoType = -1;
}
}
return selectCameraMode(mode);
}
};
}
CaptureModule 核心代码处理:
public int selectCameraMode(int mode) {
if (showLog) Log.e("CaptureModule", " mode:: ============== " + mode);
if (showLog)
Log.e("CaptureModule", " mCurrentSceneMode.mode:: =================== " + mCurrentSceneMode.mode);
for (SceneModule sceneModule : mSceneCameraIds) {
if (showLog) Log.e(TAG, " secenmode:: >> " + sceneModule.mode);
}
if (showLog)
Log.e("CaptureModule", " mSceneCameraIds.get(mode).mode:: =================== " + mSceneCameraIds.get(mode).mode);
if (showLog) Log.e("CaptureModule", " videoType:: =================== " + videoType);
if (showLog)
Log.e("CaptureModule", " videoCameraId:: =================== " + videoCameraId);
showCameraDevice();
String value = mSettingsManager.getValue(SettingsManager.KEY_FRONT_REAR_SWITCHER_VALUE);
boolean post = false;
if (mode == CameraMode.VIDEO.ordinal()) {
videoType = VIDEO_DEFAULT;
videoCameraId = 0;
} else if (mode == CameraMode.MACRO.ordinal()) {
if (value != null && value.equals("front")) {
post = true;
if (!isBackCamera()) {
mUI.performCameraSwitchClick();
}
}
} else if (mode == CameraMode.DEFAULT.ordinal()) {
videoType = -1;
videoCameraId = -1;
} else if (mode == CameraMode.NIGHT.ordinal()) {
if (value != null && value.equals("front")) {
if (!isBackCamera()) {
post = true;
mUI.performCameraSwitchClick();
}
}
if (showLog)
Log.e("xxx", " mPreviewRequestBuilder.length ===========> " + mPreviewRequestBuilder.length);
if (showLog)
Log.e("xxx", " mPreviewRequestBuilder.length ===========> " + mPreviewRequestBuilder.length);
} else if (mode == CameraMode.PRO_MODE.ordinal()) {
// if (value != null && value.equals("front")) {
// if (!isBackCamera()) {
// post = true;
// mUI.performCameraSwitchClick();
// }
// }
} else if (mode == CameraMode.HFR.ordinal()) {
if (value != null && value.equals("front")) {
if (!isBackCamera()) {
post = true;
mUI.performCameraSwitchClick();
}
}
}
if (showLog)
Log.e("CaptureModule", " mode2:: ============== " + mode);
if (showLog)
Log.e("CaptureModule", " mCurrentSceneMode.mode2 :: =================== " + mCurrentSceneMode.mode);
if (showLog)
Log.e("CaptureModule", " mSceneCameraIds.get(mode).mode2 :: =================== " + mSceneCameraIds.get(mode).mode);
showCameraDevice();
nmode = mode;
if (post) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
selectModle(nmode);
}
}, 1000);
} else {
selectModle(mode);
}
return 1;
}
以上经过定制后的代码。代码逻辑更加复杂。因为要支持,夜视和微距摄像头效果。还要支持前摄。
再调用selectModle方法
selectModle(int mode)
private int selectModle(int mode) {
// if (!isVideoModel) {
// if (mCurrentSceneMode.mode == mSceneCameraIds.get(mode).mode) {
// return -1;
// }
// }
showCameraDevice();
setCameraModeSwitcherAllowed(false);
setNextSceneMode(mode);
SceneModule nextSceneMode = mSceneCameraIds.get(mode);
String value = mSettingsManager.getValue(SettingsManager.KEY_FRONT_REAR_SWITCHER_VALUE);
if (showLog)
Log.e(TAG, " =============== current Mode is ::: " + mCurrentSceneMode.mode.ordinal());
if (value != null && value.equals("front") &&
(nextSceneMode.mode == CameraMode.RTB
|| nextSceneMode.mode == CameraMode.SAT
|| nextSceneMode.mode == CameraMode.PRO_MODE
)) {
if (showLog)
Log.e(TAG, " selectModle begin set value KEY_FRONT_REAR_SWITCHER_VALUE rear ========== mode:: " + mode);
mSettingsManager.setValue(SettingsManager.KEY_FRONT_REAR_SWITCHER_VALUE, "rear");
} else {
if (showLog) Log.e(TAG, " restartAll ========== mode:: " + mode);
restartAll();
}
updateZoomSeekBarVisible();
return 1;
}
再调用 restartAll方法
public void restartAll() {
showCameraDevice();
int nextCameraId = getNextScreneModeId(mNextModeIndex);
CURRENT_ID = getMainCameraId();
Log.d(TAG, "restart all CURRENT_ID :" + CURRENT_ID + " nextCameraId :" + nextCameraId);
if (CURRENT_ID == nextCameraId && mCameraDevice[nextCameraId] != null) {
mIsCloseCamera = false;
} else {
mIsCloseCamera = true;
}
SceneModule nextSceneModule = mSceneCameraIds.get(mNextModeIndex);
if (nextSceneModule.mode == CameraMode.DEFAULT
|| nextSceneModule.mode == CameraMode.PRO_MODE
|| nextSceneModule.mode == CameraMode.HFR
) {
mIsCloseCamera = true;
}
if (mCameraDevice[nextCameraId] == null) {
if (showLog) Log.e(TAG, " mCameraDevice[nextCameraId] is null " + nextCameraId);
} else {
if (showLog) Log.e(TAG, " mCameraDevice[nextCameraId] is not null " + nextCameraId);
}
在restartAll中执行各种Camera的初始化操作。首先要关闭原来的摄像头资源,再打开新的摄像头资源。各种操作都封装在以下几个方法。
onPauseBeforeSuper();
if (showLog) Log.e(TAG, " do onPauseBeforeSuper");
onPauseAfterSuper(false);
if (showLog) Log.e(TAG, " do onPauseAfterSuper false");
reinitSceneMode();
if (showLog) Log.e(TAG, " do reinitSceneMode ");
onResumeBeforeSuper(true);
if (showLog) Log.e(TAG, " do onResumeBeforeSuper ");
onResumeAfterSuper(true);
if (showLog) Log.e(TAG, " do onResumeAfterSuper ");
setRefocusLastTaken(false);
if (showLog) Log.e(TAG, " do setRefocusLastTaken ");
打开摄像头的操作。
onResumeAfterSuper 方法里的
if (mIsCloseCamera) {
Message msg = Message.obtain();
msg.what = OPEN_CAMERA;
msg.arg1 = mCurrentSceneMode.getCurrentId();
Log.d(TAG, "open is " + msg.arg1);
if (mCameraHandler != null) {
mCameraHandler.sendMessage(msg);
}
}
对应Handle的操作
private class MyCameraHandler extends Handler {
public MyCameraHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
int id = msg.arg1;
switch (msg.what) {
case OPEN_CAMERA:
openCamera(id);
break;
case CANCEL_TOUCH_FOCUS:
cancelTouchFocus(id);
break;
}
}
}
执行openCamra操作:
private void openCamera(int id) {
if (mPaused) {
return;
}
if (showLog) Log.e(TAG, "openCamera 1111 " + id);
CameraManager manager;
try {
manager = (CameraManager) mActivity.getSystemService(Context.CAMERA_SERVICE);
mCameraId[id] = manager.getCameraIdList()[id];
if (!mCameraOpenCloseLock.tryAcquire(5000, TimeUnit.MILLISECONDS)) {
Log.d(TAG, "Time out waiting to lock camera opening.");
throw new RuntimeException("Time out waiting to lock camera opening");
}
manager.openCamera(mCameraId[id], mStateCallback, mCameraHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
if (showLog) Log.d(TAG, "openCamera CameraAccessException 2222" + id);
} catch (InterruptedException e) {
e.printStackTrace();
if (showLog) Log.d(TAG, "openCamera InterruptedException 3333 " + id);
} catch (Exception e) {
e.printStackTrace();
if (showLog) Log.d(TAG, "openCamera Exception 44444 " + id);
}
if (showLog) Log.d(TAG, "openCamera end 55555 " + id);
}
回调mStateCallback 操作。
private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice cameraDevice) {
int id = Integer.parseInt(cameraDevice.getId());
Log.d(TAG, "onOpened " + id);
mCameraOpenCloseLock.release();
if (mPaused) {
return;
}
showCameraDevice();
if (showLog)
Log.e(TAG, "mStateCallback onOpened ========== id:: " + id);
mCameraDevice[id] = cameraDevice;
mCameraOpened[id] = true;
if (isBackCamera() && getCameraMode() == DUAL_MODE && id == BAYER_ID) {
Message msg = mCameraHandler.obtainMessage(OPEN_CAMERA, MONO_ID, 0);
mCameraHandler.sendMessage(msg);
} else {
mCamerasOpened = true;
if (showLog)
Log.e(TAG, "mStateCallback onOpened ========== mCamerasOpened:: " + mCamerasOpened);
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (showLog)
Log.e(TAG, "mStateCallback onOpened ========== mUI.onCameraOpened:: ");
mUI.onCameraOpened(mCurrentSceneMode.getCurrentId());
if (showLog)
Log.e(TAG, "mStateCallback onOpened ========== mUI.onCameraOpened:: end ");
}
});
showCameraDevice();
createSessions();
}
}
注意 mCameraDevice[id] = cameraDevice; 和 mCameraOpened[id] = true; 有几个摄像头就有几个mCameraDevice。id就是CameraId,一般就是其下标。
同样会有一个非常重要的函数 createSessions() ,有了 CameraDevice就要创建 CaptureSeesion。
private void createSessions() {
if (PersistUtil.isTraceEnable())
Trace.beginSection("createSessions");
if (mPaused || !mCamerasOpened || mTempHoldVideoInVideoIntent) return;
int cameraId = mCurrentSceneMode.getCurrentId();
if (showLog)
Log.e(TAG, "createSessions : Current SceneMode is ==== " + mCurrentSceneMode.mode);
Log.e(TAG, "createSessions : Current cameraId is ===== " + cameraId);
showCameraDevice();
switch (mCurrentSceneMode.mode) {
case VIDEO:
case VIDEO_NIGHT:
case VIDEO_MACRO:
case NIGHT:
createSessionForVideo
(cameraId);
break;
case HFR:
if (!HFR_RATE.equals("")) {
mSettingsManager.setValue(SettingsManager.KEY_VIDEO_HIGH_FRAME_RATE, HFR_RATE);
}
createSessionForVideo(cameraId);
break;
default:
createSession(cameraId);
}
if (PersistUtil.isTraceEnable())
Trace.endSection();
}
对应的会执行2个方法,一个是创建Camera的Session createSession(cameraId) 一个是创建Video的Session createSessionForVideo(cameraId)
createSession()
if (mChosenImageFormat == ImageFormat.YUV_420_888 || mChosenImageFormat == ImageFormat.PRIVATE) {
if (mPostProcessor.isZSLEnabled()) {
mPreviewRequestBuilder[id].addTarget(mImageReader[id].getSurface());
list.add(mPostProcessor.getZSLReprocessImageReader().getSurface());
if (mSaveRaw) {
mPreviewRequestBuilder[id].addTarget(mRawImageReader[id].getSurface());
}
mCameraDevice[id].createReprocessableCaptureSession(new InputConfiguration(mImageReader[id].getWidth(),
mImageReader[id].getHeight(), mImageReader[id].getImageFormat()), list, captureSessionCallback, mCameraHandler);
} else {
if (mSettingsManager.isHeifWriterEncoding() && outputConfigurations != null) {
mCameraDevice[id].createCaptureSessionByOutputConfigurations(outputConfigurations,
captureSessionCallback, mCameraHandler);
} else {
mCameraDevice[id].createCaptureSession(list, captureSessionCallback, mCameraHandler);
}
}
} else {
outputConfigurations = null;
if (ApiHelper.isAndroidPOrHigher() && outputConfigurations != null) {
Log.i(TAG, "list size:" + list.size());
Log.i(TAG, "create session 111 ");
createCameraSessionWithSessionConfiguration(id, outputConfigurations,
captureSessionCallback, mCameraHandler, mPreviewRequestBuilder[id]);
// mCameraDevice[id].createCaptureSession(list, captureSessionCallback, mCameraHandler);
} else {
Log.i(TAG, "create session 222 ");
mCameraDevice[id].createCaptureSession(list, captureSessionCallback, mCameraHandler);
}
captureSessionCallback 的操作
CameraCaptureSession.StateCallback captureSessionCallback =
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession cameraCaptureSession) {
if (mPaused || null == mCameraDevice[id] ||
cameraCaptureSession == null) {
return;
}
Log.i(TAG, "cameracapturesession - onConfigured " + id);
setCameraModeSwitcherAllowed(true);
// When the session is ready, we start displaying the preview.
mCaptureSession[id] = cameraCaptureSession;
if (id == getMainCameraId()) {
mCurrentSession = cameraCaptureSession;
}
initializePreviewConfiguration(id);
setDisplayOrientation();
updateFaceDetection();
mFirstPreviewLoaded = false;
try {
if (isBackCamera() && getCameraMode() == DUAL_MODE) {
linkBayerMono(id);
mIsLinked = true;
}
// Finally, we start displaying the camera preview.
// for cases where we are in dual mode with mono preview off,
// don't set repeating request for mono
if (mCaptureSession[id] == null) {
return;
}
// if (id == NIGHT_CAMRA_ID) { //Night模式
// mPreviewRequestBuilder[id].set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
// }
if (id == MONO_ID && !canStartMonoPreview()
&& getCameraMode() == DUAL_MODE) {
mCaptureSession[id].capture(mPreviewRequestBuilder[id]
.build(), mCaptureCallback, mCameraHandler);
} else {
if (id == NIGHT_CAMRA_ID) { //Night模式
mPreviewRequestBuilder[id].set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
// mPreviewRequestBuilder[id].set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
Log.d(TAG, "createSession : mPreviewRequestBuilder FLASH_MODE_TORCH ===== ");
}
mCaptureSession[id].setRepeatingRequest(mPreviewRequestBuilder[id]
.build(), mCaptureCallback, mCameraHandler);
}
if (mIntentMode == INTENT_MODE_STILL_IMAGE_CAMERA &&
mIsVoiceTakePhote) {
mHandler.sendEmptyMessageDelayed(VOICE_INTERACTION_CAPTURE, 500);
}
if (isClearSightOn()) {
ClearSightImageProcessor.getInstance().onCaptureSessionConfigured(id == BAYER_ID, cameraCaptureSession);
} else if (mChosenImageFormat == ImageFormat.PRIVATE && id == getMainCameraId()) {
mPostProcessor.onSessionConfigured(mCameraDevice[id], mCaptureSession[id]);
}
} catch (CameraAccessException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
mCurrentSessionClosed = false;
}
@Override
public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
if (showLog)
Log.e(TAG, "cameracapturesession - onConfigureFailed " + id);
setCameraModeSwitcherAllowed(true);
if (mActivity.isFinishing()) {
return;
}
// Toast.makeText(mActivity, "Camera Initialization Failed",
// Toast.LENGTH_SHORT).show();
}
@Override
public void onClosed(CameraCaptureSession session) {
Log.d(TAG, "cameracapturesession - onClosed");
setCameraModeSwitcherAllowed(true);
}
};
createSessionForVideo()
if (showLog)
Log.e(TAG, "createSessionForVideo 66666666666666 ");
if (isHighSpeedRateCapture()) {
int optionMode = isSSMEnabled() ? STREAM_CONFIG_SSM : SESSION_HIGH_SPEED;
if (showLog)
Log.e("TAG", " buildConstrainedCameraSession in ");
buildConstrainedCameraSession(mCameraDevice[cameraId], optionMode,
surfaces, mSessionListener, mCameraHandler, mVideoRecordRequestBuilder);
if (showLog)
Log.e(TAG, "createSessionForVideo 77777777777777777");
} else {
if (showLog)
Log.e("TAG", " configureCameraSessionWithParameters in cameraId :: " + cameraId);
configureCameraSessionWithParameters(cameraId, surfaces,
mSessionListener, mCameraHandler, mVideoRecordRequestBuilder);
if (showLog)
Log.e(TAG, "createSessionForVideo 888888888888");
}
创建CameraSession和VideoSession的主要区别。
CameraSession 使用了 mVideoRecordRequestBuilder 和 mPreviewRequestBuilder。
VideoSession 使用了 mVideoPreviewSurface 和 mMediaRecorderSurface。
CameraSession 通过拍照操作,来使用ImageReader获取图片数据。对应CameraSession有ImageReader实现的地方。
mCurrentSession.setRepeatingRequest(mVideoRecordRequestBuilder.build(),
mCaptureCallback, mCameraHandler);
执行以上操作后,就可以预览看到的内容了。
对应的,还有关闭Camera的操作。
closeCamera()
/**
* Closes the current {@link CameraDevice}.
*/
private void closeCamera() {
Log.d(TAG, "closeCamera ============== begin");
closeProcessors();
/* no need to set this in the callback and handle asynchronously. This is the same
reason as why we release the semaphore here, not in camera close callback function
as we don't have to protect the case where camera open() gets called during camera
close(). The low level framework/HAL handles the synchronization for open()
happens after close() */
try {
// Close camera starting with AUX first
for (int i = MAX_NUM_CAM - 1; i >= 0; i--) {
if (null != mCameraDevice[i]) {
try {
if (!mCameraOpenCloseLock.tryAcquire(2000, TimeUnit.MILLISECONDS)) {
Log.d(TAG, "Time out waiting to lock camera closing.");
// throw new RuntimeException("Time out waiting to lock camera closing");
}
} catch (Exception e) {
mCameraOpenCloseLock.release();
e.printStackTrace();
}
Log.d(TAG, "Closing camera: " + mCameraDevice[i].getId());
// session was closed here if intentMode is INTENT_MODE_VIDEO
if (mIntentMode != INTENT_MODE_VIDEO) {
try {
if (isAbortCapturesEnable() && mCaptureSession[i] != null) {
mCaptureSession[i].abortCaptures();
Log.d(TAG, "Closing camera call abortCaptures ");
}
if (isSendRequestAfterFlushEnable() && mCaptureSession[i] != null) {
Log.v(TAG, "Closing camera call setRepeatingRequest");
mCaptureSession[i].setRepeatingRequest(mPreviewRequestBuilder[i].build(),
mCaptureCallback, mCameraHandler);
}
} catch (IllegalStateException | CameraAccessException e) {
e.printStackTrace();
}
}
mCameraDevice[i].close();
mCameraDevice[i] = null;
mCameraOpened[i] = false;
mCaptureSession[i] = null;
}
}
mIsLinked = false;
if (null != mMediaRecorder) {
mMediaRecorder.release();
mMediaRecorder = null;
}
} catch (RuntimeException e) {
mCameraOpenCloseLock.release();
// throw new RuntimeException("Interrupted while trying to lock camera closing.", e);
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
mCurrentSessionClosed = true;
mCameraOpenCloseLock.release();
}
Log.d(TAG, "closeCamera ============== end");
}
closeImageReader()的操作
private void closeImageReader() {
for (int i = MAX_NUM_CAM - 1; i >= 0; i--) {
if (null != mImageReader[i]) {
mImageReader[i].close();
mImageReader[i] = null;
}
if (null != mRawImageReader[i]) {
mRawImageReader[i].close();
mRawImageReader[i] = null;
}
}
for (int i = mYUVCount - 1; i >= 0; i--) {
if (null != mYUVImageReader[i]) {
mYUVImageReader[i].close();
mYUVImageReader[i] = null;
}
}
if (null != mVideoSnapshotImageReader) {
mVideoSnapshotImageReader.close();
mVideoSnapshotImageReader = null;
}
}
closeProcessors()
private void closeProcessors() {
if (mPostProcessor != null) {
mPostProcessor.onClose();
}
if (mFrameProcessor != null) {
mFrameProcessor.onClose();
}
}
closeSessions()
private void closeSessions() {
for (int i = MAX_NUM_CAM - 1; i >= 0; i--) {
if (null != mCaptureSession[i]) {
if (mCamerasOpened) {
try {
if (mCurrentSession instanceof CameraConstrainedHighSpeedCaptureSession) {
List requestList = ((CameraConstrainedHighSpeedCaptureSession)
mCurrentSession).createHighSpeedRequestList(
mVideoRecordRequestBuilder.build());
mCurrentSession.captureBurst(requestList, null, mCameraHandler);
} else {
mCaptureSession[i].capture(mPreviewRequestBuilder[i].build(), null,
mCameraHandler);
}
} catch (CameraAccessException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
mCaptureSession[i].close();
mCaptureSession[i] = null;
}
}
}
以上是Camera的初始化流程,很复杂。这里单纯的是CaptureModule的逻辑。其中还要涉及到
CaptureUI的逻辑交互。
其中主要调用 showRelatedIcons(CaptureModule.CameraMode mode),根据显示模式显示不同的界面。
public void showRelatedIcons(CaptureModule.CameraMode mode) {
//common settings
mShutterButton.setVisibility(View.VISIBLE);
mFrontBackSwitcher.setVisibility(View.VISIBLE);
photoVideoSwitcher.setVisibility(View.INVISIBLE);
txt_macro_advice.setVisibility(View.INVISIBLE);
mMakeupButton.setVisibility(View.INVISIBLE);
mSceneModeSwitcher.setVisibility(View.INVISIBLE);
//settings for each mode
switch (mode) {
case DEFAULT:
mFilterModeSwitcher.setVisibility(View.VISIBLE);
mSceneModeSwitcher.setVisibility(View.VISIBLE);
mVideoButton.setVisibility(View.INVISIBLE);
mMuteButton.setVisibility(View.INVISIBLE);
mPauseButton.setVisibility(View.INVISIBLE);
break;
case RTB:
case SAT:
mFilterModeSwitcher.setVisibility(View.VISIBLE);
mSceneModeSwitcher.setVisibility(View.VISIBLE);
mVideoButton.setVisibility(View.INVISIBLE);
mFlashButton.setVisibility(View.INVISIBLE);
mMuteButton.setVisibility(View.INVISIBLE);
mPauseButton.setVisibility(View.INVISIBLE);
if (!DEV_LEVEL_ALL) {
mFrontBackSwitcher.setVisibility(View.INVISIBLE);
}
break;
case VIDEO:
case HFR:
mFrontBackSwitcher.setVisibility(View.VISIBLE);
photoVideoSwitcher.setVisibility(View.INVISIBLE);
mVideoButton.setVisibility(View.VISIBLE);
mFilterModeSwitcher.setVisibility(View.VISIBLE);
if (mModule.isBackCamera()) {
mFlashButton.setVisibility(View.INVISIBLE);
} else {
mFlashButton.setVisibility(View.VISIBLE);
}
mShutterButton.setVisibility(View.INVISIBLE);
break;
case PRO_MODE:
mFilterModeSwitcher.setVisibility(View.INVISIBLE);
mVideoButton.setVisibility(View.INVISIBLE);
mFrontBackSwitcher.setVisibility(View.INVISIBLE);
mMuteButton.setVisibility(View.INVISIBLE);
mPauseButton.setVisibility(View.INVISIBLE);
// if (mModule.isBackCamera()) {
// mFlashButton.setVisibility(View.VISIBLE);
// } else {
mFlashButton.setVisibility(View.INVISIBLE);
// }
break;
case MACRO:
mFrontBackSwitcher.setVisibility(View.INVISIBLE);
photoVideoSwitcher.setVisibility(View.VISIBLE);
((RotateImageView) photoVideoSwitcher).setImageResource(R.drawable.video_switch);
mVideoButton.setVisibility(View.INVISIBLE);
mFilterModeSwitcher.setVisibility(View.INVISIBLE);
txt_macro_advice.setVisibility(View.VISIBLE);
break;
case VIDEO_MACRO:
mFrontBackSwitcher.setVisibility(View.INVISIBLE);
photoVideoSwitcher.setVisibility(View.VISIBLE);
((RotateImageView) photoVideoSwitcher).setImageResource(R.drawable.photo_switch);
mVideoButton.setVisibility(View.VISIBLE);
mFilterModeSwitcher.setVisibility(View.INVISIBLE);
mShutterButton.setVisibility(View.INVISIBLE);
txt_macro_advice.setVisibility(View.VISIBLE);
break;
case VIDEO_NIGHT:
mFlashButton.setVisibility(View.VISIBLE);
mFrontBackSwitcher.setVisibility(View.INVISIBLE);
photoVideoSwitcher.setVisibility(View.VISIBLE);
((RotateImageView) photoVideoSwitcher).setImageResource(R.drawable.photo_switch);
mFilterModeSwitcher.setVisibility(View.INVISIBLE);
mShutterButton.setVisibility(View.INVISIBLE);
mVideoButton.setVisibility(View.VISIBLE);
break;
case NIGHT:
mFlashButton.setVisibility(View.INVISIBLE);
mFrontBackSwitcher.setVisibility(View.INVISIBLE);
photoVideoSwitcher.setVisibility(View.VISIBLE);
((RotateImageView) photoVideoSwitcher).setImageResource(R.drawable.video_switch);
mVideoButton.setVisibility(View.INVISIBLE);
mFilterModeSwitcher.setVisibility(View.INVISIBLE);
break;
default:
break;
}
String value = mSettingsManager.getValue(SettingsManager.KEY_FRONT_REAR_SWITCHER_VALUE);
if (value == null) {
mFrontBackSwitcher.setVisibility(View.INVISIBLE);
}
if (mModule.getVideoType() == CaptureModule.VIDEO_DEFAULT || mModule.getCurrenCameraMode() == CaptureModule.CameraMode.HFR) {
photoVideoSwitcher.setVisibility(View.INVISIBLE);
if (mModule.getCurrenCameraMode() == CaptureModule.CameraMode.HFR) {
if (mModule.isBackCamera()) {
mFlashButton.setVisibility(View.VISIBLE);
} else {
mFlashButton.setVisibility(View.INVISIBLE);
}
}
}
if (mModule.mMFNREnable && mModule.getMainCameraId() == android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT) {
mFilterModeSwitcher.setVisibility(View.INVISIBLE);
}
}
源码多读,多多比较思考和跟踪代码的流程。
如何编译 在SnapdragonCamera工程呢?
执行
source ./build/envsetup.sh
执行
lunch
选择正确的配置
在SnapdragonCamera工程下,执行 ,
mm
编译即可。
执行
adb install -r ../../../../SnapdragonCamera.apk
安装即可。