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 // #define LOG_NDEBUG 0
18 #define LOG_TAG "GCH_ZslResultDispatcher"
19 #define ATRACE_TAG ATRACE_TAG_CAMERA
20 #include "zsl_result_dispatcher.h"
21 
22 #include <inttypes.h>
23 #include <log/log.h>
24 #include <utils/Trace.h>
25 
26 #include "utils.h"
27 
28 namespace android {
29 namespace google_camera_hal {
30 
Create(uint32_t partial_result_count,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify,const StreamConfiguration & stream_config)31 std::unique_ptr<ZslResultDispatcher> ZslResultDispatcher::Create(
32     uint32_t partial_result_count,
33     ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
34     const StreamConfiguration& stream_config) {
35   ATRACE_CALL();
36   auto dispatcher = std::unique_ptr<ZslResultDispatcher>(
37       new ZslResultDispatcher(process_capture_result, notify));
38   if (dispatcher == nullptr) {
39     ALOGE("%s: Creating ZslResultDispatcher failed.", __FUNCTION__);
40     return nullptr;
41   }
42 
43   status_t res = dispatcher->Initialize(partial_result_count, stream_config);
44   if (res != OK) {
45     ALOGE("%s: Initialize failed.", __FUNCTION__);
46     return nullptr;
47   }
48 
49   return dispatcher;
50 }
51 
ZslResultDispatcher(ProcessCaptureResultFunc process_capture_result,NotifyFunc notify)52 ZslResultDispatcher::ZslResultDispatcher(
53     ProcessCaptureResultFunc process_capture_result, NotifyFunc notify)
54     : device_session_process_capture_result_(process_capture_result),
55       device_session_notify_(notify) {
56 }
57 
Initialize(uint32_t partial_result_count,const StreamConfiguration & stream_config)58 status_t ZslResultDispatcher::Initialize(
59     uint32_t partial_result_count, const StreamConfiguration& stream_config) {
60   ATRACE_CALL();
61   process_capture_result_ =
62       ProcessCaptureResultFunc([this](std::unique_ptr<CaptureResult> result) {
63         ProcessCaptureResult(std::move(result));
64       });
65   notify_ = NotifyFunc(
66       [this](const NotifyMessage& message) { NotifyHalMessage(message); });
67 
68   normal_result_dispatcher_ = std::unique_ptr<ResultDispatcher>(
69       new ResultDispatcher(partial_result_count, process_capture_result_,
70                            /*process_batch_capture_result=*/nullptr, notify_,
71                            stream_config, "ZslNormalDispatcher"));
72   if (normal_result_dispatcher_ == nullptr) {
73     ALOGE("%s: Creating normal_result_dispatcher_ failed.", __FUNCTION__);
74     return BAD_VALUE;
75   }
76 
77   zsl_result_dispatcher_ = std::unique_ptr<ResultDispatcher>(
78       new ResultDispatcher(partial_result_count, process_capture_result_,
79                            /*process_batch_capture_result=*/nullptr, notify_,
80                            stream_config, "ZslZslDispatcher"));
81   if (zsl_result_dispatcher_ == nullptr) {
82     ALOGE("%s: Creating zsl_result_dispatcher_ failed.", __FUNCTION__);
83     return BAD_VALUE;
84   }
85 
86   return OK;
87 }
88 
ProcessCaptureResult(std::unique_ptr<CaptureResult> result)89 void ZslResultDispatcher::ProcessCaptureResult(
90     std::unique_ptr<CaptureResult> result) {
91   std::lock_guard<std::mutex> lock(process_capture_result_lock_);
92   device_session_process_capture_result_(std::move(result));
93 }
94 
IsZslFrame(uint32_t frame_number)95 bool ZslResultDispatcher::IsZslFrame(uint32_t frame_number) {
96   std::lock_guard<std::mutex> lock(zsl_frames_lock_);
97   if (zsl_frames_.empty()) {
98     return false;
99   }
100   if (std::find(zsl_frames_.begin(), zsl_frames_.end(), frame_number) ==
101       zsl_frames_.end()) {
102     return false;
103   }
104   return true;
105 }
106 
NotifyHalMessage(const NotifyMessage & message)107 void ZslResultDispatcher::NotifyHalMessage(const NotifyMessage& message) {
108   std::lock_guard<std::mutex> lock(result_lock_);
109   device_session_notify_(message);
110 }
111 
AddPendingRequest(const CaptureRequest & pending_request,bool is_zsl_request)112 status_t ZslResultDispatcher::AddPendingRequest(
113     const CaptureRequest& pending_request, bool is_zsl_request) {
114   ATRACE_CALL();
115   if (is_zsl_request) {
116     uint32_t frame_number = pending_request.frame_number;
117     {
118       std::lock_guard<std::mutex> lock(zsl_frames_lock_);
119       zsl_frames_.push_back(frame_number);
120     }
121 
122     status_t res = zsl_result_dispatcher_->AddPendingRequest(pending_request);
123     if (res != OK) {
124       std::lock_guard<std::mutex> lock(zsl_frames_lock_);
125       zsl_frames_.erase(
126           std::find(zsl_frames_.begin(), zsl_frames_.end(), frame_number));
127     }
128     return res;
129   } else {
130     return normal_result_dispatcher_->AddPendingRequest(pending_request);
131   }
132 }
133 
AddResult(std::unique_ptr<CaptureResult> result)134 status_t ZslResultDispatcher::AddResult(std::unique_ptr<CaptureResult> result) {
135   ATRACE_CALL();
136   if (result == nullptr) {
137     ALOGE("%s: result is nullptr", __FUNCTION__);
138     return BAD_VALUE;
139   }
140   uint32_t frame_number = result->frame_number;
141   bool is_zsl_request = IsZslFrame(frame_number);
142   if (is_zsl_request) {
143     return zsl_result_dispatcher_->AddResult(std::move(result));
144   } else {
145     return normal_result_dispatcher_->AddResult(std::move(result));
146   }
147 }
148 
AddShutter(uint32_t frame_number,int64_t timestamp_ns,int64_t readout_timestamp_ns)149 status_t ZslResultDispatcher::AddShutter(uint32_t frame_number,
150                                          int64_t timestamp_ns,
151                                          int64_t readout_timestamp_ns) {
152   ATRACE_CALL();
153   bool is_zsl_request = IsZslFrame(frame_number);
154   if (is_zsl_request) {
155     return zsl_result_dispatcher_->AddShutter(frame_number, timestamp_ns,
156                                               readout_timestamp_ns);
157   } else {
158     return normal_result_dispatcher_->AddShutter(frame_number, timestamp_ns,
159                                                  readout_timestamp_ns);
160   }
161 }
162 
AddError(const ErrorMessage & error)163 status_t ZslResultDispatcher::AddError(const ErrorMessage& error) {
164   ATRACE_CALL();
165   uint32_t frame_number = error.frame_number;
166   bool is_zsl_request = IsZslFrame(frame_number);
167   if (is_zsl_request) {
168     return zsl_result_dispatcher_->AddError(error);
169   } else {
170     return normal_result_dispatcher_->AddError(error);
171   }
172 }
173 
RemovePendingRequest(uint32_t frame_number)174 void ZslResultDispatcher::RemovePendingRequest(uint32_t frame_number) {
175   ATRACE_CALL();
176   bool is_zsl_request = IsZslFrame(frame_number);
177   if (is_zsl_request) {
178     zsl_result_dispatcher_->RemovePendingRequest(frame_number);
179     std::lock_guard<std::mutex> lock(zsl_frames_lock_);
180     zsl_frames_.erase(
181         std::find(zsl_frames_.begin(), zsl_frames_.end(), frame_number));
182   } else {
183     normal_result_dispatcher_->RemovePendingRequest(frame_number);
184   }
185 }
186 
187 }  // namespace google_camera_hal
188 }  // namespace android
189