External: Switch to legacy V4L2 buffer mapping
Required for older kernels like 3.x
Change-Id: I0680320b606727bdb0b22dab1df8c5954d623f10
diff --git a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
index e8982e5..51bfe36 100644
--- a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
+++ b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
@@ -611,7 +611,12 @@
}
}
}
- 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 @@
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 @@
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 @@
{
std::unique_lock<std::mutex> 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 @@
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 @@
}
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<V4L2Frame>& frame) {
@@ -2243,7 +2244,7 @@
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 124f0bd..212573a 100644
--- a/camera/device/3.4/default/ExternalCameraUtils.cpp
+++ b/camera/device/3.4/default/ExternalCameraUtils.cpp
@@ -40,9 +40,9 @@
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 @@
std::lock_guard<std::mutex> 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 e1e1198..fabf26a 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 @@
bool mV4l2Streaming = false;
SupportedV4L2Format mV4l2StreamingFmt;
- std::vector<unique_fd> 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 562dacf..849f947 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 @@
// 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 @@
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;
};