Loading camera/device/3.2/default/CameraDeviceSession.cpp +67 −19 Original line number Diff line number Diff line Loading @@ -44,13 +44,15 @@ static constexpr int METADATA_SHRINK_ABS_THRESHOLD = 4096; static constexpr int METADATA_SHRINK_REL_THRESHOLD = 2; HandleImporter CameraDeviceSession::sHandleImporter; buffer_handle_t CameraDeviceSession::sEmptyBuffer = nullptr; const int CameraDeviceSession::ResultBatcher::NOT_BATCHED; CameraDeviceSession::CameraDeviceSession( camera3_device_t* device, const camera_metadata_t* deviceInfo, const sp<ICameraDeviceCallback>& callback) : camera3_callback_ops({&sProcessCaptureResult, &sNotify}), camera3_callback_ops({&sProcessCaptureResult, &sNotify, nullptr, nullptr}), mDevice(device), mDeviceVersion(device->common.version), mFreeBufEarly(shouldFreeBufEarly()), Loading Loading @@ -246,10 +248,50 @@ void CameraDeviceSession::overrideResultForPrecaptureCancelLocked( } } Status CameraDeviceSession::importBuffer(int32_t streamId, uint64_t bufId, buffer_handle_t buf, /*out*/buffer_handle_t** outBufPtr, bool allowEmptyBuf) { if (buf == nullptr && bufId == BUFFER_ID_NO_BUFFER) { if (allowEmptyBuf) { *outBufPtr = &sEmptyBuffer; return Status::OK; } else { ALOGE("%s: bufferId %" PRIu64 " has null buffer handle!", __FUNCTION__, bufId); return Status::ILLEGAL_ARGUMENT; } } Mutex::Autolock _l(mInflightLock); CirculatingBuffers& cbs = mCirculatingBuffers[streamId]; if (cbs.count(bufId) == 0) { // Register a newly seen buffer buffer_handle_t importedBuf = buf; sHandleImporter.importBuffer(importedBuf); if (importedBuf == nullptr) { ALOGE("%s: output buffer for stream %d is invalid!", __FUNCTION__, streamId); return Status::INTERNAL_ERROR; } else { cbs[bufId] = importedBuf; } } *outBufPtr = &cbs[bufId]; return Status::OK; } Status CameraDeviceSession::importRequest( const CaptureRequest& request, hidl_vec<buffer_handle_t*>& allBufPtrs, hidl_vec<int>& allFences) { return importRequestImpl(request, allBufPtrs, allFences); } Status CameraDeviceSession::importRequestImpl( const CaptureRequest& request, hidl_vec<buffer_handle_t*>& allBufPtrs, hidl_vec<int>& allFences, bool allowEmptyBuf) { bool hasInputBuf = (request.inputBuffer.streamId != -1 && request.inputBuffer.bufferId != 0); size_t numOutputBufs = request.outputBuffers.size(); Loading Loading @@ -277,25 +319,15 @@ Status CameraDeviceSession::importRequest( } for (size_t i = 0; i < numBufs; i++) { buffer_handle_t buf = allBufs[i]; uint64_t bufId = allBufIds[i]; CirculatingBuffers& cbs = mCirculatingBuffers[streamIds[i]]; if (cbs.count(bufId) == 0) { if (buf == nullptr) { ALOGE("%s: bufferId %" PRIu64 " has null buffer handle!", __FUNCTION__, bufId); return Status::ILLEGAL_ARGUMENT; } // Register a newly seen buffer buffer_handle_t importedBuf = buf; sHandleImporter.importBuffer(importedBuf); if (importedBuf == nullptr) { ALOGE("%s: output buffer %zu is invalid!", __FUNCTION__, i); return Status::INTERNAL_ERROR; } else { cbs[bufId] = importedBuf; } Status st = importBuffer( streamIds[i], allBufIds[i], allBufs[i], &allBufPtrs[i], // Disallow empty buf for input stream, otherwise follow // the allowEmptyBuf argument. (hasInputBuf && i == numOutputBufs) ? false : allowEmptyBuf); if (st != Status::OK) { // Detailed error logs printed in importBuffer return st; } allBufPtrs[i] = &cbs[bufId]; } // All buffers are imported. Now validate output buffer acquire fences Loading Loading @@ -1271,18 +1303,26 @@ Return<void> CameraDeviceSession::close() { ATRACE_END(); // free all imported buffers Mutex::Autolock _l(mInflightLock); for(auto& pair : mCirculatingBuffers) { CirculatingBuffers& buffers = pair.second; for (auto& p2 : buffers) { sHandleImporter.freeBuffer(p2.second); } buffers.clear(); } mCirculatingBuffers.clear(); mClosed = true; } return Void(); } uint64_t CameraDeviceSession::getCapResultBufferId(const buffer_handle_t&, int) { // No need to fill in bufferId by default return BUFFER_ID_NO_BUFFER; } status_t CameraDeviceSession::constructCaptureResult(CaptureResult& result, const camera3_capture_result *hal_result) { uint32_t frameNumber = hal_result->frame_number; Loading Loading @@ -1396,6 +1436,14 @@ status_t CameraDeviceSession::constructCaptureResult(CaptureResult& result, result.outputBuffers[i].streamId = static_cast<Camera3Stream*>(hal_result->output_buffers[i].stream)->mId; result.outputBuffers[i].buffer = nullptr; if (hal_result->output_buffers[i].buffer != nullptr) { result.outputBuffers[i].bufferId = getCapResultBufferId( *(hal_result->output_buffers[i].buffer), result.outputBuffers[i].streamId); } else { result.outputBuffers[i].bufferId = 0; } result.outputBuffers[i].status = (BufferStatus) hal_result->output_buffers[i].status; // skip acquire fence since it's of no use to camera service if (hal_result->output_buffers[i].release_fence != -1) { Loading camera/device/3.2/default/CameraDeviceSession.h +20 −1 Original line number Diff line number Diff line Loading @@ -161,6 +161,7 @@ protected: std::map<uint32_t, bool> mInflightRawBoostPresent; ::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenRequest; static const uint64_t BUFFER_ID_NO_BUFFER = 0; // buffers currently ciculating between HAL and camera service // key: bufferId sent via HIDL interface // value: imported buffer_handle_t Loading @@ -171,6 +172,7 @@ protected: std::map<int, CirculatingBuffers> mCirculatingBuffers; static HandleImporter sHandleImporter; static buffer_handle_t sEmptyBuffer; bool mInitFail; bool mFirstRequest = false; Loading Loading @@ -301,11 +303,23 @@ protected: Status initStatus() const; // Validate and import request's input buffer and acquire fence Status importRequest( virtual Status importRequest( const CaptureRequest& request, hidl_vec<buffer_handle_t*>& allBufPtrs, hidl_vec<int>& allFences); Status importRequestImpl( const CaptureRequest& request, hidl_vec<buffer_handle_t*>& allBufPtrs, hidl_vec<int>& allFences, // Optional argument for ICameraDeviceSession@3.5 impl bool allowEmptyBuf = false); Status importBuffer(int32_t streamId, uint64_t bufId, buffer_handle_t buf, /*out*/buffer_handle_t** outBufPtr, bool allowEmptyBuf); static void cleanupInflightFences( hidl_vec<int>& allFences, size_t numFences); Loading @@ -332,6 +346,11 @@ protected: static callbacks_process_capture_result_t sProcessCaptureResult; static callbacks_notify_t sNotify; // By default camera service uses frameNumber/streamId pair to retrieve the buffer that // was sent to HAL. Override this implementation if HAL is using buffers from buffer management // APIs to send output buffer. virtual uint64_t getCapResultBufferId(const buffer_handle_t& buf, int streamId); status_t constructCaptureResult(CaptureResult& result, const camera3_capture_result *hal_result); Loading camera/device/3.4/default/CameraDeviceSession.cpp +16 −7 Original line number Diff line number Diff line Loading @@ -87,6 +87,14 @@ CameraDeviceSession::~CameraDeviceSession() { Return<void> CameraDeviceSession::configureStreams_3_4( const StreamConfiguration& requestedConfiguration, ICameraDeviceSession::configureStreams_3_4_cb _hidl_cb) { configureStreams_3_4_Impl(requestedConfiguration, _hidl_cb); return Void(); } void CameraDeviceSession::configureStreams_3_4_Impl( const StreamConfiguration& requestedConfiguration, ICameraDeviceSession::configureStreams_3_4_cb _hidl_cb, uint32_t streamConfigCounter) { Status status = initStatus(); HalStreamConfiguration outStreams; Loading @@ -97,7 +105,7 @@ Return<void> CameraDeviceSession::configureStreams_3_4( ALOGE("%s: trying to configureStreams with physical camera id with V3.2 callback", __FUNCTION__); _hidl_cb(Status::INTERNAL_ERROR, outStreams); return Void(); return; } } } Loading @@ -109,7 +117,7 @@ Return<void> CameraDeviceSession::configureStreams_3_4( ALOGE("%s: trying to configureStreams while there are still %zu inflight buffers!", __FUNCTION__, mInflightBuffers.size()); _hidl_cb(Status::INTERNAL_ERROR, outStreams); return Void(); return; } if (!mInflightAETriggerOverrides.empty()) { Loading @@ -117,7 +125,7 @@ Return<void> CameraDeviceSession::configureStreams_3_4( " trigger overrides!", __FUNCTION__, mInflightAETriggerOverrides.size()); _hidl_cb(Status::INTERNAL_ERROR, outStreams); return Void(); return; } if (!mInflightRawBoostPresent.empty()) { Loading @@ -125,12 +133,12 @@ Return<void> CameraDeviceSession::configureStreams_3_4( " boost overrides!", __FUNCTION__, mInflightRawBoostPresent.size()); _hidl_cb(Status::INTERNAL_ERROR, outStreams); return Void(); return; } if (status != Status::OK) { _hidl_cb(status, outStreams); return Void(); return; } const camera_metadata_t *paramBuffer = nullptr; Loading @@ -139,11 +147,12 @@ Return<void> CameraDeviceSession::configureStreams_3_4( } camera3_stream_configuration_t stream_list{}; stream_list.stream_configuration_counter = streamConfigCounter; hidl_vec<camera3_stream_t*> streams; stream_list.session_parameters = paramBuffer; if (!preProcessConfigurationLocked_3_4(requestedConfiguration, &stream_list, &streams)) { _hidl_cb(Status::INTERNAL_ERROR, outStreams); return Void(); return; } ATRACE_BEGIN("camera3->configure_streams"); Loading @@ -168,7 +177,7 @@ Return<void> CameraDeviceSession::configureStreams_3_4( } _hidl_cb(status, outStreams); return Void(); return; } bool CameraDeviceSession::preProcessConfigurationLocked_3_4( Loading camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h +6 −0 Original line number Diff line number Diff line Loading @@ -87,6 +87,12 @@ protected: void postProcessConfigurationFailureLocked_3_4( const StreamConfiguration& requestedConfiguration); void configureStreams_3_4_Impl( const StreamConfiguration& requestedConfiguration, ICameraDeviceSession::configureStreams_3_4_cb _hidl_cb, // Optional argument for ICameraDeviceSession@3.5 impl uint32_t streamConfigCounter = 0); Return<void> processCaptureRequest_3_4( const hidl_vec<V3_4::CaptureRequest>& requests, const hidl_vec<V3_2::BufferCache>& cachesToRemove, Loading camera/device/3.5/default/CameraDeviceSession.cpp +302 −4 Original line number Diff line number Diff line Loading @@ -15,8 +15,10 @@ */ #define LOG_TAG "CamDevSession@3.5-impl" #define ATRACE_TAG ATRACE_TAG_CAMERA #include <android/log.h> #include <vector> #include <utils/Trace.h> #include "CameraDeviceSession.h" Loading @@ -33,13 +35,26 @@ CameraDeviceSession::CameraDeviceSession( const sp<V3_2::ICameraDeviceCallback>& callback) : V3_4::implementation::CameraDeviceSession(device, deviceInfo, callback) { mHasCallback_3_5 = false; mCallback_3_5 = nullptr; auto castResult = ICameraDeviceCallback::castFrom(callback); if (castResult.isOk()) { sp<ICameraDeviceCallback> callback3_5 = castResult; if (callback3_5 != nullptr) { mHasCallback_3_5 = true; mCallback_3_5 = callback3_5; } } if (mCallback_3_5 != nullptr) { camera_metadata_entry bufMgrVersion = mDeviceInfo.find( ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION); if (bufMgrVersion.count > 0) { mSupportBufMgr = (bufMgrVersion.data.u8[0] == ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5); if (mSupportBufMgr) { request_stream_buffers = sRequestStreamBuffers; return_stream_buffers = sReturnStreamBuffers; } } } } Loading @@ -50,14 +65,297 @@ CameraDeviceSession::~CameraDeviceSession() { Return<void> CameraDeviceSession::configureStreams_3_5( const StreamConfiguration& requestedConfiguration, ICameraDeviceSession::configureStreams_3_5_cb _hidl_cb) { return configureStreams_3_4(requestedConfiguration.v3_4, _hidl_cb); configureStreams_3_4_Impl(requestedConfiguration.v3_4, _hidl_cb, requestedConfiguration.streamConfigCounter); return Void(); } Return<void> CameraDeviceSession::signalStreamFlush( const hidl_vec<int32_t>& /*requests*/, uint32_t /*streamConfigCounter*/) { const hidl_vec<int32_t>& streamIds, uint32_t streamConfigCounter) { std::vector<camera3_stream_t*> streams(streamIds.size()); { Mutex::Autolock _l(mInflightLock); for (size_t i = 0; i < streamIds.size(); i++) { int32_t id = streamIds[i]; if (mStreamMap.count(id) == 0) { ALOGE("%s: unknown streamId %d", __FUNCTION__, id); return Void(); } streams[i] = &mStreamMap[id]; } } if (mDevice->ops->signal_stream_flush != nullptr) { mDevice->ops->signal_stream_flush(mDevice, streamConfigCounter, streams.size(), streams.data()); } return Void(); } Status CameraDeviceSession::importRequest( const CaptureRequest& request, hidl_vec<buffer_handle_t*>& allBufPtrs, hidl_vec<int>& allFences) { if (mSupportBufMgr) { return importRequestImpl(request, allBufPtrs, allFences, /*allowEmptyBuf*/ true); } return importRequestImpl(request, allBufPtrs, allFences, /*allowEmptyBuf*/ false); } void CameraDeviceSession::pushBufferId( const buffer_handle_t& buf, uint64_t bufferId, int streamId) { std::lock_guard<std::mutex> lock(mBufferIdMapLock); // emplace will return existing entry if there is one. auto pair = mBufferIdMaps.emplace(streamId, BufferIdMap{}); BufferIdMap& bIdMap = pair.first->second; bIdMap[buf] = bufferId; } uint64_t CameraDeviceSession::popBufferId( const buffer_handle_t& buf, int streamId) { std::lock_guard<std::mutex> lock(mBufferIdMapLock); auto streamIt = mBufferIdMaps.find(streamId); if (streamIt == mBufferIdMaps.end()) { return BUFFER_ID_NO_BUFFER; } BufferIdMap& bIdMap = streamIt->second; auto it = bIdMap.find(buf); if (it == bIdMap.end()) { return BUFFER_ID_NO_BUFFER; } uint64_t bufId = it->second; bIdMap.erase(it); if (bIdMap.empty()) { mBufferIdMaps.erase(streamIt); } return bufId; } uint64_t CameraDeviceSession::getCapResultBufferId(const buffer_handle_t& buf, int streamId) { if (mSupportBufMgr) { return popBufferId(buf, streamId); } return BUFFER_ID_NO_BUFFER; } Camera3Stream* CameraDeviceSession::getStreamPointer(int32_t streamId) { Mutex::Autolock _l(mInflightLock); if (mStreamMap.count(streamId) == 0) { ALOGE("%s: unknown streamId %d", __FUNCTION__, streamId); return nullptr; } return &mStreamMap[streamId]; } void CameraDeviceSession::cleanupInflightBufferFences( std::vector<int>& fences, std::vector<std::pair<buffer_handle_t, int>>& bufs) { hidl_vec<int> hFences = fences; cleanupInflightFences(hFences, fences.size()); for (auto& p : bufs) { popBufferId(p.first, p.second); } } camera3_buffer_request_status_t CameraDeviceSession::requestStreamBuffers( uint32_t num_buffer_reqs, const camera3_buffer_request_t *buffer_reqs, /*out*/uint32_t *num_returned_buf_reqs, /*out*/camera3_stream_buffer_ret_t *returned_buf_reqs) { ATRACE_CALL(); *num_returned_buf_reqs = 0; hidl_vec<BufferRequest> hBufReqs(num_buffer_reqs); for (size_t i = 0; i < num_buffer_reqs; i++) { hBufReqs[i].streamId = static_cast<Camera3Stream*>(buffer_reqs[i].stream)->mId; hBufReqs[i].numBuffersRequested = buffer_reqs[i].num_buffers_requested; } ATRACE_BEGIN("HIDL requestStreamBuffers"); BufferRequestStatus status; hidl_vec<StreamBufferRet> bufRets; auto err = mCallback_3_5->requestStreamBuffers(hBufReqs, [&status, &bufRets] (BufferRequestStatus s, const hidl_vec<StreamBufferRet>& rets) { status = s; bufRets = std::move(rets); }); if (!err.isOk()) { ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str()); return CAMERA3_BUF_REQ_FAILED_UNKNOWN; } ATRACE_END(); if (status == BufferRequestStatus::OK || status == BufferRequestStatus::FAILED_PARTIAL) { if (bufRets.size() != num_buffer_reqs) { ALOGE("%s: expect %d buffer requests returned, only got %zu", __FUNCTION__, num_buffer_reqs, bufRets.size()); return CAMERA3_BUF_REQ_FAILED_UNKNOWN; } for (size_t i = 0; i < num_buffer_reqs; i++) { // maybe we can query all streams in one call to avoid frequent locking device here? Camera3Stream* stream = getStreamPointer(bufRets[i].streamId); if (stream == nullptr) { ALOGE("%s: unknown streamId %d", __FUNCTION__, bufRets[i].streamId); return CAMERA3_BUF_REQ_FAILED_UNKNOWN; } returned_buf_reqs[i].stream = stream; } std::vector<int> importedFences; std::vector<std::pair<buffer_handle_t, int>> importedBuffers; for (size_t i = 0; i < num_buffer_reqs; i++) { int streamId = bufRets[i].streamId; switch (bufRets[i].val.getDiscriminator()) { case StreamBuffersVal::hidl_discriminator::error: returned_buf_reqs[i].num_output_buffers = 0; switch (bufRets[i].val.error()) { case StreamBufferRequestError::NO_BUFFER_AVAILABLE: returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_NO_BUFFER_AVAILABLE; break; case StreamBufferRequestError::MAX_BUFFER_EXCEEDED: returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_MAX_BUFFER_EXCEEDED; break; case StreamBufferRequestError::STREAM_DISCONNECTED: returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_STREAM_DISCONNECTED; break; case StreamBufferRequestError::UNKNOWN_ERROR: returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_UNKNOWN_ERROR; break; default: ALOGE("%s: Unknown StreamBufferRequestError %d", __FUNCTION__, bufRets[i].val.error()); cleanupInflightBufferFences(importedFences, importedBuffers); return CAMERA3_BUF_REQ_FAILED_UNKNOWN; } break; case StreamBuffersVal::hidl_discriminator::buffers: { const hidl_vec<StreamBuffer>& hBufs = bufRets[i].val.buffers(); camera3_stream_buffer_t* outBufs = returned_buf_reqs[i].output_buffers; for (size_t b = 0; b < hBufs.size(); b++) { const StreamBuffer& hBuf = hBufs[b]; camera3_stream_buffer_t& outBuf = outBufs[b]; // maybe add importBuffers API to avoid frequent locking device? Status s = importBuffer(streamId, hBuf.bufferId, hBuf.buffer.getNativeHandle(), /*out*/&(outBuf.buffer), /*allowEmptyBuf*/false); if (s != Status::OK) { ALOGE("%s: import stream %d bufferId %" PRIu64 " failed!", __FUNCTION__, streamId, hBuf.bufferId); cleanupInflightBufferFences(importedFences, importedBuffers); // Buffer import should never fail - restart HAL since something is very // wrong. assert(false); return CAMERA3_BUF_REQ_FAILED_UNKNOWN; } pushBufferId(*(outBuf.buffer), hBuf.bufferId, streamId); importedBuffers.push_back(std::make_pair(*(outBuf.buffer), streamId)); if (!sHandleImporter.importFence( hBuf.acquireFence, outBuf.acquire_fence)) { ALOGE("%s: stream %d bufferId %" PRIu64 "acquire fence is invalid", __FUNCTION__, streamId, hBuf.bufferId); cleanupInflightBufferFences(importedFences, importedBuffers); return CAMERA3_BUF_REQ_FAILED_UNKNOWN; } importedFences.push_back(outBuf.acquire_fence); outBuf.stream = returned_buf_reqs[i].stream; outBuf.status = CAMERA3_BUFFER_STATUS_OK; outBuf.release_fence = -1; } returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_OK; } break; default: ALOGE("%s: unknown StreamBuffersVal discrimator!", __FUNCTION__); cleanupInflightBufferFences(importedFences, importedBuffers); return CAMERA3_BUF_REQ_FAILED_UNKNOWN; } } *num_returned_buf_reqs = num_buffer_reqs; return (status == BufferRequestStatus::OK) ? CAMERA3_BUF_REQ_OK : CAMERA3_BUF_REQ_FAILED_PARTIAL; } switch (status) { case BufferRequestStatus::FAILED_CONFIGURING: return CAMERA3_BUF_REQ_FAILED_CONFIGURING; case BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS: return CAMERA3_BUF_REQ_FAILED_ILLEGAL_ARGUMENTS; case BufferRequestStatus::FAILED_UNKNOWN: default: return CAMERA3_BUF_REQ_FAILED_UNKNOWN; } } void CameraDeviceSession::returnStreamBuffers( uint32_t num_buffers, const camera3_stream_buffer_t* const* buffers) { ATRACE_CALL(); hidl_vec<StreamBuffer> hBufs(num_buffers); for (size_t i = 0; i < num_buffers; i++) { hBufs[i].streamId = static_cast<Camera3Stream*>(buffers[i]->stream)->mId; hBufs[i].buffer = nullptr; // use bufferId hBufs[i].bufferId = popBufferId(*(buffers[i]->buffer), hBufs[i].streamId); if (hBufs[i].bufferId == BUFFER_ID_NO_BUFFER) { ALOGE("%s: unknown buffer is returned to stream %d", __FUNCTION__, hBufs[i].streamId); } // ERROR since the buffer is not for application to consume hBufs[i].status = BufferStatus::ERROR; // skip acquire fence since it's of no use to camera service if (buffers[i]->release_fence != -1) { native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0); handle->data[0] = buffers[i]->release_fence; hBufs[i].releaseFence.setTo(handle, /*shouldOwn*/true); } } mCallback_3_5->returnStreamBuffers(hBufs); return; } /** * Static callback forwarding methods from HAL to instance */ camera3_buffer_request_status_t CameraDeviceSession::sRequestStreamBuffers( const struct camera3_callback_ops *cb, uint32_t num_buffer_reqs, const camera3_buffer_request_t *buffer_reqs, /*out*/uint32_t *num_returned_buf_reqs, /*out*/camera3_stream_buffer_ret_t *returned_buf_reqs) { CameraDeviceSession *d = const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb)); if (num_buffer_reqs == 0 || buffer_reqs == nullptr || num_returned_buf_reqs == nullptr || returned_buf_reqs == nullptr) { ALOGE("%s: bad argument: numBufReq %d, bufReqs %p, numRetBufReq %p, retBufReqs %p", __FUNCTION__, num_buffer_reqs, buffer_reqs, num_returned_buf_reqs, returned_buf_reqs); return CAMERA3_BUF_REQ_FAILED_ILLEGAL_ARGUMENTS; } return d->requestStreamBuffers(num_buffer_reqs, buffer_reqs, num_returned_buf_reqs, returned_buf_reqs); } void CameraDeviceSession::sReturnStreamBuffers( const struct camera3_callback_ops *cb, uint32_t num_buffers, const camera3_stream_buffer_t* const* buffers) { CameraDeviceSession *d = const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb)); d->returnStreamBuffers(num_buffers, buffers); } } // namespace implementation } // namespace V3_5 } // namespace device Loading Loading
camera/device/3.2/default/CameraDeviceSession.cpp +67 −19 Original line number Diff line number Diff line Loading @@ -44,13 +44,15 @@ static constexpr int METADATA_SHRINK_ABS_THRESHOLD = 4096; static constexpr int METADATA_SHRINK_REL_THRESHOLD = 2; HandleImporter CameraDeviceSession::sHandleImporter; buffer_handle_t CameraDeviceSession::sEmptyBuffer = nullptr; const int CameraDeviceSession::ResultBatcher::NOT_BATCHED; CameraDeviceSession::CameraDeviceSession( camera3_device_t* device, const camera_metadata_t* deviceInfo, const sp<ICameraDeviceCallback>& callback) : camera3_callback_ops({&sProcessCaptureResult, &sNotify}), camera3_callback_ops({&sProcessCaptureResult, &sNotify, nullptr, nullptr}), mDevice(device), mDeviceVersion(device->common.version), mFreeBufEarly(shouldFreeBufEarly()), Loading Loading @@ -246,10 +248,50 @@ void CameraDeviceSession::overrideResultForPrecaptureCancelLocked( } } Status CameraDeviceSession::importBuffer(int32_t streamId, uint64_t bufId, buffer_handle_t buf, /*out*/buffer_handle_t** outBufPtr, bool allowEmptyBuf) { if (buf == nullptr && bufId == BUFFER_ID_NO_BUFFER) { if (allowEmptyBuf) { *outBufPtr = &sEmptyBuffer; return Status::OK; } else { ALOGE("%s: bufferId %" PRIu64 " has null buffer handle!", __FUNCTION__, bufId); return Status::ILLEGAL_ARGUMENT; } } Mutex::Autolock _l(mInflightLock); CirculatingBuffers& cbs = mCirculatingBuffers[streamId]; if (cbs.count(bufId) == 0) { // Register a newly seen buffer buffer_handle_t importedBuf = buf; sHandleImporter.importBuffer(importedBuf); if (importedBuf == nullptr) { ALOGE("%s: output buffer for stream %d is invalid!", __FUNCTION__, streamId); return Status::INTERNAL_ERROR; } else { cbs[bufId] = importedBuf; } } *outBufPtr = &cbs[bufId]; return Status::OK; } Status CameraDeviceSession::importRequest( const CaptureRequest& request, hidl_vec<buffer_handle_t*>& allBufPtrs, hidl_vec<int>& allFences) { return importRequestImpl(request, allBufPtrs, allFences); } Status CameraDeviceSession::importRequestImpl( const CaptureRequest& request, hidl_vec<buffer_handle_t*>& allBufPtrs, hidl_vec<int>& allFences, bool allowEmptyBuf) { bool hasInputBuf = (request.inputBuffer.streamId != -1 && request.inputBuffer.bufferId != 0); size_t numOutputBufs = request.outputBuffers.size(); Loading Loading @@ -277,25 +319,15 @@ Status CameraDeviceSession::importRequest( } for (size_t i = 0; i < numBufs; i++) { buffer_handle_t buf = allBufs[i]; uint64_t bufId = allBufIds[i]; CirculatingBuffers& cbs = mCirculatingBuffers[streamIds[i]]; if (cbs.count(bufId) == 0) { if (buf == nullptr) { ALOGE("%s: bufferId %" PRIu64 " has null buffer handle!", __FUNCTION__, bufId); return Status::ILLEGAL_ARGUMENT; } // Register a newly seen buffer buffer_handle_t importedBuf = buf; sHandleImporter.importBuffer(importedBuf); if (importedBuf == nullptr) { ALOGE("%s: output buffer %zu is invalid!", __FUNCTION__, i); return Status::INTERNAL_ERROR; } else { cbs[bufId] = importedBuf; } Status st = importBuffer( streamIds[i], allBufIds[i], allBufs[i], &allBufPtrs[i], // Disallow empty buf for input stream, otherwise follow // the allowEmptyBuf argument. (hasInputBuf && i == numOutputBufs) ? false : allowEmptyBuf); if (st != Status::OK) { // Detailed error logs printed in importBuffer return st; } allBufPtrs[i] = &cbs[bufId]; } // All buffers are imported. Now validate output buffer acquire fences Loading Loading @@ -1271,18 +1303,26 @@ Return<void> CameraDeviceSession::close() { ATRACE_END(); // free all imported buffers Mutex::Autolock _l(mInflightLock); for(auto& pair : mCirculatingBuffers) { CirculatingBuffers& buffers = pair.second; for (auto& p2 : buffers) { sHandleImporter.freeBuffer(p2.second); } buffers.clear(); } mCirculatingBuffers.clear(); mClosed = true; } return Void(); } uint64_t CameraDeviceSession::getCapResultBufferId(const buffer_handle_t&, int) { // No need to fill in bufferId by default return BUFFER_ID_NO_BUFFER; } status_t CameraDeviceSession::constructCaptureResult(CaptureResult& result, const camera3_capture_result *hal_result) { uint32_t frameNumber = hal_result->frame_number; Loading Loading @@ -1396,6 +1436,14 @@ status_t CameraDeviceSession::constructCaptureResult(CaptureResult& result, result.outputBuffers[i].streamId = static_cast<Camera3Stream*>(hal_result->output_buffers[i].stream)->mId; result.outputBuffers[i].buffer = nullptr; if (hal_result->output_buffers[i].buffer != nullptr) { result.outputBuffers[i].bufferId = getCapResultBufferId( *(hal_result->output_buffers[i].buffer), result.outputBuffers[i].streamId); } else { result.outputBuffers[i].bufferId = 0; } result.outputBuffers[i].status = (BufferStatus) hal_result->output_buffers[i].status; // skip acquire fence since it's of no use to camera service if (hal_result->output_buffers[i].release_fence != -1) { Loading
camera/device/3.2/default/CameraDeviceSession.h +20 −1 Original line number Diff line number Diff line Loading @@ -161,6 +161,7 @@ protected: std::map<uint32_t, bool> mInflightRawBoostPresent; ::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenRequest; static const uint64_t BUFFER_ID_NO_BUFFER = 0; // buffers currently ciculating between HAL and camera service // key: bufferId sent via HIDL interface // value: imported buffer_handle_t Loading @@ -171,6 +172,7 @@ protected: std::map<int, CirculatingBuffers> mCirculatingBuffers; static HandleImporter sHandleImporter; static buffer_handle_t sEmptyBuffer; bool mInitFail; bool mFirstRequest = false; Loading Loading @@ -301,11 +303,23 @@ protected: Status initStatus() const; // Validate and import request's input buffer and acquire fence Status importRequest( virtual Status importRequest( const CaptureRequest& request, hidl_vec<buffer_handle_t*>& allBufPtrs, hidl_vec<int>& allFences); Status importRequestImpl( const CaptureRequest& request, hidl_vec<buffer_handle_t*>& allBufPtrs, hidl_vec<int>& allFences, // Optional argument for ICameraDeviceSession@3.5 impl bool allowEmptyBuf = false); Status importBuffer(int32_t streamId, uint64_t bufId, buffer_handle_t buf, /*out*/buffer_handle_t** outBufPtr, bool allowEmptyBuf); static void cleanupInflightFences( hidl_vec<int>& allFences, size_t numFences); Loading @@ -332,6 +346,11 @@ protected: static callbacks_process_capture_result_t sProcessCaptureResult; static callbacks_notify_t sNotify; // By default camera service uses frameNumber/streamId pair to retrieve the buffer that // was sent to HAL. Override this implementation if HAL is using buffers from buffer management // APIs to send output buffer. virtual uint64_t getCapResultBufferId(const buffer_handle_t& buf, int streamId); status_t constructCaptureResult(CaptureResult& result, const camera3_capture_result *hal_result); Loading
camera/device/3.4/default/CameraDeviceSession.cpp +16 −7 Original line number Diff line number Diff line Loading @@ -87,6 +87,14 @@ CameraDeviceSession::~CameraDeviceSession() { Return<void> CameraDeviceSession::configureStreams_3_4( const StreamConfiguration& requestedConfiguration, ICameraDeviceSession::configureStreams_3_4_cb _hidl_cb) { configureStreams_3_4_Impl(requestedConfiguration, _hidl_cb); return Void(); } void CameraDeviceSession::configureStreams_3_4_Impl( const StreamConfiguration& requestedConfiguration, ICameraDeviceSession::configureStreams_3_4_cb _hidl_cb, uint32_t streamConfigCounter) { Status status = initStatus(); HalStreamConfiguration outStreams; Loading @@ -97,7 +105,7 @@ Return<void> CameraDeviceSession::configureStreams_3_4( ALOGE("%s: trying to configureStreams with physical camera id with V3.2 callback", __FUNCTION__); _hidl_cb(Status::INTERNAL_ERROR, outStreams); return Void(); return; } } } Loading @@ -109,7 +117,7 @@ Return<void> CameraDeviceSession::configureStreams_3_4( ALOGE("%s: trying to configureStreams while there are still %zu inflight buffers!", __FUNCTION__, mInflightBuffers.size()); _hidl_cb(Status::INTERNAL_ERROR, outStreams); return Void(); return; } if (!mInflightAETriggerOverrides.empty()) { Loading @@ -117,7 +125,7 @@ Return<void> CameraDeviceSession::configureStreams_3_4( " trigger overrides!", __FUNCTION__, mInflightAETriggerOverrides.size()); _hidl_cb(Status::INTERNAL_ERROR, outStreams); return Void(); return; } if (!mInflightRawBoostPresent.empty()) { Loading @@ -125,12 +133,12 @@ Return<void> CameraDeviceSession::configureStreams_3_4( " boost overrides!", __FUNCTION__, mInflightRawBoostPresent.size()); _hidl_cb(Status::INTERNAL_ERROR, outStreams); return Void(); return; } if (status != Status::OK) { _hidl_cb(status, outStreams); return Void(); return; } const camera_metadata_t *paramBuffer = nullptr; Loading @@ -139,11 +147,12 @@ Return<void> CameraDeviceSession::configureStreams_3_4( } camera3_stream_configuration_t stream_list{}; stream_list.stream_configuration_counter = streamConfigCounter; hidl_vec<camera3_stream_t*> streams; stream_list.session_parameters = paramBuffer; if (!preProcessConfigurationLocked_3_4(requestedConfiguration, &stream_list, &streams)) { _hidl_cb(Status::INTERNAL_ERROR, outStreams); return Void(); return; } ATRACE_BEGIN("camera3->configure_streams"); Loading @@ -168,7 +177,7 @@ Return<void> CameraDeviceSession::configureStreams_3_4( } _hidl_cb(status, outStreams); return Void(); return; } bool CameraDeviceSession::preProcessConfigurationLocked_3_4( Loading
camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h +6 −0 Original line number Diff line number Diff line Loading @@ -87,6 +87,12 @@ protected: void postProcessConfigurationFailureLocked_3_4( const StreamConfiguration& requestedConfiguration); void configureStreams_3_4_Impl( const StreamConfiguration& requestedConfiguration, ICameraDeviceSession::configureStreams_3_4_cb _hidl_cb, // Optional argument for ICameraDeviceSession@3.5 impl uint32_t streamConfigCounter = 0); Return<void> processCaptureRequest_3_4( const hidl_vec<V3_4::CaptureRequest>& requests, const hidl_vec<V3_2::BufferCache>& cachesToRemove, Loading
camera/device/3.5/default/CameraDeviceSession.cpp +302 −4 Original line number Diff line number Diff line Loading @@ -15,8 +15,10 @@ */ #define LOG_TAG "CamDevSession@3.5-impl" #define ATRACE_TAG ATRACE_TAG_CAMERA #include <android/log.h> #include <vector> #include <utils/Trace.h> #include "CameraDeviceSession.h" Loading @@ -33,13 +35,26 @@ CameraDeviceSession::CameraDeviceSession( const sp<V3_2::ICameraDeviceCallback>& callback) : V3_4::implementation::CameraDeviceSession(device, deviceInfo, callback) { mHasCallback_3_5 = false; mCallback_3_5 = nullptr; auto castResult = ICameraDeviceCallback::castFrom(callback); if (castResult.isOk()) { sp<ICameraDeviceCallback> callback3_5 = castResult; if (callback3_5 != nullptr) { mHasCallback_3_5 = true; mCallback_3_5 = callback3_5; } } if (mCallback_3_5 != nullptr) { camera_metadata_entry bufMgrVersion = mDeviceInfo.find( ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION); if (bufMgrVersion.count > 0) { mSupportBufMgr = (bufMgrVersion.data.u8[0] == ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5); if (mSupportBufMgr) { request_stream_buffers = sRequestStreamBuffers; return_stream_buffers = sReturnStreamBuffers; } } } } Loading @@ -50,14 +65,297 @@ CameraDeviceSession::~CameraDeviceSession() { Return<void> CameraDeviceSession::configureStreams_3_5( const StreamConfiguration& requestedConfiguration, ICameraDeviceSession::configureStreams_3_5_cb _hidl_cb) { return configureStreams_3_4(requestedConfiguration.v3_4, _hidl_cb); configureStreams_3_4_Impl(requestedConfiguration.v3_4, _hidl_cb, requestedConfiguration.streamConfigCounter); return Void(); } Return<void> CameraDeviceSession::signalStreamFlush( const hidl_vec<int32_t>& /*requests*/, uint32_t /*streamConfigCounter*/) { const hidl_vec<int32_t>& streamIds, uint32_t streamConfigCounter) { std::vector<camera3_stream_t*> streams(streamIds.size()); { Mutex::Autolock _l(mInflightLock); for (size_t i = 0; i < streamIds.size(); i++) { int32_t id = streamIds[i]; if (mStreamMap.count(id) == 0) { ALOGE("%s: unknown streamId %d", __FUNCTION__, id); return Void(); } streams[i] = &mStreamMap[id]; } } if (mDevice->ops->signal_stream_flush != nullptr) { mDevice->ops->signal_stream_flush(mDevice, streamConfigCounter, streams.size(), streams.data()); } return Void(); } Status CameraDeviceSession::importRequest( const CaptureRequest& request, hidl_vec<buffer_handle_t*>& allBufPtrs, hidl_vec<int>& allFences) { if (mSupportBufMgr) { return importRequestImpl(request, allBufPtrs, allFences, /*allowEmptyBuf*/ true); } return importRequestImpl(request, allBufPtrs, allFences, /*allowEmptyBuf*/ false); } void CameraDeviceSession::pushBufferId( const buffer_handle_t& buf, uint64_t bufferId, int streamId) { std::lock_guard<std::mutex> lock(mBufferIdMapLock); // emplace will return existing entry if there is one. auto pair = mBufferIdMaps.emplace(streamId, BufferIdMap{}); BufferIdMap& bIdMap = pair.first->second; bIdMap[buf] = bufferId; } uint64_t CameraDeviceSession::popBufferId( const buffer_handle_t& buf, int streamId) { std::lock_guard<std::mutex> lock(mBufferIdMapLock); auto streamIt = mBufferIdMaps.find(streamId); if (streamIt == mBufferIdMaps.end()) { return BUFFER_ID_NO_BUFFER; } BufferIdMap& bIdMap = streamIt->second; auto it = bIdMap.find(buf); if (it == bIdMap.end()) { return BUFFER_ID_NO_BUFFER; } uint64_t bufId = it->second; bIdMap.erase(it); if (bIdMap.empty()) { mBufferIdMaps.erase(streamIt); } return bufId; } uint64_t CameraDeviceSession::getCapResultBufferId(const buffer_handle_t& buf, int streamId) { if (mSupportBufMgr) { return popBufferId(buf, streamId); } return BUFFER_ID_NO_BUFFER; } Camera3Stream* CameraDeviceSession::getStreamPointer(int32_t streamId) { Mutex::Autolock _l(mInflightLock); if (mStreamMap.count(streamId) == 0) { ALOGE("%s: unknown streamId %d", __FUNCTION__, streamId); return nullptr; } return &mStreamMap[streamId]; } void CameraDeviceSession::cleanupInflightBufferFences( std::vector<int>& fences, std::vector<std::pair<buffer_handle_t, int>>& bufs) { hidl_vec<int> hFences = fences; cleanupInflightFences(hFences, fences.size()); for (auto& p : bufs) { popBufferId(p.first, p.second); } } camera3_buffer_request_status_t CameraDeviceSession::requestStreamBuffers( uint32_t num_buffer_reqs, const camera3_buffer_request_t *buffer_reqs, /*out*/uint32_t *num_returned_buf_reqs, /*out*/camera3_stream_buffer_ret_t *returned_buf_reqs) { ATRACE_CALL(); *num_returned_buf_reqs = 0; hidl_vec<BufferRequest> hBufReqs(num_buffer_reqs); for (size_t i = 0; i < num_buffer_reqs; i++) { hBufReqs[i].streamId = static_cast<Camera3Stream*>(buffer_reqs[i].stream)->mId; hBufReqs[i].numBuffersRequested = buffer_reqs[i].num_buffers_requested; } ATRACE_BEGIN("HIDL requestStreamBuffers"); BufferRequestStatus status; hidl_vec<StreamBufferRet> bufRets; auto err = mCallback_3_5->requestStreamBuffers(hBufReqs, [&status, &bufRets] (BufferRequestStatus s, const hidl_vec<StreamBufferRet>& rets) { status = s; bufRets = std::move(rets); }); if (!err.isOk()) { ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str()); return CAMERA3_BUF_REQ_FAILED_UNKNOWN; } ATRACE_END(); if (status == BufferRequestStatus::OK || status == BufferRequestStatus::FAILED_PARTIAL) { if (bufRets.size() != num_buffer_reqs) { ALOGE("%s: expect %d buffer requests returned, only got %zu", __FUNCTION__, num_buffer_reqs, bufRets.size()); return CAMERA3_BUF_REQ_FAILED_UNKNOWN; } for (size_t i = 0; i < num_buffer_reqs; i++) { // maybe we can query all streams in one call to avoid frequent locking device here? Camera3Stream* stream = getStreamPointer(bufRets[i].streamId); if (stream == nullptr) { ALOGE("%s: unknown streamId %d", __FUNCTION__, bufRets[i].streamId); return CAMERA3_BUF_REQ_FAILED_UNKNOWN; } returned_buf_reqs[i].stream = stream; } std::vector<int> importedFences; std::vector<std::pair<buffer_handle_t, int>> importedBuffers; for (size_t i = 0; i < num_buffer_reqs; i++) { int streamId = bufRets[i].streamId; switch (bufRets[i].val.getDiscriminator()) { case StreamBuffersVal::hidl_discriminator::error: returned_buf_reqs[i].num_output_buffers = 0; switch (bufRets[i].val.error()) { case StreamBufferRequestError::NO_BUFFER_AVAILABLE: returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_NO_BUFFER_AVAILABLE; break; case StreamBufferRequestError::MAX_BUFFER_EXCEEDED: returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_MAX_BUFFER_EXCEEDED; break; case StreamBufferRequestError::STREAM_DISCONNECTED: returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_STREAM_DISCONNECTED; break; case StreamBufferRequestError::UNKNOWN_ERROR: returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_UNKNOWN_ERROR; break; default: ALOGE("%s: Unknown StreamBufferRequestError %d", __FUNCTION__, bufRets[i].val.error()); cleanupInflightBufferFences(importedFences, importedBuffers); return CAMERA3_BUF_REQ_FAILED_UNKNOWN; } break; case StreamBuffersVal::hidl_discriminator::buffers: { const hidl_vec<StreamBuffer>& hBufs = bufRets[i].val.buffers(); camera3_stream_buffer_t* outBufs = returned_buf_reqs[i].output_buffers; for (size_t b = 0; b < hBufs.size(); b++) { const StreamBuffer& hBuf = hBufs[b]; camera3_stream_buffer_t& outBuf = outBufs[b]; // maybe add importBuffers API to avoid frequent locking device? Status s = importBuffer(streamId, hBuf.bufferId, hBuf.buffer.getNativeHandle(), /*out*/&(outBuf.buffer), /*allowEmptyBuf*/false); if (s != Status::OK) { ALOGE("%s: import stream %d bufferId %" PRIu64 " failed!", __FUNCTION__, streamId, hBuf.bufferId); cleanupInflightBufferFences(importedFences, importedBuffers); // Buffer import should never fail - restart HAL since something is very // wrong. assert(false); return CAMERA3_BUF_REQ_FAILED_UNKNOWN; } pushBufferId(*(outBuf.buffer), hBuf.bufferId, streamId); importedBuffers.push_back(std::make_pair(*(outBuf.buffer), streamId)); if (!sHandleImporter.importFence( hBuf.acquireFence, outBuf.acquire_fence)) { ALOGE("%s: stream %d bufferId %" PRIu64 "acquire fence is invalid", __FUNCTION__, streamId, hBuf.bufferId); cleanupInflightBufferFences(importedFences, importedBuffers); return CAMERA3_BUF_REQ_FAILED_UNKNOWN; } importedFences.push_back(outBuf.acquire_fence); outBuf.stream = returned_buf_reqs[i].stream; outBuf.status = CAMERA3_BUFFER_STATUS_OK; outBuf.release_fence = -1; } returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_OK; } break; default: ALOGE("%s: unknown StreamBuffersVal discrimator!", __FUNCTION__); cleanupInflightBufferFences(importedFences, importedBuffers); return CAMERA3_BUF_REQ_FAILED_UNKNOWN; } } *num_returned_buf_reqs = num_buffer_reqs; return (status == BufferRequestStatus::OK) ? CAMERA3_BUF_REQ_OK : CAMERA3_BUF_REQ_FAILED_PARTIAL; } switch (status) { case BufferRequestStatus::FAILED_CONFIGURING: return CAMERA3_BUF_REQ_FAILED_CONFIGURING; case BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS: return CAMERA3_BUF_REQ_FAILED_ILLEGAL_ARGUMENTS; case BufferRequestStatus::FAILED_UNKNOWN: default: return CAMERA3_BUF_REQ_FAILED_UNKNOWN; } } void CameraDeviceSession::returnStreamBuffers( uint32_t num_buffers, const camera3_stream_buffer_t* const* buffers) { ATRACE_CALL(); hidl_vec<StreamBuffer> hBufs(num_buffers); for (size_t i = 0; i < num_buffers; i++) { hBufs[i].streamId = static_cast<Camera3Stream*>(buffers[i]->stream)->mId; hBufs[i].buffer = nullptr; // use bufferId hBufs[i].bufferId = popBufferId(*(buffers[i]->buffer), hBufs[i].streamId); if (hBufs[i].bufferId == BUFFER_ID_NO_BUFFER) { ALOGE("%s: unknown buffer is returned to stream %d", __FUNCTION__, hBufs[i].streamId); } // ERROR since the buffer is not for application to consume hBufs[i].status = BufferStatus::ERROR; // skip acquire fence since it's of no use to camera service if (buffers[i]->release_fence != -1) { native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0); handle->data[0] = buffers[i]->release_fence; hBufs[i].releaseFence.setTo(handle, /*shouldOwn*/true); } } mCallback_3_5->returnStreamBuffers(hBufs); return; } /** * Static callback forwarding methods from HAL to instance */ camera3_buffer_request_status_t CameraDeviceSession::sRequestStreamBuffers( const struct camera3_callback_ops *cb, uint32_t num_buffer_reqs, const camera3_buffer_request_t *buffer_reqs, /*out*/uint32_t *num_returned_buf_reqs, /*out*/camera3_stream_buffer_ret_t *returned_buf_reqs) { CameraDeviceSession *d = const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb)); if (num_buffer_reqs == 0 || buffer_reqs == nullptr || num_returned_buf_reqs == nullptr || returned_buf_reqs == nullptr) { ALOGE("%s: bad argument: numBufReq %d, bufReqs %p, numRetBufReq %p, retBufReqs %p", __FUNCTION__, num_buffer_reqs, buffer_reqs, num_returned_buf_reqs, returned_buf_reqs); return CAMERA3_BUF_REQ_FAILED_ILLEGAL_ARGUMENTS; } return d->requestStreamBuffers(num_buffer_reqs, buffer_reqs, num_returned_buf_reqs, returned_buf_reqs); } void CameraDeviceSession::sReturnStreamBuffers( const struct camera3_callback_ops *cb, uint32_t num_buffers, const camera3_stream_buffer_t* const* buffers) { CameraDeviceSession *d = const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb)); d->returnStreamBuffers(num_buffers, buffers); } } // namespace implementation } // namespace V3_5 } // namespace device Loading