1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "preview_output_impl.h"
17 #include "camera_error.h"
18 #include "camera_log.h"
19 #include "camera_manager.h"
20 #include "cj_lambda.h"
21 #include "image_receiver.h"
22 #include "surface_utils.h"
23
24 namespace OHOS {
25 namespace CameraStandard {
26
27 thread_local sptr<PreviewOutput> CJPreviewOutput::sPreviewOutput_ = nullptr;
OnFrameStarted() const28 void CJPreviewOutputCallback::OnFrameStarted() const
29 {
30 std::lock_guard<std::mutex> lock(frameStartedMutex);
31 if (frameStartedCallbackList.size() == 0) {
32 return;
33 }
34 for (size_t i = 0; i < frameStartedCallbackList.size(); i++) {
35 if (frameStartedCallbackList[i] != nullptr) {
36 frameStartedCallbackList[i]->ref();
37 }
38 }
39 }
40
OnFrameEnded(const int32_t frameCount) const41 void CJPreviewOutputCallback::OnFrameEnded(const int32_t frameCount) const
42 {
43 std::lock_guard<std::mutex> lock(frameEndedMutex);
44 if (frameEndedCallbackList.size() == 0) {
45 return;
46 }
47 for (size_t i = 0; i < frameEndedCallbackList.size(); i++) {
48 if (frameEndedCallbackList[i] != nullptr) {
49 frameEndedCallbackList[i]->ref();
50 }
51 }
52 }
53
OnError(const int32_t errorCode) const54 void CJPreviewOutputCallback::OnError(const int32_t errorCode) const
55 {
56 std::lock_guard<std::mutex> lock(errorMutex);
57 if (errorCallbackList.size() == 0) {
58 return;
59 }
60 for (size_t i = 0; i < errorCallbackList.size(); i++) {
61 if (errorCallbackList[i] != nullptr) {
62 errorCallbackList[i]->ref(errorCode);
63 }
64 }
65 }
66
OnSketchStatusDataChanged(const SketchStatusData & statusData) const67 void CJPreviewOutputCallback::OnSketchStatusDataChanged(const SketchStatusData &statusData) const
68 {
69 }
70
CJPreviewOutput()71 CJPreviewOutput::CJPreviewOutput()
72 {
73 previewOutput_ = sPreviewOutput_;
74 sPreviewOutput_ = nullptr;
75 }
76
GetCameraOutput()77 sptr<CameraStandard::CaptureOutput> CJPreviewOutput::GetCameraOutput()
78 {
79 return previewOutput_;
80 }
81
Release()82 int32_t CJPreviewOutput::Release()
83 {
84 if (previewOutput_ == nullptr) {
85 return CameraError::CAMERA_SERVICE_ERROR;
86 }
87 return previewOutput_->Release();
88 }
89
CreatePreviewOutput(Profile & profile,std::string & surfaceId)90 int32_t CJPreviewOutput::CreatePreviewOutput(Profile &profile, std::string &surfaceId)
91 {
92 uint64_t iSurfaceId;
93 std::istringstream iss(surfaceId);
94 iss >> iSurfaceId;
95 sptr<Surface> surface = SurfaceUtils::GetInstance()->GetSurface(iSurfaceId);
96 if (!surface) {
97 surface = Media::ImageReceiver::getSurfaceById(surfaceId);
98 }
99 if (surface == nullptr) {
100 MEDIA_ERR_LOG("Failed to get previewOutput surface");
101 return CameraError::CAMERA_SERVICE_ERROR;
102 }
103 surface->SetUserData(CameraManager::surfaceFormat, std::to_string(profile.GetCameraFormat()));
104 int retCode = CameraManager::GetInstance()->CreatePreviewOutput(profile, surface, &sPreviewOutput_);
105 if (sPreviewOutput_ == nullptr) {
106 MEDIA_ERR_LOG("failed to create previewOutput");
107 return CameraError::CAMERA_SERVICE_ERROR;
108 }
109
110 return retCode;
111 }
112
CreatePreviewOutputWithoutProfile(std::string & surfaceId)113 int32_t CJPreviewOutput::CreatePreviewOutputWithoutProfile(std::string &surfaceId)
114 {
115 uint64_t iSurfaceId;
116 std::istringstream iss(surfaceId);
117 iss >> iSurfaceId;
118 sptr<Surface> surface = SurfaceUtils::GetInstance()->GetSurface(iSurfaceId);
119 if (!surface) {
120 surface = Media::ImageReceiver::getSurfaceById(surfaceId);
121 }
122 if (surface == nullptr) {
123 MEDIA_ERR_LOG("failed to get surface");
124 return CameraError::CAMERA_SERVICE_ERROR;
125 }
126 int retCode = CameraManager::GetInstance()->CreatePreviewOutputWithoutProfile(surface, &sPreviewOutput_);
127 if (sPreviewOutput_ == nullptr) {
128 MEDIA_ERR_LOG("failed to create previewOutput");
129 return CameraError::CAMERA_SERVICE_ERROR;
130 }
131
132 return retCode;
133 }
134
GetSupportedFrameRates(int32_t * errCode)135 CArrFrameRateRange CJPreviewOutput::GetSupportedFrameRates(int32_t *errCode)
136 {
137 MEDIA_INFO_LOG("GetSupportedFrameRates is called!");
138 CArrFrameRateRange cArrFrameRateRange = CArrFrameRateRange{0};
139 if (previewOutput_ == nullptr) {
140 MEDIA_ERR_LOG("previewOutput_ is nullptr.");
141 *errCode = CameraError::CAMERA_SERVICE_ERROR;
142 return cArrFrameRateRange;
143 }
144 std::vector<std::vector<int32_t>> supportedFrameRatesRange = previewOutput_->GetSupportedFrameRates();
145 if (supportedFrameRatesRange.size() > 0) {
146 FrameRateRange *retArrFrameRateRange =
147 (FrameRateRange *)malloc(sizeof(FrameRateRange) * supportedFrameRatesRange.size());
148 if (retArrFrameRateRange == nullptr) {
149 *errCode = CameraError::CAMERA_SERVICE_ERROR;
150 return cArrFrameRateRange;
151 }
152 for (size_t i = 0; i < supportedFrameRatesRange.size(); i++) {
153 retArrFrameRateRange[i].min = supportedFrameRatesRange[i][0];
154 retArrFrameRateRange[i].max = supportedFrameRatesRange[i][1];
155 }
156 cArrFrameRateRange.head = retArrFrameRateRange;
157 cArrFrameRateRange.size = static_cast<int64_t>(supportedFrameRatesRange.size());
158 } else {
159 MEDIA_INFO_LOG("supportedFrameRates is empty");
160 }
161 return cArrFrameRateRange;
162 }
163
SetFrameRate(int32_t min,int32_t max)164 int32_t CJPreviewOutput::SetFrameRate(int32_t min, int32_t max)
165 {
166 MEDIA_INFO_LOG("SetFrameRate is called!");
167 if (previewOutput_ == nullptr) {
168 MEDIA_ERR_LOG("previewOutput is nullptr.");
169 return CameraError::CAMERA_SERVICE_ERROR;
170 }
171 int32_t retCode = previewOutput_->SetFrameRate(min, max);
172 if (retCode != 0) {
173 MEDIA_ERR_LOG("SetFrameRate call Failed!");
174 }
175 return retCode;
176 }
177
GetActiveFrameRate(int32_t * errCode)178 FrameRateRange CJPreviewOutput::GetActiveFrameRate(int32_t *errCode)
179 {
180 MEDIA_INFO_LOG("GetActiveFrameRate is called!");
181 FrameRateRange frameRateRange = FrameRateRange{0};
182 if (previewOutput_ == nullptr) {
183 MEDIA_ERR_LOG("previewOutput is nullptr.");
184 *errCode = CameraError::CAMERA_SERVICE_ERROR;
185 return frameRateRange;
186 }
187 std::vector<int32_t> fRateRange = previewOutput_->GetFrameRateRange();
188 frameRateRange.min = fRateRange[0];
189 frameRateRange.max = fRateRange[1];
190 return frameRateRange;
191 }
192
GetActiveProfile(int32_t * errCode)193 CJProfile CJPreviewOutput::GetActiveProfile(int32_t *errCode)
194 {
195 MEDIA_DEBUG_LOG("GetActiveProfile is called");
196 if (previewOutput_ == nullptr) {
197 MEDIA_ERR_LOG("previewOutput is nullptr.");
198 *errCode = CameraError::CAMERA_SERVICE_ERROR;
199 return CJProfile{0};
200 }
201 auto profile = previewOutput_->GetPreviewProfile();
202 if (profile == nullptr) {
203 *errCode = CameraError::CAMERA_SERVICE_ERROR;
204 return CJProfile{0};
205 }
206 CJProfile cjProfile = CJProfile{
207 .format = profile->GetCameraFormat(), .width = profile->GetSize().width, .height = profile->GetSize().height};
208 return cjProfile;
209 }
210
GetPreviewRotation(int32_t value,int32_t * errCode)211 int32_t CJPreviewOutput::GetPreviewRotation(int32_t value, int32_t *errCode)
212 {
213 MEDIA_DEBUG_LOG("GetPreviewRotation is called!");
214 if (previewOutput_ == nullptr) {
215 *errCode = CameraError::CAMERA_SERVICE_ERROR;
216 return CameraError::CAMERA_SERVICE_ERROR;
217 }
218 int32_t res = previewOutput_->GetPreviewRotation(value);
219 if (res == CameraError::CAMERA_SERVICE_ERROR) {
220 *errCode = CameraError::CAMERA_SERVICE_ERROR;
221 }
222 return res;
223 }
224
SetPreviewRotation(int32_t imageRotation,bool isDisplayLocked)225 int32_t CJPreviewOutput::SetPreviewRotation(int32_t imageRotation, bool isDisplayLocked)
226 {
227 MEDIA_DEBUG_LOG("SetPreviewRotation is called!");
228 if (previewOutput_ == nullptr) {
229 return CameraError::CAMERA_SERVICE_ERROR;
230 }
231 int32_t errCode = previewOutput_->SetPreviewRotation(imageRotation, isDisplayLocked);
232 if (errCode == CameraError::CAMERA_SERVICE_ERROR) {
233 return errCode;
234 }
235 return CameraError::NO_ERROR;
236 }
237
OnFrameStart(int64_t callbackId)238 void CJPreviewOutput::OnFrameStart(int64_t callbackId)
239 {
240 if (previewCallback_ == nullptr) {
241 previewCallback_ = std::make_shared<CJPreviewOutputCallback>();
242 if (previewCallback_ == nullptr || previewOutput_ == nullptr) {
243 return;
244 }
245 previewOutput_->SetCallback(previewCallback_);
246 }
247 auto cFunc = reinterpret_cast<void (*)()>(callbackId);
248 auto callback = [lambda = CJLambda::Create(cFunc)]() -> void { lambda(); };
249 auto callbackRef = std::make_shared<CallbackRef<>>(callback, callbackId);
250
251 std::lock_guard<std::mutex> lock(previewCallback_->frameStartedMutex);
252 previewCallback_->frameStartedCallbackList.push_back(callbackRef);
253 }
254
OnFrameEnd(int64_t callbackId)255 void CJPreviewOutput::OnFrameEnd(int64_t callbackId)
256 {
257 if (previewCallback_ == nullptr) {
258 previewCallback_ = std::make_shared<CJPreviewOutputCallback>();
259 if (previewCallback_ == nullptr || previewOutput_ == nullptr) {
260 return;
261 }
262 previewOutput_->SetCallback(previewCallback_);
263 }
264 auto cFunc = reinterpret_cast<void (*)()>(callbackId);
265 auto callback = [lambda = CJLambda::Create(cFunc)]() -> void { lambda(); };
266 auto callbackRef = std::make_shared<CallbackRef<>>(callback, callbackId);
267
268 std::lock_guard<std::mutex> lock(previewCallback_->frameEndedMutex);
269 previewCallback_->frameEndedCallbackList.push_back(callbackRef);
270 }
271
OnError(int64_t callbackId)272 void CJPreviewOutput::OnError(int64_t callbackId)
273 {
274 if (previewCallback_ == nullptr) {
275 previewCallback_ = std::make_shared<CJPreviewOutputCallback>();
276 if (previewCallback_ == nullptr || previewOutput_ == nullptr) {
277 return;
278 }
279 previewOutput_->SetCallback(previewCallback_);
280 }
281 auto cFunc = reinterpret_cast<void (*)(const int32_t errorCode)>(callbackId);
282 auto callback = [lambda = CJLambda::Create(cFunc)](const int32_t errorCode) -> void { lambda(errorCode); };
283 auto callbackRef = std::make_shared<CallbackRef<const int32_t>>(callback, callbackId);
284
285 std::lock_guard<std::mutex> lock(previewCallback_->errorMutex);
286 previewCallback_->errorCallbackList.push_back(callbackRef);
287 }
288
OffFrameStart(int64_t callbackId)289 void CJPreviewOutput::OffFrameStart(int64_t callbackId)
290 {
291 if (previewCallback_ == nullptr) {
292 return;
293 }
294 std::lock_guard<std::mutex> lock(previewCallback_->frameStartedMutex);
295 for (auto it = previewCallback_->frameStartedCallbackList.begin();
296 it != previewCallback_->frameStartedCallbackList.end(); it++) {
297 if ((*it)->id == callbackId) {
298 previewCallback_->frameStartedCallbackList.erase(it);
299 break;
300 }
301 }
302 }
303
OffFrameEnd(int64_t callbackId)304 void CJPreviewOutput::OffFrameEnd(int64_t callbackId)
305 {
306 if (previewCallback_ == nullptr) {
307 return;
308 }
309 std::lock_guard<std::mutex> lock(previewCallback_->frameEndedMutex);
310 for (auto it = previewCallback_->frameEndedCallbackList.begin();
311 it != previewCallback_->frameEndedCallbackList.end(); it++) {
312 if ((*it)->id == callbackId) {
313 previewCallback_->frameEndedCallbackList.erase(it);
314 break;
315 }
316 }
317 }
318
OffError(int64_t callbackId)319 void CJPreviewOutput::OffError(int64_t callbackId)
320 {
321 if (previewCallback_ == nullptr) {
322 return;
323 }
324 std::lock_guard<std::mutex> lock(previewCallback_->errorMutex);
325 for (auto it = previewCallback_->errorCallbackList.begin(); it != previewCallback_->errorCallbackList.end(); it++) {
326 if ((*it)->id == callbackId) {
327 previewCallback_->errorCallbackList.erase(it);
328 break;
329 }
330 }
331 }
332
OffAllFrameStart()333 void CJPreviewOutput::OffAllFrameStart()
334 {
335 if (previewCallback_ == nullptr) {
336 return;
337 }
338 std::lock_guard<std::mutex> lock(previewCallback_->frameStartedMutex);
339 previewCallback_->frameStartedCallbackList.clear();
340 }
341
OffAllFrameEnd()342 void CJPreviewOutput::OffAllFrameEnd()
343 {
344 if (previewCallback_ == nullptr) {
345 return;
346 }
347 std::lock_guard<std::mutex> lock(previewCallback_->frameEndedMutex);
348 previewCallback_->frameEndedCallbackList.clear();
349 }
350
OffAllError()351 void CJPreviewOutput::OffAllError()
352 {
353 if (previewCallback_ == nullptr) {
354 return;
355 }
356
357 std::lock_guard<std::mutex> lock(previewCallback_->errorMutex);
358 previewCallback_->errorCallbackList.clear();
359 }
360
361 } // namespace CameraStandard
362 } // namespace OHOS