1/* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <vector> 18#include <inttypes.h> 19#include <android/frameworks/cameraservice/service/2.0/ICameraService.h> 20#include <android/frameworks/cameraservice/device/2.0/types.h> 21#include <CameraMetadata.h> 22 23#include "ndk_vendor/impl/ACameraDevice.h" 24#include "ACameraCaptureSession.h" 25#include "ACameraMetadata.h" 26#include "ACaptureRequest.h" 27#include "utils.h" 28 29using namespace android; 30 31namespace android { 32namespace acam { 33 34template<class T> 35camera_status_t 36CameraDevice::captureLocked( 37 sp<ACameraCaptureSession> session, 38 /*optional*/T* cbs, 39 int numRequests, ACaptureRequest** requests, 40 /*optional*/int* captureSequenceId) { 41 return submitRequestsLocked( 42 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/false); 43} 44 45template<class T> 46camera_status_t 47CameraDevice::setRepeatingRequestsLocked( 48 sp<ACameraCaptureSession> session, 49 /*optional*/T* cbs, 50 int numRequests, ACaptureRequest** requests, 51 /*optional*/int* captureSequenceId) { 52 return submitRequestsLocked( 53 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/true); 54} 55 56template<class T> 57camera_status_t CameraDevice::submitRequestsLocked( 58 sp<ACameraCaptureSession> session, 59 /*optional*/T* cbs, 60 int numRequests, ACaptureRequest** requests, 61 /*out*/int* captureSequenceId, 62 bool isRepeating) 63{ 64 camera_status_t ret = checkCameraClosedOrErrorLocked(); 65 if (ret != ACAMERA_OK) { 66 ALOGE("Camera %s submit capture request failed! ret %d", getId(), ret); 67 return ret; 68 } 69 70 // Form two vectors of capture request, one for internal tracking 71 std::vector<frameworks::cameraservice::device::V2_0::CaptureRequest> requestList; 72 Vector<sp<CaptureRequest>> requestsV; 73 requestsV.setCapacity(numRequests); 74 for (int i = 0; i < numRequests; i++) { 75 sp<CaptureRequest> req; 76 ret = allocateCaptureRequestLocked(requests[i], req); 77 // We need to call this method since after submitRequestList is called, 78 // the request metadata queue might have removed the capture request 79 // metadata. Therefore we simply add the metadata to its wrapper class, 80 // so that it can be retrieved later. 81 addRequestSettingsMetadata(requests[i], req); 82 if (ret != ACAMERA_OK) { 83 ALOGE("Convert capture request to internal format failure! ret %d", ret); 84 return ret; 85 } 86 if (req->mCaptureRequest.streamAndWindowIds.size() == 0) { 87 ALOGE("Capture request without output target cannot be submitted!"); 88 return ACAMERA_ERROR_INVALID_PARAMETER; 89 } 90 requestList.push_back(utils::convertToHidl(req.get())); 91 requestsV.push_back(req); 92 } 93 if (isRepeating) { 94 ret = stopRepeatingLocked(); 95 if (ret != ACAMERA_OK) { 96 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret); 97 return ret; 98 } 99 } 100 101 SubmitInfo info; 102 Status status; 103 auto remoteRet = mRemote->submitRequestList(requestList, isRepeating, 104 [&status, &info](auto s, auto &submitInfo) { 105 status = s; 106 info = submitInfo; 107 }); 108 if (!remoteRet.isOk()) { 109 ALOGE("%s: Transaction error for submitRequestList call: %s", __FUNCTION__, 110 remoteRet.description().c_str()); 111 } 112 if (status != Status::NO_ERROR) { 113 return utils::convertFromHidl(status); 114 } 115 int32_t sequenceId = info.requestId; 116 int64_t lastFrameNumber = info.lastFrameNumber; 117 if (sequenceId < 0) { 118 ALOGE("Camera %s submit request remote failure: ret %d", getId(), sequenceId); 119 return ACAMERA_ERROR_UNKNOWN; 120 } 121 122 CallbackHolder cbHolder(session, requestsV, isRepeating, cbs); 123 mSequenceCallbackMap.insert(std::make_pair(sequenceId, cbHolder)); 124 if (isRepeating) { 125 // stopRepeating above should have cleanup repeating sequence id 126 if (mRepeatingSequenceId != REQUEST_ID_NONE) { 127 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE); 128 return ACAMERA_ERROR_CAMERA_DEVICE; 129 } 130 mRepeatingSequenceId = sequenceId; 131 } else { 132 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber)); 133 } 134 135 if (mIdle) { 136 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler); 137 msg->setPointer(kContextKey, session->mUserSessionCallback.context); 138 msg->setObject(kSessionSpKey, session); 139 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive); 140 postSessionMsgAndCleanup(msg); 141 } 142 mIdle = false; 143 mBusySession = session; 144 145 if (captureSequenceId) { 146 *captureSequenceId = sequenceId; 147 } 148 return ACAMERA_OK; 149} 150 151} // namespace acam 152} // namespace android 153