大家使用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 &(submitInfo->mLastFrameNumber));
395 if (err != OK) {
396 String8 msg = String8::format(
397 "Camera %s: Got error %s (%d) after trying to set streaming request",
398 mCameraIdStr.string(), strerror(-err), err);
399 ALOGE("%s: %s", __FUNCTION__, msg.string());
400 res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
401 msg.string());
402 } else {
403 Mutex::Autolock idLock(mStreamingRequestIdLock);
404 mStreamingRequestId = submitInfo->mRequestId;
405 }
406 } else {
//拍照
407 err = mDevice->captureList(metadataRequestList, surfaceMapList,
408 &(submitInfo->mLastFrameNumber));
409 if (err != OK) {
410 String8 msg = String8::format(
411 "Camera %s: Got error %s (%d) after trying to submit capture request",
412 mCameraIdStr.string(), strerror(-err), err);
413 ALOGE("%s: %s", __FUNCTION__, msg.string());
414 res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
415 msg.string());
416 }
417 ALOGV("%s: requestId = %d ", __FUNCTION__, submitInfo->mRequestId);
418 }
419
420 ALOGV("%s: Camera %s: End of function", __FUNCTION__, mCameraIdStr.string());
421 return res;
}
/frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cpp
status_t Camera3Device::setStreamingRequestList(
1184 const List<const PhysicalCameraSettingsList> &requestsList,
1185 const std::list<const SurfaceMap> &surfaceMaps, int64_t *lastFrameNumber) {
1186 ATRACE_CALL();
1187
1188 return submitRequestsHelper(requestsList, surfaceMaps, /*repeating*/true, lastFrameNumber);
}
949status_t Camera3Device::submitRequestsHelper(
950 const List<const PhysicalCameraSettingsList> &requests,
951 const std::list<const SurfaceMap> &surfaceMaps,
952 bool repeating,
953 /*out*/
954 int64_t *lastFrameNumber) {
955 ATRACE_CALL();
956 Mutex::Autolock il(mInterfaceLock);
957 Mutex::Autolock l(mLock);
958
959 status_t res = checkStatusOkToCaptureLocked();
960 if (res != OK) {
961 // error logged by previous call
962 return res;
963 }
964
965 RequestList requestList;
966
967 res = convertMetadataListToRequestListLocked(requests, surfaceMaps,
968 repeating, /*out*/&requestList);
969 if (res != OK) {
970 // error logged by previous call
971 return res;
972 }
973
974 if (repeating) {
975 res = mRequestThread->setRepeatingRequests(requestList, lastFrameNumber);
976 } else {
977 res = mRequestThread->queueRequestList(requestList, lastFrameNumber);
978 }
979
980 if (res == OK) {
981 waitUntilStateThenRelock(/*active*/true, kActiveTimeout);
982 if (res != OK) {
983 SET_ERR_L("Can't transition to active in %f seconds!",
984 kActiveTimeout/1e9);
985 }
986 ALOGV("Camera %s: Capture request %" PRId32 " enqueued", mId.string(),
987 (*(requestList.begin()))->mResultExtras.requestId);
988 } else {
989 CLOGE("Cannot queue request. Impossible.");
990 return BAD_VALUE;
991 }
992
993 return res;
994}
status_t Camera3Device::RequestThread::setRepeatingRequests(
3901 const RequestList &requests,
3902 /*out*/
3903 int64_t *lastFrameNumber) {
3904 ATRACE_CALL();
3905 Mutex::Autolock l(mRequestLock);
3906 if (lastFrameNumber != NULL) {
3907 *lastFrameNumber = mRepeatingLastFrameNumber;
3908 }
3909 mRepeatingRequests.clear();
3910 mRepeatingRequests.insert(mRepeatingRequests.begin(),
3911 requests.begin(), requests.end());
3912
3913 unpauseForNewRequests();
3914
3915 mRepeatingLastFrameNumber = hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES;
3916 return OK;
}
RequestThread
下面重点看一下RequestThread,看看是如何实现连续预览的。
RequestThread是在Camera3Device初始化的时候构造的
status_t Camera3Device::initialize(sp<CameraProviderManager> manager, const String8& monitorTags) {
。。。。。。
。。。。。。
256 return initializeCommonLocked();
}
status_t Camera3Device::initializeCommonLocked() {
260
261 /** Start up status tracker thread */
262 mStatusTracker = new StatusTracker(this);
263 status_t res = mStatusTracker->run(String8::format("C3Dev-%s-Status", mId.string()).string());
264 if (res != OK) {
265 SET_ERR_L("Unable to start status tracking thread: %s (%d)",
266 strerror(-res), res);
267 mInterface->close();
268 mStatusTracker.clear();
269 return res;
270 }
271
272 /** Register in-flight map to the status tracker */
273 mInFlightStatusId = mStatusTracker->addComponent();
274
275 if (mUseHalBufManager) {
276 res = mRequestBufferSM.initialize(mStatusTracker);
277 if (res != OK) {
278 SET_ERR_L("Unable to start request buffer state machine: %s (%d)",
279 strerror(-res), res);
280 mInterface->close();
281 mStatusTracker.clear();
282 return res;
283 }
284 }
285
286 /** Create buffer manager */
287 mBufferManager = new Camera3BufferManager();
288
289 Vector<int32_t> sessionParamKeys;
290 camera_metadata_entry_t sessionKeysEntry = mDeviceInfo.find(
291 ANDROID_REQUEST_AVAILABLE_SESSION_KEYS);
292 if (sessionKeysEntry.count > 0) {
293 sessionParamKeys.insertArrayAt(sessionKeysEntry.data.i32, 0, sessionKeysEntry.count);
294 }
//构造RequestThread
296 /** Start up request queue thread */
297 mRequestThread = new RequestThread(
298 this, mStatusTracker, mInterface, sessionParamKeys, mUseHalBufManager);
299 res = mRequestThread->run(String8::format("C3Dev-%s-ReqQueue", mId.string()).string());
300 if (res != OK) {
301 SET_ERR_L("Unable to start request queue thread: %s (%d)",
302 strerror(-res), res);
303 mInterface->close();
304 mRequestThread.clear();
305 return res;
306 }
......
......
359 return OK;
}
RequestThread是继承Android的Thread类的,主函数就是threadLoop
bool Camera3Device::RequestThread::threadLoop() {
4258 ATRACE_CALL();
4259 status_t res;
4260 // Any function called from threadLoop() must not hold mInterfaceLock since
4261 // it could lead to deadlocks (disconnect() -> hold mInterfaceMutex -> wait for request thread
4262 // to finish -> request thread waits on mInterfaceMutex) http://b/143513518
4263
4264 // Handle paused state.
4265 if (waitIfPaused()) {
4266 return true;
4267 }
//准备下一次的Request请求
4269 // Wait for the next batch of requests.
4270 waitForNextRequestBatch();
4271 if (mNextRequests.size() == 0) {
4272 return true;
4273 }
4274
4275 // Get the latest request ID, if any
4276 int latestRequestId;
4277 camera_metadata_entry_t requestIdEntry = mNextRequests[mNextRequests.size() - 1].
4278 captureRequest->mSettingsList.begin()->metadata.find(ANDROID_REQUEST_ID);
4279 if (requestIdEntry.count > 0) {
4280 latestRequestId = requestIdEntry.data.i32[0];
4281 } else {
4282 ALOGW("%s: Did not have android.request.id set in the request.", __FUNCTION__);
4283 latestRequestId = NAME_NOT_FOUND;
4284 }
4285
4286 // 'mNextRequests' will at this point contain either a set of HFR batched requests
4287 // or a single request from streaming or burst. In either case the first element
4288 // should contain the latest camera settings that we need to check for any session
4289 // parameter updates.
4290 if (updateSessionParameters(mNextRequests[0].captureRequest->mSettingsList.begin()->metadata)) {
4291 res = OK;
4292
4293 //Input stream buffers are already acquired at this point so an input stream
4294 //will not be able to move to idle state unless we force it.
4295 if (mNextRequests[0].captureRequest->mInputStream != nullptr) {
4296 res = mNextRequests[0].captureRequest->mInputStream->forceToIdle();
4297 if (res != OK) {
4298 ALOGE("%s: Failed to force idle input stream: %d", __FUNCTION__, res);
4299 cleanUpFailedRequests(/*sendRequestError*/ false);
4300 return false;
4301 }
4302 }
4303
4304 if (res == OK) {
4305 sp<Camera3Device> parent = mParent.promote();
4306 if (parent != nullptr) {
4307 mReconfigured |= parent->reconfigureCamera(mLatestSessionParams, mStatusId);
4308 }
4309 setPaused(false);
4310
4311 if (mNextRequests[0].captureRequest->mInputStream != nullptr) {
4312 mNextRequests[0].captureRequest->mInputStream->restoreConfiguredState();
4313 if (res != OK) {
4314 ALOGE("%s: Failed to restore configured input stream: %d", __FUNCTION__, res);
4315 cleanUpFailedRequests(/*sendRequestError*/ false);
4316 return false;
4317 }
4318 }
4319 }
4320 }
//为上一步准备好的Request请求的hal_request赋值,继续完善这个Request
4322 // Prepare a batch of HAL requests and output buffers.
4323 res = prepareHalRequests();
4324 if (res == TIMED_OUT) {
4325 // Not a fatal error if getting output buffers time out.
4326 cleanUpFailedRequests(/*sendRequestError*/ true);
4327 // Check if any stream is abandoned.
4328 checkAndStopRepeatingRequest();
4329 return true;
4330 } else if (res != OK) {
4331 cleanUpFailedRequests(/*sendRequestError*/ false);
4332 return false;
4333 }
4334
4335 // Inform waitUntilRequestProcessed thread of a new request ID
4336 {
4337 Mutex::Autolock al(mLatestRequestMutex);
4338
4339 mLatestRequestId = latestRequestId;
4340 mLatestRequestSignal.signal();
4341 }
//将准备好的Request发送到HAL进程,也就是CameraHalServer当中去处理
4343 // Submit a batch of requests to HAL.
4344 // Use flush lock only when submitting multilple requests in a batch.
4345 // TODO: The problem with flush lock is flush() will be blocked by process_capture_request()
4346 // which may take a long time to finish so synchronizing flush() and
4347 // process_capture_request() defeats the purpose of cancelling requests ASAP with flush().
4348 // For now, only synchronize for high speed recording and we should figure something out for
4349 // removing the synchronization.
4350 bool useFlushLock = mNextRequests.size() > 1;
4351
4352 if (useFlushLock) {
4353 mFlushLock.lock();
4354 }
4355
4356 ALOGVV("%s: %d: submitting %zu requests in a batch.", __FUNCTION__, __LINE__,
4357 mNextRequests.size());
4358
4359 sp<Camera3Device> parent = mParent.promote();
4360 if (parent != nullptr) {
4361 parent->mRequestBufferSM.onSubmittingRequest();
4362 }
4363
4364 bool submitRequestSuccess = false;
4365 nsecs_t tRequestStart = systemTime(SYSTEM_TIME_MONOTONIC);
4366 submitRequestSuccess = sendRequestsBatch();
4367
4368 nsecs_t tRequestEnd = systemTime(SYSTEM_TIME_MONOTONIC);
4369 mRequestLatency.add(tRequestStart, tRequestEnd);
4370
4371 if (useFlushLock) {
4372 mFlushLock.unlock();
4373 }
4374
4375 // Unset as current request
4376 {
4377 Mutex::Autolock l(mRequestLock);
4378 mNextRequests.clear();
4379 }
4380 mRequestSubmittedSignal.signal();
4381
4382 return submitRequestSuccess;
}
关注一下waitIfPaused,如果是pause状态的话,就什么不作,直接返回true,刚好该返回值就决定了线程是否要继续循环。看一下这个方法的实现:
bool Camera3Device::RequestThread::waitIfPaused() {
5128 ATRACE_CALL();
5129 status_t res;
5130 Mutex::Autolock l(mPauseLock);
5131 while (mDoPause) {
5132 if (mPaused == false) {
5133 mPaused = true;
5134 ALOGV("%s: RequestThread: Paused", __FUNCTION__);
5135 if (mNotifyPipelineDrain) {
5136 mInterface->signalPipelineDrain(mStreamIdsToBeDrained);
5137 mNotifyPipelineDrain = false;
5138 mStreamIdsToBeDrained.clear();
5139 }
5140 // Let the tracker know
5141 sp<StatusTracker> statusTracker = mStatusTracker.promote();
5142 if (statusTracker != 0) {
5143 statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
5144 }
5145 sp<Camera3Device> parent = mParent.promote();
5146 if (parent != nullptr) {
5147 parent->mRequestBufferSM.onRequestThreadPaused();
5148 }
5149 }
//如果没有Request请求时,将会等待50ms,再进行下一次判断。
5151 res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout);
5152 if (res == TIMED_OUT || exitPending()) {
5153 return true;
5154 }
5155 }
5156 // We don't set mPaused to false here, because waitForNextRequest needs
5157 // to further manage the paused state in case of starvation.
5158 return false;
}
waitForNextRequestBatch准备下一次的Request请求;prepareHalRequests为上一步准备好的Request请求的hal_request赋值,继续完善这个Request;最后根据mInterface->supportBatchRequest()是否支持批处理,分别调用sendRequestsBatch、sendRequestsOneByOne将准备好的Request发送到HAL进程,也就是CameraHalServer当中去处理了,最终返回submitRequestSuccess,如果该值为true,那么继续循环,如果为false,那么肯定是中间出问题,RequestThread线程就会退出了。
相机整个预览循环的工作就是在这里完成的,也全部是围绕着mNextRequests成员变量来进行的。下面来看一下waitForNextRequestBatch、prepareHalRequests、sendRequestsBatch(我们假定支持批处理)三个函数的实现。
waitForNextRequestBatch:
void Camera3Device::RequestThread::waitForNextRequestBatch() {
4969 ATRACE_CALL();
4970 // Optimized a bit for the simple steady-state case (single repeating
4971 // request), to avoid putting that request in the queue temporarily.
4972 Mutex::Autolock l(mRequestLock);
4973
4974 assert(mNextRequests.empty());
//这个局部变量nextRequest就是要添加到mNextRequests当中的目标
4976 NextRequest nextRequest;
4977 nextRequest.captureRequest = waitForNextRequestLocked();
4978 if (nextRequest.captureRequest == nullptr) {
4979 return;
4980 }
4981
4982 nextRequest.halRequest = camera3_capture_request_t();
4983 nextRequest.submitted = false;
4984 mNextRequests.add(nextRequest);
4985
4986 // Wait for additional requests
4987 const size_t batchSize = nextRequest.captureRequest->mBatchSize;
4988
4989 for (size_t i = 1; i < batchSize; i++) {
4990 NextRequest additionalRequest;
4991 additionalRequest.captureRequest = waitForNextRequestLocked();
4992 if (additionalRequest.captureRequest == nullptr) {
4993 break;
4994 }
4995
4996 additionalRequest.halRequest = camera3_capture_request_t();
4997 additionalRequest.submitted = false;
4998 mNextRequests.add(additionalRequest);
4999 }
5000
5001 if (mNextRequests.size() < batchSize) {
5002 ALOGE("RequestThread: only get %zu out of %zu requests. Skipping requests.",
5003 mNextRequests.size(), batchSize);
5004 cleanUpFailedRequests(/*sendRequestError*/true);
5005 }
5006
5007 return;
}
sp<Camera3Device::CaptureRequest>
5011 Camera3Device::RequestThread::waitForNextRequestLocked() {
5012 status_t res;
5013 sp<CaptureRequest> nextRequest;
//mRequestQueue是拍照队列,可见拍照优先级高于预览
5015 while (mRequestQueue.empty()) {
//预览request, 那么mRepeatingRequests不为空
5016 if (!mRepeatingRequests.empty()) {
5017 // Always atomically enqueue all requests in a repeating request
5018 // list. Guarantees a complete in-sequence set of captures to
5019 // application.
5020 const RequestList &requests = mRepeatingRequests;
5021 RequestList::const_iterator firstRequest =
5022 requests.begin();
5023 nextRequest = *firstRequest;
5024 mRequestQueue.insert(mRequestQueue.end(),
5025 ++firstRequest,
5026 requests.end());
5027 // No need to wait any longer
//预览帧变量赋值
5029 mRepeatingLastFrameNumber = mFrameNumber + requests.size() - 1;
5030
5031 break;
5032 }
5033
5034 res = mRequestSignal.waitRelative(mRequestLock, kRequestTimeout);
5035
5036 if ((mRequestQueue.empty() && mRepeatingRequests.empty()) ||
5037 exitPending()) {
5038 Mutex::Autolock pl(mPauseLock);
5039 if (mPaused == false) {
5040 ALOGV("%s: RequestThread: Going idle", __FUNCTION__);
5041 mPaused = true;
5042 if (mNotifyPipelineDrain) {
5043 mInterface->signalPipelineDrain(mStreamIdsToBeDrained);
5044 mNotifyPipelineDrain = false;
5045 mStreamIdsToBeDrained.clear();
5046 }
5047 // Let the tracker know
5048 sp<StatusTracker> statusTracker = mStatusTracker.promote();
5049 if (statusTracker != 0) {
5050 statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
5051 }
5052 sp<Camera3Device> parent = mParent.promote();
5053 if (parent != nullptr) {
5054 parent->mRequestBufferSM.onRequestThreadPaused();
5055 }
5056 }
5057 // Stop waiting for now and let thread management happen
5058 return NULL;
5059 }
5060 }
5061
5062 if (nextRequest == NULL) {
5063 // Don't have a repeating request already in hand, so queue
5064 // must have an entry now.
5065 RequestList::iterator firstRequest =
5066 mRequestQueue.begin();
5067 nextRequest = *firstRequest;
5068 mRequestQueue.erase(firstRequest);
5069 if (mRequestQueue.empty() && !nextRequest->mRepeating) {
5070 sp<NotificationListener> listener = mListener.promote();
5071 if (listener != NULL) {
5072 listener->notifyRequestQueueEmpty();
5073 }
5074 }
5075 }
5076
5077 // In case we've been unpaused by setPaused clearing mDoPause, need to
5078 // update internal pause state (capture/setRepeatingRequest unpause
5079 // directly).
5080 Mutex::Autolock pl(mPauseLock);
5081 if (mPaused) {
5082 ALOGV("%s: RequestThread: Unpaused", __FUNCTION__);
5083 sp<StatusTracker> statusTracker = mStatusTracker.promote();
5084 if (statusTracker != 0) {
5085 statusTracker->markComponentActive(mStatusId);
5086 }
5087 }
5088 mPaused = false;
5089
5090 // Check if we've reconfigured since last time, and reset the preview
5091 // request if so. Can't use 'NULL request == repeat' across configure calls.
5092 if (mReconfigured) {
5093 mPrevRequest.clear();
5094 mReconfigured = false;
5095 }
5096
5097 if (nextRequest != NULL) {
5098 nextRequest->mResultExtras.frameNumber = mFrameNumber++;
5099 nextRequest->mResultExtras.afTriggerId = mCurrentAfTriggerId;
5100 nextRequest->mResultExtras.precaptureTriggerId = mCurrentPreCaptureTriggerId;
5101
5102 // Since RequestThread::clear() removes buffers from the input stream,
5103 // get the right buffer here before unlocking mRequestLock
5104 if (nextRequest->mInputStream != NULL) {
5105 res = nextRequest->mInputStream->getInputBuffer(&nextRequest->mInputBuffer);
5106 if (res != OK) {
5107 // Can't get input buffer from gralloc queue - this could be due to
5108 // disconnected queue or other producer misbehavior, so not a fatal
5109 // error
5110 ALOGE("%s: Can't get input buffer, skipping request:"
5111 " %s (%d)", __FUNCTION__, strerror(-res), res);
5112
5113 sp<NotificationListener> listener = mListener.promote();
5114 if (listener != NULL) {
5115 listener->notifyError(
5116 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
5117 nextRequest->mResultExtras);
5118 }
5119 return NULL;
5120 }
5121 }
5122 }
5123
5124 return nextRequest;
}
waitForNextRequestLocked准备好了NextRequest,回到waitForNextRequestBatch方法当中,下一帧的请求Request也就添加到成员变量mNextRequests当中了,然后再回到threadLoop方法当中,当时size等于1,接下来执行prepareHalRequests方法。
prepareHalRequests:
status_t Camera3Device::RequestThread::prepareHalRequests() {
4386 ATRACE_CALL();
4387
4388 bool batchedRequest = mNextRequests[0].captureRequest->mBatchSize > 1;
4389 for (size_t i = 0; i < mNextRequests.size(); i++) {
4390 auto& nextRequest = mNextRequests.editItemAt(i);
4391 sp<CaptureRequest> captureRequest = nextRequest.captureRequest;
4392 camera3_capture_request_t* halRequest = &nextRequest.halRequest;
4393 Vector<camera3_stream_buffer_t>* outputBuffers = &nextRequest.outputBuffers;
4394
4395 // Prepare a request to HAL
4396 halRequest->frame_number = captureRequest->mResultExtras.frameNumber;
4397
4398 // Insert any queued triggers (before metadata is locked)
4399 status_t res = insertTriggers(captureRequest);
4400 if (res < 0) {
4401 SET_ERR("RequestThread: Unable to insert triggers "
4402 "(capture request %d, HAL device: %s (%d)",
4403 halRequest->frame_number, strerror(-res), res);
4404 return INVALID_OPERATION;
4405 }
4406
4407 int triggerCount = res;
4408 bool triggersMixedIn = (triggerCount > 0 || mPrevTriggers > 0);
4409 mPrevTriggers = triggerCount;
4410
4411 bool rotateAndCropChanged = overrideAutoRotateAndCrop(captureRequest);
4412
4413 // If the request is the same as last, or we had triggers last time
4414 bool newRequest =
4415 (mPrevRequest != captureRequest || triggersMixedIn || rotateAndCropChanged) &&
4416 // Request settings are all the same within one batch, so only treat the first
4417 // request in a batch as new
4418 !(batchedRequest && i > 0);
4419 if (newRequest) {
4420 std::set<std::string> cameraIdsWithZoom;
4421 /**
4422 * HAL workaround:
4423 * Insert a dummy trigger ID if a trigger is set but no trigger ID is
4424 */
4425 res = addDummyTriggerIds(captureRequest);
4426 if (res != OK) {
4427 SET_ERR("RequestThread: Unable to insert dummy trigger IDs "
4428 "(capture request %d, HAL device: %s (%d)",
4429 halRequest->frame_number, strerror(-res), res);
4430 return INVALID_OPERATION;
4431 }
4432
4433 {
4434 // Correct metadata regions for distortion correction if enabled
4435 sp<Camera3Device> parent = mParent.promote();
4436 if (parent != nullptr) {
4437 List<PhysicalCameraSettings>::iterator it;
4438 for (it = captureRequest->mSettingsList.begin();
4439 it != captureRequest->mSettingsList.end(); it++) {
4440 if (parent->mDistortionMappers.find(it->cameraId) ==
4441 parent->mDistortionMappers.end()) {
4442 continue;
4443 }
4444
4445 if (!captureRequest->mDistortionCorrectionUpdated) {
4446 res = parent->mDistortionMappers[it->cameraId].correctCaptureRequest(
4447 &(it->metadata));
4448 if (res != OK) {
4449 SET_ERR("RequestThread: Unable to correct capture requests "
4450 "for lens distortion for request %d: %s (%d)",
4451 halRequest->frame_number, strerror(-res), res);
4452 return INVALID_OPERATION;
4453 }
4454 captureRequest->mDistortionCorrectionUpdated = true;
4455 }
4456 }
4457
4458 for (it = captureRequest->mSettingsList.begin();
4459 it != captureRequest->mSettingsList.end(); it++) {
4460 if (parent->mZoomRatioMappers.find(it->cameraId) ==
4461 parent->mZoomRatioMappers.end()) {
4462 continue;
4463 }
4464
4465 if (!captureRequest->mZoomRatioIs1x) {
4466 cameraIdsWithZoom.insert(it->cameraId);
4467 }
4468
4469 if (!captureRequest->mZoomRatioUpdated) {
4470 res = parent->mZoomRatioMappers[it->cameraId].updateCaptureRequest(
4471 &(it->metadata));
4472 if (res != OK) {
4473 SET_ERR("RequestThread: Unable to correct capture requests "
4474 "for zoom ratio for request %d: %s (%d)",
4475 halRequest->frame_number, strerror(-res), res);
4476 return INVALID_OPERATION;
4477 }
4478 captureRequest->mZoomRatioUpdated = true;
4479 }
4480 }
4481 if (captureRequest->mRotateAndCropAuto &&
4482 !captureRequest->mRotationAndCropUpdated) {
4483 for (it = captureRequest->mSettingsList.begin();
4484 it != captureRequest->mSettingsList.end(); it++) {
4485 auto mapper = parent->mRotateAndCropMappers.find(it->cameraId);
4486 if (mapper != parent->mRotateAndCropMappers.end()) {
4487 res = mapper->second.updateCaptureRequest(&(it->metadata));
4488 if (res != OK) {
4489 SET_ERR("RequestThread: Unable to correct capture requests "
4490 "for rotate-and-crop for request %d: %s (%d)",
4491 halRequest->frame_number, strerror(-res), res);
4492 return INVALID_OPERATION;
4493 }
4494 }
4495 }
4496 captureRequest->mRotationAndCropUpdated = true;
4497 }
4498 }
4499 }
4500
4501 /**
4502 * The request should be presorted so accesses in HAL
4503 * are O(logn). Sidenote, sorting a sorted metadata is nop.
4504 */
4505 captureRequest->mSettingsList.begin()->metadata.sort();
4506 halRequest->settings = captureRequest->mSettingsList.begin()->metadata.getAndLock();
4507 mPrevRequest = captureRequest;
4508 mPrevCameraIdsWithZoom = cameraIdsWithZoom;
4509 ALOGVV("%s: Request settings are NEW", __FUNCTION__);
4510
4511 IF_ALOGV() {
4512 camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
4513 find_camera_metadata_ro_entry(
4514 halRequest->settings,
4515 ANDROID_CONTROL_AF_TRIGGER,
4516 &e
4517 );
4518 if (e.count > 0) {
4519 ALOGV("%s: Request (frame num %d) had AF trigger 0x%x",
4520 __FUNCTION__,
4521 halRequest->frame_number,
4522 e.data.u8[0]);
4523 }
4524 }
4525 } else {
4526 // leave request.settings NULL to indicate 'reuse latest given'
4527 ALOGVV("%s: Request settings are REUSED",
4528 __FUNCTION__);
4529 }
4530
4531 if (captureRequest->mSettingsList.size() > 1) {
4532 halRequest->num_physcam_settings = captureRequest->mSettingsList.size() - 1;
4533 halRequest->physcam_id = new const char* [halRequest->num_physcam_settings];
4534 if (newRequest) {
4535 halRequest->physcam_settings =
4536 new const camera_metadata* [halRequest->num_physcam_settings];
4537 } else {
4538 halRequest->physcam_settings = nullptr;
4539 }
4540 auto it = ++captureRequest->mSettingsList.begin();
4541 size_t i = 0;
4542 for (; it != captureRequest->mSettingsList.end(); it++, i++) {
4543 halRequest->physcam_id[i] = it->cameraId.c_str();
4544 if (newRequest) {
4545 it->metadata.sort();
4546 halRequest->physcam_settings[i] = it->metadata.getAndLock();
4547 }
4548 }
4549 }
4550
4551 uint32_t totalNumBuffers = 0;
4552
4553 // Fill in buffers
4554 if (captureRequest->mInputStream != NULL) {
4555 halRequest->input_buffer = &captureRequest->mInputBuffer;
4556 totalNumBuffers += 1;
4557 } else {
4558 halRequest->input_buffer = NULL;
4559 }
4560
4561 outputBuffers->insertAt(camera3_stream_buffer_t(), 0,
4562 captureRequest->mOutputStreams.size());
4563 halRequest->output_buffers = outputBuffers->array();
4564 std::set<String8> requestedPhysicalCameras;
4565
4566 sp<Camera3Device> parent = mParent.promote();
4567 if (parent == NULL) {
4568 // Should not happen, and nowhere to send errors to, so just log it
4569 CLOGE("RequestThread: Parent is gone");
4570 return INVALID_OPERATION;
4571 }
4572 nsecs_t waitDuration = kBaseGetBufferWait + parent->getExpectedInFlightDuration();
4573
4574 SurfaceMap uniqueSurfaceIdMap;
4575 for (size_t j = 0; j < captureRequest->mOutputStreams.size(); j++) {
4576 sp<Camera3OutputStreamInterface> outputStream =
4577 captureRequest->mOutputStreams.editItemAt(j);
4578 int streamId = outputStream->getId();
4579
4580 // Prepare video buffers for high speed recording on the first video request.
4581 if (mPrepareVideoStream && outputStream->isVideoStream()) {
4582 // Only try to prepare video stream on the first video request.
4583 mPrepareVideoStream = false;
4584
4585 res = outputStream->startPrepare(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX,
4586 false /*blockRequest*/);
4587 while (res == NOT_ENOUGH_DATA) {
4588 res = outputStream->prepareNextBuffer();
4589 }
4590 if (res != OK) {
4591 ALOGW("%s: Preparing video buffers for high speed failed: %s (%d)",
4592 __FUNCTION__, strerror(-res), res);
4593 outputStream->cancelPrepare();
4594 }
4595 }
4596
4597 std::vector<size_t> uniqueSurfaceIds;
4598 res = outputStream->getUniqueSurfaceIds(
4599 captureRequest->mOutputSurfaces[streamId],
4600 &uniqueSurfaceIds);
4601 // INVALID_OPERATION is normal output for streams not supporting surfaceIds
4602 if (res != OK && res != INVALID_OPERATION) {
4603 ALOGE("%s: failed to query stream %d unique surface IDs",
4604 __FUNCTION__, streamId);
4605 return res;
4606 }
4607 if (res == OK) {
4608 uniqueSurfaceIdMap.insert({streamId, std::move(uniqueSurfaceIds)});
4609 }
4610
4611 if (mUseHalBufManager) {
4612 if (outputStream->isAbandoned()) {
4613 ALOGV("%s: stream %d is abandoned, skipping request", __FUNCTION__, streamId);
4614 return TIMED_OUT;
4615 }
4616 // HAL will request buffer through requestStreamBuffer API
4617 camera3_stream_buffer_t& buffer = outputBuffers->editItemAt(j);
4618 buffer.stream = outputStream->asHalStream();
4619 buffer.buffer = nullptr;
4620 buffer.status = CAMERA3_BUFFER_STATUS_OK;
4621 buffer.acquire_fence = -1;
4622 buffer.release_fence = -1;
4623 } else {
4624 res = outputStream->getBuffer(&outputBuffers->editItemAt(j),
4625 waitDuration,
4626 captureRequest->mOutputSurfaces[streamId]);
4627 if (res != OK) {
4628 // Can't get output buffer from gralloc queue - this could be due to
4629 // abandoned queue or other consumer misbehavior, so not a fatal
4630 // error
4631 ALOGV("RequestThread: Can't get output buffer, skipping request:"
4632 " %s (%d)", strerror(-res), res);
4633
4634 return TIMED_OUT;
4635 }
4636 }
4637
4638 {
4639 sp<Camera3Device> parent = mParent.promote();
4640 if (parent != nullptr) {
4641 const String8& streamCameraId = outputStream->getPhysicalCameraId();
4642 for (const auto& settings : captureRequest->mSettingsList) {
4643 if ((streamCameraId.isEmpty() &&
4644 parent->getId() == settings.cameraId.c_str()) ||
4645 streamCameraId == settings.cameraId.c_str()) {
4646 outputStream->fireBufferRequestForFrameNumber(
4647 captureRequest->mResultExtras.frameNumber,
4648 settings.metadata);
4649 }
4650 }
4651 }
4652 }
4653
4654 String8 physicalCameraId = outputStream->getPhysicalCameraId();
4655
4656 if (!physicalCameraId.isEmpty()) {
4657 // Physical stream isn't supported for input request.
4658 if (halRequest->input_buffer) {
4659 CLOGE("Physical stream is not supported for input request");
4660 return INVALID_OPERATION;
4661 }
4662 requestedPhysicalCameras.insert(physicalCameraId);
4663 }
4664 halRequest->num_output_buffers++;
4665 }
4666 totalNumBuffers += halRequest->num_output_buffers;
4667
4668 // Log request in the in-flight queue
4669 // If this request list is for constrained high speed recording (not
4670 // preview), and the current request is not the last one in the batch,
4671 // do not send callback to the app.
4672 bool hasCallback = true;
4673 if (batchedRequest && i != mNextRequests.size()-1) {
4674 hasCallback = false;
4675 }
4676 bool isStillCapture = false;
4677 bool isZslCapture = false;
4678 if (!mNextRequests[0].captureRequest->mSettingsList.begin()->metadata.isEmpty()) {
4679 camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
4680 find_camera_metadata_ro_entry(halRequest->settings, ANDROID_CONTROL_CAPTURE_INTENT, &e);
4681 if ((e.count > 0) && (e.data.u8[0] == ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE)) {
4682 isStillCapture = true;
4683 ATRACE_ASYNC_BEGIN("still capture", mNextRequests[i].halRequest.frame_number);
4684 }
4685
4686 find_camera_metadata_ro_entry(halRequest->settings, ANDROID_CONTROL_ENABLE_ZSL, &e);
4687 if ((e.count > 0) && (e.data.u8[0] == ANDROID_CONTROL_ENABLE_ZSL_TRUE)) {
4688 isZslCapture = true;
4689 }
4690 }
4691 res = parent->registerInFlight(halRequest->frame_number,
4692 totalNumBuffers, captureRequest->mResultExtras,
4693 /*hasInput*/halRequest->input_buffer != NULL,
4694 hasCallback,
4695 calculateMaxExpectedDuration(halRequest->settings),
4696 requestedPhysicalCameras, isStillCapture, isZslCapture,
4697 captureRequest->mRotateAndCropAuto, mPrevCameraIdsWithZoom,
4698 (mUseHalBufManager) ? uniqueSurfaceIdMap :
4699 SurfaceMap{});
4700 ALOGVV("%s: registered in flight requestId = %" PRId32 ", frameNumber = %" PRId64
4701 ", burstId = %" PRId32 ".",
4702 __FUNCTION__,
4703 captureRequest->mResultExtras.requestId, captureRequest->mResultExtras.frameNumber,
4704 captureRequest->mResultExtras.burstId);
4705 if (res != OK) {
4706 SET_ERR("RequestThread: Unable to register new in-flight request:"
4707 " %s (%d)", strerror(-res), res);
4708 return INVALID_OPERATION;
4709 }
4710 }
4711
4712 return OK;
}
prepareHalRequests主要就是通过for循环,对入参的每个Request进行处理,给成员变量halRequest的子变量进行赋值,一步一步的完成halRequest的构建。
输出Buffer就是成员变量outputBuffers,它的准备就是调用outputStream->getBuffer()实现的。
/frameworks/av/services/camera/libcameraservice/device3/Camera3Stream.cpp
status_t Camera3Stream::getBuffer(camera3_stream_buffer *buffer,
603 nsecs_t waitBufferTimeout,
604 const std::vector<size_t>& surface_ids) {
605 ATRACE_HFR_CALL();
606 Mutex::Autolock l(mLock);
607 status_t res = OK;
608
609 // This function should be only called when the stream is configured already.
610 if (mState != STATE_CONFIGURED) {
611 ALOGE("%s: Stream %d: Can't get buffers if stream is not in CONFIGURED state %d",
612 __FUNCTION__, mId, mState);
613 if (mState == STATE_ABANDONED) {
614 return DEAD_OBJECT;
615 } else {
616 return INVALID_OPERATION;
617 }
618 }
619
620 // Wait for new buffer returned back if we are running into the limit.
621 if (getHandoutOutputBufferCountLocked() == camera3_stream::max_buffers) {
622 ALOGV("%s: Already dequeued max output buffers (%d), wait for next returned one.",
623 __FUNCTION__, camera3_stream::max_buffers);
624 nsecs_t waitStart = systemTime(SYSTEM_TIME_MONOTONIC);
625 if (waitBufferTimeout < kWaitForBufferDuration) {
626 waitBufferTimeout = kWaitForBufferDuration;
627 }
628 res = mOutputBufferReturnedSignal.waitRelative(mLock, waitBufferTimeout);
629 nsecs_t waitEnd = systemTime(SYSTEM_TIME_MONOTONIC);
630 mBufferLimitLatency.add(waitStart, waitEnd);
631 if (res != OK) {
632 if (res == TIMED_OUT) {
633 ALOGE("%s: wait for output buffer return timed out after %lldms (max_buffers %d)",
634 __FUNCTION__, waitBufferTimeout / 1000000LL,
635 camera3_stream::max_buffers);
636 }
637 return res;
638 }
639 }
640
641 res = getBufferLocked(buffer, surface_ids);
642 if (res == OK) {
643 fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true);
644 if (buffer->buffer) {
645 Mutex::Autolock l(mOutstandingBuffersLock);
646 mOutstandingBuffers.push_back(*buffer->buffer);
647 }
648 }
649
650 return res;
}
/frameworks/av/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
status_t Camera3OutputStream::getBufferLocked(camera3_stream_buffer *buffer,
163 const std::vector<size_t>&) {
164 ATRACE_HFR_CALL();
165
166 ANativeWindowBuffer* anb;
167 int fenceFd = -1;
168
169 status_t res;
170 res = getBufferLockedCommon(&anb, &fenceFd);
171 if (res != OK) {
172 return res;
173 }
174
175 /**
176 * FenceFD now owned by HAL except in case of error,
177 * in which case we reassign it to acquire_fence
178 */
179 handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd,
180 /*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK, /*output*/true);
181
182 return OK;
}
status_t Camera3OutputStream::getBufferLockedCommon(ANativeWindowBuffer** anb, int* fenceFd) {
520 ATRACE_HFR_CALL();
521 status_t res;
522
523 if ((res = getBufferPreconditionCheckLocked()) != OK) {
524 return res;
525 }
526
527 bool gotBufferFromManager = false;
//目前,mUseBufferManager的值一直是false。此处不走
529 if (mUseBufferManager) {
530 sp<GraphicBuffer> gb;
531 res = mBufferManager->getBufferForStream(getId(), getStreamSetId(), &gb, fenceFd);
532 if (res == OK) {
533 // Attach this buffer to the bufferQueue: the buffer will be in dequeue state after a
534 // successful return.
535 *anb = gb.get();
536 res = mConsumer->attachBuffer(*anb);
537 if (shouldLogError(res, mState)) {
538 ALOGE("%s: Stream %d: Can't attach the output buffer to this surface: %s (%d)",
539 __FUNCTION__, mId, strerror(-res), res);
540 }
541 if (res != OK) {
542 checkRetAndSetAbandonedLocked(res);
543 return res;
544 }
545 gotBufferFromManager = true;
546 ALOGV("Stream %d: Attached new buffer", getId());
547 } else if (res == ALREADY_EXISTS) {
548 // Have sufficient free buffers already attached, can just
549 // dequeue from buffer queue
550 ALOGV("Stream %d: Reusing attached buffer", getId());
551 gotBufferFromManager = false;
552 } else if (res != OK) {
553 ALOGE("%s: Stream %d: Can't get next output buffer from buffer manager: %s (%d)",
554 __FUNCTION__, mId, strerror(-res), res);
555 return res;
556 }
557 }
//由于mUseBufferManager的值是false。此处gotBufferFromManager还是false,进入下面逻辑
558 if (!gotBufferFromManager) {
559 /**
560 * Release the lock briefly to avoid deadlock for below scenario:
561 * Thread 1: StreamingProcessor::startStream -> Camera3Stream::isConfiguring().
562 * This thread acquired StreamingProcessor lock and try to lock Camera3Stream lock.
563 * Thread 2: Camera3Stream::returnBuffer->StreamingProcessor::onFrameAvailable().
564 * This thread acquired Camera3Stream lock and bufferQueue lock, and try to lock
565 * StreamingProcessor lock.
566 * Thread 3: Camera3Stream::getBuffer(). This thread acquired Camera3Stream lock
567 * and try to lock bufferQueue lock.
568 * Then there is circular locking dependency.
569 */
570 sp<ANativeWindow> currentConsumer = mConsumer;
571 mLock.unlock();
572
573 nsecs_t dequeueStart = systemTime(SYSTEM_TIME_MONOTONIC);
//所有HAL层操作的Buffer就是这里分配的,是通过configureStream时配置的Surface中,使用Android原生的Buffer管理系统,也就是原生定义的buffer_handle_t取出来的,
//这些Buffer全部是由gralloc驱动创建的,是使用共享内存的实现的,所以各进程间要操作的话,不需要拷贝,操作完释放锁就可以了
574 res = currentConsumer->dequeueBuffer(currentConsumer.get(), anb, fenceFd);
575 nsecs_t dequeueEnd = systemTime(SYSTEM_TIME_MONOTONIC);
576 mDequeueBufferLatency.add(dequeueStart, dequeueEnd);
577
578 mLock.lock();
579
580 if (mUseBufferManager && res == TIMED_OUT) {
581 checkRemovedBuffersLocked();
582
583 sp<GraphicBuffer> gb;
584 res = mBufferManager->getBufferForStream(
585 getId(), getStreamSetId(), &gb, fenceFd, /*noFreeBuffer*/true);
586
587 if (res == OK) {
588 // Attach this buffer to the bufferQueue: the buffer will be in dequeue state after
589 // a successful return.
590 *anb = gb.get();
591 res = mConsumer->attachBuffer(*anb);
592 gotBufferFromManager = true;
593 ALOGV("Stream %d: Attached new buffer", getId());
594
595 if (res != OK) {
596 if (shouldLogError(res, mState)) {
597 ALOGE("%s: Stream %d: Can't attach the output buffer to this surface:"
598 " %s (%d)", __FUNCTION__, mId, strerror(-res), res);
599 }
600 checkRetAndSetAbandonedLocked(res);
601 return res;
602 }
603 } else {
604 ALOGE("%s: Stream %d: Can't get next output buffer from buffer manager:"
605 " %s (%d)", __FUNCTION__, mId, strerror(-res), res);
606 return res;
607 }
608 } else if (res != OK) {
609 if (shouldLogError(res, mState)) {
610 ALOGE("%s: Stream %d: Can't dequeue next output buffer: %s (%d)",
611 __FUNCTION__, mId, strerror(-res), res);
612 }
613 checkRetAndSetAbandonedLocked(res);
614 return res;
615 }
616 }
617
618 if (res == OK) {
619 checkRemovedBuffersLocked();
620 }
621
622 return res;
}
再往上回到threadLoop方法中,最后来看一下第三步sendRequestsBatch,将准备好的Request发往HAL进程去处理:
bool Camera3Device::RequestThread::sendRequestsBatch() {
4070 ATRACE_CALL();
4071 status_t res;
4072 size_t batchSize = mNextRequests.size();
4073 std::vector<camera3_capture_request_t*> requests(batchSize);
4074 uint32_t numRequestProcessed = 0;
4075 for (size_t i = 0; i < batchSize; i++) {
4076 requests[i] = &mNextRequests.editItemAt(i).halRequest;
4077 ATRACE_ASYNC_BEGIN("frame capture", mNextRequests[i].halRequest.frame_number);
4078 }
//处理请求
4080 res = mInterface->processBatchCaptureRequests(requests, &numRequestProcessed);
4081
4082 bool triggerRemoveFailed = false;
4083 NextRequest& triggerFailedRequest = mNextRequests.editItemAt(0);
4084 for (size_t i = 0; i < numRequestProcessed; i++) {
4085 NextRequest& nextRequest = mNextRequests.editItemAt(i);
//nextRequest.submitted被赋值为true
4086 nextRequest.submitted = true;
4087
4088 updateNextRequest(nextRequest);
4089
4090 if (!triggerRemoveFailed) {
4091 // Remove any previously queued triggers (after unlock)
4092 status_t removeTriggerRes = removeTriggers(mPrevRequest);
4093 if (removeTriggerRes != OK) {
4094 triggerRemoveFailed = true;
4095 triggerFailedRequest = nextRequest;
4096 }
4097 }
4098 }
4099
4100 if (triggerRemoveFailed) {
4101 SET_ERR("RequestThread: Unable to remove triggers "
4102 "(capture request %d, HAL device: %s (%d)",
4103 triggerFailedRequest.halRequest.frame_number, strerror(-res), res);
4104 cleanUpFailedRequests(/*sendRequestError*/ false);
4105 return false;
4106 }
4107
4108 if (res != OK) {
4109 // Should only get a failure here for malformed requests or device-level
4110 // errors, so consider all errors fatal. Bad metadata failures should
4111 // come through notify.
4112 SET_ERR("RequestThread: Unable to submit capture request %d to HAL device: %s (%d)",
4113 mNextRequests[numRequestProcessed].halRequest.frame_number,
4114 strerror(-res), res);
4115 cleanUpFailedRequests(/*sendRequestError*/ false);
4116 return false;
4117 }
4118 return true;
}
status_t Camera3Device::HalInterface::processBatchCaptureRequests(
3438 std::vector<camera3_capture_request_t*>& requests,/*out*/uint32_t* numRequestProcessed) {
3439 ATRACE_NAME("CameraHal::processBatchCaptureRequests");
3440 if (!valid()) return INVALID_OPERATION;
3441
3442 sp<device::V3_4::ICameraDeviceSession> hidlSession_3_4;
3443 auto castResult_3_4 = device::V3_4::ICameraDeviceSession::castFrom(mHidlSession);
3444 if (castResult_3_4.isOk()) {
3445 hidlSession_3_4 = castResult_3_4;
3446 }
3447
3448 hardware::hidl_vec<device::V3_2::CaptureRequest> captureRequests;
3449 hardware::hidl_vec<device::V3_4::CaptureRequest> captureRequests_3_4;
3450 size_t batchSize = requests.size();
3451 if (hidlSession_3_4 != nullptr) {
3452 captureRequests_3_4.resize(batchSize);
3453 } else {
3454 captureRequests.resize(batchSize);
3455 }
3456 std::vector<native_handle_t*> handlesCreated;
3457 std::vector<std::pair<int32_t, int32_t>> inflightBuffers;
3458
3459 status_t res = OK;
3460 for (size_t i = 0; i < batchSize; i++) {
3461 if (hidlSession_3_4 != nullptr) {
//wrapAsHidlRequest对每个Request进行包装
3462 res = wrapAsHidlRequest(requests[i], /*out*/&captureRequests_3_4[i].v3_2,
3463 /*out*/&handlesCreated, /*out*/&inflightBuffers);
3464 } else {
3465 res = wrapAsHidlRequest(requests[i], /*out*/&captureRequests[i],
3466 /*out*/&handlesCreated, /*out*/&inflightBuffers);
3467 }
3468 if (res != OK) {
3469 mBufferRecords.popInflightBuffers(inflightBuffers);
3470 cleanupNativeHandles(&handlesCreated);
3471 return res;
3472 }
3473 }
3474
3475 std::vector<device::V3_2::BufferCache> cachesToRemove;
3476 {
3477 std::lock_guard<std::mutex> lock(mFreedBuffersLock);
3478 for (auto& pair : mFreedBuffers) {
3479 // The stream might have been removed since onBufferFreed
3480 if (mBufferRecords.isStreamCached(pair.first)) {
3481 cachesToRemove.push_back({pair.first, pair.second});
3482 }
3483 }
3484 mFreedBuffers.clear();
3485 }
3486
3487 common::V1_0::Status status = common::V1_0::Status::INTERNAL_ERROR;
3488 *numRequestProcessed = 0;
3489
3490 // Write metadata to FMQ.
3491 for (size_t i = 0; i < batchSize; i++) {
3492 camera3_capture_request_t* request = requests[i];
3493 device::V3_2::CaptureRequest* captureRequest;
3494 if (hidlSession_3_4 != nullptr) {
3495 captureRequest = &captureRequests_3_4[i].v3_2;
3496 } else {
3497 captureRequest = &captureRequests[i];
3498 }
3499
3500 if (request->settings != nullptr) {
3501 size_t settingsSize = get_camera_metadata_size(request->settings);
3502 if (mRequestMetadataQueue != nullptr && mRequestMetadataQueue->write(
3503 reinterpret_cast<const uint8_t*>(request->settings), settingsSize)) {
3504 captureRequest->settings.resize(0);
3505 captureRequest->fmqSettingsSize = settingsSize;
3506 } else {
3507 if (mRequestMetadataQueue != nullptr) {
3508 ALOGW("%s: couldn't utilize fmq, fallback to hwbinder", __FUNCTION__);
3509 }
3510 captureRequest->settings.setToExternal(
3511 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(request->settings)),
3512 get_camera_metadata_size(request->settings));
3513 captureRequest->fmqSettingsSize = 0u;
3514 }
3515 } else {
3516 // A null request settings maps to a size-0 CameraMetadata
3517 captureRequest->settings.resize(0);
3518 captureRequest->fmqSettingsSize = 0u;
3519 }
3520
3521 if (hidlSession_3_4 != nullptr) {
3522 captureRequests_3_4[i].physicalCameraSettings.resize(request->num_physcam_settings);
3523 for (size_t j = 0; j < request->num_physcam_settings; j++) {
3524 if (request->physcam_settings != nullptr) {
3525 size_t settingsSize = get_camera_metadata_size(request->physcam_settings[j]);
3526 if (mRequestMetadataQueue != nullptr && mRequestMetadataQueue->write(
3527 reinterpret_cast<const uint8_t*>(request->physcam_settings[j]),
3528 settingsSize)) {
3529 captureRequests_3_4[i].physicalCameraSettings[j].settings.resize(0);
3530 captureRequests_3_4[i].physicalCameraSettings[j].fmqSettingsSize =
3531 settingsSize;
3532 } else {
3533 if (mRequestMetadataQueue != nullptr) {
3534 ALOGW("%s: couldn't utilize fmq, fallback to hwbinder", __FUNCTION__);
3535 }
3536 captureRequests_3_4[i].physicalCameraSettings[j].settings.setToExternal(
3537 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(
3538 request->physcam_settings[j])),
3539 get_camera_metadata_size(request->physcam_settings[j]));
3540 captureRequests_3_4[i].physicalCameraSettings[j].fmqSettingsSize = 0u;
3541 }
3542 } else {
3543 captureRequests_3_4[i].physicalCameraSettings[j].fmqSettingsSize = 0u;
3544 captureRequests_3_4[i].physicalCameraSettings[j].settings.resize(0);
3545 }
3546 captureRequests_3_4[i].physicalCameraSettings[j].physicalCameraId =
3547 request->physcam_id[j];
3548 }
3549 }
3550 }
3551
3552 hardware::details::return_status err;
3553 auto resultCallback =
3554 [&status, &numRequestProcessed] (auto s, uint32_t n) {
3555 status = s;
3556 *numRequestProcessed = n;
3557 };
//把Request发到HAL进程当中
3558 if (hidlSession_3_4 != nullptr) {
3559 err = hidlSession_3_4->processCaptureRequest_3_4(captureRequests_3_4, cachesToRemove,
3560 resultCallback);
3561 } else {
3562 err = mHidlSession->processCaptureRequest(captureRequests, cachesToRemove,
3563 resultCallback);
3564 }
3565 if (!err.isOk()) {
3566 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3567 status = common::V1_0::Status::CAMERA_DISCONNECTED;
3568 }
3569
3570 if (status == common::V1_0::Status::OK && *numRequestProcessed != batchSize) {
3571 ALOGE("%s: processCaptureRequest returns OK but processed %d/%zu requests",
3572 __FUNCTION__, *numRequestProcessed, batchSize);
3573 status = common::V1_0::Status::INTERNAL_ERROR;
3574 }
3575
3576 res = CameraProviderManager::mapToStatusT(status);
3577 if (res == OK) {
3578 if (mHidlSession->isRemote()) {
3579 // Only close acquire fence FDs when the HIDL transaction succeeds (so the FDs have been
3580 // sent to camera HAL processes)
3581 cleanupNativeHandles(&handlesCreated, /*closeFd*/true);
3582 } else {
3583 // In passthrough mode the FDs are now owned by HAL
3584 cleanupNativeHandles(&handlesCreated);
3585 }
3586 } else {
3587 mBufferRecords.popInflightBuffers(inflightBuffers);
3588 cleanupNativeHandles(&handlesCreated);
3589 }
3590 return res;
}
status_t Camera3Device::HalInterface::wrapAsHidlRequest(camera3_capture_request_t* request,
3336 /*out*/device::V3_2::CaptureRequest* captureRequest,
3337 /*out*/std::vector<native_handle_t*>* handlesCreated,
3338 /*out*/std::vector<std::pair<int32_t, int32_t>>* inflightBuffers) {
3339 ATRACE_CALL();
3340 if (captureRequest == nullptr || handlesCreated == nullptr || inflightBuffers == nullptr) {
3341 ALOGE("%s: captureRequest (%p), handlesCreated (%p), and inflightBuffers(%p) "
3342 "must not be null", __FUNCTION__, captureRequest, handlesCreated, inflightBuffers);
3343 return BAD_VALUE;
3344 }
3345
3346 captureRequest->frameNumber = request->frame_number;
3347
3348 captureRequest->fmqSettingsSize = 0;
3349
3350 {
3351 if (request->input_buffer != nullptr) {
3352 int32_t streamId = Camera3Stream::cast(request->input_buffer->stream)->getId();
3353 buffer_handle_t buf = *(request->input_buffer->buffer);
3354 auto pair = getBufferId(buf, streamId);
3355 bool isNewBuffer = pair.first;
3356 uint64_t bufferId = pair.second;
3357 captureRequest->inputBuffer.streamId = streamId;
3358 captureRequest->inputBuffer.bufferId = bufferId;
3359 captureRequest->inputBuffer.buffer = (isNewBuffer) ? buf : nullptr;
3360 captureRequest->inputBuffer.status = BufferStatus::OK;
3361 native_handle_t *acquireFence = nullptr;
3362 if (request->input_buffer->acquire_fence != -1) {
3363 acquireFence = native_handle_create(1,0);
3364 acquireFence->data[0] = request->input_buffer->acquire_fence;
3365 handlesCreated->push_back(acquireFence);
3366 }
3367 captureRequest->inputBuffer.acquireFence = acquireFence;
3368 captureRequest->inputBuffer.releaseFence = nullptr;
3369
3370 mBufferRecords.pushInflightBuffer(captureRequest->frameNumber, streamId,
3371 request->input_buffer->buffer);
3372 inflightBuffers->push_back(std::make_pair(captureRequest->frameNumber, streamId));
3373 } else {
3374 captureRequest->inputBuffer.streamId = -1;
3375 captureRequest->inputBuffer.bufferId = BUFFER_ID_NO_BUFFER;
3376 }
3377
3378 captureRequest->outputBuffers.resize(request->num_output_buffers);
3379 for (size_t i = 0; i < request->num_output_buffers; i++) {
3380 const camera3_stream_buffer_t *src = request->output_buffers + i;
3381 StreamBuffer &dst = captureRequest->outputBuffers[i];
3382 int32_t streamId = Camera3Stream::cast(src->stream)->getId();
3383 if (src->buffer != nullptr) {
3384 buffer_handle_t buf = *(src->buffer);
3385 auto pair = getBufferId(buf, streamId);
3386 bool isNewBuffer = pair.first;
3387 dst.bufferId = pair.second;
3388 dst.buffer = isNewBuffer ? buf : nullptr;
3389 native_handle_t *acquireFence = nullptr;
3390 if (src->acquire_fence != -1) {
3391 acquireFence = native_handle_create(1,0);
3392 acquireFence->data[0] = src->acquire_fence;
3393 handlesCreated->push_back(acquireFence);
3394 }
3395 dst.acquireFence = acquireFence;
3396 } else if (mUseHalBufManager) {
3397 // HAL buffer management path
3398 dst.bufferId = BUFFER_ID_NO_BUFFER;
3399 dst.buffer = nullptr;
3400 dst.acquireFence = nullptr;
3401 } else {
3402 ALOGE("%s: cannot send a null buffer in capture request!", __FUNCTION__);
3403 return BAD_VALUE;
3404 }
3405 dst.streamId = streamId;
3406 dst.status = BufferStatus::OK;
3407 dst.releaseFence = nullptr;
3408
3409 // Output buffers are empty when using HAL buffer manager
3410 if (!mUseHalBufManager) {
3411 mBufferRecords.pushInflightBuffer(
3412 captureRequest->frameNumber, streamId, src->buffer);
3413 inflightBuffers->push_back(std::make_pair(captureRequest->frameNumber, streamId));
3414 }
3415 }
3416 }
3417 return OK;
}
可以看到,captureRequest->frameNumber = request->frame_number帧号的赋值,非常重要!!
下面就是对buffer处理了,在output buffer中,通过const camera3_stream_buffer_t *src = request->output_buffers + i 将上面我们已经分析过的Surface中取出的buffer拿出来,然后调用 dst.buffer = isNewBuffer ? buf : nullptr 将它操作赋值给dst,申请的几个buffer一直是复用的,isNewBuffer肯定是true,要不然输出buffer就为空了,而复用的就是分配了几个buffer,然后这几个buffer一直不断的轮转,比如1、2、3、4、5、6,然后又1、2、3、4、5、6一直往复循环的,最后调用pushInflightBufferLocked以帧号(captureRequest->frameNumber)、streamId、src->buffer、src->acquire_fence为参数将buffer保存在成员变量mInflightBufferMap中,后续HAL层对buffer填充完毕后,这里就可以直接从mInflightBufferMap当中取出来了。
再往上回到processBatchCaptureRequests方法中,所有的Request的参数都赋值完成了,最后调用mHidlSession->processCaptureRequest把Request发到HAL进程当中,这是通过HIDL来实现的,其实最根本的还是Binder框架!!第三个参数是lambda表达式,在HAL那边直接就是个hidl_cb的回调接口。mHidlSession是在HAL打开的Session对象,vendor HAL都会有自己不同的实现。
再往上再回到threadLoop方法当中,一帧请求处理完成,最后调用mNextRequests.clear()清空数据,成功返回true,继续下一次循环。
到这里就明白Camera预览的RequestThread到底是怎么一回事了。当我们收到APP的预览请求时,往mRepeatingRequests队列中添加了一个元素,后续的预览都是在对这一个元素不断的取出来处理的过程,或者有拍照请求时,就取拍照的元素,这样在threadLoop无限循环就构成了不断的预览。