CameraDeviceSession.h revision 50fe43099495dcb388fdd7eb1ff78609aaa0cf88
1/*
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
20#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>
26#include <deque>
27#include <map>
28#include <unordered_map>
29#include "CameraMetadata.h"
30#include "HandleImporter.h"
31#include "hardware/camera3.h"
32#include "hardware/camera_common.h"
33#include "utils/Mutex.h"
34
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;
47using ::android::hardware::camera::common::V1_0::helper::HandleImporter;
48using ::android::hardware::kSynchronizedReadWrite;
49using ::android::hardware::MessageQueue;
50using ::android::hardware::MQDescriptorSync;
51using ::android::hardware::Return;
52using ::android::hardware::Void;
53using ::android::hardware::hidl_vec;
54using ::android::hardware::hidl_string;
55using ::android::sp;
56using ::android::Mutex;
57
58struct Camera3Stream;
59
60/**
61 * Function pointer types with C calling convention to
62 * use for HAL callback functions.
63 */
64extern "C" {
65    typedef void (callbacks_process_capture_result_t)(
66        const struct camera3_callback_ops *,
67        const camera3_capture_result_t *);
68
69    typedef void (callbacks_notify_t)(
70        const struct camera3_callback_ops *,
71        const camera3_notify_msg_t *);
72}
73
74struct CameraDeviceSession : public virtual RefBase, protected camera3_callback_ops  {
75
76    CameraDeviceSession(camera3_device_t*,
77                        const camera_metadata_t* deviceInfo,
78                        const sp<ICameraDeviceCallback>&);
79    virtual ~CameraDeviceSession();
80    // Call by CameraDevice to dump active device states
81    void dumpState(const native_handle_t* fd);
82    // Caller must use this method to check if CameraDeviceSession ctor failed
83    bool isInitFailed() { return mInitFail; }
84    // Used by CameraDevice to signal external camera disconnected
85    void disconnect();
86    bool isClosed();
87
88    // Retrieve the HIDL interface, split into its own class to avoid inheritance issues when
89    // dealing with minor version revs and simultaneous implementation and interface inheritance
90    virtual sp<ICameraDeviceSession> getInterface() {
91        return new TrampolineSessionInterface_3_2(this);
92    }
93
94protected:
95
96    // Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow
97
98    Return<void> constructDefaultRequestSettings(
99            RequestTemplate type,
100            ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb);
101    Return<void> configureStreams(
102            const StreamConfiguration& requestedConfiguration,
103            ICameraDeviceSession::configureStreams_cb _hidl_cb);
104    Return<void> getCaptureRequestMetadataQueue(
105        ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb);
106    Return<void> getCaptureResultMetadataQueue(
107        ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb);
108    Return<void> processCaptureRequest(
109            const hidl_vec<CaptureRequest>& requests,
110            const hidl_vec<BufferCache>& cachesToRemove,
111            ICameraDeviceSession::processCaptureRequest_cb _hidl_cb);
112    Return<Status> flush();
113    Return<void> close();
114
115protected:
116
117    // protecting mClosed/mDisconnected/mInitFail
118    mutable Mutex mStateLock;
119    // device is closed either
120    //    - closed by user
121    //    - init failed
122    //    - camera disconnected
123    bool mClosed = false;
124
125    // Set by CameraDevice (when external camera is disconnected)
126    bool mDisconnected = false;
127
128    struct AETriggerCancelOverride {
129        bool applyAeLock;
130        uint8_t aeLock;
131        bool applyAePrecaptureTrigger;
132        uint8_t aePrecaptureTrigger;
133    };
134
135    camera3_device_t* mDevice;
136    uint32_t mDeviceVersion;
137    bool mIsAELockAvailable;
138    bool mDerivePostRawSensKey;
139    uint32_t mNumPartialResults;
140    // Stream ID -> Camera3Stream cache
141    std::map<int, Camera3Stream> mStreamMap;
142
143    mutable Mutex mInflightLock; // protecting mInflightBuffers and mCirculatingBuffers
144    // (streamID, frameNumber) -> inflight buffer cache
145    std::map<std::pair<int, uint32_t>, camera3_stream_buffer_t>  mInflightBuffers;
146
147    // (frameNumber, AETriggerOverride) -> inflight request AETriggerOverrides
148    std::map<uint32_t, AETriggerCancelOverride> mInflightAETriggerOverrides;
149    ::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenResult;
150    std::map<uint32_t, bool> mInflightRawBoostPresent;
151    ::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenRequest;
152
153    // buffers currently ciculating between HAL and camera service
154    // key: bufferId sent via HIDL interface
155    // value: imported buffer_handle_t
156    // Buffer will be imported during process_capture_request and will be freed
157    // when the its stream is deleted or camera device session is closed
158    typedef std::unordered_map<uint64_t, buffer_handle_t> CirculatingBuffers;
159    // Stream ID -> circulating buffers map
160    std::map<int, CirculatingBuffers> mCirculatingBuffers;
161
162    static HandleImporter sHandleImporter;
163
164    bool mInitFail;
165    bool mFirstRequest = false;
166
167    common::V1_0::helper::CameraMetadata mDeviceInfo;
168
169    using RequestMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
170    std::unique_ptr<RequestMetadataQueue> mRequestMetadataQueue;
171    using ResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
172    std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue;
173
174    class ResultBatcher {
175    public:
176        ResultBatcher(const sp<ICameraDeviceCallback>& callback);
177        void setNumPartialResults(uint32_t n);
178        void setBatchedStreams(const std::vector<int>& streamsToBatch);
179        void setResultMetadataQueue(std::shared_ptr<ResultMetadataQueue> q);
180
181        void registerBatch(const hidl_vec<CaptureRequest>& requests);
182        void notify(NotifyMsg& msg);
183        void processCaptureResult(CaptureResult& result);
184
185    private:
186        struct InflightBatch {
187            // Protect access to entire struct. Acquire this lock before read/write any data or
188            // calling any methods. processCaptureResult and notify will compete for this lock
189            // HIDL IPCs might be issued while the lock is held
190            Mutex mLock;
191
192            bool allDelivered() const;
193
194            uint32_t mFirstFrame;
195            uint32_t mLastFrame;
196            uint32_t mBatchSize;
197
198            bool mShutterDelivered = false;
199            std::vector<NotifyMsg> mShutterMsgs;
200
201            struct BufferBatch {
202                BufferBatch(uint32_t batchSize) {
203                    mBuffers.reserve(batchSize);
204                }
205                bool mDelivered = false;
206                // This currently assumes every batched request will output to the batched stream
207                // and since HAL must always send buffers in order, no frameNumber tracking is
208                // needed
209                std::vector<StreamBuffer> mBuffers;
210            };
211            // Stream ID -> VideoBatch
212            std::unordered_map<int, BufferBatch> mBatchBufs;
213
214            struct MetadataBatch {
215                //                   (frameNumber, metadata)
216                std::vector<std::pair<uint32_t, CameraMetadata>> mMds;
217            };
218            // Partial result IDs that has been delivered to framework
219            uint32_t mNumPartialResults;
220            uint32_t mPartialResultProgress = 0;
221            // partialResult -> MetadataBatch
222            std::map<uint32_t, MetadataBatch> mResultMds;
223
224            // Set to true when batch is removed from mInflightBatches
225            // processCaptureResult and notify must check this flag after acquiring mLock to make
226            // sure this batch isn't removed while waiting for mLock
227            bool mRemoved = false;
228        };
229
230        static const int NOT_BATCHED = -1;
231
232        // Get the batch index and pointer to InflightBatch (nullptrt if the frame is not batched)
233        // Caller must acquire the InflightBatch::mLock before accessing the InflightBatch
234        // It's possible that the InflightBatch is removed from mInflightBatches before the
235        // InflightBatch::mLock is acquired (most likely caused by an error notification), so
236        // caller must check InflightBatch::mRemoved flag after the lock is acquried.
237        // This method will hold ResultBatcher::mLock briefly
238        std::pair<int, std::shared_ptr<InflightBatch>> getBatch(uint32_t frameNumber);
239
240        // Check if the first batch in mInflightBatches is ready to be removed, and remove it if so
241        // This method will hold ResultBatcher::mLock briefly
242        void checkAndRemoveFirstBatch();
243
244        // The following sendXXXX methods must be called while the InflightBatch::mLock is locked
245        // HIDL IPC methods will be called during these methods.
246        void sendBatchShutterCbsLocked(std::shared_ptr<InflightBatch> batch);
247        // send buffers for all batched streams
248        void sendBatchBuffersLocked(std::shared_ptr<InflightBatch> batch);
249        // send buffers for specified streams
250        void sendBatchBuffersLocked(
251                std::shared_ptr<InflightBatch> batch, const std::vector<int>& streams);
252        void sendBatchMetadataLocked(
253                std::shared_ptr<InflightBatch> batch, uint32_t lastPartialResultIdx);
254        // End of sendXXXX methods
255
256        // helper methods
257        void freeReleaseFences(hidl_vec<CaptureResult>&);
258        void notifySingleMsg(NotifyMsg& msg);
259        void processOneCaptureResult(CaptureResult& result);
260        void invokeProcessCaptureResultCallback(hidl_vec<CaptureResult> &results, bool tryWriteFmq);
261
262        // move/push function avoids "hidl_handle& operator=(hidl_handle&)", which clones native
263        // handle
264        void moveStreamBuffer(StreamBuffer&& src, StreamBuffer& dst);
265        void pushStreamBuffer(StreamBuffer&& src, std::vector<StreamBuffer>& dst);
266
267        // Protect access to mInflightBatches, mNumPartialResults and mStreamsToBatch
268        // processCaptureRequest, processCaptureResult, notify will compete for this lock
269        // Do NOT issue HIDL IPCs while holding this lock (except when HAL reports error)
270        mutable Mutex mLock;
271        std::deque<std::shared_ptr<InflightBatch>> mInflightBatches;
272        uint32_t mNumPartialResults;
273        std::vector<int> mStreamsToBatch;
274        const sp<ICameraDeviceCallback> mCallback;
275        std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue;
276
277        // Protect against invokeProcessCaptureResultCallback()
278        Mutex mProcessCaptureResultLock;
279
280    } mResultBatcher;
281
282    std::vector<int> mVideoStreamIds;
283
284    bool initialize();
285
286    Status initStatus() const;
287
288    // Validate and import request's input buffer and acquire fence
289    Status importRequest(
290            const CaptureRequest& request,
291            hidl_vec<buffer_handle_t*>& allBufPtrs,
292            hidl_vec<int>& allFences);
293
294    static void cleanupInflightFences(
295            hidl_vec<int>& allFences, size_t numFences);
296
297    void cleanupBuffersLocked(int id);
298
299    void updateBufferCaches(const hidl_vec<BufferCache>& cachesToRemove);
300
301    android_dataspace mapToLegacyDataspace(
302            android_dataspace dataSpace) const;
303
304    bool handleAePrecaptureCancelRequestLocked(
305            const camera3_capture_request_t &halRequest,
306            android::hardware::camera::common::V1_0::helper::CameraMetadata *settings /*out*/,
307            AETriggerCancelOverride *override /*out*/);
308
309    void overrideResultForPrecaptureCancelLocked(
310            const AETriggerCancelOverride &aeTriggerCancelOverride,
311            ::android::hardware::camera::common::V1_0::helper::CameraMetadata *settings /*out*/);
312
313    Status processOneCaptureRequest(const CaptureRequest& request);
314    /**
315     * Static callback forwarding methods from HAL to instance
316     */
317    static callbacks_process_capture_result_t sProcessCaptureResult;
318    static callbacks_notify_t sNotify;
319
320private:
321
322    struct TrampolineSessionInterface_3_2 : public ICameraDeviceSession {
323        TrampolineSessionInterface_3_2(sp<CameraDeviceSession> parent) :
324                mParent(parent) {}
325
326        virtual Return<void> constructDefaultRequestSettings(
327                V3_2::RequestTemplate type,
328                V3_2::ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) override {
329            return mParent->constructDefaultRequestSettings(type, _hidl_cb);
330        }
331
332        virtual Return<void> configureStreams(
333                const V3_2::StreamConfiguration& requestedConfiguration,
334                V3_2::ICameraDeviceSession::configureStreams_cb _hidl_cb) override {
335            return mParent->configureStreams(requestedConfiguration, _hidl_cb);
336        }
337
338        virtual Return<void> processCaptureRequest(const hidl_vec<V3_2::CaptureRequest>& requests,
339                const hidl_vec<V3_2::BufferCache>& cachesToRemove,
340                V3_2::ICameraDeviceSession::processCaptureRequest_cb _hidl_cb) override {
341            return mParent->processCaptureRequest(requests, cachesToRemove, _hidl_cb);
342        }
343
344        virtual Return<void> getCaptureRequestMetadataQueue(
345                V3_2::ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb) override  {
346            return mParent->getCaptureRequestMetadataQueue(_hidl_cb);
347        }
348
349        virtual Return<void> getCaptureResultMetadataQueue(
350                V3_2::ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb) override  {
351            return mParent->getCaptureResultMetadataQueue(_hidl_cb);
352        }
353
354        virtual Return<Status> flush() override {
355            return mParent->flush();
356        }
357
358        virtual Return<void> close() override {
359            return mParent->close();
360        }
361
362    private:
363        sp<CameraDeviceSession> mParent;
364    };
365};
366
367}  // namespace implementation
368}  // namespace V3_2
369}  // namespace device
370}  // namespace camera
371}  // namespace hardware
372}  // namespace android
373
374#endif  // ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H
375