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   ResultDispatcher(uint32_t partial_result_count,
69                    ProcessCaptureResultFunc process_capture_result,
70                    NotifyFunc notify);
71 
72  private:
73   static constexpr uint32_t kCallbackThreadTimeoutMs = 500;
74   const uint32_t kPartialResultCount;
75 
76   // Define a pending shutter that will be ready later when AddShutter() is
77   // called.
78   struct PendingShutter {
79     int64_t timestamp_ns = 0;
80     bool ready = false;
81   };
82 
83   // Define a pending buffer that will be ready later when AddResult() is called.
84   struct PendingBuffer {
85     StreamBuffer buffer = {};
86     bool is_input = false;
87     bool ready = false;
88   };
89 
90   // Define a pending final result metadata that will be ready later when
91   // AddResult() is called.
92   struct PendingFinalResultMetadata {
93     std::unique_ptr<HalCameraMetadata> metadata;
94     std::vector<PhysicalCameraMetadata> physical_metadata;
95     bool ready = false;
96   };
97 
98   // Add a pending request for a frame. Must be protected with result_lock_.
99   status_t AddPendingRequestLocked(const CaptureRequest& pending_request);
100 
101   // Add a pending shutter for a frame. Must be protected with result_lock_.
102   status_t AddPendingShutterLocked(uint32_t frame_number);
103 
104   // Add a pending final metadata for a frame. Must be protected with
105   // result_lock_.
106   status_t AddPendingFinalResultMetadataLocked(uint32_t frame_number);
107 
108   // Add a pending buffer for a frame. Must be protected with result_lock_.
109   status_t AddPendingBufferLocked(uint32_t frame_number,
110                                   const StreamBuffer& buffer, bool is_input);
111 
112   // Remove pending shutter, result metadata, and buffers for a frame number.
113   void RemovePendingRequestLocked(uint32_t frame_number);
114 
115   // Invoke process_capture_result_ to notify metadata.
116   void NotifyResultMetadata(uint32_t frame_number,
117                             std::unique_ptr<HalCameraMetadata> metadata,
118                             std::vector<PhysicalCameraMetadata> physical_metadata,
119                             uint32_t partial_result);
120 
121   status_t AddFinalResultMetadata(
122       uint32_t frame_number, std::unique_ptr<HalCameraMetadata> final_metadata,
123       std::vector<PhysicalCameraMetadata> physical_metadata);
124 
125   status_t AddResultMetadata(
126       uint32_t frame_number, std::unique_ptr<HalCameraMetadata> metadata,
127       std::vector<PhysicalCameraMetadata> physical_metadata,
128       uint32_t partial_result);
129 
130   status_t AddBuffer(uint32_t frame_number, StreamBuffer buffer);
131 
132   // Get a shutter message that is ready to be notified via notify_.
133   status_t GetReadyShutterMessage(NotifyMessage* message);
134 
135   // Get a final metadata that is ready to be notified via
136   // process_capture_result_.
137   status_t GetReadyFinalMetadata(
138       uint32_t* frame_number, std::unique_ptr<HalCameraMetadata>* final_metadata,
139       std::vector<PhysicalCameraMetadata>* physical_metadata);
140 
141   // Get a result with a buffer that is ready to be notified via
142   // process_capture_result_.
143   status_t GetReadyBufferResult(std::unique_ptr<CaptureResult>* result);
144 
145   // Check all pending shutters and invoke notify_ with shutters that are ready.
146   void NotifyShutters();
147 
148   // Check all pending final result metadata and invoke process_capture_result_
149   // with final result metadata that are ready.
150   void NotifyFinalResultMetadata();
151 
152   // Check all pending buffers and invoke notify_ with buffers that are ready.
153   void NotifyBuffers();
154 
155   // Thread loop to check pending shutters, result metadata, and buffers. It
156   // notifies the client when one is ready.
157   void NotifyCallbackThreadLoop();
158 
159   void PrintTimeoutMessages();
160 
161   std::mutex result_lock_;
162 
163   // Maps from frame numbers to pending shutters.
164   // Protected by result_lock_.
165   std::map<uint32_t, PendingShutter> pending_shutters_;
166 
167   // Maps from a stream ID to "a map from a frame number to a pending buffer."
168   // Protected by result_lock_.
169   std::map<uint32_t, std::map<uint32_t, PendingBuffer>> stream_pending_buffers_map_;
170 
171   // Maps from a stream ID to pending result metadata.
172   // Protected by result_lock_.
173   std::map<uint32_t, PendingFinalResultMetadata> pending_final_metadata_;
174 
175   std::mutex process_capture_result_lock_;
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   // State of callback thread is notified or not.
191   volatile bool is_result_shutter_updated_ = false;
192 };
193 
194 }  // namespace google_camera_hal
195 }  // namespace android
196 
197 #endif  // HARDWARE_GOOGLE_CAMERA_HAL_UTILS_RESULT_DISPATCHER_H_
198