1 /*
2  * Copyright (C) 2023 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 #pragma once
18 
19 #include <chrono>
20 #include <deque>
21 #include <memory>
22 #include <mutex>
23 #include <optional>
24 #include <thread>
25 
26 #include <aidl/android/hardware/camera/common/Status.h>
27 #include <aidl/android/hardware/camera/device/BnCameraDeviceSession.h>
28 
29 #include <fmq/AidlMessageQueue.h>
30 
31 #include "BlockingQueue.h"
32 #include "HwCamera.h"
33 #include "StreamBufferCache.h"
34 
35 namespace android {
36 namespace hardware {
37 namespace camera {
38 namespace provider {
39 namespace implementation {
40 
41 using aidl::android::hardware::camera::common::Status;
42 
43 using aidl::android::hardware::camera::device::BnCameraDeviceSession;
44 using aidl::android::hardware::camera::device::BufferCache;
45 using aidl::android::hardware::camera::device::CameraMetadata;
46 using aidl::android::hardware::camera::device::CameraOfflineSessionInfo;
47 using aidl::android::hardware::camera::device::CaptureRequest;
48 using aidl::android::hardware::camera::device::CaptureResult;
49 using aidl::android::hardware::camera::device::HalStream;
50 using aidl::android::hardware::camera::device::ICameraDeviceCallback;
51 using aidl::android::hardware::camera::device::ICameraOfflineSession;
52 using aidl::android::hardware::camera::device::RequestTemplate;
53 using aidl::android::hardware::camera::device::StreamBuffer;
54 using aidl::android::hardware::camera::device::StreamConfiguration;
55 
56 using aidl::android::hardware::common::fmq::MQDescriptor;
57 using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
58 
59 using aidl::android::hardware::graphics::common::BufferUsage;
60 using aidl::android::hardware::graphics::common::PixelFormat;
61 
62 using ndk::ScopedAStatus;
63 
64 struct CameraDevice;
65 
66 struct CameraDeviceSession : public BnCameraDeviceSession {
67     CameraDeviceSession(std::shared_ptr<CameraDevice> parent,
68                         std::shared_ptr<ICameraDeviceCallback> cb,
69                         hw::HwCamera& hwCamera);
70     ~CameraDeviceSession() override;
71 
72     ScopedAStatus close() override;
73     ScopedAStatus configureStreams(const StreamConfiguration& cfg,
74                                    std::vector<HalStream>* halStreamsOut) override;
75     ScopedAStatus constructDefaultRequestSettings(RequestTemplate tpl,
76                                                   CameraMetadata* metadata) override;
77     ScopedAStatus flush() override;
78     ScopedAStatus getCaptureRequestMetadataQueue(
79         MQDescriptor<int8_t, SynchronizedReadWrite>* desc) override;
80     ScopedAStatus getCaptureResultMetadataQueue(
81         MQDescriptor<int8_t, SynchronizedReadWrite>* desc) override;
82     ScopedAStatus isReconfigurationRequired(const CameraMetadata& oldSessionParams,
83                                             const CameraMetadata& newSessionParams,
84                                             bool* result) override;
85     ScopedAStatus processCaptureRequest(const std::vector<CaptureRequest>& requests,
86                                         const std::vector<BufferCache>& cachesToRemove,
87                                         int32_t* count) override;
88     ScopedAStatus signalStreamFlush(const std::vector<int32_t>& streamIds,
89                                     int32_t streamConfigCounter) override;
90     ScopedAStatus switchToOffline(const std::vector<int32_t>& streamsToKeep,
91                                   CameraOfflineSessionInfo* offlineSessionInfo,
92                                   std::shared_ptr<ICameraOfflineSession>* session) override;
93     ScopedAStatus repeatingRequestEnd(int32_t frameNumber,
94                                       const std::vector<int32_t>& streamIds) override;
95 
96     static bool isStreamCombinationSupported(const StreamConfiguration& cfg,
97                                              hw::HwCamera& hwCamera);
98 
99 private:
100     using MetadataQueue = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
101     using HwCaptureRequest = hw::HwCaptureRequest;
102 
103     struct DelayedCaptureResult {
104         hw::DelayedStreamBuffer delayedBuffer;
105         int frameNumber;
106     };
107 
108     void closeImpl();
109     void flushImpl(std::chrono::steady_clock::time_point start);
110     int waitFlushingDone(std::chrono::steady_clock::time_point start);
111     static std::pair<Status, std::vector<HalStream>>
112         configureStreamsStatic(const StreamConfiguration& cfg,
113                                hw::HwCamera& hwCamera);
114     Status processOneCaptureRequest(const CaptureRequest& request);
115     void captureThreadLoop();
116     void delayedCaptureThreadLoop();
117     bool popCaptureRequest(HwCaptureRequest* req);
118     struct timespec captureOneFrame(struct timespec nextFrameT, HwCaptureRequest req);
119     void disposeCaptureRequest(HwCaptureRequest req);
120     void consumeCaptureResult(CaptureResult cr);
121     void notifyBuffersReturned(size_t n);
122 
123     const std::shared_ptr<CameraDevice> mParent;
124     const std::shared_ptr<ICameraDeviceCallback> mCb;
125     hw::HwCamera& mHwCamera;
126     MetadataQueue mRequestQueue;
127     MetadataQueue mResultQueue;
128     std::mutex mResultQueueMutex;
129 
130     StreamBufferCache mStreamBufferCache;
131 
132     BlockingQueue<HwCaptureRequest> mCaptureRequests;
133     BlockingQueue<DelayedCaptureResult> mDelayedCaptureResults;
134 
135     size_t mNumBuffersInFlight = 0;
136     std::condition_variable mNoBuffersInFlight;
137     std::mutex mNumBuffersInFlightMtx;
138 
139     std::thread mCaptureThread;
140     std::thread mDelayedCaptureThread;
141 
142     std::atomic<bool> mFlushing = false;
143 };
144 
145 }  // namespace implementation
146 }  // namespace provider
147 }  // namespace camera
148 }  // namespace hardware
149 }  // namespace android
150