Loading camera/device/3.2/default/CameraDeviceSession.cpp +14 −17 Original line number Diff line number Diff line Loading @@ -94,15 +94,7 @@ public: if (handle == nullptr || handle->numFds == 0) { fd = -1; } else if (handle->numFds == 1) { //TODO(b/34110242): make this hidl transport agnostic #ifdef BINDERIZED fd = dup(handle->data[0]); // TODO(b/34169301) // Camera service expect FD be closed by HAL process (in passthrough mode) // close(handle->data[0]); #else fd = handle->data[0]; #endif if (fd < 0) { ALOGE("failed to dup fence fd %d", handle->data[0]); return false; Loading @@ -118,13 +110,9 @@ public: void closeFence(int fd) { #ifdef BINDERIZED if (fd >= 0) { close(fd); } #else (void) fd; #endif } private: Loading Loading @@ -307,31 +295,40 @@ Status CameraDeviceSession::importRequest( hidl_vec<buffer_handle_t*>& allBufPtrs, hidl_vec<int>& allFences) { bool hasInputBuf = (request.inputBuffer.streamId != -1 && request.inputBuffer.buffer.getNativeHandle() != nullptr); request.inputBuffer.bufferId != 0); size_t numOutputBufs = request.outputBuffers.size(); size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0); // Validate all I/O buffers hidl_vec<buffer_handle_t> allBufs; hidl_vec<uint64_t> allBufIds; allBufs.resize(numBufs); allBufIds.resize(numBufs); allBufPtrs.resize(numBufs); allFences.resize(numBufs); std::vector<int32_t> streamIds(numBufs); for (size_t i = 0; i < numOutputBufs; i++) { allBufs[i] = request.outputBuffers[i].buffer.getNativeHandle(); allBufIds[i] = request.outputBuffers[i].bufferId; allBufPtrs[i] = &allBufs[i]; streamIds[i] = request.outputBuffers[i].streamId; } if (hasInputBuf) { allBufs[numOutputBufs] = request.inputBuffer.buffer.getNativeHandle(); allBufIds[numOutputBufs] = request.inputBuffer.bufferId; allBufPtrs[numOutputBufs] = &allBufs[numOutputBufs]; streamIds[numOutputBufs] = request.inputBuffer.streamId; } 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(buf) == 0) { 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); Loading @@ -339,10 +336,10 @@ Status CameraDeviceSession::importRequest( ALOGE("%s: output buffer %zu is invalid!", __FUNCTION__, i); return Status::INTERNAL_ERROR; } else { cbs[buf] = importedBuf; cbs[bufId] = importedBuf; } } allBufPtrs[i] = &cbs[buf]; allBufPtrs[i] = &cbs[bufId]; } // All buffers are imported. Now validate output buffer acquire fences Loading Loading @@ -509,7 +506,7 @@ Return<Status> CameraDeviceSession::processCaptureRequest(const CaptureRequest& hidl_vec<buffer_handle_t*> allBufPtrs; hidl_vec<int> allFences; bool hasInputBuf = (request.inputBuffer.streamId != -1 && request.inputBuffer.buffer.getNativeHandle() != nullptr); request.inputBuffer.bufferId != 0); size_t numOutputBufs = request.outputBuffers.size(); size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0); status = importRequest(request, allBufPtrs, allFences); Loading camera/device/3.2/default/CameraDeviceSession.h +2 −34 Original line number Diff line number Diff line Loading @@ -100,44 +100,12 @@ private: // (streamID, frameNumber) -> inflight buffer cache std::map<std::pair<int, uint32_t>, camera3_stream_buffer_t> mInflightBuffers; struct BufferHasher { size_t operator()(const buffer_handle_t& buf) const { if (buf == nullptr) return 0; size_t result = 1; result = 31 * result + buf->numFds; result = 31 * result + buf->numInts; int length = buf->numFds + buf->numInts; for (int i = 0; i < length; i++) { result = 31 * result + buf->data[i]; } return result; } }; struct BufferComparator { bool operator()(const buffer_handle_t& buf1, const buffer_handle_t& buf2) const { if (buf1->numFds == buf2->numFds && buf1->numInts == buf2->numInts) { int length = buf1->numFds + buf1->numInts; for (int i = 0; i < length; i++) { if (buf1->data[i] != buf2->data[i]) { return false; } } return true; } return false; } }; // buffers currently ciculating between HAL and camera service // key: buffer_handle_t sent via HIDL interface // key: bufferId sent via HIDL interface // value: imported buffer_handle_t // Buffer will be imported during process_capture_request and will be freed // when the its stream is deleted or camera device session is closed typedef std::unordered_map<buffer_handle_t, buffer_handle_t, BufferHasher, BufferComparator> CirculatingBuffers; typedef std::unordered_map<uint64_t, buffer_handle_t> CirculatingBuffers; // Stream ID -> circulating buffers map std::map<int, CirculatingBuffers> mCirculatingBuffers; Loading camera/device/3.2/types.hal +20 −3 Original line number Diff line number Diff line Loading @@ -405,16 +405,33 @@ struct StreamBuffer { /** * The ID of the stream this buffer is associated with. -1 indicates an * invalid (empty) StreamBuffer, in which case buffer must also point to * null. * null and bufferId must be 0. */ int32_t streamId; /** * The unique ID of the buffer within this StreamBuffer. 0 indicates this * StreamBuffer contains no buffer. * For StreamBuffers sent to the HAL in a CaptureRequest, this ID uniquely * identifies a buffer. When a buffer is sent to HAL for the first time, * both bufferId and buffer handle must be filled. HAL must keep track of * the mapping between bufferId and corresponding buffer until the * corresponding stream is removed from stream configuration or until camera * device session is closed. After the first time a buffer is introduced to * HAL, in the future camera service must refer to the same buffer using * only bufferId, and keep the buffer handle null. */ uint64_t bufferId; /** * The graphics buffer handle to the buffer. * * For StreamBuffers sent to the HAL in a CaptureRequest, this must be a * For StreamBuffers sent to the HAL in a CaptureRequest, if the bufferId * is not seen by the HAL before, this buffer handle is guaranteed to be a * valid handle to a graphics buffer, with dimensions and format matching * that of the stream. * that of the stream. If the bufferId has been sent to the HAL before, this * buffer handle must be null and HAL must look up the actual buffer handle * to use from its own bufferId to buffer handle map. * * For StreamBuffers returned in a CaptureResult, this must be null, since * the handle to the buffer is already known to the client (since the client Loading Loading
camera/device/3.2/default/CameraDeviceSession.cpp +14 −17 Original line number Diff line number Diff line Loading @@ -94,15 +94,7 @@ public: if (handle == nullptr || handle->numFds == 0) { fd = -1; } else if (handle->numFds == 1) { //TODO(b/34110242): make this hidl transport agnostic #ifdef BINDERIZED fd = dup(handle->data[0]); // TODO(b/34169301) // Camera service expect FD be closed by HAL process (in passthrough mode) // close(handle->data[0]); #else fd = handle->data[0]; #endif if (fd < 0) { ALOGE("failed to dup fence fd %d", handle->data[0]); return false; Loading @@ -118,13 +110,9 @@ public: void closeFence(int fd) { #ifdef BINDERIZED if (fd >= 0) { close(fd); } #else (void) fd; #endif } private: Loading Loading @@ -307,31 +295,40 @@ Status CameraDeviceSession::importRequest( hidl_vec<buffer_handle_t*>& allBufPtrs, hidl_vec<int>& allFences) { bool hasInputBuf = (request.inputBuffer.streamId != -1 && request.inputBuffer.buffer.getNativeHandle() != nullptr); request.inputBuffer.bufferId != 0); size_t numOutputBufs = request.outputBuffers.size(); size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0); // Validate all I/O buffers hidl_vec<buffer_handle_t> allBufs; hidl_vec<uint64_t> allBufIds; allBufs.resize(numBufs); allBufIds.resize(numBufs); allBufPtrs.resize(numBufs); allFences.resize(numBufs); std::vector<int32_t> streamIds(numBufs); for (size_t i = 0; i < numOutputBufs; i++) { allBufs[i] = request.outputBuffers[i].buffer.getNativeHandle(); allBufIds[i] = request.outputBuffers[i].bufferId; allBufPtrs[i] = &allBufs[i]; streamIds[i] = request.outputBuffers[i].streamId; } if (hasInputBuf) { allBufs[numOutputBufs] = request.inputBuffer.buffer.getNativeHandle(); allBufIds[numOutputBufs] = request.inputBuffer.bufferId; allBufPtrs[numOutputBufs] = &allBufs[numOutputBufs]; streamIds[numOutputBufs] = request.inputBuffer.streamId; } 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(buf) == 0) { 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); Loading @@ -339,10 +336,10 @@ Status CameraDeviceSession::importRequest( ALOGE("%s: output buffer %zu is invalid!", __FUNCTION__, i); return Status::INTERNAL_ERROR; } else { cbs[buf] = importedBuf; cbs[bufId] = importedBuf; } } allBufPtrs[i] = &cbs[buf]; allBufPtrs[i] = &cbs[bufId]; } // All buffers are imported. Now validate output buffer acquire fences Loading Loading @@ -509,7 +506,7 @@ Return<Status> CameraDeviceSession::processCaptureRequest(const CaptureRequest& hidl_vec<buffer_handle_t*> allBufPtrs; hidl_vec<int> allFences; bool hasInputBuf = (request.inputBuffer.streamId != -1 && request.inputBuffer.buffer.getNativeHandle() != nullptr); request.inputBuffer.bufferId != 0); size_t numOutputBufs = request.outputBuffers.size(); size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0); status = importRequest(request, allBufPtrs, allFences); Loading
camera/device/3.2/default/CameraDeviceSession.h +2 −34 Original line number Diff line number Diff line Loading @@ -100,44 +100,12 @@ private: // (streamID, frameNumber) -> inflight buffer cache std::map<std::pair<int, uint32_t>, camera3_stream_buffer_t> mInflightBuffers; struct BufferHasher { size_t operator()(const buffer_handle_t& buf) const { if (buf == nullptr) return 0; size_t result = 1; result = 31 * result + buf->numFds; result = 31 * result + buf->numInts; int length = buf->numFds + buf->numInts; for (int i = 0; i < length; i++) { result = 31 * result + buf->data[i]; } return result; } }; struct BufferComparator { bool operator()(const buffer_handle_t& buf1, const buffer_handle_t& buf2) const { if (buf1->numFds == buf2->numFds && buf1->numInts == buf2->numInts) { int length = buf1->numFds + buf1->numInts; for (int i = 0; i < length; i++) { if (buf1->data[i] != buf2->data[i]) { return false; } } return true; } return false; } }; // buffers currently ciculating between HAL and camera service // key: buffer_handle_t sent via HIDL interface // key: bufferId sent via HIDL interface // value: imported buffer_handle_t // Buffer will be imported during process_capture_request and will be freed // when the its stream is deleted or camera device session is closed typedef std::unordered_map<buffer_handle_t, buffer_handle_t, BufferHasher, BufferComparator> CirculatingBuffers; typedef std::unordered_map<uint64_t, buffer_handle_t> CirculatingBuffers; // Stream ID -> circulating buffers map std::map<int, CirculatingBuffers> mCirculatingBuffers; Loading
camera/device/3.2/types.hal +20 −3 Original line number Diff line number Diff line Loading @@ -405,16 +405,33 @@ struct StreamBuffer { /** * The ID of the stream this buffer is associated with. -1 indicates an * invalid (empty) StreamBuffer, in which case buffer must also point to * null. * null and bufferId must be 0. */ int32_t streamId; /** * The unique ID of the buffer within this StreamBuffer. 0 indicates this * StreamBuffer contains no buffer. * For StreamBuffers sent to the HAL in a CaptureRequest, this ID uniquely * identifies a buffer. When a buffer is sent to HAL for the first time, * both bufferId and buffer handle must be filled. HAL must keep track of * the mapping between bufferId and corresponding buffer until the * corresponding stream is removed from stream configuration or until camera * device session is closed. After the first time a buffer is introduced to * HAL, in the future camera service must refer to the same buffer using * only bufferId, and keep the buffer handle null. */ uint64_t bufferId; /** * The graphics buffer handle to the buffer. * * For StreamBuffers sent to the HAL in a CaptureRequest, this must be a * For StreamBuffers sent to the HAL in a CaptureRequest, if the bufferId * is not seen by the HAL before, this buffer handle is guaranteed to be a * valid handle to a graphics buffer, with dimensions and format matching * that of the stream. * that of the stream. If the bufferId has been sent to the HAL before, this * buffer handle must be null and HAL must look up the actual buffer handle * to use from its own bufferId to buffer handle map. * * For StreamBuffers returned in a CaptureResult, this must be null, since * the handle to the buffer is already known to the client (since the client Loading