diff options
author | Yin-Chia Yeh <yinchiayeh@google.com> | 2018-02-16 14:54:04 -0800 |
---|---|---|
committer | Yin-Chia Yeh <yinchiayeh@google.com> | 2018-02-20 16:28:55 -0800 |
commit | e086fb7b4a91e20533f6f17d0e307f02ee221b6e (patch) | |
tree | 9e1eca9b3ee72eeeb722af31e154646eda4d5535 /camera/device/3.4/default/ExternalCameraDeviceSession.cpp | |
parent | 4a3393cd8aaf5eeb6ff037368ebd03f540da208f (diff) |
Camera: avoid copying of HalRequest
Bug: 64874137
Change-Id: I46ea14facf467921da633cde7e24ff9703a6a8f7
Diffstat (limited to 'camera/device/3.4/default/ExternalCameraDeviceSession.cpp')
-rw-r--r-- | camera/device/3.4/default/ExternalCameraDeviceSession.cpp | 125 |
1 files changed, 63 insertions, 62 deletions
diff --git a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp index cffc40e20e..439143945a 100644 --- a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp +++ b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp @@ -537,15 +537,14 @@ Status ExternalCameraDeviceSession::processOneCaptureRequest(const CaptureReques return Status::INTERNAL_ERROR; } - // TODO: reduce object copy in this path - HalRequest halReq = { - .frameNumber = request.frameNumber, - .setting = mLatestReqSetting, - .frameIn = frameIn, - .shutterTs = shutterTs}; - halReq.buffers.resize(numOutputBufs); + std::shared_ptr<HalRequest> halReq = std::make_shared<HalRequest>(); + halReq->frameNumber = request.frameNumber; + halReq->setting = mLatestReqSetting; + halReq->frameIn = frameIn; + halReq->shutterTs = shutterTs; + halReq->buffers.resize(numOutputBufs); for (size_t i = 0; i < numOutputBufs; i++) { - HalStreamBuffer& halBuf = halReq.buffers[i]; + HalStreamBuffer& halBuf = halReq->buffers[i]; int streamId = halBuf.streamId = request.outputBuffers[i].streamId; halBuf.bufferId = request.outputBuffers[i].bufferId; const Stream& stream = mStreamMap[streamId]; @@ -557,7 +556,7 @@ Status ExternalCameraDeviceSession::processOneCaptureRequest(const CaptureReques halBuf.acquireFence = allFences[i]; halBuf.fenceTimeout = false; } - mInflightFrames.insert(halReq.frameNumber); + mInflightFrames.insert(halReq->frameNumber); // Send request to OutputThread for the rest of processing mOutputThread->submitRequest(halReq); mFirstRequest = false; @@ -583,30 +582,31 @@ void ExternalCameraDeviceSession::notifyError( } //TODO: refactor with processCaptureResult -Status ExternalCameraDeviceSession::processCaptureRequestError(const HalRequest& req) { +Status ExternalCameraDeviceSession::processCaptureRequestError( + const std::shared_ptr<HalRequest>& req) { // Return V4L2 buffer to V4L2 buffer queue - enqueueV4l2Frame(req.frameIn); + enqueueV4l2Frame(req->frameIn); // NotifyShutter - notifyShutter(req.frameNumber, req.shutterTs); + notifyShutter(req->frameNumber, req->shutterTs); - notifyError(/*frameNum*/req.frameNumber, /*stream*/-1, ErrorCode::ERROR_REQUEST); + notifyError(/*frameNum*/req->frameNumber, /*stream*/-1, ErrorCode::ERROR_REQUEST); // Fill output buffers hidl_vec<CaptureResult> results; results.resize(1); CaptureResult& result = results[0]; - result.frameNumber = req.frameNumber; + result.frameNumber = req->frameNumber; result.partialResult = 1; result.inputBuffer.streamId = -1; - result.outputBuffers.resize(req.buffers.size()); - for (size_t i = 0; i < req.buffers.size(); i++) { - result.outputBuffers[i].streamId = req.buffers[i].streamId; - result.outputBuffers[i].bufferId = req.buffers[i].bufferId; + result.outputBuffers.resize(req->buffers.size()); + for (size_t i = 0; i < req->buffers.size(); i++) { + result.outputBuffers[i].streamId = req->buffers[i].streamId; + result.outputBuffers[i].bufferId = req->buffers[i].bufferId; result.outputBuffers[i].status = BufferStatus::ERROR; - if (req.buffers[i].acquireFence >= 0) { + if (req->buffers[i].acquireFence >= 0) { native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0); - handle->data[0] = req.buffers[i].acquireFence; + handle->data[0] = req->buffers[i].acquireFence; result.outputBuffers[i].releaseFence.setTo(handle, /*shouldOwn*/false); } } @@ -614,7 +614,7 @@ Status ExternalCameraDeviceSession::processCaptureRequestError(const HalRequest& // update inflight records { Mutex::Autolock _l(mLock); - mInflightFrames.erase(req.frameNumber); + mInflightFrames.erase(req->frameNumber); } // Callback into framework @@ -623,51 +623,51 @@ Status ExternalCameraDeviceSession::processCaptureRequestError(const HalRequest& return Status::OK; } -Status ExternalCameraDeviceSession::processCaptureResult(HalRequest& req) { +Status ExternalCameraDeviceSession::processCaptureResult(std::shared_ptr<HalRequest>& req) { // Return V4L2 buffer to V4L2 buffer queue - enqueueV4l2Frame(req.frameIn); + enqueueV4l2Frame(req->frameIn); // NotifyShutter - notifyShutter(req.frameNumber, req.shutterTs); + notifyShutter(req->frameNumber, req->shutterTs); // Fill output buffers hidl_vec<CaptureResult> results; results.resize(1); CaptureResult& result = results[0]; - result.frameNumber = req.frameNumber; + result.frameNumber = req->frameNumber; result.partialResult = 1; result.inputBuffer.streamId = -1; - result.outputBuffers.resize(req.buffers.size()); - for (size_t i = 0; i < req.buffers.size(); i++) { - result.outputBuffers[i].streamId = req.buffers[i].streamId; - result.outputBuffers[i].bufferId = req.buffers[i].bufferId; - if (req.buffers[i].fenceTimeout) { + result.outputBuffers.resize(req->buffers.size()); + for (size_t i = 0; i < req->buffers.size(); i++) { + result.outputBuffers[i].streamId = req->buffers[i].streamId; + result.outputBuffers[i].bufferId = req->buffers[i].bufferId; + if (req->buffers[i].fenceTimeout) { result.outputBuffers[i].status = BufferStatus::ERROR; native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0); - handle->data[0] = req.buffers[i].acquireFence; + handle->data[0] = req->buffers[i].acquireFence; result.outputBuffers[i].releaseFence.setTo(handle, /*shouldOwn*/false); - notifyError(req.frameNumber, req.buffers[i].streamId, ErrorCode::ERROR_BUFFER); + notifyError(req->frameNumber, req->buffers[i].streamId, ErrorCode::ERROR_BUFFER); } else { result.outputBuffers[i].status = BufferStatus::OK; // TODO: refactor - if (req.buffers[i].acquireFence > 0) { + if (req->buffers[i].acquireFence > 0) { native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0); - handle->data[0] = req.buffers[i].acquireFence; + handle->data[0] = req->buffers[i].acquireFence; result.outputBuffers[i].releaseFence.setTo(handle, /*shouldOwn*/false); } } } // Fill capture result metadata - fillCaptureResult(req.setting, req.shutterTs); - const camera_metadata_t *rawResult = req.setting.getAndLock(); + fillCaptureResult(req->setting, req->shutterTs); + const camera_metadata_t *rawResult = req->setting.getAndLock(); V3_2::implementation::convertToHidl(rawResult, &result.result); - req.setting.unlock(rawResult); + req->setting.unlock(rawResult); // update inflight records { Mutex::Autolock _l(mLock); - mInflightFrames.erase(req.frameNumber); + mInflightFrames.erase(req->frameNumber); } // Callback into framework @@ -1398,7 +1398,7 @@ ssize_t ExternalCameraDeviceSession::getJpegBufferSize( int ExternalCameraDeviceSession::OutputThread::createJpegLocked( HalStreamBuffer &halBuf, - HalRequest &req) + const std::shared_ptr<HalRequest>& req) { int ret; auto lfail = [&](auto... args) { @@ -1425,17 +1425,17 @@ int ExternalCameraDeviceSession::OutputThread::createJpegLocked( int jpegQuality, thumbQuality; Size thumbSize; - if (req.setting.exists(ANDROID_JPEG_QUALITY)) { + if (req->setting.exists(ANDROID_JPEG_QUALITY)) { camera_metadata_entry entry = - req.setting.find(ANDROID_JPEG_QUALITY); + req->setting.find(ANDROID_JPEG_QUALITY); jpegQuality = entry.data.u8[0]; } else { return lfail("%s: ANDROID_JPEG_QUALITY not set",__FUNCTION__); } - if (req.setting.exists(ANDROID_JPEG_THUMBNAIL_QUALITY)) { + if (req->setting.exists(ANDROID_JPEG_THUMBNAIL_QUALITY)) { camera_metadata_entry entry = - req.setting.find(ANDROID_JPEG_THUMBNAIL_QUALITY); + req->setting.find(ANDROID_JPEG_THUMBNAIL_QUALITY); thumbQuality = entry.data.u8[0]; } else { return lfail( @@ -1443,9 +1443,9 @@ int ExternalCameraDeviceSession::OutputThread::createJpegLocked( __FUNCTION__); } - if (req.setting.exists(ANDROID_JPEG_THUMBNAIL_SIZE)) { + if (req->setting.exists(ANDROID_JPEG_THUMBNAIL_SIZE)) { camera_metadata_entry entry = - req.setting.find(ANDROID_JPEG_THUMBNAIL_SIZE); + req->setting.find(ANDROID_JPEG_THUMBNAIL_SIZE); thumbSize = Size { static_cast<uint32_t>(entry.data.i32[0]), static_cast<uint32_t>(entry.data.i32[1]) }; @@ -1505,7 +1505,7 @@ int ExternalCameraDeviceSession::OutputThread::createJpegLocked( /* Combine camera characteristics with request settings to form EXIF * metadata */ common::V1_0::helper::CameraMetadata meta(parent->mCameraCharacteristics); - meta.append(req.setting); + meta.append(req->setting); /* Generate EXIF object */ std::unique_ptr<ExifUtils> utils(ExifUtils::create()); @@ -1569,7 +1569,7 @@ int ExternalCameraDeviceSession::OutputThread::createJpegLocked( } bool ExternalCameraDeviceSession::OutputThread::threadLoop() { - HalRequest req; + std::shared_ptr<HalRequest> req; auto parent = mParent.promote(); if (parent == nullptr) { ALOGE("%s: session has been disconnected!", __FUNCTION__); @@ -1580,7 +1580,7 @@ bool ExternalCameraDeviceSession::OutputThread::threadLoop() { // regularly to prevent v4l buffer queue filled with stale buffers // when app doesn't program a preveiw request waitForNextRequest(&req); - if (req.frameIn == nullptr) { + if (req == nullptr) { // No new request, wait again return true; } @@ -1588,17 +1588,17 @@ bool ExternalCameraDeviceSession::OutputThread::threadLoop() { auto onDeviceError = [&](auto... args) { ALOGE(args...); parent->notifyError( - req.frameNumber, /*stream*/-1, ErrorCode::ERROR_DEVICE); + req->frameNumber, /*stream*/-1, ErrorCode::ERROR_DEVICE); signalRequestDone(); return false; }; - if (req.frameIn->mFourcc != V4L2_PIX_FMT_MJPEG) { + if (req->frameIn->mFourcc != V4L2_PIX_FMT_MJPEG) { return onDeviceError("%s: do not support V4L2 format %c%c%c%c", __FUNCTION__, - req.frameIn->mFourcc & 0xFF, - (req.frameIn->mFourcc >> 8) & 0xFF, - (req.frameIn->mFourcc >> 16) & 0xFF, - (req.frameIn->mFourcc >> 24) & 0xFF); + req->frameIn->mFourcc & 0xFF, + (req->frameIn->mFourcc >> 8) & 0xFF, + (req->frameIn->mFourcc >> 16) & 0xFF, + (req->frameIn->mFourcc >> 24) & 0xFF); } std::unique_lock<std::mutex> lk(mBufferLock); @@ -1606,7 +1606,7 @@ bool ExternalCameraDeviceSession::OutputThread::threadLoop() { // TODO: see if we can save some computation by converting to YV12 here uint8_t* inData; size_t inDataSize; - req.frameIn->map(&inData, &inDataSize); + req->frameIn->map(&inData, &inDataSize); // TODO: profile // TODO: in some special case maybe we can decode jpg directly to gralloc output? int res = libyuv::MJPGToI420( @@ -1634,7 +1634,7 @@ bool ExternalCameraDeviceSession::OutputThread::threadLoop() { ALOGV("%s processing new request", __FUNCTION__); const int kSyncWaitTimeoutMs = 500; - for (auto& halBuf : req.buffers) { + for (auto& halBuf : req->buffers) { if (halBuf.acquireFence != -1) { int ret = sync_wait(halBuf.acquireFence, kSyncWaitTimeoutMs); if (ret) { @@ -1791,9 +1791,9 @@ Status ExternalCameraDeviceSession::OutputThread::allocateIntermediateBuffers( return Status::OK; } -Status ExternalCameraDeviceSession::OutputThread::submitRequest(const HalRequest& req) { +Status ExternalCameraDeviceSession::OutputThread::submitRequest( + const std::shared_ptr<HalRequest>& req) { std::unique_lock<std::mutex> lk(mRequestListLock); - // TODO: reduce object copy in this path mRequestList.push_back(req); lk.unlock(); mRequestCond.notify_one(); @@ -1808,7 +1808,7 @@ void ExternalCameraDeviceSession::OutputThread::flush() { } std::unique_lock<std::mutex> lk(mRequestListLock); - std::list<HalRequest> reqs = mRequestList; + std::list<std::shared_ptr<HalRequest>> reqs = std::move(mRequestList); mRequestList.clear(); if (mProcessingRequest) { std::chrono::seconds timeout = std::chrono::seconds(kFlushWaitTimeoutSec); @@ -1824,7 +1824,8 @@ void ExternalCameraDeviceSession::OutputThread::flush() { } } -void ExternalCameraDeviceSession::OutputThread::waitForNextRequest(HalRequest* out) { +void ExternalCameraDeviceSession::OutputThread::waitForNextRequest( + std::shared_ptr<HalRequest>* out) { if (out == nullptr) { ALOGE("%s: out is null", __FUNCTION__); return; @@ -1849,7 +1850,7 @@ void ExternalCameraDeviceSession::OutputThread::waitForNextRequest(HalRequest* o *out = mRequestList.front(); mRequestList.pop_front(); mProcessingRequest = true; - mProcessingFrameNumer = out->frameNumber; + mProcessingFrameNumer = (*out)->frameNumber; } void ExternalCameraDeviceSession::OutputThread::signalRequestDone() { @@ -1869,7 +1870,7 @@ void ExternalCameraDeviceSession::OutputThread::dump(int fd) { } dprintf(fd, "OutputThread request list contains frame: "); for (const auto& req : mRequestList) { - dprintf(fd, "%d, ", req.frameNumber); + dprintf(fd, "%d, ", req->frameNumber); } dprintf(fd, "\n"); } |