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 "ACameraDevice.h" 20#include "ACameraMetadata.h" 21#include "ACaptureRequest.h" 22#include "ACameraCaptureSession.h" 23 24namespace android { 25namespace acam { 26 27template<class T> 28camera_status_t 29CameraDevice::captureLocked( 30 sp<ACameraCaptureSession> session, 31 /*optional*/T* cbs, 32 int numRequests, ACaptureRequest** requests, 33 /*optional*/int* captureSequenceId) { 34 return submitRequestsLocked( 35 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/false); 36} 37 38template<class T> 39camera_status_t 40CameraDevice::setRepeatingRequestsLocked( 41 sp<ACameraCaptureSession> session, 42 /*optional*/T* cbs, 43 int numRequests, ACaptureRequest** requests, 44 /*optional*/int* captureSequenceId) { 45 return submitRequestsLocked( 46 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/true); 47} 48 49template<class T> 50camera_status_t CameraDevice::submitRequestsLocked( 51 sp<ACameraCaptureSession> session, 52 /*optional*/T* cbs, 53 int numRequests, ACaptureRequest** requests, 54 /*optional*/int* captureSequenceId, 55 bool isRepeating) { 56 camera_status_t ret = checkCameraClosedOrErrorLocked(); 57 if (ret != ACAMERA_OK) { 58 ALOGE("Camera %s submit capture request failed! ret %d", getId(), ret); 59 return ret; 60 } 61 62 // Form two vectors of capture request, one for internal tracking 63 std::vector<hardware::camera2::CaptureRequest> requestList; 64 Vector<sp<CaptureRequest> > requestsV; 65 requestsV.setCapacity(numRequests); 66 for (int i = 0; i < numRequests; i++) { 67 sp<CaptureRequest> req; 68 ret = allocateCaptureRequest(requests[i], req); 69 if (ret != ACAMERA_OK) { 70 ALOGE("Convert capture request to internal format failure! ret %d", ret); 71 return ret; 72 } 73 if (req->mSurfaceList.empty()) { 74 ALOGE("Capture request without output target cannot be submitted!"); 75 return ACAMERA_ERROR_INVALID_PARAMETER; 76 } 77 requestList.push_back(*(req.get())); 78 requestsV.push_back(req); 79 } 80 81 if (isRepeating) { 82 ret = stopRepeatingLocked(); 83 if (ret != ACAMERA_OK) { 84 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret); 85 return ret; 86 } 87 } 88 89 binder::Status remoteRet; 90 hardware::camera2::utils::SubmitInfo info; 91 remoteRet = mRemote->submitRequestList(requestList, isRepeating, &info); 92 int sequenceId = info.mRequestId; 93 int64_t lastFrameNumber = info.mLastFrameNumber; 94 if (sequenceId < 0) { 95 ALOGE("Camera %s submit request remote failure: ret %d", getId(), sequenceId); 96 return ACAMERA_ERROR_UNKNOWN; 97 } 98 99 CallbackHolder cbHolder(session, requestsV, isRepeating, cbs); 100 mSequenceCallbackMap.insert(std::make_pair(sequenceId, cbHolder)); 101 102 if (isRepeating) { 103 // stopRepeating above should have cleanup repeating sequence id 104 if (mRepeatingSequenceId != REQUEST_ID_NONE) { 105 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE); 106 return ACAMERA_ERROR_CAMERA_DEVICE; 107 } 108 mRepeatingSequenceId = sequenceId; 109 } else { 110 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber)); 111 } 112 113 if (mIdle) { 114 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler); 115 msg->setPointer(kContextKey, session->mUserSessionCallback.context); 116 msg->setObject(kSessionSpKey, session); 117 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive); 118 postSessionMsgAndCleanup(msg); 119 } 120 mIdle = false; 121 mBusySession = session; 122 123 if (captureSequenceId) { 124 *captureSequenceId = sequenceId; 125 } 126 return ACAMERA_OK; 127} 128 129template<class T> 130camera_status_t CameraDevice::startStreamingLocked(ACameraCaptureSession* session, 131 /*optional*/T* callbacks, int numOutputWindows, 132 ANativeWindow** windows, /*optional*/int* captureSequenceId) { 133 camera_status_t ret = checkCameraClosedOrErrorLocked(); 134 if (ret != ACAMERA_OK) { 135 ALOGE("%s: camera is in closed or error state %d", __FUNCTION__, ret); 136 return ret; 137 } 138 CameraMetadata rawPreviewRequest; 139 binder::Status remoteRet = mRemote->createDefaultRequest(TEMPLATE_PREVIEW, &rawPreviewRequest); 140 if (!remoteRet.isOk()) { 141 ALOGE("%s: Create capture request failed: %s", __FUNCTION__, remoteRet.toString8().c_str()); 142 return ACAMERA_ERROR_UNKNOWN; 143 } 144 // ToDo: Check if the memory allocation can be freed automatically using either default_delete 145 // or ScopedAResource. 146 mPreviewRequest = new ACaptureRequest(); 147 mPreviewRequest->settings = new ACameraMetadata(rawPreviewRequest.release(), 148 ACameraMetadata::ACM_REQUEST); 149 mPreviewRequest->targets = new ACameraOutputTargets(); 150 for (int i = 0; i < numOutputWindows ; i++) { 151 ACameraOutputTarget* outputTarget = nullptr; 152 ret = ACameraOutputTarget_create(windows[i], &outputTarget); 153 if (ret != ACAMERA_OK) { 154 ALOGE("%s: error while ACameraOutputTarget_create %d", __FUNCTION__, ret); 155 return ret; 156 } 157 ret = ACaptureRequest_addTarget(mPreviewRequest, outputTarget); 158 if (ret != ACAMERA_OK) { 159 ALOGE("%s: error while ACaptureRequest_addTarget %d", __FUNCTION__, ret); 160 return ret; 161 } 162 mPreviewRequestOutputs.push_back(outputTarget); 163 } 164 165 sp<CaptureRequest> req; 166 ret = allocateCaptureRequest(mPreviewRequest, req); 167 if (ret != ACAMERA_OK) { 168 ALOGE("Convert capture request to internal format failure! ret %d", ret); 169 return ret; 170 } 171 if (req->mSurfaceList.empty()) { 172 ALOGE("Capture request without output target cannot be submitted!"); 173 return ACAMERA_ERROR_INVALID_PARAMETER; 174 } 175 176 // In shared session mode, if there are other active clients streaming then 177 // stoprepeating does not actually send request to HAL to cancel the request. 178 // Cameraservice will use this call to remove this client surfaces provided in its 179 // previous streaming request. If this is the only client for the shared camera device 180 // then camerservice will ask HAL to cancel the previous repeating request. 181 ret = stopRepeatingLocked(); 182 if (ret != ACAMERA_OK) { 183 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret); 184 return ret; 185 } 186 187 hardware::camera2::utils::SubmitInfo info; 188 std::vector<int> streamIds(req->mStreamIdxList.begin(), req->mStreamIdxList.end()); 189 std::vector<int> surfaceIds(req->mSurfaceIdxList.begin(), req->mSurfaceIdxList.end()); 190 remoteRet = mRemote->startStreaming(streamIds, surfaceIds, &info); 191 int sequenceId = info.mRequestId; 192 int64_t lastFrameNumber = info.mLastFrameNumber; 193 if (sequenceId < 0) { 194 ALOGE("Camera %s start streaming remote failure: ret %d", getId(), sequenceId); 195 return ACAMERA_ERROR_UNKNOWN; 196 } 197 198 Vector<sp<CaptureRequest> > requestsV; 199 requestsV.push_back(req); 200 CallbackHolder cbHolder(session, requestsV, true, callbacks); 201 mSequenceCallbackMap.insert(std::make_pair(sequenceId, cbHolder)); 202 203 // stopRepeating above should have cleanup repeating sequence id 204 if (mRepeatingSequenceId != REQUEST_ID_NONE) { 205 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE); 206 return ACAMERA_ERROR_CAMERA_DEVICE; 207 } 208 mRepeatingSequenceId = sequenceId; 209 210 if (mIdle) { 211 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler); 212 msg->setPointer(kContextKey, session->mUserSessionCallback.context); 213 msg->setObject(kSessionSpKey, session); 214 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive); 215 postSessionMsgAndCleanup(msg); 216 } 217 mIdle = false; 218 mBusySession = session; 219 220 if (captureSequenceId) { 221 *captureSequenceId = sequenceId; 222 } 223 return ACAMERA_OK; 224} 225 226} // namespace acam 227} // namespace android 228