Use fmq for camera capture request.
Test: camera works.
Bug: 35788245 [Treble] Pass camera metadata using shared memory
Change-Id: I4a1585315bf448c8c57def2964237cae21bdbe03
diff --git a/camera/device/3.2/ICameraDevice.hal b/camera/device/3.2/ICameraDevice.hal
index 6e66bf3..1f523e4 100644
--- a/camera/device/3.2/ICameraDevice.hal
+++ b/camera/device/3.2/ICameraDevice.hal
@@ -167,7 +167,7 @@
* longer available. This interface is now stale, and a new instance
* must be acquired if the device is reconnected. All subsequent
* calls on this interface must return CAMERA_DISCONNECTED.
- * @return cameraDevice The interface to the newly-opened camera session,
+ * @return session The interface to the newly-opened camera session,
* or null if status is not OK.
*/
open(ICameraDeviceCallback callback) generates
diff --git a/camera/device/3.2/ICameraDeviceSession.hal b/camera/device/3.2/ICameraDeviceSession.hal
index 731fc76..bf56881 100644
--- a/camera/device/3.2/ICameraDeviceSession.hal
+++ b/camera/device/3.2/ICameraDeviceSession.hal
@@ -248,6 +248,21 @@
generates (Status status, uint32_t numRequestProcessed);
/**
+ * getCaptureRequestMetadataQueue:
+ *
+ * Retrieves the queue used along with processCaptureRequest. If
+ * client decides to use fast message queue to pass request metadata,
+ * it must:
+ * - Call getCaptureRequestMetadataQueue to retrieve the fast message queue;
+ * - In each of the requests sent in processCaptureRequest, set
+ * fmqSettingsSize field of CaptureRequest to be the size to read from the
+ * fast message queue; leave settings field of CaptureRequest empty.
+ *
+ * @return queue the queue that client writes request metadata to.
+ */
+ getCaptureRequestMetadataQueue() generates (fmq_sync<uint8_t> queue);
+
+ /**
* flush:
*
* Flush all currently in-process captures and all buffers in the pipeline
diff --git a/camera/device/3.2/default/Android.bp b/camera/device/3.2/default/Android.bp
index e0dc5ff..d95f8f4 100644
--- a/camera/device/3.2/default/Android.bp
+++ b/camera/device/3.2/default/Android.bp
@@ -14,10 +14,14 @@
"android.hardware.camera.provider@2.4",
"liblog",
"libhardware",
- "libcamera_metadata"
+ "libcamera_metadata",
+ "libfmq"
],
static_libs: [
"android.hardware.camera.common@1.0-helper"
],
- export_include_dirs: ["."]
+ export_include_dirs: ["."],
+ export_shared_lib_headers: [
+ "libfmq",
+ ]
}
diff --git a/camera/device/3.2/default/CameraDeviceSession.cpp b/camera/device/3.2/default/CameraDeviceSession.cpp
index 5bb53c7..ebb8fcb 100644
--- a/camera/device/3.2/default/CameraDeviceSession.cpp
+++ b/camera/device/3.2/default/CameraDeviceSession.cpp
@@ -30,6 +30,9 @@
namespace V3_2 {
namespace implementation {
+// Size of request metadata fast message queue. Change to 0 to always use hwbinder buffer.
+static constexpr size_t CAMERA_REQUEST_METADATA_QUEUE_SIZE = 1 << 20 /* 1MB */;
+
HandleImporter& CameraDeviceSession::sHandleImporter = HandleImporter::getInstance();
const int CameraDeviceSession::ResultBatcher::NOT_BATCHED;
@@ -66,6 +69,14 @@
mClosed = true;
return true;
}
+
+ mRequestMetadataQueue = std::make_unique<RequestMetadataQueue>(
+ CAMERA_REQUEST_METADATA_QUEUE_SIZE, false /* non blocking */);
+ if (!mRequestMetadataQueue->isValid()) {
+ ALOGE("%s: invalid fmq", __FUNCTION__);
+ return true;
+ }
+
return false;
}
@@ -699,6 +710,12 @@
}
}
+Return<void> CameraDeviceSession::getCaptureRequestMetadataQueue(
+ getCaptureRequestMetadataQueue_cb _hidl_cb) {
+ _hidl_cb(*mRequestMetadataQueue->getDesc());
+ return Void();
+}
+
Return<void> CameraDeviceSession::processCaptureRequest(
const hidl_vec<CaptureRequest>& requests,
const hidl_vec<BufferCache>& cachesToRemove,
@@ -731,7 +748,24 @@
camera3_capture_request_t halRequest;
halRequest.frame_number = request.frameNumber;
- bool converted = convertFromHidl(request.settings, &halRequest.settings);
+
+ bool converted = true;
+ CameraMetadata settingsFmq; // settings from FMQ
+ if (request.fmqSettingsSize > 0) {
+ // non-blocking read; client must write metadata before calling
+ // processOneCaptureRequest
+ settingsFmq.resize(request.fmqSettingsSize);
+ bool read = mRequestMetadataQueue->read(settingsFmq.data(), request.fmqSettingsSize);
+ if (read) {
+ converted = convertFromHidl(settingsFmq, &halRequest.settings);
+ } else {
+ ALOGE("%s: capture request settings metadata couldn't be read from fmq!", __FUNCTION__);
+ converted = false;
+ }
+ } else {
+ converted = convertFromHidl(request.settings, &halRequest.settings);
+ }
+
if (!converted) {
ALOGE("%s: capture request settings metadata is corrupt!", __FUNCTION__);
return Status::INTERNAL_ERROR;
diff --git a/camera/device/3.2/default/CameraDeviceSession.h b/camera/device/3.2/default/CameraDeviceSession.h
index 781056e..f59f503 100644
--- a/camera/device/3.2/default/CameraDeviceSession.h
+++ b/camera/device/3.2/default/CameraDeviceSession.h
@@ -17,19 +17,20 @@
#ifndef ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H
#define ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H
+#include <android/hardware/camera/device/3.2/ICameraDevice.h>
+#include <android/hardware/camera/device/3.2/ICameraDeviceSession.h>
+#include <fmq/MessageQueue.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <include/convert.h>
#include <deque>
#include <map>
#include <unordered_map>
-#include "hardware/camera_common.h"
-#include "hardware/camera3.h"
-#include "utils/Mutex.h"
-#include <android/hardware/camera/device/3.2/ICameraDevice.h>
-#include <android/hardware/camera/device/3.2/ICameraDeviceSession.h>
-#include <hidl/Status.h>
-#include <hidl/MQDescriptor.h>
-#include <include/convert.h>
-#include "HandleImporter.h"
#include "CameraMetadata.h"
+#include "HandleImporter.h"
+#include "hardware/camera3.h"
+#include "hardware/camera_common.h"
+#include "utils/Mutex.h"
namespace android {
namespace hardware {
@@ -44,6 +45,9 @@
using ::android::hardware::camera::device::V3_2::ICameraDeviceSession;
using ::android::hardware::camera::common::V1_0::Status;
using ::android::hardware::camera::common::V1_0::helper::HandleImporter;
+using ::android::hardware::kSynchronizedReadWrite;
+using ::android::hardware::MessageQueue;
+using ::android::hardware::MQDescriptorSync;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::hidl_vec;
@@ -84,6 +88,8 @@
RequestTemplate type, constructDefaultRequestSettings_cb _hidl_cb) override;
Return<void> configureStreams(
const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) override;
+ Return<void> getCaptureRequestMetadataQueue(
+ getCaptureRequestMetadataQueue_cb _hidl_cb) override;
Return<void> processCaptureRequest(
const hidl_vec<CaptureRequest>& requests,
const hidl_vec<BufferCache>& cachesToRemove,
@@ -126,6 +132,9 @@
common::V1_0::helper::CameraMetadata mDeviceInfo;
+ using RequestMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+ std::unique_ptr<RequestMetadataQueue> mRequestMetadataQueue;
+
class ResultBatcher {
public:
ResultBatcher(const sp<ICameraDeviceCallback>& callback);
diff --git a/camera/device/3.2/types.hal b/camera/device/3.2/types.hal
index 1632570..8e433f6 100644
--- a/camera/device/3.2/types.hal
+++ b/camera/device/3.2/types.hal
@@ -753,11 +753,22 @@
uint32_t frameNumber;
/**
- * The settings buffer contains the capture and processing parameters for
+ * If non-zero, read settings from request queue instead
+ * (see ICameraDeviceSession.getCaptureRequestMetadataQueue).
+ * If zero, read settings from .settings field.
+ */
+ uint64_t fmqSettingsSize;
+
+ /**
+ * If fmqSettingsSize is zero,
+ * the settings buffer contains the capture and processing parameters for
* the request. As a special case, an empty settings buffer indicates that
* the settings are identical to the most-recently submitted capture
* request. A empty buffer cannot be used as the first submitted request
* after a configureStreams() call.
+ *
+ * This field must be used if fmqSettingsSize is zero. It must not be used
+ * if fmqSettingsSize is non-zero.
*/
CameraMetadata settings;