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 #define LOG_TAG "CamDevSession (at) 3.5-impl" 18 #define ATRACE_TAG ATRACE_TAG_CAMERA 19 #include <android/log.h> 20 21 #include <vector> 22 #include <utils/Trace.h> 23 #include "CameraDeviceSession.h" 24 25 namespace android { 26 namespace hardware { 27 namespace camera { 28 namespace device { 29 namespace V3_5 { 30 namespace implementation { 31 32 CameraDeviceSession::CameraDeviceSession( 33 camera3_device_t* device, 34 const camera_metadata_t* deviceInfo, 35 const sp<V3_2::ICameraDeviceCallback>& callback) : 36 V3_4::implementation::CameraDeviceSession(device, deviceInfo, callback) { 37 38 mCallback_3_5 = nullptr; 39 40 auto castResult = ICameraDeviceCallback::castFrom(callback); 41 if (castResult.isOk()) { 42 sp<ICameraDeviceCallback> callback3_5 = castResult; 43 if (callback3_5 != nullptr) { 44 mCallback_3_5 = callback3_5; 45 } 46 } 47 48 if (mCallback_3_5 != nullptr) { 49 camera_metadata_entry bufMgrVersion = mDeviceInfo.find( 50 ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION); 51 if (bufMgrVersion.count > 0) { 52 mSupportBufMgr = (bufMgrVersion.data.u8[0] == 53 ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5); 54 if (mSupportBufMgr) { 55 request_stream_buffers = sRequestStreamBuffers; 56 return_stream_buffers = sReturnStreamBuffers; 57 } 58 } 59 } 60 } 61 62 CameraDeviceSession::~CameraDeviceSession() { 63 } 64 65 Return<void> CameraDeviceSession::configureStreams_3_5( 66 const StreamConfiguration& requestedConfiguration, 67 ICameraDeviceSession::configureStreams_3_5_cb _hidl_cb) { 68 configureStreams_3_4_Impl(requestedConfiguration.v3_4, _hidl_cb, 69 requestedConfiguration.streamConfigCounter, false /*useOverriddenFields*/); 70 return Void(); 71 } 72 73 Return<void> CameraDeviceSession::signalStreamFlush( 74 const hidl_vec<int32_t>& streamIds, uint32_t streamConfigCounter) { 75 if (mDevice->ops->signal_stream_flush == nullptr) { 76 return Void(); 77 } 78 79 uint32_t currentCounter = 0; 80 { 81 Mutex::Autolock _l(mStreamConfigCounterLock); 82 currentCounter = mStreamConfigCounter; 83 } 84 85 if (streamConfigCounter < currentCounter) { 86 ALOGV("%s: streamConfigCounter %d is stale (current %d), skipping signal_stream_flush call", 87 __FUNCTION__, streamConfigCounter, mStreamConfigCounter); 88 return Void(); 89 } 90 91 std::vector<camera3_stream_t*> streams(streamIds.size()); 92 { 93 Mutex::Autolock _l(mInflightLock); 94 for (size_t i = 0; i < streamIds.size(); i++) { 95 int32_t id = streamIds[i]; 96 if (mStreamMap.count(id) == 0) { 97 ALOGE("%s: unknown streamId %d", __FUNCTION__, id); 98 return Void(); 99 } 100 streams[i] = &mStreamMap[id]; 101 } 102 } 103 104 mDevice->ops->signal_stream_flush(mDevice, streams.size(), streams.data()); 105 return Void(); 106 } 107 108 Status CameraDeviceSession::importRequest( 109 const CaptureRequest& request, 110 hidl_vec<buffer_handle_t*>& allBufPtrs, 111 hidl_vec<int>& allFences) { 112 if (mSupportBufMgr) { 113 return importRequestImpl(request, allBufPtrs, allFences, /*allowEmptyBuf*/ true); 114 } 115 return importRequestImpl(request, allBufPtrs, allFences, /*allowEmptyBuf*/ false); 116 } 117 118 void CameraDeviceSession::pushBufferId( 119 const buffer_handle_t& buf, uint64_t bufferId, int streamId) { 120 std::lock_guard<std::mutex> lock(mBufferIdMapLock); 121 122 // emplace will return existing entry if there is one. 123 auto pair = mBufferIdMaps.emplace(streamId, BufferIdMap{}); 124 BufferIdMap& bIdMap = pair.first->second; 125 bIdMap[buf] = bufferId; 126 } 127 128 uint64_t CameraDeviceSession::popBufferId( 129 const buffer_handle_t& buf, int streamId) { 130 std::lock_guard<std::mutex> lock(mBufferIdMapLock); 131 132 auto streamIt = mBufferIdMaps.find(streamId); 133 if (streamIt == mBufferIdMaps.end()) { 134 return BUFFER_ID_NO_BUFFER; 135 } 136 BufferIdMap& bIdMap = streamIt->second; 137 auto it = bIdMap.find(buf); 138 if (it == bIdMap.end()) { 139 return BUFFER_ID_NO_BUFFER; 140 } 141 uint64_t bufId = it->second; 142 bIdMap.erase(it); 143 if (bIdMap.empty()) { 144 mBufferIdMaps.erase(streamIt); 145 } 146 return bufId; 147 } 148 149 uint64_t CameraDeviceSession::getCapResultBufferId(const buffer_handle_t& buf, int streamId) { 150 if (mSupportBufMgr) { 151 return popBufferId(buf, streamId); 152 } 153 return BUFFER_ID_NO_BUFFER; 154 } 155 156 Camera3Stream* CameraDeviceSession::getStreamPointer(int32_t streamId) { 157 Mutex::Autolock _l(mInflightLock); 158 if (mStreamMap.count(streamId) == 0) { 159 ALOGE("%s: unknown streamId %d", __FUNCTION__, streamId); 160 return nullptr; 161 } 162 return &mStreamMap[streamId]; 163 } 164 165 void CameraDeviceSession::cleanupInflightBufferFences( 166 std::vector<int>& fences, std::vector<std::pair<buffer_handle_t, int>>& bufs) { 167 hidl_vec<int> hFences = fences; 168 cleanupInflightFences(hFences, fences.size()); 169 for (auto& p : bufs) { 170 popBufferId(p.first, p.second); 171 } 172 } 173 174 camera3_buffer_request_status_t CameraDeviceSession::requestStreamBuffers( 175 uint32_t num_buffer_reqs, 176 const camera3_buffer_request_t *buffer_reqs, 177 /*out*/uint32_t *num_returned_buf_reqs, 178 /*out*/camera3_stream_buffer_ret_t *returned_buf_reqs) { 179 ATRACE_CALL(); 180 *num_returned_buf_reqs = 0; 181 hidl_vec<BufferRequest> hBufReqs(num_buffer_reqs); 182 for (size_t i = 0; i < num_buffer_reqs; i++) { 183 hBufReqs[i].streamId = 184 static_cast<Camera3Stream*>(buffer_reqs[i].stream)->mId; 185 hBufReqs[i].numBuffersRequested = buffer_reqs[i].num_buffers_requested; 186 } 187 188 ATRACE_BEGIN("HIDL requestStreamBuffers"); 189 BufferRequestStatus status; 190 hidl_vec<StreamBufferRet> bufRets; 191 auto err = mCallback_3_5->requestStreamBuffers(hBufReqs, 192 [&status, &bufRets] 193 (BufferRequestStatus s, const hidl_vec<StreamBufferRet>& rets) { 194 status = s; 195 bufRets = std::move(rets); 196 }); 197 if (!err.isOk()) { 198 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str()); 199 return CAMERA3_BUF_REQ_FAILED_UNKNOWN; 200 } 201 ATRACE_END(); 202 203 switch (status) { 204 case BufferRequestStatus::FAILED_CONFIGURING: 205 return CAMERA3_BUF_REQ_FAILED_CONFIGURING; 206 case BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS: 207 return CAMERA3_BUF_REQ_FAILED_ILLEGAL_ARGUMENTS; 208 default: 209 break; // Other status Handled by following code 210 } 211 212 if (status != BufferRequestStatus::OK && status != BufferRequestStatus::FAILED_PARTIAL && 213 status != BufferRequestStatus::FAILED_UNKNOWN) { 214 ALOGE("%s: unknown buffer request error code %d", __FUNCTION__, status); 215 return CAMERA3_BUF_REQ_FAILED_UNKNOWN; 216 } 217 218 // Only OK, FAILED_PARTIAL and FAILED_UNKNOWN reaches here 219 if (bufRets.size() != num_buffer_reqs) { 220 ALOGE("%s: expect %d buffer requests returned, only got %zu", 221 __FUNCTION__, num_buffer_reqs, bufRets.size()); 222 return CAMERA3_BUF_REQ_FAILED_UNKNOWN; 223 } 224 225 *num_returned_buf_reqs = num_buffer_reqs; 226 for (size_t i = 0; i < num_buffer_reqs; i++) { 227 // maybe we can query all streams in one call to avoid frequent locking device here? 228 Camera3Stream* stream = getStreamPointer(bufRets[i].streamId); 229 if (stream == nullptr) { 230 ALOGE("%s: unknown streamId %d", __FUNCTION__, bufRets[i].streamId); 231 return CAMERA3_BUF_REQ_FAILED_UNKNOWN; 232 } 233 returned_buf_reqs[i].stream = stream; 234 } 235 236 // Handle failed streams 237 for (size_t i = 0; i < num_buffer_reqs; i++) { 238 if (bufRets[i].val.getDiscriminator() == StreamBuffersVal::hidl_discriminator::error) { 239 returned_buf_reqs[i].num_output_buffers = 0; 240 switch (bufRets[i].val.error()) { 241 case StreamBufferRequestError::NO_BUFFER_AVAILABLE: 242 returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_NO_BUFFER_AVAILABLE; 243 break; 244 case StreamBufferRequestError::MAX_BUFFER_EXCEEDED: 245 returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_MAX_BUFFER_EXCEEDED; 246 break; 247 case StreamBufferRequestError::STREAM_DISCONNECTED: 248 returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_STREAM_DISCONNECTED; 249 break; 250 case StreamBufferRequestError::UNKNOWN_ERROR: 251 returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_UNKNOWN_ERROR; 252 break; 253 default: 254 ALOGE("%s: Unknown StreamBufferRequestError %d", 255 __FUNCTION__, bufRets[i].val.error()); 256 return CAMERA3_BUF_REQ_FAILED_UNKNOWN; 257 } 258 } 259 } 260 261 if (status == BufferRequestStatus::FAILED_UNKNOWN) { 262 return CAMERA3_BUF_REQ_FAILED_UNKNOWN; 263 } 264 265 // Only BufferRequestStatus::OK and BufferRequestStatus::FAILED_PARTIAL reaches here 266 std::vector<int> importedFences; 267 std::vector<std::pair<buffer_handle_t, int>> importedBuffers; 268 for (size_t i = 0; i < num_buffer_reqs; i++) { 269 if (bufRets[i].val.getDiscriminator() != 270 StreamBuffersVal::hidl_discriminator::buffers) { 271 continue; 272 } 273 int streamId = bufRets[i].streamId; 274 const hidl_vec<StreamBuffer>& hBufs = bufRets[i].val.buffers(); 275 camera3_stream_buffer_t* outBufs = returned_buf_reqs[i].output_buffers; 276 returned_buf_reqs[i].num_output_buffers = hBufs.size(); 277 for (size_t b = 0; b < hBufs.size(); b++) { 278 const StreamBuffer& hBuf = hBufs[b]; 279 camera3_stream_buffer_t& outBuf = outBufs[b]; 280 // maybe add importBuffers API to avoid frequent locking device? 281 Status s = importBuffer(streamId, 282 hBuf.bufferId, hBuf.buffer.getNativeHandle(), 283 /*out*/&(outBuf.buffer), 284 /*allowEmptyBuf*/false); 285 // Buffer import should never fail - restart HAL since something is very wrong. 286 LOG_ALWAYS_FATAL_IF(s != Status::OK, 287 "%s: import stream %d bufferId %" PRIu64 " failed!", 288 __FUNCTION__, streamId, hBuf.bufferId); 289 290 pushBufferId(*(outBuf.buffer), hBuf.bufferId, streamId); 291 importedBuffers.push_back(std::make_pair(*(outBuf.buffer), streamId)); 292 293 bool succ = sHandleImporter.importFence(hBuf.acquireFence, outBuf.acquire_fence); 294 // Fence import should never fail - restart HAL since something is very wrong. 295 LOG_ALWAYS_FATAL_IF(!succ, 296 "%s: stream %d bufferId %" PRIu64 "acquire fence is invalid", 297 __FUNCTION__, streamId, hBuf.bufferId); 298 importedFences.push_back(outBuf.acquire_fence); 299 outBuf.stream = returned_buf_reqs[i].stream; 300 outBuf.status = CAMERA3_BUFFER_STATUS_OK; 301 outBuf.release_fence = -1; 302 } 303 returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_OK; 304 } 305 306 return (status == BufferRequestStatus::OK) ? 307 CAMERA3_BUF_REQ_OK : CAMERA3_BUF_REQ_FAILED_PARTIAL; 308 } 309 310 void CameraDeviceSession::returnStreamBuffers( 311 uint32_t num_buffers, 312 const camera3_stream_buffer_t* const* buffers) { 313 ATRACE_CALL(); 314 hidl_vec<StreamBuffer> hBufs(num_buffers); 315 316 for (size_t i = 0; i < num_buffers; i++) { 317 hBufs[i].streamId = 318 static_cast<Camera3Stream*>(buffers[i]->stream)->mId; 319 hBufs[i].buffer = nullptr; // use bufferId 320 hBufs[i].bufferId = popBufferId(*(buffers[i]->buffer), hBufs[i].streamId); 321 if (hBufs[i].bufferId == BUFFER_ID_NO_BUFFER) { 322 ALOGE("%s: unknown buffer is returned to stream %d", 323 __FUNCTION__, hBufs[i].streamId); 324 } 325 // ERROR since the buffer is not for application to consume 326 hBufs[i].status = BufferStatus::ERROR; 327 // skip acquire fence since it's of no use to camera service 328 if (buffers[i]->release_fence != -1) { 329 native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0); 330 handle->data[0] = buffers[i]->release_fence; 331 hBufs[i].releaseFence.setTo(handle, /*shouldOwn*/true); 332 } 333 } 334 335 mCallback_3_5->returnStreamBuffers(hBufs); 336 return; 337 } 338 339 /** 340 * Static callback forwarding methods from HAL to instance 341 */ 342 camera3_buffer_request_status_t CameraDeviceSession::sRequestStreamBuffers( 343 const struct camera3_callback_ops *cb, 344 uint32_t num_buffer_reqs, 345 const camera3_buffer_request_t *buffer_reqs, 346 /*out*/uint32_t *num_returned_buf_reqs, 347 /*out*/camera3_stream_buffer_ret_t *returned_buf_reqs) { 348 CameraDeviceSession *d = 349 const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb)); 350 351 if (num_buffer_reqs == 0 || buffer_reqs == nullptr || num_returned_buf_reqs == nullptr || 352 returned_buf_reqs == nullptr) { 353 ALOGE("%s: bad argument: numBufReq %d, bufReqs %p, numRetBufReq %p, retBufReqs %p", 354 __FUNCTION__, num_buffer_reqs, buffer_reqs, 355 num_returned_buf_reqs, returned_buf_reqs); 356 return CAMERA3_BUF_REQ_FAILED_ILLEGAL_ARGUMENTS; 357 } 358 359 return d->requestStreamBuffers(num_buffer_reqs, buffer_reqs, 360 num_returned_buf_reqs, returned_buf_reqs); 361 } 362 363 void CameraDeviceSession::sReturnStreamBuffers( 364 const struct camera3_callback_ops *cb, 365 uint32_t num_buffers, 366 const camera3_stream_buffer_t* const* buffers) { 367 CameraDeviceSession *d = 368 const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb)); 369 370 d->returnStreamBuffers(num_buffers, buffers); 371 } 372 373 Return<void> CameraDeviceSession::isReconfigurationRequired( 374 const V3_2::CameraMetadata& oldSessionParams, const V3_2::CameraMetadata& newSessionParams, 375 ICameraDeviceSession::isReconfigurationRequired_cb _hidl_cb) { 376 if (mDevice->ops->is_reconfiguration_required != nullptr) { 377 const camera_metadata_t *oldParams, *newParams; 378 V3_2::implementation::convertFromHidl(oldSessionParams, &oldParams); 379 V3_2::implementation::convertFromHidl(newSessionParams, &newParams); 380 auto ret = mDevice->ops->is_reconfiguration_required(mDevice, oldParams, newParams); 381 switch (ret) { 382 case 0: 383 _hidl_cb(Status::OK, true); 384 break; 385 case -EINVAL: 386 _hidl_cb(Status::OK, false); 387 break; 388 case -ENOSYS: 389 _hidl_cb(Status::METHOD_NOT_SUPPORTED, true); 390 break; 391 default: 392 _hidl_cb(Status::INTERNAL_ERROR, true); 393 break; 394 }; 395 } else { 396 _hidl_cb(Status::METHOD_NOT_SUPPORTED, true); 397 } 398 399 return Void(); 400 } 401 402 } // namespace implementation 403 } // namespace V3_5 404 } // namespace device 405 } // namespace camera 406 } // namespace hardware 407 } // namespace android 408