diff --git a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp index e8982e5975..51bfe3602b 100644 --- a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp +++ b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp @@ -611,7 +611,12 @@ void ExternalCameraDeviceSession::invokeProcessCaptureResultCallback( } } } - mCallback->processCaptureResult(results); + auto status = mCallback->processCaptureResult(results); + if (!status.isOk()) { + ALOGE("%s: processCaptureResult ERROR : %s", __FUNCTION__, + status.description().c_str()); + } + mProcessCaptureResultLock.unlock(); } @@ -1835,7 +1840,7 @@ int ExternalCameraDeviceSession::v4l2StreamOffLocked() { return -1; } } - mV4l2Buffers.clear(); // VIDIOC_REQBUFS will fail if FDs are not clear first + mV4L2BufferCount = 0; // VIDIOC_STREAMOFF v4l2_buf_type capture_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; @@ -1955,24 +1960,20 @@ int ExternalCameraDeviceSession::configureV4l2StreamLocked(const SupportedV4L2Fo return NO_MEMORY; } - // VIDIOC_EXPBUF: export buffers as FD + // VIDIOC_QUERYBUF: get buffer offset in the V4L2 fd // VIDIOC_QBUF: send buffer to driver - mV4l2Buffers.resize(req_buffers.count); + mV4L2BufferCount = req_buffers.count; for (uint32_t i = 0; i < req_buffers.count; i++) { - v4l2_exportbuffer expbuf {}; - expbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - expbuf.index = i; - if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_EXPBUF, &expbuf)) < 0) { - ALOGE("%s: EXPBUF %d failed: %s", __FUNCTION__, i, strerror(errno)); - return -errno; - } - mV4l2Buffers[i].reset(expbuf.fd); - v4l2_buffer buffer = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, .index = i, .memory = V4L2_MEMORY_MMAP}; + if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_QUERYBUF, &buffer)) < 0) { + ALOGE("%s: QUERYBUF %d failed: %s", __FUNCTION__, i, strerror(errno)); + return -errno; + } + if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_QBUF, &buffer)) < 0) { ALOGE("%s: QBUF %d failed: %s", __FUNCTION__, i, strerror(errno)); return -errno; @@ -2012,7 +2013,7 @@ sp ExternalCameraDeviceSession::dequeueV4l2FrameLocked() { { std::unique_lock lk(mV4l2BufferLock); - if (mNumDequeuedV4l2Buffers == mV4l2Buffers.size()) { + if (mNumDequeuedV4l2Buffers == mV4L2BufferCount) { std::chrono::seconds timeout = std::chrono::seconds(kBufferWaitTimeoutSec); mLock.unlock(); auto st = mV4L2BufferReturned.wait_for(lk, timeout); @@ -2032,7 +2033,7 @@ sp ExternalCameraDeviceSession::dequeueV4l2FrameLocked() { return ret; } - if (buffer.index >= mV4l2Buffers.size()) { + if (buffer.index >= mV4L2BufferCount) { ALOGE("%s: Invalid buffer id: %d", __FUNCTION__, buffer.index); return ret; } @@ -2048,7 +2049,7 @@ sp ExternalCameraDeviceSession::dequeueV4l2FrameLocked() { } return new V4L2Frame( mV4l2StreamingFmt.width, mV4l2StreamingFmt.height, mV4l2StreamingFmt.fourcc, - buffer.index, mV4l2Buffers[buffer.index].get(), buffer.bytesused); + buffer.index, mV4l2Fd.get(), buffer.bytesused, buffer.m.offset); } void ExternalCameraDeviceSession::enqueueV4l2Frame(const sp& frame) { @@ -2243,7 +2244,7 @@ Status ExternalCameraDeviceSession::configureStreams( BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CAMERA_OUTPUT; out->streams[i].v3_2.consumerUsage = 0; - out->streams[i].v3_2.maxBuffers = mV4l2Buffers.size(); + out->streams[i].v3_2.maxBuffers = mV4L2BufferCount; switch (config.streams[i].format) { case PixelFormat::BLOB: diff --git a/camera/device/3.4/default/ExternalCameraUtils.cpp b/camera/device/3.4/default/ExternalCameraUtils.cpp index 124f0bdbae..212573aa4f 100644 --- a/camera/device/3.4/default/ExternalCameraUtils.cpp +++ b/camera/device/3.4/default/ExternalCameraUtils.cpp @@ -40,9 +40,9 @@ const char* ExternalCameraDeviceConfig::kDefaultCfgPath = "/vendor/etc/external_ V4L2Frame::V4L2Frame( uint32_t w, uint32_t h, uint32_t fourcc, - int bufIdx, int fd, uint32_t dataSize) : + int bufIdx, int fd, uint32_t dataSize, uint64_t offset) : mWidth(w), mHeight(h), mFourcc(fourcc), - mBufferIndex(bufIdx), mFd(fd), mDataSize(dataSize) {} + mBufferIndex(bufIdx), mFd(fd), mDataSize(dataSize), mOffset(offset) {} int V4L2Frame::map(uint8_t** data, size_t* dataSize) { if (data == nullptr || dataSize == nullptr) { @@ -53,7 +53,7 @@ int V4L2Frame::map(uint8_t** data, size_t* dataSize) { std::lock_guard lk(mLock); if (!mMapped) { - void* addr = mmap(NULL, mDataSize, PROT_READ, MAP_SHARED, mFd, 0); + void* addr = mmap(NULL, mDataSize, PROT_READ, MAP_SHARED, mFd, mOffset); if (addr == MAP_FAILED) { ALOGE("%s: V4L2 buffer map failed: %s", __FUNCTION__, strerror(errno)); return -EINVAL; diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h index e1e1198f70..fabf26a3af 100644 --- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h +++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h @@ -293,7 +293,7 @@ protected: bool mV4l2Streaming = false; SupportedV4L2Format mV4l2StreamingFmt; - std::vector mV4l2Buffers; + size_t mV4L2BufferCount; static const int kBufferWaitTimeoutSec = 3; // TODO: handle long exposure (or not allowing) std::mutex mV4l2BufferLock; // protect the buffer count and condition below diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h index 562dacfda4..849f947143 100644 --- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h +++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h @@ -45,7 +45,8 @@ struct SupportedV4L2Format { // Also contains necessary information to enqueue the buffer back to V4L2 buffer queue class V4L2Frame : public virtual VirtualLightRefBase { public: - V4L2Frame(uint32_t w, uint32_t h, uint32_t fourcc, int bufIdx, int fd, uint32_t dataSize); + V4L2Frame(uint32_t w, uint32_t h, uint32_t fourcc, int bufIdx, int fd, + uint32_t dataSize, uint64_t offset); ~V4L2Frame() override; const uint32_t mWidth; const uint32_t mHeight; @@ -57,6 +58,7 @@ private: std::mutex mLock; const int mFd; // used for mmap but doesn't claim ownership const size_t mDataSize; + const uint64_t mOffset; // used for mmap uint8_t* mData = nullptr; bool mMapped = false; };