Camera: HAL1 recording batching support

Test: Angler HAL1 + batching normal recording mode
Bug: 35997432
Change-Id: If088715ccdb40163f44150c16deed62432692c07
diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp b/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
index b52c0d8..9c058bc 100644
--- a/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
+++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
@@ -193,6 +193,36 @@
     return hardware::Void();
 }
 
+hardware::Return<void> CameraHardwareInterface::handleCallbackTimestampBatch(
+        DataCallbackMsg msgType,
+        const hardware::hidl_vec<hardware::camera::device::V1_0::HandleTimestampMessage>& messages) {
+    std::vector<android::HandleTimestampMessage> msgs;
+    msgs.reserve(messages.size());
+
+    for (const auto& hidl_msg : messages) {
+        if (mHidlMemPoolMap.count(hidl_msg.data) == 0) {
+            ALOGE("%s: memory pool ID %d not found", __FUNCTION__, hidl_msg.data);
+            return hardware::Void();
+        }
+        sp<CameraHeapMemory> mem(
+                static_cast<CameraHeapMemory *>(mHidlMemPoolMap.at(hidl_msg.data)->handle));
+
+        if (hidl_msg.bufferIndex >= mem->mNumBufs) {
+            ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
+                 hidl_msg.bufferIndex, mem->mNumBufs);
+            return hardware::Void();
+        }
+        VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
+                mem->mBuffers[hidl_msg.bufferIndex]->pointer();
+        md->pHandle = const_cast<native_handle_t*>(hidl_msg.frameData.getNativeHandle());
+
+        msgs.push_back({hidl_msg.timestamp, mem->mBuffers[hidl_msg.bufferIndex]});
+    }
+
+    mDataCbTimestampBatch((int32_t) msgType, msgs, mCbUser);
+    return hardware::Void();
+}
+
 std::pair<bool, uint64_t> CameraHardwareInterface::getBufferId(
         ANativeWindowBuffer* anb) {
     std::lock_guard<std::mutex> lock(mBufferIdMapLock);
@@ -468,11 +498,13 @@
 void CameraHardwareInterface::setCallbacks(notify_callback notify_cb,
         data_callback data_cb,
         data_callback_timestamp data_cb_timestamp,
+        data_callback_timestamp_batch data_cb_timestamp_batch,
         void* user)
 {
     mNotifyCb = notify_cb;
     mDataCb = data_cb;
     mDataCbTimestamp = data_cb_timestamp;
+    mDataCbTimestampBatch = data_cb_timestamp_batch;
     mCbUser = user;
 
     ALOGV("%s(%s)", __FUNCTION__, mName.string());
@@ -628,6 +660,44 @@
     }
 }
 
+void CameraHardwareInterface::releaseRecordingFrameBatch(const std::vector<sp<IMemory>>& frames)
+{
+    ALOGV("%s(%s)", __FUNCTION__, mName.string());
+    size_t n = frames.size();
+    std::vector<VideoFrameMessage> msgs;
+    msgs.reserve(n);
+    for (auto& mem : frames) {
+        if (CC_LIKELY(mHidlDevice != nullptr)) {
+            ssize_t offset;
+            size_t size;
+            sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
+            if (size == sizeof(VideoNativeHandleMetadata)) {
+                uint32_t heapId = heap->getHeapID();
+                uint32_t bufferIndex = offset / size;
+                VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) mem->pointer();
+                // Caching the handle here because md->pHandle will be subject to HAL's edit
+                native_handle_t* nh = md->pHandle;
+                VideoFrameMessage msg;
+                msgs.push_back({nh, heapId, bufferIndex});
+            } else {
+                ALOGE("%s only supports VideoNativeHandleMetadata mode", __FUNCTION__);
+                return;
+            }
+        } else {
+            ALOGE("Non HIDL mode do not support %s", __FUNCTION__);
+            return;
+        }
+    }
+
+    mHidlDevice->releaseRecordingFrameHandleBatch(msgs);
+
+    for (auto& msg : msgs) {
+        native_handle_t* nh = const_cast<native_handle_t*>(msg.frameData.getNativeHandle());
+        native_handle_close(nh);
+        native_handle_delete(nh);
+    }
+}
+
 status_t CameraHardwareInterface::autoFocus()
 {
     ALOGV("%s(%s)", __FUNCTION__, mName.string());
diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.h b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
index 88ab2e9..c2b0e9c 100644
--- a/services/camera/libcameraservice/device1/CameraHardwareInterface.h
+++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
@@ -48,6 +48,15 @@
                             const sp<IMemory> &dataPtr,
                             void *user);
 
+struct HandleTimestampMessage {
+    nsecs_t timestamp;
+    const sp<IMemory> dataPtr;
+};
+
+typedef void (*data_callback_timestamp_batch)(
+        int32_t msgType,
+        const std::vector<HandleTimestampMessage>&, void* user);
+
 /**
  * CameraHardwareInterface.h defines the interface to the
  * camera hardware abstraction layer, used for setting and getting
@@ -112,6 +121,7 @@
     void setCallbacks(notify_callback notify_cb,
                       data_callback data_cb,
                       data_callback_timestamp data_cb_timestamp,
+                      data_callback_timestamp_batch data_cb_timestamp_batch,
                       void* user);
 
     /**
@@ -227,6 +237,20 @@
     void releaseRecordingFrame(const sp<IMemory>& mem);
 
     /**
+     * Release a batch of recording frames previously returned by
+     * CAMERA_MSG_VIDEO_FRAME. This method only supports frames that are
+     * stored as VideoNativeHandleMetadata.
+     *
+     * It is camera hal client's responsibility to release video recording
+     * frames sent out by the camera hal before the camera hal receives
+     * a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME). After it receives
+     * the call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is camera hal's
+     * responsibility of managing the life-cycle of the video recording
+     * frames.
+     */
+    void releaseRecordingFrameBatch(const std::vector<sp<IMemory>>& frames);
+
+    /**
      * Start auto focus, the notification callback routine is called
      * with CAMERA_MSG_FOCUS once when focusing is complete. autoFocus()
      * will be called again if another auto focus is needed.
@@ -416,6 +440,10 @@
             hardware::camera::device::V1_0::DataCallbackMsg msgType,
             const hardware::hidl_handle& frameData, uint32_t data,
             uint32_t bufferIndex, int64_t timestamp) override;
+    hardware::Return<void> handleCallbackTimestampBatch(
+            hardware::camera::device::V1_0::DataCallbackMsg msgType,
+            const hardware::hidl_vec<
+                    hardware::camera::device::V1_0::HandleTimestampMessage>&) override;
 
     /**
      * Implementation of android::hardware::camera::device::V1_0::ICameraDevicePreviewCallback
@@ -450,9 +478,10 @@
 
     struct camera_preview_window mHalPreviewWindow;
 
-    notify_callback         mNotifyCb;
-    data_callback           mDataCb;
-    data_callback_timestamp mDataCbTimestamp;
+    notify_callback               mNotifyCb;
+    data_callback                 mDataCb;
+    data_callback_timestamp       mDataCbTimestamp;
+    data_callback_timestamp_batch mDataCbTimestampBatch;
     void *mCbUser;
 
     // Cached values for preview stream parameters