1 /*
2 * Copyright (C) 2021 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 "dcamera_client.h"
17
18 #include "anonymous_string.h"
19 #include "dcamera_input_callback.h"
20 #include "dcamera_manager_callback.h"
21 #include "dcamera_photo_callback.h"
22 #include "dcamera_session_callback.h"
23 #include "dcamera_utils_tools.h"
24 #include "dcamera_video_callback.h"
25 #include "distributed_camera_constants.h"
26 #include "distributed_camera_errno.h"
27 #include "distributed_hardware_log.h"
28 #include "metadata_utils.h"
29
30 namespace OHOS {
31 namespace DistributedHardware {
DCameraClient(const std::string & dhId)32 DCameraClient::DCameraClient(const std::string& dhId)
33 {
34 DHLOGI("DCameraClient Constructor dhId: %s", GetAnonyString(dhId).c_str());
35 cameraId_ = dhId.substr(CAMERA_ID_PREFIX.size());
36 isInit_ = false;
37 }
38
~DCameraClient()39 DCameraClient::~DCameraClient()
40 {
41 if (isInit_) {
42 UnInit();
43 }
44 }
45
Init()46 int32_t DCameraClient::Init()
47 {
48 DHLOGI("DCameraClient::Init cameraId: %s", GetAnonyString(cameraId_).c_str());
49 cameraManager_ = CameraStandard::CameraManager::GetInstance();
50 if (cameraManager_ == nullptr) {
51 DHLOGE("DCameraClient::Init cameraManager getInstance failed");
52 return DCAMERA_BAD_VALUE;
53 }
54 cameraManager_->SetCallback(std::make_shared<DCameraManagerCallback>());
55
56 std::vector<sptr<CameraStandard::CameraInfo>> cameraList = cameraManager_->GetCameras();
57 DHLOGI("DCameraClient::Init camera size: %d", cameraList.size());
58 for (auto& info : cameraList) {
59 if (info->GetID() == cameraId_) {
60 DHLOGI("DCameraClient::Init cameraInfo get id: %s", GetAnonyString(info->GetID()).c_str());
61 cameraInfo_ = info;
62 break;
63 }
64 }
65 if (cameraInfo_ == nullptr) {
66 DHLOGE("DCameraClient::Init cameraInfo is null");
67 return DCAMERA_BAD_VALUE;
68 }
69
70 isInit_ = true;
71 DHLOGI("DCameraClient::Init %s success", GetAnonyString(cameraId_).c_str());
72 return DCAMERA_OK;
73 }
74
UnInit()75 int32_t DCameraClient::UnInit()
76 {
77 DHLOGI("DCameraClient::UnInit cameraId: %s", GetAnonyString(cameraId_).c_str());
78 if (cameraManager_ != nullptr) {
79 DHLOGI("DCameraClient::UnInit unregister cameraManager callback");
80 cameraManager_->SetCallback(nullptr);
81 }
82
83 isInit_ = false;
84 cameraInfo_ = nullptr;
85 cameraManager_ = nullptr;
86 DHLOGI("DCameraClient::UnInit %s success", GetAnonyString(cameraId_).c_str());
87 return DCAMERA_OK;
88 }
89
UpdateSettings(std::vector<std::shared_ptr<DCameraSettings>> & settings)90 int32_t DCameraClient::UpdateSettings(std::vector<std::shared_ptr<DCameraSettings>>& settings)
91 {
92 DHLOGI("DCameraClient::UpdateCameraSettings cameraId: %s", GetAnonyString(cameraId_).c_str());
93 for (auto& setting : settings) {
94 switch (setting->type_) {
95 case UPDATE_METADATA: {
96 DHLOGI("DCameraClient::UpdateCameraSettings %s update metadata settings",
97 GetAnonyString(cameraId_).c_str());
98 std::string metadataStr = Base64Decode(setting->value_);
99 int32_t ret = ((sptr<CameraStandard::CameraInput> &)cameraInput_)->SetCameraSettings(metadataStr);
100 if (ret != DCAMERA_OK) {
101 DHLOGE("DCameraClient::UpdateSettings %s update metadata settings failed, ret: %d",
102 GetAnonyString(cameraId_).c_str(), ret);
103 return ret;
104 }
105 break;
106 }
107 default: {
108 DHLOGE("DCameraClient::UpdateSettings unknown setting type");
109 break;
110 }
111 }
112 }
113 DHLOGI("DCameraClient::UpdateCameraSettings %s success", GetAnonyString(cameraId_).c_str());
114 return DCAMERA_OK;
115 }
116
StartCapture(std::vector<std::shared_ptr<DCameraCaptureInfo>> & captureInfos)117 int32_t DCameraClient::StartCapture(std::vector<std::shared_ptr<DCameraCaptureInfo>>& captureInfos)
118 {
119 DHLOGI("DCameraClient::StartCapture cameraId: %s", GetAnonyString(cameraId_).c_str());
120 if ((photoOutput_ == nullptr) && (videoOutput_ == nullptr)) {
121 DHLOGI("DCameraClient::StartCapture %s config capture session", GetAnonyString(cameraId_).c_str());
122 int32_t ret = ConfigCaptureSession(captureInfos);
123 if (ret != DCAMERA_OK) {
124 DHLOGE("DCameraClient::StartCapture config capture session failed, cameraId: %s, ret: %d",
125 GetAnonyString(cameraId_).c_str(), ret);
126 return ret;
127 }
128 }
129
130 for (auto& info : captureInfos) {
131 if (!(info->isCapture_)) {
132 continue;
133 }
134 int32_t ret = StartCaptureInner(info);
135 if (ret != DCAMERA_OK) {
136 DHLOGE("DCameraClient::StartCapture failed, cameraId: %s, ret: %d", GetAnonyString(cameraId_).c_str(), ret);
137 return ret;
138 }
139 }
140 DHLOGI("DCameraClient::StartCapture %s success", GetAnonyString(cameraId_).c_str());
141 return DCAMERA_OK;
142 }
143
StopCapture()144 int32_t DCameraClient::StopCapture()
145 {
146 DHLOGI("DCameraClient::StopCapture cameraId: %s", GetAnonyString(cameraId_).c_str());
147 if (videoOutput_ != nullptr) {
148 DHLOGI("DCameraClient::StopCapture %s stop videoOutput", GetAnonyString(cameraId_).c_str());
149 int32_t ret = ((sptr<CameraStandard::VideoOutput> &)videoOutput_)->Stop();
150 if (ret != DCAMERA_OK) {
151 DHLOGE("DCameraClient::StopCapture videoOutput stop failed, cameraId: %s, ret: %d",
152 GetAnonyString(cameraId_).c_str(), ret);
153 }
154 }
155
156 if (captureSession_ != nullptr) {
157 DHLOGI("DCameraClient::StopCapture %s stop captureSession", GetAnonyString(cameraId_).c_str());
158 int32_t ret = captureSession_->Stop();
159 if (ret != DCAMERA_OK) {
160 DHLOGE("DCameraClient::StopCapture captureSession stop failed, cameraId: %s, ret: %d",
161 GetAnonyString(cameraId_).c_str(), ret);
162 }
163 DHLOGI("DCameraClient::StopCapture %s release captureSession", GetAnonyString(cameraId_).c_str());
164 captureSession_->Release();
165 }
166
167 if (cameraInput_ != nullptr) {
168 DHLOGI("DCameraClient::StopCapture %s release cameraInput", GetAnonyString(cameraId_).c_str());
169 cameraInput_->Release();
170 }
171
172 photoOutput_ = nullptr;
173 videoOutput_ = nullptr;
174 cameraInput_ = nullptr;
175 captureSession_ = nullptr;
176 DHLOGI("DCameraClient::StopCapture %s success", GetAnonyString(cameraId_).c_str());
177 return DCAMERA_OK;
178 }
179
SetStateCallback(std::shared_ptr<StateCallback> & callback)180 int32_t DCameraClient::SetStateCallback(std::shared_ptr<StateCallback>& callback)
181 {
182 DHLOGI("DCameraClient::SetStateCallback cameraId: %s", GetAnonyString(cameraId_).c_str());
183 if (callback == nullptr) {
184 DHLOGE("DCameraClient::SetStateCallback %s unregistering state callback", GetAnonyString(cameraId_).c_str());
185 }
186 stateCallback_ = callback;
187 return DCAMERA_OK;
188 }
189
SetResultCallback(std::shared_ptr<ResultCallback> & callback)190 int32_t DCameraClient::SetResultCallback(std::shared_ptr<ResultCallback>& callback)
191 {
192 DHLOGI("DCameraClient::SetResultCallback cameraId: %s", GetAnonyString(cameraId_).c_str());
193 if (callback == nullptr) {
194 DHLOGE("DCameraClient::SetResultCallback %s unregistering result callback", GetAnonyString(cameraId_).c_str());
195 }
196 resultCallback_ = callback;
197 return DCAMERA_OK;
198 }
199
ConfigCaptureSession(std::vector<std::shared_ptr<DCameraCaptureInfo>> & captureInfos)200 int32_t DCameraClient::ConfigCaptureSession(std::vector<std::shared_ptr<DCameraCaptureInfo>>& captureInfos)
201 {
202 DHLOGI("DCameraClient::ConfigCaptureSession cameraId: %s", GetAnonyString(cameraId_).c_str());
203 cameraInput_ = cameraManager_->CreateCameraInput(cameraInfo_);
204 if (cameraInput_ == nullptr) {
205 DHLOGE("DCameraClient::ConfigCaptureSession %s create cameraInput failed", GetAnonyString(cameraId_).c_str());
206 return DCAMERA_BAD_VALUE;
207 }
208 std::shared_ptr<DCameraInputCallback> inputCallback = std::make_shared<DCameraInputCallback>(stateCallback_);
209 ((sptr<CameraStandard::CameraInput> &)cameraInput_)->SetErrorCallback(inputCallback);
210
211 captureSession_ = cameraManager_->CreateCaptureSession();
212 if (captureSession_ == nullptr) {
213 DHLOGE("DCameraClient::ConfigCaptureSession %s create captureSession failed",
214 GetAnonyString(cameraId_).c_str());
215 return DCAMERA_BAD_VALUE;
216 }
217 captureSession_->SetCallback(std::make_shared<DCameraSessionCallback>(stateCallback_));
218
219 int32_t ret = CreateCaptureOutput(captureInfos);
220 if (ret != DCAMERA_OK) {
221 DHLOGE("DCameraClient::ConfigCaptureSession create capture output failed, cameraId: %s, ret: %d",
222 GetAnonyString(cameraId_).c_str(), ret);
223 return ret;
224 }
225
226 return ConfigCaptureSessionInner();
227 }
228
ConfigCaptureSessionInner()229 int32_t DCameraClient::ConfigCaptureSessionInner()
230 {
231 int32_t ret = captureSession_->BeginConfig();
232 if (ret != DCAMERA_OK) {
233 DHLOGE("DCameraClient::ConfigCaptureSession %s config captureSession failed, ret: %d",
234 GetAnonyString(cameraId_).c_str(), ret);
235 return ret;
236 }
237
238 ret = captureSession_->AddInput(cameraInput_);
239 if (ret != DCAMERA_OK) {
240 DHLOGE("DCameraClient::ConfigCaptureSession %s add cameraInput to captureSession failed, ret: %d",
241 GetAnonyString(cameraId_).c_str(), ret);
242 return ret;
243 }
244
245 if (photoOutput_ != nullptr) {
246 ret = captureSession_->AddOutput(photoOutput_);
247 if (ret != DCAMERA_OK) {
248 DHLOGE("DCameraClient::ConfigCaptureSession %s add photoOutput to captureSession failed, ret: %d",
249 GetAnonyString(cameraId_).c_str(), ret);
250 return ret;
251 }
252 }
253
254 if (videoOutput_ != nullptr) {
255 ret = captureSession_->AddOutput(videoOutput_);
256 if (ret != DCAMERA_OK) {
257 DHLOGE("DCameraClient::ConfigCaptureSession %s add videoOutput to captureSession failed, ret: %d",
258 GetAnonyString(cameraId_).c_str(), ret);
259 return ret;
260 }
261 }
262
263 ret = captureSession_->CommitConfig();
264 if (ret != DCAMERA_OK) {
265 DHLOGE("DCameraClient::ConfigCaptureSession %s commit captureSession failed, ret: %d",
266 GetAnonyString(cameraId_).c_str(), ret);
267 return ret;
268 }
269
270 ret = captureSession_->Start();
271 if (ret != DCAMERA_OK) {
272 DHLOGE("DCameraClient::ConfigCaptureSession %s start captureSession failed, ret: %d",
273 GetAnonyString(cameraId_).c_str(), ret);
274 }
275
276 DHLOGI("DCameraClient::ConfigCaptureSession %s success", GetAnonyString(cameraId_).c_str());
277 return DCAMERA_OK;
278 }
279
CreateCaptureOutput(std::vector<std::shared_ptr<DCameraCaptureInfo>> & captureInfos)280 int32_t DCameraClient::CreateCaptureOutput(std::vector<std::shared_ptr<DCameraCaptureInfo>>& captureInfos)
281 {
282 if (captureInfos.empty()) {
283 DHLOGE("DCameraClient::CreateCaptureOutput no capture info, cameraId: %s", GetAnonyString(cameraId_).c_str());
284 return DCAMERA_BAD_VALUE;
285 }
286
287 for (auto& info : captureInfos) {
288 if (info->streamType_ == SNAPSHOT_FRAME) {
289 int32_t ret = CreatePhotoOutput(info);
290 if (ret != DCAMERA_OK) {
291 DHLOGE("DCameraClient::CreateCaptureOutput %s create photo output failed, ret: %d",
292 GetAnonyString(cameraId_).c_str(), ret);
293 return ret;
294 }
295 } else if (info->streamType_ == CONTINUOUS_FRAME) {
296 int32_t ret = CreateVideoOutput(info);
297 if (ret != DCAMERA_OK) {
298 DHLOGE("DCameraClient::CreateCaptureOutput %s create video output failed, ret: %d",
299 GetAnonyString(cameraId_).c_str(), ret);
300 return ret;
301 }
302 } else {
303 DHLOGE("DCameraClient::CreateCaptureOutput unknown stream type");
304 return DCAMERA_BAD_VALUE;
305 }
306 }
307 return DCAMERA_OK;
308 }
309
CreatePhotoOutput(std::shared_ptr<DCameraCaptureInfo> & info)310 int32_t DCameraClient::CreatePhotoOutput(std::shared_ptr<DCameraCaptureInfo>& info)
311 {
312 DHLOGI("DCameraClient::CreatePhotoOutput camId: %s, width: %d, height: %d, format: %d, stream: %d, isCapture: %d",
313 GetAnonyString(cameraId_).c_str(), info->width_, info->height_, info->format_,
314 info->streamType_, info->isCapture_);
315 photoSurface_ = Surface::CreateSurfaceAsConsumer();
316 photoSurface_->SetDefaultWidthAndHeight(info->width_, info->height_);
317 photoSurface_->SetUserData(CAMERA_SURFACE_FORMAT, std::to_string(info->format_));
318 photoListener_ = std::make_shared<DCameraPhotoSurfaceListener>(photoSurface_, resultCallback_);
319 photoSurface_->RegisterConsumerListener((sptr<IBufferConsumerListener> &)photoListener_);
320 photoOutput_ = cameraManager_->CreatePhotoOutput(photoSurface_);
321 if (photoOutput_ == nullptr) {
322 DHLOGE("DCameraClient::CreatePhotoOutput %s create photo output failed", GetAnonyString(cameraId_).c_str());
323 return DCAMERA_BAD_VALUE;
324 }
325 std::shared_ptr<DCameraPhotoCallback> photoCallback = std::make_shared<DCameraPhotoCallback>(stateCallback_);
326 ((sptr<CameraStandard::PhotoOutput> &)photoOutput_)->SetCallback(photoCallback);
327 DHLOGI("DCameraClient::CreatePhotoOutput %s success", GetAnonyString(cameraId_).c_str());
328 return DCAMERA_OK;
329 }
330
CreateVideoOutput(std::shared_ptr<DCameraCaptureInfo> & info)331 int32_t DCameraClient::CreateVideoOutput(std::shared_ptr<DCameraCaptureInfo>& info)
332 {
333 DHLOGI("DCameraClient::CreateVideoOutput camId: %s, width: %d, height: %d, format: %d, stream: %d, isCapture: %d",
334 GetAnonyString(cameraId_).c_str(), info->width_, info->height_, info->format_,
335 info->streamType_, info->isCapture_);
336 videoSurface_ = Surface::CreateSurfaceAsConsumer();
337 videoSurface_->SetDefaultWidthAndHeight(info->width_, info->height_);
338 videoSurface_->SetUserData(CAMERA_SURFACE_FORMAT, std::to_string(info->format_));
339 videoListener_ = std::make_shared<DCameraVideoSurfaceListener>(videoSurface_, resultCallback_);
340 videoSurface_->RegisterConsumerListener((sptr<IBufferConsumerListener> &)videoListener_);
341 videoOutput_ = cameraManager_->CreateVideoOutput(videoSurface_);
342 if (videoOutput_ == nullptr) {
343 DHLOGE("DCameraClient::CreateVideoOutput %s create video output failed", GetAnonyString(cameraId_).c_str());
344 return DCAMERA_BAD_VALUE;
345 }
346 std::shared_ptr<DCameraVideoCallback> videoCallback = std::make_shared<DCameraVideoCallback>(stateCallback_);
347 ((sptr<CameraStandard::VideoOutput> &)videoOutput_)->SetCallback(videoCallback);
348 DHLOGI("DCameraClient::CreateVideoOutput %s success", GetAnonyString(cameraId_).c_str());
349 return DCAMERA_OK;
350 }
351
StartCaptureInner(std::shared_ptr<DCameraCaptureInfo> & info)352 int32_t DCameraClient::StartCaptureInner(std::shared_ptr<DCameraCaptureInfo>& info)
353 {
354 switch (info->streamType_) {
355 case CONTINUOUS_FRAME: {
356 return StartVideoOutput();
357 }
358 case SNAPSHOT_FRAME: {
359 return StartPhotoOutput(info);
360 }
361 default: {
362 DHLOGE("DCameraClient::StartCaptureInner unknown stream type");
363 return DCAMERA_BAD_VALUE;
364 }
365 }
366 }
367
StartPhotoOutput(std::shared_ptr<DCameraCaptureInfo> & info)368 int32_t DCameraClient::StartPhotoOutput(std::shared_ptr<DCameraCaptureInfo>& info)
369 {
370 DHLOGI("DCameraClient::StartPhotoOutput cameraId: %s", GetAnonyString(cameraId_).c_str());
371 if (photoOutput_ == nullptr) {
372 DHLOGE("DCameraClient::StartPhotoOutput photoOutput is null");
373 return DCAMERA_BAD_VALUE;
374 }
375
376 std::vector<std::shared_ptr<DCameraSettings>> captureSettings = info->captureSettings_;
377 std::string metadataSetting;
378 for (auto& setting : captureSettings) {
379 if (setting->type_ == UPDATE_METADATA) {
380 DHLOGI("DCameraClient::StartPhotoOutput %s update metadata settings", GetAnonyString(cameraId_).c_str());
381 metadataSetting = setting->value_;
382 }
383 }
384
385 if (metadataSetting.empty()) {
386 DHLOGE("DCameraClient::StartPhotoOutput no metadata settings to update");
387 int32_t ret = ((sptr<CameraStandard::PhotoOutput> &)photoOutput_)->Capture();
388 if (ret != DCAMERA_OK) {
389 DHLOGE("DCameraClient::StartPhotoOutput %s photoOutput capture failed, ret: %d",
390 GetAnonyString(cameraId_).c_str(), ret);
391 return ret;
392 }
393 return DCAMERA_OK;
394 }
395
396 camera_metadata_item_t item;
397 CameraStandard::PhotoCaptureSetting::RotationConfig rotation =
398 CameraStandard::PhotoCaptureSetting::RotationConfig::Rotation_0;
399 std::shared_ptr<Camera::CameraMetadata> cameraMetadata =
400 Camera::MetadataUtils::DecodeFromString(Base64Decode(metadataSetting));
401 int32_t ret = Camera::FindCameraMetadataItem(cameraMetadata->get(), OHOS_JPEG_ORIENTATION, &item);
402 if (ret == DCAMERA_OK) {
403 DHLOGI("DCameraClient::StartPhotoOutput %s find camera metadata item", GetAnonyString(cameraId_).c_str());
404 rotation = static_cast<CameraStandard::PhotoCaptureSetting::RotationConfig>(item.data.i32[0]);
405 }
406
407 DHLOGI("DCameraClient::StartPhotoOutput %s photo capture settings set rotation: %d",
408 GetAnonyString(cameraId_).c_str(), rotation);
409 std::shared_ptr<CameraStandard::PhotoCaptureSetting> photoCaptureSettings =
410 std::make_shared<CameraStandard::PhotoCaptureSetting>();
411 photoCaptureSettings->SetRotation(rotation);
412 ret = ((sptr<CameraStandard::PhotoOutput> &)photoOutput_)->Capture(photoCaptureSettings);
413 if (ret != DCAMERA_OK) {
414 DHLOGE("DCameraClient::StartPhotoOutput %s photoOutput capture failed, ret: %d",
415 GetAnonyString(cameraId_).c_str(), ret);
416 return ret;
417 }
418 return DCAMERA_OK;
419 }
420
StartVideoOutput()421 int32_t DCameraClient::StartVideoOutput()
422 {
423 DHLOGI("DCameraClient::StartVideoOutput cameraId: %s", GetAnonyString(cameraId_).c_str());
424 if (videoOutput_ == nullptr) {
425 DHLOGE("DCameraClient::StartVideoOutput videoOutput is null");
426 return DCAMERA_BAD_VALUE;
427 }
428 int32_t ret = ((sptr<CameraStandard::VideoOutput> &)videoOutput_)->Start();
429 if (ret != DCAMERA_OK) {
430 DHLOGE("DCameraClient::StartVideoOutput %s videoOutput start failed, ret: %d",
431 GetAnonyString(cameraId_).c_str(), ret);
432 return ret;
433 }
434 return DCAMERA_OK;
435 }
436 } // namespace DistributedHardware
437 } // namespace OHOS