Camera: add batching support
Currently only batching high speed recording request/results.
Test: GCA slow motion recording working
Bug: 34899394
Change-Id: Id83b9d1cefe011391c86a5e7e898262a169cc9e7
diff --git a/camera/device/3.2/default/CameraDeviceSession.h b/camera/device/3.2/default/CameraDeviceSession.h
index 3786e4b..8923c05 100644
--- a/camera/device/3.2/default/CameraDeviceSession.h
+++ b/camera/device/3.2/default/CameraDeviceSession.h
@@ -17,6 +17,8 @@
#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"
@@ -27,6 +29,7 @@
#include <hidl/MQDescriptor.h>
#include <include/convert.h>
#include "HandleImporter.h"
+#include "CameraMetadata.h"
namespace android {
namespace hardware {
@@ -64,7 +67,9 @@
struct CameraDeviceSession : public ICameraDeviceSession, private camera3_callback_ops {
- CameraDeviceSession(camera3_device_t*, const sp<ICameraDeviceCallback>&);
+ CameraDeviceSession(camera3_device_t*,
+ const camera_metadata_t* deviceInfo,
+ const sp<ICameraDeviceCallback>&);
~CameraDeviceSession();
// Call by CameraDevice to dump active device states
void dumpState(const native_handle_t* fd);
@@ -75,9 +80,12 @@
bool isClosed();
// Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow.
- Return<void> constructDefaultRequestSettings(RequestTemplate type, constructDefaultRequestSettings_cb _hidl_cb) override;
- Return<void> configureStreams(const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) override;
- Return<Status> processCaptureRequest(const CaptureRequest& request) override;
+ Return<void> constructDefaultRequestSettings(
+ RequestTemplate type, constructDefaultRequestSettings_cb _hidl_cb) override;
+ Return<void> configureStreams(
+ const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) override;
+ Return<void> processCaptureRequest(
+ const hidl_vec<CaptureRequest>& requests, processCaptureRequest_cb _hidl_cb) override;
Return<Status> flush() override;
Return<void> close() override;
@@ -94,7 +102,6 @@
bool mDisconnected = false;
camera3_device_t* mDevice;
- const sp<ICameraDeviceCallback> mCallback;
// Stream ID -> Camera3Stream cache
std::map<int, Camera3Stream> mStreamMap;
@@ -114,6 +121,104 @@
static HandleImporter& sHandleImporter;
bool mInitFail;
+
+ common::V1_0::helper::CameraMetadata mDeviceInfo;
+
+ class ResultBatcher {
+ public:
+ ResultBatcher(const sp<ICameraDeviceCallback>& callback);
+ void setNumPartialResults(uint32_t n);
+ void setBatchedStreams(const std::vector<int>& streamsToBatch);
+
+ void registerBatch(const hidl_vec<CaptureRequest>& requests);
+ void notify(NotifyMsg& msg);
+ void processCaptureResult(CaptureResult& result);
+
+ private:
+ struct InflightBatch {
+ // Protect access to entire struct. Acquire this lock before read/write any data or
+ // calling any methods. processCaptureResult and notify will compete for this lock
+ // HIDL IPCs might be issued while the lock is held
+ Mutex mLock;
+
+ bool allDelivered() const;
+
+ uint32_t mFirstFrame;
+ uint32_t mLastFrame;
+ uint32_t mBatchSize;
+
+ bool mShutterDelivered = false;
+ std::vector<NotifyMsg> mShutterMsgs;
+
+ struct BufferBatch {
+ bool mDelivered = false;
+ // This currently assumes every batched request will output to the batched stream
+ // and since HAL must always send buffers in order, no frameNumber tracking is
+ // needed
+ std::vector<StreamBuffer> mBuffers;
+ };
+ // Stream ID -> VideoBatch
+ std::unordered_map<int, BufferBatch> mBatchBufs;
+
+ struct MetadataBatch {
+ // (frameNumber, metadata)
+ std::vector<std::pair<uint32_t, CameraMetadata>> mMds;
+ };
+ // Partial result IDs that has been delivered to framework
+ uint32_t mNumPartialResults;
+ uint32_t mPartialResultProgress = 0;
+ // partialResult -> MetadataBatch
+ std::map<uint32_t, MetadataBatch> mResultMds;
+
+ // Set to true when batch is removed from mInflightBatches
+ // processCaptureResult and notify must check this flag after acquiring mLock to make
+ // sure this batch isn't removed while waiting for mLock
+ bool mRemoved = false;
+ };
+
+ static const int NOT_BATCHED = -1;
+
+ // Get the batch index and pointer to InflightBatch (nullptrt if the frame is not batched)
+ // Caller must acquire the InflightBatch::mLock before accessing the InflightBatch
+ // It's possible that the InflightBatch is removed from mInflightBatches before the
+ // InflightBatch::mLock is acquired (most likely caused by an error notification), so
+ // caller must check InflightBatch::mRemoved flag after the lock is acquried.
+ // This method will hold ResultBatcher::mLock briefly
+ std::pair<int, std::shared_ptr<InflightBatch>> getBatch(uint32_t frameNumber);
+
+ // Check if the first batch in mInflightBatches is ready to be removed, and remove it if so
+ // This method will hold ResultBatcher::mLock briefly
+ void checkAndRemoveFirstBatch();
+
+ // The following sendXXXX methods must be called while the InflightBatch::mLock is locked
+ // HIDL IPC methods will be called during these methods.
+ void sendBatchShutterCbsLocked(std::shared_ptr<InflightBatch> batch);
+ // send buffers for all batched streams
+ void sendBatchBuffersLocked(std::shared_ptr<InflightBatch> batch);
+ // send buffers for specified streams
+ void sendBatchBuffersLocked(
+ std::shared_ptr<InflightBatch> batch, const std::vector<int>& streams);
+ void sendBatchMetadataLocked(
+ std::shared_ptr<InflightBatch> batch, uint32_t lastPartialResultIdx);
+ // End of sendXXXX methods
+
+ // helper methods
+ void freeReleaseFences(hidl_vec<CaptureResult>&);
+ void notifySingleMsg(NotifyMsg& msg);
+ void processOneCaptureResult(CaptureResult& result);
+
+ // Protect access to mInflightBatches, mNumPartialResults and mStreamsToBatch
+ // processCaptureRequest, processCaptureResult, notify will compete for this lock
+ // Do NOT issue HIDL IPCs while holding this lock (except when HAL reports error)
+ mutable Mutex mLock;
+ std::deque<std::shared_ptr<InflightBatch>> mInflightBatches;
+ uint32_t mNumPartialResults;
+ std::vector<int> mStreamsToBatch;
+ const sp<ICameraDeviceCallback> mCallback;
+ } mResultBatcher;
+
+ std::vector<int> mVideoStreamIds;
+
bool initialize();
Status initStatus() const;
@@ -129,6 +234,7 @@
void cleanupBuffersLocked(int id);
+ Status processOneCaptureRequest(const CaptureRequest& request);
/**
* Static callback forwarding methods from HAL to instance
*/