准备工作做好后,还需要响应点击拍照事件,我们设置点击拍照按钮调用capture()方法,capture()方法即实现拍照
private void capture() {
try {
//创建拍照请求
final CaptureRequest.Builder mCaptureBuilder =
mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
//获取屏幕方向
int rotation = getWindowManager().getDefaultDisplay().getRotation();
//绑定请求和mImageReader,不加的话就会导致mImageReader的onImageAvailable()方法不会回调
mCaptureBuilder.addTarget(mImageReader.getSurface());
//设置拍照方向
mCaptureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATION.get(rotation));
CameraCaptureSession.CaptureCallback CaptureCallback = new CameraCaptureSession.CaptureCallback() {
//回调函数,通知拍照数据处理完成
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
TotalCaptureResult result) {
//显示拍照完成的提示
Toast.makeText(getApplicationContext(), "Image Saved!", Toast.LENGTH_SHORT).show();
//重新预览
unLockFocus();
}
};
//停止预览
mCameraCaptureSession.stopRepeating();
//开始拍照
mCameraCaptureSession.capture(mCaptureBuilder.build(), CaptureCallback, null);
}
}
Request阶段
构造 CaptureRequest->UserRequestParams->ParsedAppRequest->IPipelineFrame,最终交给PipelineContextImpl处理
alps/frameworks/base/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
public int capture(CaptureRequest request, CaptureCallback callback, Executor executor){
List<CaptureRequest> requestList = new ArrayList<CaptureRequest>();
requestList.add(request);
return submitCaptureRequest(requestList, callback, executor, /*streaming*/false);
}
private int submitCaptureRequest(List<CaptureRequest> requestList, CaptureCallback callback,
Executor executor, boolean repeating) throws CameraAccessException {
executor = checkExecutor(executor, callback);
synchronized(mInterfaceLock) {
if (repeating) {
stopRepeating();
}
SubmitInfo requestInfo;
CaptureRequest[] requestArray = requestList.toArray(new CaptureRequest[requestList.size()]);
// Convert Surface to streamIdx and surfaceIdx
for (CaptureRequest request : requestArray) {
request.convertSurfaceToStreamId(mConfiguredOutputs);
}
requestInfo = mRemoteDevice.submitRequestList(requestArray, repeating);
for (CaptureRequest request : requestArray) {
request.recoverStreamIdToSurface();
}
if (callback != null) {
mCaptureCallbackMap.put(requestInfo.getRequestId(),
new CaptureCallbackHolder(
callback, requestList, executor, repeating, mNextSessionId - 1));
}
if (repeating) {
if (mRepeatingRequestId != REQUEST_ID_NONE) {
checkEarlyTriggerSequenceComplete(mRepeatingRequestId,
requestInfo.getLastFrameNumber());
}
mRepeatingRequestId = requestInfo.getRequestId();
} else {
mRequestLastFrameNumbersList.add(
new RequestLastFrameNumbersHolder(requestList, requestInfo));
}
return requestInfo.getRequestId();
}
}
alps/frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
转换请求对象CaptureRequest->PhysicalCameraSettingsList
binder::Status CameraDeviceClient::submitRequestList(
const std::vector<hardware::camera2::CaptureRequest>& requests,
bool streaming,
hardware::camera2::utils::SubmitInfo *submitInfo) {
List<const CameraDeviceBase::PhysicalCameraSettingsList> metadataRequestList;//Metadata链表
std::list<const SurfaceMap> surfaceMapList;
submitInfo->mRequestId = mRequestIdCounter;
for (auto&& request: requests) {
SurfaceMap surfaceMap;
Vector<int32_t> outputStreamIds;
std::vector<std::string> requestedPhysicalIds;
if (request.mSurfaceList.size() > 0) {//循环初始化Surface
for (sp<Surface> surface : request.mSurfaceList) {
int32_t streamId;
sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer();
res = insertGbpLocked(gbp, &surfaceMap, &outputStreamIds, &streamId);
ssize_t index = mConfiguredOutputs.indexOfKey(streamId);
if (index >= 0) {
String8 requestedPhysicalId(
mConfiguredOutputs.valueAt(index).getPhysicalCameraId());
requestedPhysicalIds.push_back(requestedPhysicalId.string());
}
}
} else {//拍照和预览
for (size_t i = 0; i < request.mStreamIdxList.size(); i++) {
int streamId = request.mStreamIdxList.itemAt(i);
int surfaceIdx = request.mSurfaceIdxList.itemAt(i);
ssize_t index = mConfiguredOutputs.indexOfKey(streamId);
const auto& gbps = mConfiguredOutputs.valueAt(index).getGraphicBufferProducers();
res = insertGbpLocked(gbps[surfaceIdx], &surfaceMap, &outputStreamIds, nullptr);
String8 requestedPhysicalId(mConfiguredOutputs.valueAt(index).getPhysicalCameraId());
requestedPhysicalIds.push_back(requestedPhysicalId.string());
}
}
构造PhysicalCameraSettingsList对象
CameraDeviceBase::PhysicalCameraSettingsList physicalSettingsList;
for (const auto& it : request.mPhysicalCameraSettings) {
String8 physicalId(it.id.c_str());
if (physicalId != mDevice->getId()) {
auto found = std::find(requestedPhysicalIds.begin(), requestedPhysicalIds.end(), it.id);
if (!mSupportedPhysicalRequestKeys.empty()) {
CameraMetadata filteredParams(mSupportedPhysicalRequestKeys.size());
camera_metadata_t *meta = const_cast<camer