diff --git a/camera/device/3.2/ICameraDevice.hal b/camera/device/3.2/ICameraDevice.hal index 6e66bf31ad..1f523e420d 100644 --- a/camera/device/3.2/ICameraDevice.hal +++ b/camera/device/3.2/ICameraDevice.hal @@ -167,7 +167,7 @@ interface ICameraDevice { * 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 731fc764aa..bf568813ba 100644 --- a/camera/device/3.2/ICameraDeviceSession.hal +++ b/camera/device/3.2/ICameraDeviceSession.hal @@ -247,6 +247,21 @@ interface ICameraDeviceSession { vec cachesToRemove) 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 queue); + /** * flush: * diff --git a/camera/device/3.2/default/Android.bp b/camera/device/3.2/default/Android.bp index e0dc5ff410..d95f8f4e8b 100644 --- a/camera/device/3.2/default/Android.bp +++ b/camera/device/3.2/default/Android.bp @@ -14,10 +14,14 @@ cc_library_shared { "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 5bb53c7d5f..ebb8fcb735 100644 --- a/camera/device/3.2/default/CameraDeviceSession.cpp +++ b/camera/device/3.2/default/CameraDeviceSession.cpp @@ -30,6 +30,9 @@ namespace device { 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 @@ bool CameraDeviceSession::initialize() { mClosed = true; return true; } + + mRequestMetadataQueue = std::make_unique( + CAMERA_REQUEST_METADATA_QUEUE_SIZE, false /* non blocking */); + if (!mRequestMetadataQueue->isValid()) { + ALOGE("%s: invalid fmq", __FUNCTION__); + return true; + } + return false; } @@ -699,6 +710,12 @@ void CameraDeviceSession::updateBufferCaches(const hidl_vec& caches } } +Return CameraDeviceSession::getCaptureRequestMetadataQueue( + getCaptureRequestMetadataQueue_cb _hidl_cb) { + _hidl_cb(*mRequestMetadataQueue->getDesc()); + return Void(); +} + Return CameraDeviceSession::processCaptureRequest( const hidl_vec& requests, const hidl_vec& cachesToRemove, @@ -731,7 +748,24 @@ Status CameraDeviceSession::processOneCaptureRequest(const CaptureRequest& reque 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 781056eb3b..f59f503b9a 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 +#include +#include +#include +#include +#include #include #include #include -#include "hardware/camera_common.h" -#include "hardware/camera3.h" -#include "utils/Mutex.h" -#include -#include -#include -#include -#include -#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::StreamConfiguration; 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 @@ struct CameraDeviceSession : public ICameraDeviceSession, private camera3_callba RequestTemplate type, constructDefaultRequestSettings_cb _hidl_cb) override; Return configureStreams( const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) override; + Return getCaptureRequestMetadataQueue( + getCaptureRequestMetadataQueue_cb _hidl_cb) override; Return processCaptureRequest( const hidl_vec& requests, const hidl_vec& cachesToRemove, @@ -126,6 +132,9 @@ private: common::V1_0::helper::CameraMetadata mDeviceInfo; + using RequestMetadataQueue = MessageQueue; + std::unique_ptr mRequestMetadataQueue; + class ResultBatcher { public: ResultBatcher(const sp& callback); diff --git a/camera/device/3.2/types.hal b/camera/device/3.2/types.hal index 1632570953..8e433f62b1 100644 --- a/camera/device/3.2/types.hal +++ b/camera/device/3.2/types.hal @@ -753,11 +753,22 @@ struct CaptureRequest { 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; diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp index e37f989c58..b7ce858f2a 100644 --- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp +++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp @@ -2493,7 +2493,7 @@ TEST_F(CameraHidlTest, processCaptureRequestPreview) { outputBuffer}; StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr}; - CaptureRequest request = {frameNumber, settings, + CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings, emptyInputBuffer, outputBuffers}; { @@ -2599,7 +2599,7 @@ TEST_F(CameraHidlTest, processCaptureRequestInvalidSinglePreview) { outputBuffer}; StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr}; - CaptureRequest request = {frameNumber, settings, + CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings, emptyInputBuffer, outputBuffers}; //Settings were not correctly initialized, we should fail here @@ -2654,7 +2654,7 @@ TEST_F(CameraHidlTest, processCaptureRequestInvalidBuffer) { ::android::hardware::hidl_vec emptyOutputBuffers; StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr}; - CaptureRequest request = {frameNumber, settings, + CaptureRequest request = {frameNumber, 0/* fmqSettingsSize */, settings, emptyInputBuffer, emptyOutputBuffers}; //Output buffers are missing, we should fail here @@ -2719,7 +2719,7 @@ TEST_F(CameraHidlTest, flushPreviewRequest) { outputBuffer}; const StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr}; - CaptureRequest request = {frameNumber, settings, + CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings, emptyInputBuffer, outputBuffers}; {