1 /*
2  * Copyright (C) 2019 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 HARDWARE_GOOGLE_CAMERA_HAL_UTILS_RESULT_DISPATCHER_H_
18 #define HARDWARE_GOOGLE_CAMERA_HAL_UTILS_RESULT_DISPATCHER_H_
19 
20 #include <map>
21 #include <thread>
22 
23 #include "hal_types.h"
24 
25 namespace android {
26 namespace google_camera_hal {
27 
28 // ResultDispatcher dispatches capture results in the order of frame numbers,
29 // including result metadata, shutters, and stream buffers.
30 //
31 // The client can add results and shutters via AddResult() and AddShutter() in
32 // any order. ResultDispatcher will invoke ProcessCaptureResultFunc and
33 // NotifyFunc to notify result metadata, shutters, and stream buffers in the
34 // in the order of increasing frame numbers.
35 class ResultDispatcher {
36  public:
37   // Create a ResultDispatcher.
38   // partial_result_count is the partial result count.
39   // process_capture_result is the function to notify capture results.
40   // notify is the function to notify shutter messages.
41   static std::unique_ptr<ResultDispatcher> Create(
42       uint32_t partial_result_count,
43       ProcessCaptureResultFunc process_capture_result, NotifyFunc notify);
44 
45   virtual ~ResultDispatcher();
46 
47   // Add a pending request. This tells ResultDispatcher to watch for
48   // the shutter, result metadata, and stream buffers for this request,
49   // that will be added later via AddResult() and AddShutter().
50   status_t AddPendingRequest(const CaptureRequest& pending_request);
51 
52   // Add a ready result. If the result doesn't belong to a pending request that
53   // was previously added via AddPendingRequest(), an error will be returned.
54   status_t AddResult(std::unique_ptr<CaptureResult> result);
55 
56   // Add a shutter for a frame number. If the frame number doesn't belong to a
57   // pending request that was previously added via AddPendingRequest(), an error
58   // will be returned.
59   status_t AddShutter(uint32_t frame_number, int64_t timestamp_ns);
60 
61   // Add an error notification for a frame number. When this is called, we no
62   // longer wait for a shutter message or result metadata for the given frame.
63   status_t AddError(const ErrorMessage& error);
64 
65   // Remove a pending request.
66   void RemovePendingRequest(uint32_t frame_number);
67 
68  protected:
69   ResultDispatcher(uint32_t partial_result_count,
70                    ProcessCaptureResultFunc process_capture_result,
71                    NotifyFunc notify);
72 
73  private:
74   static constexpr uint32_t kCallbackThreadTimeoutMs = 500;
75   const uint32_t kPartialResultCount;
76 
77   // Define a pending shutter that will be ready later when AddShutter() is
78   // called.
79   struct PendingShutter {
80     int64_t timestamp_ns = 0;
81     bool ready = false;
82   };
83 
84   // Define a pending buffer that will be ready later when AddResult() is called.
85   struct PendingBuffer {
86     StreamBuffer buffer = {};
87     bool is_input = false;
88     bool ready = false;
89   };
90 
91   // Define a pending final result metadata that will be ready later when
92   // AddResult() is called.
93   struct PendingFinalResultMetadata {
94     std::unique_ptr<HalCameraMetadata> metadata;
95     std::vector<PhysicalCameraMetadata> physical_metadata;
96     bool ready = false;
97   };
98 
99   // Add a pending request for a frame. Must be protected with result_lock_.
100   status_t AddPendingRequestLocked(const CaptureRequest& pending_request);
101 
102   // Add a pending shutter for a frame. Must be protected with result_lock_.
103   status_t AddPendingShutterLocked(uint32_t frame_number);
104 
105   // Add a pending final metadata for a frame. Must be protected with
106   // result_lock_.
107   status_t AddPendingFinalResultMetadataLocked(uint32_t frame_number);
108 
109   // Add a pending buffer for a frame. Must be protected with result_lock_.
110   status_t AddPendingBufferLocked(uint32_t frame_number,
111                                   const StreamBuffer& buffer, bool is_input);
112 
113   // Remove pending shutter, result metadata, and buffers for a frame number.
114   void RemovePendingRequestLocked(uint32_t frame_number);
115 
116   // Invoke process_capture_result_ to notify metadata.
117   void NotifyResultMetadata(uint32_t frame_number,
118                             std::unique_ptr<HalCameraMetadata> metadata,
119                             std::vector<PhysicalCameraMetadata> physical_metadata,
120                             uint32_t partial_result);
121 
122   status_t AddFinalResultMetadata(
123       uint32_t frame_number, std::unique_ptr<HalCameraMetadata> final_metadata,
124       std::vector<PhysicalCameraMetadata> physical_metadata);
125 
126   status_t AddResultMetadata(
127       uint32_t frame_number, std::unique_ptr<HalCameraMetadata> metadata,
128       std::vector<PhysicalCameraMetadata> physical_metadata,
129       uint32_t partial_result);
130 
131   status_t AddBuffer(uint32_t frame_number, StreamBuffer buffer);
132 
133   // Get a shutter message that is ready to be notified via notify_.
134   status_t GetReadyShutterMessage(NotifyMessage* message);
135 
136   // Get a final metadata that is ready to be notified via
137   // process_capture_result_.
138   status_t GetReadyFinalMetadata(
139       uint32_t* frame_number, std::unique_ptr<HalCameraMetadata>* final_metadata,
140       std::vector<PhysicalCameraMetadata>* physical_metadata);
141 
142   // Get a result with a buffer that is ready to be notified via
143   // process_capture_result_.
144   status_t GetReadyBufferResult(std::unique_ptr<CaptureResult>* result);
145 
146   // Check all pending shutters and invoke notify_ with shutters that are ready.
147   void NotifyShutters();
148 
149   // Check all pending final result metadata and invoke process_capture_result_
150   // with final result metadata that are ready.
151   void NotifyFinalResultMetadata();
152 
153   // Check all pending buffers and invoke notify_ with buffers that are ready.
154   void NotifyBuffers();
155 
156   // Thread loop to check pending shutters, result metadata, and buffers. It
157   // notifies the client when one is ready.
158   void NotifyCallbackThreadLoop();
159 
160   void PrintTimeoutMessages();
161 
162   std::mutex result_lock_;
163 
164   // Maps from frame numbers to pending shutters.
165   // Protected by result_lock_.
166   std::map<uint32_t, PendingShutter> pending_shutters_;
167 
168   // Maps from a stream ID to "a map from a frame number to a pending buffer."
169   // Protected by result_lock_.
170   std::map<uint32_t, std::map<uint32_t, PendingBuffer>> stream_pending_buffers_map_;
171 
172   // Maps from a stream ID to pending result metadata.
173   // Protected by result_lock_.
174   std::map<uint32_t, PendingFinalResultMetadata> pending_final_metadata_;
175 
176   ProcessCaptureResultFunc process_capture_result_;
177   NotifyFunc notify_;
178 
179   // A thread to run NotifyCallbackThreadLoop().
180   std::thread notify_callback_thread_;
181 
182   std::mutex notify_callback_lock;
183 
184   // Condition to wake up notify_callback_thread_. Used with notify_callback_lock.
185   std::condition_variable notify_callback_condition_;
186 
187   // Protected by notify_callback_lock.
188   bool notify_callback_thread_exiting = false;
189 };
190 
191 }  // namespace google_camera_hal
192 }  // namespace android
193 
194 #endif  // HARDWARE_GOOGLE_CAMERA_HAL_UTILS_RESULT_DISPATCHER_H_
195