blob: bbf39e60e539c07367c930f28a55a31f5c7f7620 [file] [log] [blame]
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H
18#define ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H
19
Yifan Hong1192e1d2017-04-11 14:45:00 -070020#include <android/hardware/camera/device/3.2/ICameraDevice.h>
21#include <android/hardware/camera/device/3.2/ICameraDeviceSession.h>
22#include <fmq/MessageQueue.h>
23#include <hidl/MQDescriptor.h>
24#include <hidl/Status.h>
25#include <include/convert.h>
Yin-Chia Yehbed3a942017-03-06 14:14:17 -080026#include <deque>
27#include <map>
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -080028#include <unordered_map>
Yin-Chia Yehbed3a942017-03-06 14:14:17 -080029#include "CameraMetadata.h"
Yifan Hong1192e1d2017-04-11 14:45:00 -070030#include "HandleImporter.h"
31#include "hardware/camera3.h"
32#include "hardware/camera_common.h"
33#include "utils/Mutex.h"
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -070034
35namespace android {
36namespace hardware {
37namespace camera {
38namespace device {
39namespace V3_2 {
40namespace implementation {
41
42using ::android::hardware::camera::device::V3_2::CaptureRequest;
43using ::android::hardware::camera::device::V3_2::HalStreamConfiguration;
44using ::android::hardware::camera::device::V3_2::StreamConfiguration;
45using ::android::hardware::camera::device::V3_2::ICameraDeviceSession;
46using ::android::hardware::camera::common::V1_0::Status;
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080047using ::android::hardware::camera::common::V1_0::helper::HandleImporter;
Yifan Hong1192e1d2017-04-11 14:45:00 -070048using ::android::hardware::kSynchronizedReadWrite;
49using ::android::hardware::MessageQueue;
50using ::android::hardware::MQDescriptorSync;
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -070051using ::android::hardware::Return;
52using ::android::hardware::Void;
53using ::android::hardware::hidl_vec;
54using ::android::hardware::hidl_string;
55using ::android::sp;
56using ::android::Mutex;
57
58/**
59 * Function pointer types with C calling convention to
60 * use for HAL callback functions.
61 */
62extern "C" {
63 typedef void (callbacks_process_capture_result_t)(
64 const struct camera3_callback_ops *,
65 const camera3_capture_result_t *);
66
67 typedef void (callbacks_notify_t)(
68 const struct camera3_callback_ops *,
69 const camera3_notify_msg_t *);
70}
71
72struct CameraDeviceSession : public ICameraDeviceSession, private camera3_callback_ops {
73
Yin-Chia Yehbed3a942017-03-06 14:14:17 -080074 CameraDeviceSession(camera3_device_t*,
75 const camera_metadata_t* deviceInfo,
76 const sp<ICameraDeviceCallback>&);
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -070077 ~CameraDeviceSession();
78 // Call by CameraDevice to dump active device states
79 void dumpState(const native_handle_t* fd);
80 // Caller must use this method to check if CameraDeviceSession ctor failed
81 bool isInitFailed() { return mInitFail; }
82 // Used by CameraDevice to signal external camera disconnected
83 void disconnect();
84 bool isClosed();
85
86 // Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow.
Yin-Chia Yehbed3a942017-03-06 14:14:17 -080087 Return<void> constructDefaultRequestSettings(
88 RequestTemplate type, constructDefaultRequestSettings_cb _hidl_cb) override;
89 Return<void> configureStreams(
90 const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) override;
Yifan Hong1192e1d2017-04-11 14:45:00 -070091 Return<void> getCaptureRequestMetadataQueue(
92 getCaptureRequestMetadataQueue_cb _hidl_cb) override;
Yifan Hong993e3d02017-04-12 16:31:23 -070093 Return<void> getCaptureResultMetadataQueue(
94 getCaptureResultMetadataQueue_cb _hidl_cb) override;
Yin-Chia Yehbed3a942017-03-06 14:14:17 -080095 Return<void> processCaptureRequest(
Yin-Chia Yeh28eebbf2017-03-30 15:06:20 -070096 const hidl_vec<CaptureRequest>& requests,
97 const hidl_vec<BufferCache>& cachesToRemove,
98 processCaptureRequest_cb _hidl_cb) override;
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -070099 Return<Status> flush() override;
100 Return<void> close() override;
101
102private:
103 // protecting mClosed/mDisconnected/mInitFail
104 mutable Mutex mStateLock;
105 // device is closed either
106 // - closed by user
107 // - init failed
108 // - camera disconnected
109 bool mClosed = false;
110
111 // Set by CameraDevice (when external camera is disconnected)
112 bool mDisconnected = false;
113
Emilian Peevcf581372017-04-07 13:53:10 +0100114 struct AETriggerCancelOverride {
115 bool applyAeLock;
116 uint8_t aeLock;
117 bool applyAePrecaptureTrigger;
118 uint8_t aePrecaptureTrigger;
119 };
120
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700121 camera3_device_t* mDevice;
Emilian Peev7d52a6f2017-04-07 09:53:48 +0100122 uint32_t mDeviceVersion;
Emilian Peevcf581372017-04-07 13:53:10 +0100123 bool mIsAELockAvailable;
Emilian Peeva13ac992017-04-10 12:02:17 +0100124 bool mDerivePostRawSensKey;
Emilian Peevcf581372017-04-07 13:53:10 +0100125 uint32_t mNumPartialResults;
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700126 // Stream ID -> Camera3Stream cache
127 std::map<int, Camera3Stream> mStreamMap;
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800128
129 mutable Mutex mInflightLock; // protecting mInflightBuffers and mCirculatingBuffers
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700130 // (streamID, frameNumber) -> inflight buffer cache
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800131 std::map<std::pair<int, uint32_t>, camera3_stream_buffer_t> mInflightBuffers;
132
Emilian Peevcf581372017-04-07 13:53:10 +0100133 // (frameNumber, AETriggerOverride) -> inflight request AETriggerOverrides
134 std::map<uint32_t, AETriggerCancelOverride> mInflightAETriggerOverrides;
135 ::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenResult;
Emilian Peeva13ac992017-04-10 12:02:17 +0100136 std::map<uint32_t, bool> mInflightRawBoostPresent;
137 ::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenRequest;
Emilian Peevcf581372017-04-07 13:53:10 +0100138
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800139 // buffers currently ciculating between HAL and camera service
Yin-Chia Yehd926f932017-01-09 15:21:11 -0800140 // key: bufferId sent via HIDL interface
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800141 // value: imported buffer_handle_t
142 // Buffer will be imported during process_capture_request and will be freed
143 // when the its stream is deleted or camera device session is closed
Yin-Chia Yehd926f932017-01-09 15:21:11 -0800144 typedef std::unordered_map<uint64_t, buffer_handle_t> CirculatingBuffers;
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800145 // Stream ID -> circulating buffers map
146 std::map<int, CirculatingBuffers> mCirculatingBuffers;
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700147
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800148 static HandleImporter& sHandleImporter;
149
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700150 bool mInitFail;
Yin-Chia Yehbed3a942017-03-06 14:14:17 -0800151
152 common::V1_0::helper::CameraMetadata mDeviceInfo;
153
Yifan Hong1192e1d2017-04-11 14:45:00 -0700154 using RequestMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
155 std::unique_ptr<RequestMetadataQueue> mRequestMetadataQueue;
Yifan Hong993e3d02017-04-12 16:31:23 -0700156 using ResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
157 std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue;
Yifan Hong1192e1d2017-04-11 14:45:00 -0700158
Yin-Chia Yehbed3a942017-03-06 14:14:17 -0800159 class ResultBatcher {
160 public:
161 ResultBatcher(const sp<ICameraDeviceCallback>& callback);
162 void setNumPartialResults(uint32_t n);
163 void setBatchedStreams(const std::vector<int>& streamsToBatch);
Yifan Hong993e3d02017-04-12 16:31:23 -0700164 void setResultMetadataQueue(std::shared_ptr<ResultMetadataQueue> q);
Yin-Chia Yehbed3a942017-03-06 14:14:17 -0800165
166 void registerBatch(const hidl_vec<CaptureRequest>& requests);
167 void notify(NotifyMsg& msg);
168 void processCaptureResult(CaptureResult& result);
169
170 private:
171 struct InflightBatch {
172 // Protect access to entire struct. Acquire this lock before read/write any data or
173 // calling any methods. processCaptureResult and notify will compete for this lock
174 // HIDL IPCs might be issued while the lock is held
175 Mutex mLock;
176
177 bool allDelivered() const;
178
179 uint32_t mFirstFrame;
180 uint32_t mLastFrame;
181 uint32_t mBatchSize;
182
183 bool mShutterDelivered = false;
184 std::vector<NotifyMsg> mShutterMsgs;
185
186 struct BufferBatch {
187 bool mDelivered = false;
188 // This currently assumes every batched request will output to the batched stream
189 // and since HAL must always send buffers in order, no frameNumber tracking is
190 // needed
191 std::vector<StreamBuffer> mBuffers;
192 };
193 // Stream ID -> VideoBatch
194 std::unordered_map<int, BufferBatch> mBatchBufs;
195
196 struct MetadataBatch {
197 // (frameNumber, metadata)
198 std::vector<std::pair<uint32_t, CameraMetadata>> mMds;
199 };
200 // Partial result IDs that has been delivered to framework
201 uint32_t mNumPartialResults;
202 uint32_t mPartialResultProgress = 0;
203 // partialResult -> MetadataBatch
204 std::map<uint32_t, MetadataBatch> mResultMds;
205
206 // Set to true when batch is removed from mInflightBatches
207 // processCaptureResult and notify must check this flag after acquiring mLock to make
208 // sure this batch isn't removed while waiting for mLock
209 bool mRemoved = false;
210 };
211
212 static const int NOT_BATCHED = -1;
213
214 // Get the batch index and pointer to InflightBatch (nullptrt if the frame is not batched)
215 // Caller must acquire the InflightBatch::mLock before accessing the InflightBatch
216 // It's possible that the InflightBatch is removed from mInflightBatches before the
217 // InflightBatch::mLock is acquired (most likely caused by an error notification), so
218 // caller must check InflightBatch::mRemoved flag after the lock is acquried.
219 // This method will hold ResultBatcher::mLock briefly
220 std::pair<int, std::shared_ptr<InflightBatch>> getBatch(uint32_t frameNumber);
221
222 // Check if the first batch in mInflightBatches is ready to be removed, and remove it if so
223 // This method will hold ResultBatcher::mLock briefly
224 void checkAndRemoveFirstBatch();
225
226 // The following sendXXXX methods must be called while the InflightBatch::mLock is locked
227 // HIDL IPC methods will be called during these methods.
228 void sendBatchShutterCbsLocked(std::shared_ptr<InflightBatch> batch);
229 // send buffers for all batched streams
230 void sendBatchBuffersLocked(std::shared_ptr<InflightBatch> batch);
231 // send buffers for specified streams
232 void sendBatchBuffersLocked(
233 std::shared_ptr<InflightBatch> batch, const std::vector<int>& streams);
234 void sendBatchMetadataLocked(
235 std::shared_ptr<InflightBatch> batch, uint32_t lastPartialResultIdx);
236 // End of sendXXXX methods
237
238 // helper methods
239 void freeReleaseFences(hidl_vec<CaptureResult>&);
240 void notifySingleMsg(NotifyMsg& msg);
241 void processOneCaptureResult(CaptureResult& result);
Yifan Hong993e3d02017-04-12 16:31:23 -0700242 void invokeProcessCaptureResultCallback(hidl_vec<CaptureResult> &results, bool tryWriteFmq);
Yin-Chia Yehbed3a942017-03-06 14:14:17 -0800243
244 // Protect access to mInflightBatches, mNumPartialResults and mStreamsToBatch
245 // processCaptureRequest, processCaptureResult, notify will compete for this lock
246 // Do NOT issue HIDL IPCs while holding this lock (except when HAL reports error)
247 mutable Mutex mLock;
248 std::deque<std::shared_ptr<InflightBatch>> mInflightBatches;
249 uint32_t mNumPartialResults;
250 std::vector<int> mStreamsToBatch;
251 const sp<ICameraDeviceCallback> mCallback;
Yifan Hong993e3d02017-04-12 16:31:23 -0700252 std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue;
253
254 // Protect against invokeProcessCaptureResultCallback()
255 Mutex mProcessCaptureResultLock;
256
Yin-Chia Yehbed3a942017-03-06 14:14:17 -0800257 } mResultBatcher;
258
259 std::vector<int> mVideoStreamIds;
260
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700261 bool initialize();
262
263 Status initStatus() const;
264
265 // Validate and import request's input buffer and acquire fence
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800266 Status importRequest(
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700267 const CaptureRequest& request,
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800268 hidl_vec<buffer_handle_t*>& allBufPtrs,
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700269 hidl_vec<int>& allFences);
270
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800271 static void cleanupInflightFences(
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700272 hidl_vec<int>& allFences, size_t numFences);
273
Emilian Peev98014ff2017-02-02 16:20:12 +0000274 void cleanupBuffersLocked(int id);
275
Yin-Chia Yeh28eebbf2017-03-30 15:06:20 -0700276 void updateBufferCaches(const hidl_vec<BufferCache>& cachesToRemove);
277
Emilian Peev7d52a6f2017-04-07 09:53:48 +0100278 android_dataspace mapToLegacyDataspace(
279 android_dataspace dataSpace) const;
280
Emilian Peevcf581372017-04-07 13:53:10 +0100281 bool handleAePrecaptureCancelRequestLocked(
282 const camera3_capture_request_t &halRequest,
283 android::hardware::camera::common::V1_0::helper::CameraMetadata *settings /*out*/,
284 AETriggerCancelOverride *override /*out*/);
285
286 void overrideResultForPrecaptureCancelLocked(
287 const AETriggerCancelOverride &aeTriggerCancelOverride,
288 ::android::hardware::camera::common::V1_0::helper::CameraMetadata *settings /*out*/);
289
Yin-Chia Yehbed3a942017-03-06 14:14:17 -0800290 Status processOneCaptureRequest(const CaptureRequest& request);
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700291 /**
292 * Static callback forwarding methods from HAL to instance
293 */
294 static callbacks_process_capture_result_t sProcessCaptureResult;
295 static callbacks_notify_t sNotify;
296};
297
298} // namespace implementation
299} // namespace V3_2
300} // namespace device
301} // namespace camera
302} // namespace hardware
303} // namespace android
304
305#endif // ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H