OSDN Git Service

Use fmq for camera capture request.
authorYifan Hong <elsk@google.com>
Tue, 11 Apr 2017 21:45:00 +0000 (14:45 -0700)
committerYifan Hong <elsk@google.com>
Thu, 13 Apr 2017 20:25:29 +0000 (13:25 -0700)
Test: camera works.

Bug: 35788245 [Treble] Pass camera metadata using shared memory
Change-Id: I4a1585315bf448c8c57def2964237cae21bdbe03

camera/device/3.2/ICameraDevice.hal
camera/device/3.2/ICameraDeviceSession.hal
camera/device/3.2/default/Android.bp
camera/device/3.2/default/CameraDeviceSession.cpp
camera/device/3.2/default/CameraDeviceSession.h
camera/device/3.2/types.hal
camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp

index 6e66bf3..1f523e4 100644 (file)
@@ -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
index 731fc76..bf56881 100644 (file)
@@ -248,6 +248,21 @@ interface ICameraDeviceSession {
             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
index e0dc5ff..d95f8f4 100644 (file)
@@ -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",
+    ]
 }
index 5bb53c7..ebb8fcb 100644 (file)
@@ -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<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 @@ void CameraDeviceSession::updateBufferCaches(const hidl_vec<BufferCache>& caches
     }
 }
 
+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 @@ 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;
index 781056e..f59f503 100644 (file)
 #ifndef ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H
 #define ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_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 <fmq/MessageQueue.h>
 #include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
 #include <include/convert.h>
-#include "HandleImporter.h"
+#include <deque>
+#include <map>
+#include <unordered_map>
 #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<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 @@ private:
 
     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);
index 1632570..8e433f6 100644 (file)
@@ -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;
 
index e37f989..b7ce858 100644 (file)
@@ -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<StreamBuffer> 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};
 
             {