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;
 };