大家使用API2开发相机APP时预览是调用CameraCaptureSession类的setRepeatingRequest方法,该方法的实现是由CameraCaptureSessionImpl完成的。
/frameworks\base\core\java\android\hardware\camera2\impl\CameraCaptureSessionImpl.java
@Override
public int setRepeatingRequest(CaptureRequest request, CaptureCallback callback,
299 Handler handler) throws CameraAccessException {
300 checkRepeatingRequest(request);
301
302 synchronized (mDeviceImpl.mInterfaceLock) {
303 checkNotClosed();
304
305 handler = checkHandler(handler, callback);
306
307 if (DEBUG) {
308 Log.v(TAG, mIdString + "setRepeatingRequest - request " + request + ", callback " +
309 callback + " handler" + " " + handler);
310 }
311
312 return addPendingSequence(mDeviceImpl.setRepeatingRequest(request,
313 createCaptureCallbackProxy(handler, callback), mDeviceExecutor));
314 }
}
/frameworks/base/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
public int setRepeatingRequest(CaptureRequest request, CaptureCallback callback,
1224 Executor executor) throws CameraAccessException {
1225 List<CaptureRequest> requestList = new ArrayList<CaptureRequest>();
1226 requestList.add(request);
1227 return submitCaptureRequest(requestList, callback, executor, /*streaming*/true);
}
上层APP传下来的Request被进一步包装成List,而List的元素只有一个,然后继续调用submitCaptureRequest方法进行处理:
private int submitCaptureRequest(List<CaptureRequest> requestList, CaptureCallback callback,
1147 Executor executor, boolean repeating) throws CameraAccessException {
1148
1149 // Need a valid executor, or current thread needs to have a looper, if
1150 // callback is valid
1151 executor = checkExecutor(executor, callback);
1152
1153 synchronized(mInterfaceLock) {
1154 checkIfCameraClosedOrInError();
1155
1156 // Make sure that there all requests have at least 1 surface; all surfaces are non-null;
1157 for (CaptureRequest request : requestList) {
1158 if (request.getTargets().isEmpty()) {
1159 throw new IllegalArgumentException(
1160 "Each request must have at least one Surface target");
1161 }
//getTargets得到的就是我们在APP层放进去的Surface对象
1163 for (Surface surface : request.getTargets()) {
1164 if (surface == null) {
1165 throw new IllegalArgumentException("Null Surface targets are not allowed");
1166 }
1167 }
1168 }
1169
1170 if (repeating) {
1171 stopRepeating();
1172 }
1173
1174 SubmitInfo requestInfo;
1175
1176 CaptureRequest[] requestArray = requestList.toArray(new CaptureRequest[requestList.size()]);
1177 // Convert Surface to streamIdx and surfaceIdx
1178 for (CaptureRequest request : requestArray) {
1179 request.convertSurfaceToStreamId(mConfiguredOutputs);
1180 }
//repeating: true表示是预览请求,需要重复;false表示是拍照,只有一帧,不需要重复
//通过Binder进程间通信调用到CameraDeviceClient对象中
1182 requestInfo = mRemoteDevice.submitRequestList(requestArray, repeating);
1183 if (DEBUG) {
1184 Log.v(TAG, "last frame number " + requestInfo.getLastFrameNumber());
1185 }
1186
1187 for (CaptureRequest request : requestArray) {
1188 request.recoverStreamIdToSurface();
1189 }
1190
1191 if (callback != null) {
1192 mCaptureCallbackMap.put(requestInfo.getRequestId(),
1193 new CaptureCallbackHolder(
1194 callback, requestList, executor, repeating, mNextSessionId - 1));
1195 } else {
1196 if (DEBUG) {
1197 Log.d(TAG, "Listen for request " + requestInfo.getRequestId() + " is null");
1198 }
1199 }
1200
1201 if (repeating) {
1202 if (mRepeatingRequestId != REQUEST_ID_NONE) {
1203 checkEarlyTriggerSequenceCompleteLocked(mRepeatingRequestId,
1204 requestInfo.getLastFrameNumber(),
1205 mRepeatingRequestTypes);
1206 }
1207 mRepeatingRequestId = requestInfo.getRequestId();
1208 mRepeatingRequestTypes = getRequestTypes(requestArray);
1209 } else {
1210 mRequestLastFrameNumbersList.add(
1211 new RequestLastFrameNumbersHolder(requestList, requestInfo));
1212 }
1213
1214 if (mIdle) {
1215 mDeviceExecutor.execute(mCallOnActive);
1216 }
1217 mIdle = false;
1218
1219 return requestInfo.getRequestId();
1220 }
}
/frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
binder::Status CameraDeviceClient::submitRequestList(
188 const std::vector<hardware::camera2::CaptureRequest>& requests,
189 bool streaming,
190 /*out*/
191 hardware::camera2::utils::SubmitInfo *submitInfo) {
192 ATRACE_CALL();
193 ALOGV("%s-start of function. Request list size %zu", __FUNCTION__, requests.size());
194
195 binder::Status res = binder::Status::ok();
196 status_t err;
197 if ( !(res = checkPidStatus(__FUNCTION__) ).isOk()) {
198 return res;
199 }
200
201 Mutex::Autolock icl(mBinderSerializationLock);
202
203 if (!mDevice.get()) {
204 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
205 }
206
207 if (requests.empty()) {
208 ALOGE("%s: Camera %s: Sent null request. Rejecting request.",
209 __FUNCTION__, mCameraIdStr.string());
210 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Empty request list");
211 }
212
213 List<const CameraDeviceBase::PhysicalCameraSettingsList> metadataRequestList;
214 std::list<const SurfaceMap> surfaceMapList;
215 submitInfo->mRequestId = mRequestIdCounter;
216 uint32_t loopCounter = 0;
217
218 for (auto&& request: requests) {
219 if (request.mIsReprocess) {
220 if (!mInputStream.configured) {
221 ALOGE("%s: Camera %s: no input stream is configured.", __FUNCTION__,
222 mCameraIdStr.string());
223 return STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
224 "No input configured for camera %s but request is for reprocessing",
225 mCameraIdStr.string());
226 } else if (streaming) {
227 ALOGE("%s: Camera %s: streaming reprocess requests not supported.", __FUNCTION__,
228 mCameraIdStr.string());
229 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
230 "Repeating reprocess requests not supported");
231 } else if (request.mPhysicalCameraSettings.size() > 1) {
232 ALOGE("%s: Camera %s: reprocess requests not supported for "
233 "multiple physical cameras.", __FUNCTION__,
234 mCameraIdStr.string());
235 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
236 "Reprocess requests not supported for multiple cameras");
237 }
238 }
239
240 if (request.mPhysicalCameraSettings.empty()) {
241 ALOGE("%s: Camera %s: request doesn't contain any settings.", __FUNCTION__,
242 mCameraIdStr.string());
243 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
244 "Request doesn't contain any settings");
245 }
246
247 //The first capture settings should always match the logical camera id
248 String8 logicalId(request.mPhysicalCameraSettings.begin()->id.c_str());
249 if (mDevice->getId() != logicalId) {
250 ALOGE("%s: Camera %s: Invalid camera request settings.", __FUNCTION__,
251 mCameraIdStr.string());
252 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
253 "Invalid camera request settings");
254 }
255
256 if (request.mSurfaceList.isEmpty() && request.mStreamIdxList.size() == 0) {
257 ALOGE("%s: Camera %s: Requests must have at least one surface target. "
258 "Rejecting request.", __FUNCTION__, mCameraIdStr.string());
259 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
260 "Request has no output targets");
261 }
262
263 /**
264 * Write in the output stream IDs and map from stream ID to surface ID
265 * which we calculate from the capture request's list of surface target
266 */
267 SurfaceMap surfaceMap;
268 Vector<int32_t> outputStreamIds;
269 std::vector<std::string> requestedPhysicalIds;
270 if (request.mSurfaceList.size() > 0) {
271 for (const sp<Surface>& surface : request.mSurfaceList) {
272 if (surface == 0) continue;
273
274 int32_t streamId;
275 sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer();
276 res = insertGbpLocked(gbp, &surfaceMap, &outputStreamIds, &streamId);
277 if (!res.isOk()) {
278 return res;
279 }
280
281 ssize_t index = mConfiguredOutputs.indexOfKey(streamId);
282 if (index >= 0) {
283 String8 requestedPhysicalId(
284 mConfiguredOutputs.valueAt(index).getPhysicalCameraId());
285 requestedPhysicalIds.push_back(requestedPhysicalId.string());
286 } else {
287 ALOGW("%s: Output stream Id not found among configured outputs!", __FUNCTION__);
288 }
289 }
290 } else {
291 for (size_t i = 0; i < request.mStreamIdxList.size(); i++) {
292 int streamId = request.mStreamIdxList.itemAt(i);
293 int surfaceIdx = request.mSurfaceIdxList.itemAt(i);
294
295 ssize_t index = mConfiguredOutputs.indexOfKey(streamId);
296 if (index < 0) {
297 ALOGE("%s: Camera %s: Tried to submit a request with a surface that"
298 " we have not called createStream on: stream %d",
299 __FUNCTION__, mCameraIdStr.string(), streamId);
300 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
301 "Request targets Surface that is not part of current capture session");
302 }
303
304 const auto& gbps = mConfiguredOutputs.valueAt(index).getGraphicBufferProducers();
305 if ((size_t)surfaceIdx >= gbps.size()) {
306 ALOGE("%s: Camera %s: Tried to submit a request with a surface that"
307 " we have not called createStream on: stream %d, surfaceIdx %d",
308 __FUNCTION__, mCameraIdStr.string(), streamId, surfaceIdx);
309 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
310 "Request targets Surface has invalid surface index");
311 }
312
313 res = insertGbpLocked(gbps[surfaceIdx], &surfaceMap, &outputStreamIds, nullptr);
314 if (!res.isOk()) {
315 return res;
316 }
317
318 String8 requestedPhysicalId(
319 mConfiguredOutputs.valueAt(index).getPhysicalCameraId());
320 requestedPhysicalIds.push_back(requestedPhysicalId.string());
321 }
322 }
323
324 CameraDeviceBase::PhysicalCameraSettingsList physicalSettingsList;
325 for (const auto& it : request.mPhysicalCameraSettings) {
326 if (it.settings.isEmpty()) {
327 ALOGE("%s: Camera %s: Sent empty metadata packet. Rejecting request.",
328 __FUNCTION__, mCameraIdStr.string());
329 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
330 "Request settings are empty");
331 }
332
333 String8 physicalId(it.id.c_str());
334 if (physicalId != mDevice->getId()) {
335 auto found = std::find(requestedPhysicalIds.begin(), requestedPhysicalIds.end(),
336 it.id);
337 if (found == requestedPhysicalIds.end()) {
338 ALOGE("%s: Camera %s: Physical camera id: %s not part of attached outputs.",
339 __FUNCTION__, mCameraIdStr.string(), physicalId.string());
340 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
341 "Invalid physical camera id");
342 }
343
344 if (!mSupportedPhysicalRequestKeys.empty()) {
345 // Filter out any unsupported physical request keys.
346 CameraMetadata filteredParams(mSupportedPhysicalRequestKeys.size());
347 camera_metadata_t *meta = const_cast<camera_metadata_t *>(
348 filteredParams.getAndLock());
349 set_camera_metadata_vendor_id(meta, mDevice->getVendorTagId());
350 filteredParams.unlock(meta);
351
352 for (const auto& keyIt : mSupportedPhysicalRequestKeys) {
353 camera_metadata_ro_entry entry = it.settings.find(keyIt);
354 if (entry.count > 0) {
355 filteredParams.update(entry);
356 }
357 }
358
359 physicalSettingsList.push_back({it.id, filteredParams});
360 }
361 } else {
362 physicalSettingsList.push_back({it.id, it.settings});
363 }
364 }
365
366 if (!enforceRequestPermissions(physicalSettingsList.begin()->metadata)) {
367 // Callee logs
368 return STATUS_ERROR(CameraService::ERROR_PERMISSION_DENIED,
369 "Caller does not have permission to change restricted controls");
370 }
371
372 physicalSettingsList.begin()->metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS,
373 &outputStreamIds[0], outputStreamIds.size());
374
375 if (request.mIsReprocess) {
376 physicalSettingsList.begin()->metadata.update(ANDROID_REQUEST_INPUT_STREAMS,
377 &mInputStream.id, 1);
378 }
379
380 physicalSettingsList.begin()->metadata.update(ANDROID_REQUEST_ID,
381 &(submitInfo->mRequestId), /*size*/1);
382 loopCounter++; // loopCounter starts from 1
383 ALOGV("%s: Camera %s: Creating request with ID %d (%d of %zu)",
384 __FUNCTION__, mCameraIdStr.string(), submitInfo->mRequestId,
385 loopCounter, requests.size());
386
387 metadataRequestList.push_back(physicalSettingsList);
388 surfaceMapList.push_back(surfaceMap);
389 }
390 mRequestIdCounter++;
//预览, streaming就是上面repeating, 为true,执行if逻辑
392 if (streaming) {
393 err = mDevice->setStreamingRequestList(metadataRequestList, surfaceMapList,
394