• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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