Android Camera preview分析

大家使用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       
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值