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_HdrplusProcessBlock"
19 #define ATRACE_TAG ATRACE_TAG_CAMERA
20 #include <log/log.h>
21 #include <utils/Trace.h>
22
23 #include "hal_utils.h"
24 #include "hdrplus_process_block.h"
25 #include "result_processor.h"
26
27 namespace android {
28 namespace google_camera_hal {
29
Create(CameraDeviceSessionHwl * device_session_hwl,uint32_t cameraId)30 std::unique_ptr<HdrplusProcessBlock> HdrplusProcessBlock::Create(
31 CameraDeviceSessionHwl* device_session_hwl, uint32_t cameraId) {
32 ATRACE_CALL();
33 if (!IsSupported(device_session_hwl)) {
34 ALOGE("%s: Not supported.", __FUNCTION__);
35 return nullptr;
36 }
37 ALOGI("%s: cameraId: %d", __FUNCTION__, cameraId);
38 auto block = std::unique_ptr<HdrplusProcessBlock>(
39 new HdrplusProcessBlock(cameraId, device_session_hwl));
40 if (block == nullptr) {
41 ALOGE("%s: Creating HdrplusProcessBlock failed.", __FUNCTION__);
42 return nullptr;
43 }
44
45 return block;
46 }
47
IsSupported(CameraDeviceSessionHwl * device_session_hwl)48 bool HdrplusProcessBlock::IsSupported(CameraDeviceSessionHwl* device_session_hwl) {
49 ATRACE_CALL();
50 if (device_session_hwl == nullptr) {
51 ALOGE("%s: device_session_hwl is nullptr", __FUNCTION__);
52 return false;
53 }
54
55 return true;
56 }
57
HdrplusProcessBlock(uint32_t cameraId,CameraDeviceSessionHwl * device_session_hwl)58 HdrplusProcessBlock::HdrplusProcessBlock(
59 uint32_t cameraId, CameraDeviceSessionHwl* device_session_hwl)
60 : kCameraId(cameraId), device_session_hwl_(device_session_hwl) {
61 ATRACE_CALL();
62 hwl_pipeline_callback_.process_pipeline_result = HwlProcessPipelineResultFunc(
63 [this](std::unique_ptr<HwlPipelineResult> result) {
64 NotifyHwlPipelineResult(std::move(result));
65 });
66
67 hwl_pipeline_callback_.notify = NotifyHwlPipelineMessageFunc(
68 [this](uint32_t pipeline_id, const NotifyMessage& message) {
69 NotifyHwlPipelineMessage(pipeline_id, message);
70 });
71 }
72
SetResultProcessor(std::unique_ptr<ResultProcessor> result_processor)73 status_t HdrplusProcessBlock::SetResultProcessor(
74 std::unique_ptr<ResultProcessor> result_processor) {
75 ATRACE_CALL();
76 if (result_processor == nullptr) {
77 ALOGE("%s: result_processor is nullptr", __FUNCTION__);
78 return BAD_VALUE;
79 }
80
81 std::lock_guard<std::mutex> lock(result_processor_lock_);
82 if (result_processor_ != nullptr) {
83 ALOGE("%s: result_processor_ was already set.", __FUNCTION__);
84 return ALREADY_EXISTS;
85 }
86
87 result_processor_ = std::move(result_processor);
88 return OK;
89 }
90
ConfigureStreams(const StreamConfiguration & stream_config,const StreamConfiguration & overall_config)91 status_t HdrplusProcessBlock::ConfigureStreams(
92 const StreamConfiguration& stream_config,
93 const StreamConfiguration& overall_config) {
94 ATRACE_CALL();
95 std::lock_guard<std::mutex> lock(configure_lock_);
96 if (is_configured_) {
97 ALOGE("%s: Already configured.", __FUNCTION__);
98 return ALREADY_EXISTS;
99 }
100
101 status_t res = device_session_hwl_->ConfigurePipeline(
102 kCameraId, hwl_pipeline_callback_, stream_config, overall_config,
103 &pipeline_id_);
104 if (res != OK) {
105 ALOGE("%s: Configuring a pipeline failed: %s(%d)", __FUNCTION__,
106 strerror(-res), res);
107 return res;
108 }
109
110 is_configured_ = true;
111 return OK;
112 }
113
GetConfiguredHalStreams(std::vector<HalStream> * hal_streams) const114 status_t HdrplusProcessBlock::GetConfiguredHalStreams(
115 std::vector<HalStream>* hal_streams) const {
116 ATRACE_CALL();
117 std::lock_guard<std::mutex> lock(configure_lock_);
118 if (hal_streams == nullptr) {
119 ALOGE("%s: hal_streams is nullptr.", __FUNCTION__);
120 return BAD_VALUE;
121 }
122
123 if (!is_configured_) {
124 ALOGE("%s: Not configured yet.", __FUNCTION__);
125 return NO_INIT;
126 }
127
128 return device_session_hwl_->GetConfiguredHalStream(pipeline_id_, hal_streams);
129 }
130
ProcessRequests(const std::vector<ProcessBlockRequest> & process_block_requests,const CaptureRequest & remaining_session_request)131 status_t HdrplusProcessBlock::ProcessRequests(
132 const std::vector<ProcessBlockRequest>& process_block_requests,
133 const CaptureRequest& remaining_session_request) {
134 ATRACE_CALL();
135 if (process_block_requests.size() != 1) {
136 ALOGE("%s: Only a single request is supported but there are %zu",
137 __FUNCTION__, process_block_requests.size());
138 return BAD_VALUE;
139 }
140
141 {
142 std::lock_guard<std::mutex> lock(result_processor_lock_);
143 if (result_processor_ == nullptr) {
144 ALOGE("%s: result processor was not set.", __FUNCTION__);
145 return NO_INIT;
146 }
147
148 status_t res = result_processor_->AddPendingRequests(
149 process_block_requests, remaining_session_request);
150 if (res != OK) {
151 ALOGE("%s: Adding a pending request to result processor failed: %s(%d)",
152 __FUNCTION__, strerror(-res), res);
153 return res;
154 }
155 }
156
157 std::lock_guard<std::mutex> lock(configure_lock_);
158 if (!is_configured_) {
159 ALOGE("%s: block is not configured.", __FUNCTION__);
160 return NO_INIT;
161 }
162
163 std::vector<HwlPipelineRequest> hwl_requests(1);
164 status_t res = hal_utils::CreateHwlPipelineRequest(
165 &hwl_requests[0], pipeline_id_, process_block_requests[0].request);
166 if (res != OK) {
167 ALOGE("%s: Creating HWL pipeline request failed: %s(%d)", __FUNCTION__,
168 strerror(-res), res);
169 return res;
170 }
171
172 return device_session_hwl_->SubmitRequests(
173 process_block_requests[0].request.frame_number, hwl_requests);
174 }
175
Flush()176 status_t HdrplusProcessBlock::Flush() {
177 ATRACE_CALL();
178 std::lock_guard<std::mutex> lock(configure_lock_);
179 if (!is_configured_) {
180 return OK;
181 }
182
183 return device_session_hwl_->Flush();
184 }
185
NotifyHwlPipelineResult(std::unique_ptr<HwlPipelineResult> hwl_result)186 void HdrplusProcessBlock::NotifyHwlPipelineResult(
187 std::unique_ptr<HwlPipelineResult> hwl_result) {
188 ATRACE_CALL();
189 std::lock_guard<std::mutex> lock(result_processor_lock_);
190 if (result_processor_ == nullptr) {
191 ALOGE("%s: result processor is nullptr. Dropping a result", __FUNCTION__);
192 return;
193 }
194
195 auto capture_result = hal_utils::ConvertToCaptureResult(std::move(hwl_result));
196 if (capture_result == nullptr) {
197 ALOGE("%s: Converting to capture result failed.", __FUNCTION__);
198 return;
199 }
200
201 ProcessBlockResult result = {.result = std::move(capture_result)};
202 result_processor_->ProcessResult(std::move(result));
203 }
204
NotifyHwlPipelineMessage(uint32_t,const NotifyMessage & message)205 void HdrplusProcessBlock::NotifyHwlPipelineMessage(uint32_t /*pipeline_id*/,
206 const NotifyMessage& message) {
207 ATRACE_CALL();
208 std::lock_guard<std::mutex> lock(result_processor_lock_);
209 if (result_processor_ == nullptr) {
210 ALOGE("%s: result processor is nullptr. Dropping a message", __FUNCTION__);
211 return;
212 }
213
214 ProcessBlockNotifyMessage block_message = {.message = message};
215 result_processor_->Notify(block_message);
216 }
217
218 } // namespace google_camera_hal
219 } // namespace android
220