blob: 8923c05bcf89ea195e7a7ae0a0948f7333c8aa2c [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
Yin-Chia Yehbed3a942017-03-06 14:14:17 -080020#include <deque>
21#include <map>
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -080022#include <unordered_map>
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -070023#include "hardware/camera_common.h"
24#include "hardware/camera3.h"
25#include "utils/Mutex.h"
26#include <android/hardware/camera/device/3.2/ICameraDevice.h>
27#include <android/hardware/camera/device/3.2/ICameraDeviceSession.h>
28#include <hidl/Status.h>
29#include <hidl/MQDescriptor.h>
30#include <include/convert.h>
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080031#include "HandleImporter.h"
Yin-Chia Yehbed3a942017-03-06 14:14:17 -080032#include "CameraMetadata.h"
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -070033
34namespace android {
35namespace hardware {
36namespace camera {
37namespace device {
38namespace V3_2 {
39namespace implementation {
40
41using ::android::hardware::camera::device::V3_2::CaptureRequest;
42using ::android::hardware::camera::device::V3_2::HalStreamConfiguration;
43using ::android::hardware::camera::device::V3_2::StreamConfiguration;
44using ::android::hardware::camera::device::V3_2::ICameraDeviceSession;
45using ::android::hardware::camera::common::V1_0::Status;
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080046using ::android::hardware::camera::common::V1_0::helper::HandleImporter;
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -070047using ::android::hardware::Return;
48using ::android::hardware::Void;
49using ::android::hardware::hidl_vec;
50using ::android::hardware::hidl_string;
51using ::android::sp;
52using ::android::Mutex;
53
54/**
55 * Function pointer types with C calling convention to
56 * use for HAL callback functions.
57 */
58extern "C" {
59 typedef void (callbacks_process_capture_result_t)(
60 const struct camera3_callback_ops *,
61 const camera3_capture_result_t *);
62
63 typedef void (callbacks_notify_t)(
64 const struct camera3_callback_ops *,
65 const camera3_notify_msg_t *);
66}
67
68struct CameraDeviceSession : public ICameraDeviceSession, private camera3_callback_ops {
69
Yin-Chia Yehbed3a942017-03-06 14:14:17 -080070 CameraDeviceSession(camera3_device_t*,
71 const camera_metadata_t* deviceInfo,
72 const sp<ICameraDeviceCallback>&);
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -070073 ~CameraDeviceSession();
74 // Call by CameraDevice to dump active device states
75 void dumpState(const native_handle_t* fd);
76 // Caller must use this method to check if CameraDeviceSession ctor failed
77 bool isInitFailed() { return mInitFail; }
78 // Used by CameraDevice to signal external camera disconnected
79 void disconnect();
80 bool isClosed();
81
82 // Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow.
Yin-Chia Yehbed3a942017-03-06 14:14:17 -080083 Return<void> constructDefaultRequestSettings(
84 RequestTemplate type, constructDefaultRequestSettings_cb _hidl_cb) override;
85 Return<void> configureStreams(
86 const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) override;
87 Return<void> processCaptureRequest(
88 const hidl_vec<CaptureRequest>& requests, processCaptureRequest_cb _hidl_cb) override;
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -070089 Return<Status> flush() override;
90 Return<void> close() override;
91
92private:
93 // protecting mClosed/mDisconnected/mInitFail
94 mutable Mutex mStateLock;
95 // device is closed either
96 // - closed by user
97 // - init failed
98 // - camera disconnected
99 bool mClosed = false;
100
101 // Set by CameraDevice (when external camera is disconnected)
102 bool mDisconnected = false;
103
104 camera3_device_t* mDevice;
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700105 // Stream ID -> Camera3Stream cache
106 std::map<int, Camera3Stream> mStreamMap;
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800107
108 mutable Mutex mInflightLock; // protecting mInflightBuffers and mCirculatingBuffers
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700109 // (streamID, frameNumber) -> inflight buffer cache
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800110 std::map<std::pair<int, uint32_t>, camera3_stream_buffer_t> mInflightBuffers;
111
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800112 // buffers currently ciculating between HAL and camera service
Yin-Chia Yehd926f932017-01-09 15:21:11 -0800113 // key: bufferId sent via HIDL interface
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800114 // value: imported buffer_handle_t
115 // Buffer will be imported during process_capture_request and will be freed
116 // when the its stream is deleted or camera device session is closed
Yin-Chia Yehd926f932017-01-09 15:21:11 -0800117 typedef std::unordered_map<uint64_t, buffer_handle_t> CirculatingBuffers;
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800118 // Stream ID -> circulating buffers map
119 std::map<int, CirculatingBuffers> mCirculatingBuffers;
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700120
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800121 static HandleImporter& sHandleImporter;
122
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700123 bool mInitFail;
Yin-Chia Yehbed3a942017-03-06 14:14:17 -0800124
125 common::V1_0::helper::CameraMetadata mDeviceInfo;
126
127 class ResultBatcher {
128 public:
129 ResultBatcher(const sp<ICameraDeviceCallback>& callback);
130 void setNumPartialResults(uint32_t n);
131 void setBatchedStreams(const std::vector<int>& streamsToBatch);
132
133 void registerBatch(const hidl_vec<CaptureRequest>& requests);
134 void notify(NotifyMsg& msg);
135 void processCaptureResult(CaptureResult& result);
136
137 private:
138 struct InflightBatch {
139 // Protect access to entire struct. Acquire this lock before read/write any data or
140 // calling any methods. processCaptureResult and notify will compete for this lock
141 // HIDL IPCs might be issued while the lock is held
142 Mutex mLock;
143
144 bool allDelivered() const;
145
146 uint32_t mFirstFrame;
147 uint32_t mLastFrame;
148 uint32_t mBatchSize;
149
150 bool mShutterDelivered = false;
151 std::vector<NotifyMsg> mShutterMsgs;
152
153 struct BufferBatch {
154 bool mDelivered = false;
155 // This currently assumes every batched request will output to the batched stream
156 // and since HAL must always send buffers in order, no frameNumber tracking is
157 // needed
158 std::vector<StreamBuffer> mBuffers;
159 };
160 // Stream ID -> VideoBatch
161 std::unordered_map<int, BufferBatch> mBatchBufs;
162
163 struct MetadataBatch {
164 // (frameNumber, metadata)
165 std::vector<std::pair<uint32_t, CameraMetadata>> mMds;
166 };
167 // Partial result IDs that has been delivered to framework
168 uint32_t mNumPartialResults;
169 uint32_t mPartialResultProgress = 0;
170 // partialResult -> MetadataBatch
171 std::map<uint32_t, MetadataBatch> mResultMds;
172
173 // Set to true when batch is removed from mInflightBatches
174 // processCaptureResult and notify must check this flag after acquiring mLock to make
175 // sure this batch isn't removed while waiting for mLock
176 bool mRemoved = false;
177 };
178
179 static const int NOT_BATCHED = -1;
180
181 // Get the batch index and pointer to InflightBatch (nullptrt if the frame is not batched)
182 // Caller must acquire the InflightBatch::mLock before accessing the InflightBatch
183 // It's possible that the InflightBatch is removed from mInflightBatches before the
184 // InflightBatch::mLock is acquired (most likely caused by an error notification), so
185 // caller must check InflightBatch::mRemoved flag after the lock is acquried.
186 // This method will hold ResultBatcher::mLock briefly
187 std::pair<int, std::shared_ptr<InflightBatch>> getBatch(uint32_t frameNumber);
188
189 // Check if the first batch in mInflightBatches is ready to be removed, and remove it if so
190 // This method will hold ResultBatcher::mLock briefly
191 void checkAndRemoveFirstBatch();
192
193 // The following sendXXXX methods must be called while the InflightBatch::mLock is locked
194 // HIDL IPC methods will be called during these methods.
195 void sendBatchShutterCbsLocked(std::shared_ptr<InflightBatch> batch);
196 // send buffers for all batched streams
197 void sendBatchBuffersLocked(std::shared_ptr<InflightBatch> batch);
198 // send buffers for specified streams
199 void sendBatchBuffersLocked(
200 std::shared_ptr<InflightBatch> batch, const std::vector<int>& streams);
201 void sendBatchMetadataLocked(
202 std::shared_ptr<InflightBatch> batch, uint32_t lastPartialResultIdx);
203 // End of sendXXXX methods
204
205 // helper methods
206 void freeReleaseFences(hidl_vec<CaptureResult>&);
207 void notifySingleMsg(NotifyMsg& msg);
208 void processOneCaptureResult(CaptureResult& result);
209
210 // Protect access to mInflightBatches, mNumPartialResults and mStreamsToBatch
211 // processCaptureRequest, processCaptureResult, notify will compete for this lock
212 // Do NOT issue HIDL IPCs while holding this lock (except when HAL reports error)
213 mutable Mutex mLock;
214 std::deque<std::shared_ptr<InflightBatch>> mInflightBatches;
215 uint32_t mNumPartialResults;
216 std::vector<int> mStreamsToBatch;
217 const sp<ICameraDeviceCallback> mCallback;
218 } mResultBatcher;
219
220 std::vector<int> mVideoStreamIds;
221
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700222 bool initialize();
223
224 Status initStatus() const;
225
226 // Validate and import request's input buffer and acquire fence
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800227 Status importRequest(
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700228 const CaptureRequest& request,
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800229 hidl_vec<buffer_handle_t*>& allBufPtrs,
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700230 hidl_vec<int>& allFences);
231
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800232 static void cleanupInflightFences(
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700233 hidl_vec<int>& allFences, size_t numFences);
234
Emilian Peev98014ff2017-02-02 16:20:12 +0000235 void cleanupBuffersLocked(int id);
236
Yin-Chia Yehbed3a942017-03-06 14:14:17 -0800237 Status processOneCaptureRequest(const CaptureRequest& request);
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700238 /**
239 * Static callback forwarding methods from HAL to instance
240 */
241 static callbacks_process_capture_result_t sProcessCaptureResult;
242 static callbacks_notify_t sNotify;
243};
244
245} // namespace implementation
246} // namespace V3_2
247} // namespace device
248} // namespace camera
249} // namespace hardware
250} // namespace android
251
252#endif // ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H