1 /*
2 * Copyright (c) 2021-2022 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 "input/camera_input.h"
17
18 #include <cinttypes>
19 #include <securec.h>
20 #include "camera_device_ability_items.h"
21 #include "camera_util.h"
22 #include "hcamera_device_callback_stub.h"
23 #include "camera_log.h"
24 #include "metadata_utils.h"
25 #include "session/capture_session.h"
26 #include "icamera_util.h"
27
28 namespace OHOS {
29 namespace CameraStandard {
30 class CameraDeviceServiceCallback : public HCameraDeviceCallbackStub {
31 public:
32 sptr<CameraInput> camInput_ = nullptr;
CameraDeviceServiceCallback()33 CameraDeviceServiceCallback() : camInput_(nullptr) {
34 }
35
CameraDeviceServiceCallback(const sptr<CameraInput> & camInput)36 explicit CameraDeviceServiceCallback(const sptr<CameraInput>& camInput) : camInput_(camInput) {
37 }
38
~CameraDeviceServiceCallback()39 ~CameraDeviceServiceCallback()
40 {
41 camInput_ = nullptr;
42 }
43
OnError(const int32_t errorType,const int32_t errorMsg)44 int32_t OnError(const int32_t errorType, const int32_t errorMsg) override
45 {
46 MEDIA_ERR_LOG("CameraDeviceServiceCallback::OnError() is called!, errorType: %{public}d, errorMsg: %{public}d",
47 errorType, errorMsg);
48 if (camInput_ != nullptr && camInput_->GetErrorCallback() != nullptr) {
49 camInput_->GetErrorCallback()->OnError(errorType, errorMsg);
50 } else {
51 MEDIA_INFO_LOG("CameraDeviceServiceCallback::ErrorCallback not set!, Discarding callback");
52 }
53 return CAMERA_OK;
54 }
55
OnResult(const uint64_t timestamp,const std::shared_ptr<Camera::CameraMetadata> & result)56 int32_t OnResult(const uint64_t timestamp, const std::shared_ptr<Camera::CameraMetadata> &result) override
57 {
58 MEDIA_INFO_LOG("CameraDeviceServiceCallback::OnResult() is called!, cameraId: %{public}s, timestamp: %{public}"
59 PRIu64, camInput_->GetCameraDeviceInfo()->GetID().c_str(), timestamp);
60
61 camInput_->ProcessDeviceCallbackUpdates(result);
62 return CAMERA_OK;
63 }
64 };
65
CameraInput(sptr<ICameraDeviceService> & deviceObj,sptr<CameraDevice> & cameraObj)66 CameraInput::CameraInput(sptr<ICameraDeviceService> &deviceObj,
67 sptr<CameraDevice> &cameraObj) : cameraObj_(cameraObj), deviceObj_(deviceObj)
68 {
69 CameraDeviceSvcCallback_ = new(std::nothrow) CameraDeviceServiceCallback(this);
70 if (CameraDeviceSvcCallback_ == nullptr) {
71 MEDIA_ERR_LOG("CameraInput::CameraInput CameraDeviceServiceCallback alloc failed");
72 return;
73 }
74 if (deviceObj_) {
75 deviceObj_->SetCallback(CameraDeviceSvcCallback_);
76 } else {
77 MEDIA_ERR_LOG("CameraInput::CameraInput() deviceObj_ is nullptr");
78 }
79 }
80
Open()81 int CameraInput::Open()
82 {
83 std::lock_guard<std::mutex> lock(interfaceMutex_);
84 int32_t retCode = CAMERA_UNKNOWN_ERROR;
85 if (deviceObj_) {
86 retCode = deviceObj_->Open();
87 if (retCode != CAMERA_OK) {
88 MEDIA_ERR_LOG("Failed to open Camera Input, retCode: %{public}d", retCode);
89 }
90 } else {
91 MEDIA_ERR_LOG("CameraInput::Open() deviceObj_ is nullptr");
92 }
93 return ServiceToCameraError(retCode);
94 }
95
Close()96 int CameraInput::Close()
97 {
98 std::lock_guard<std::mutex> lock(interfaceMutex_);
99 int32_t retCode = CAMERA_UNKNOWN_ERROR;
100 if (deviceObj_) {
101 retCode = deviceObj_->Close();
102 if (retCode != CAMERA_OK) {
103 MEDIA_ERR_LOG("Failed to close Camera Input, retCode: %{public}d", retCode);
104 }
105 } else {
106 MEDIA_ERR_LOG("CameraInput::Close() deviceObj_ is nullptr");
107 }
108 cameraObj_ = nullptr;
109 deviceObj_ = nullptr;
110 CameraDeviceSvcCallback_ = nullptr;
111 CaptureInput::Release();
112 return ServiceToCameraError(retCode);
113 }
114
Release()115 int CameraInput::Release()
116 {
117 int32_t retCode = CAMERA_UNKNOWN_ERROR;
118 if (deviceObj_) {
119 retCode = deviceObj_->Release();
120 if (retCode != CAMERA_OK) {
121 MEDIA_ERR_LOG("Failed to release Camera Input, retCode: %{public}d", retCode);
122 }
123 } else {
124 MEDIA_ERR_LOG("CameraInput::Release() deviceObj_ is nullptr");
125 }
126 cameraObj_ = nullptr;
127 deviceObj_ = nullptr;
128 CameraDeviceSvcCallback_ = nullptr;
129 CaptureInput::Release();
130 return ServiceToCameraError(retCode);
131 }
132
SetErrorCallback(std::shared_ptr<ErrorCallback> errorCallback)133 void CameraInput::SetErrorCallback(std::shared_ptr<ErrorCallback> errorCallback)
134 {
135 if (errorCallback == nullptr) {
136 MEDIA_ERR_LOG("SetErrorCallback: Unregistering error callback");
137 }
138 errorCallback_ = errorCallback;
139 return;
140 }
141
GetCameraId()142 std::string CameraInput::GetCameraId()
143 {
144 return cameraObj_->GetID();
145 }
146
GetCameraDevice()147 sptr<ICameraDeviceService> CameraInput::GetCameraDevice()
148 {
149 return deviceObj_;
150 }
151
GetErrorCallback()152 std::shared_ptr<ErrorCallback> CameraInput::GetErrorCallback()
153 {
154 return errorCallback_;
155 }
156
GetCameraDeviceInfo()157 sptr<CameraDevice> CameraInput::GetCameraDeviceInfo()
158 {
159 return cameraObj_;
160 }
161
ProcessDeviceCallbackUpdates(const std::shared_ptr<Camera::CameraMetadata> & result)162 void CameraInput::ProcessDeviceCallbackUpdates(const std::shared_ptr<Camera::CameraMetadata> &result)
163 {
164 CaptureSession* captureSession = GetSession();
165 if (captureSession == nullptr) {
166 return;
167 }
168
169 captureSession->ProcessAutoExposureUpdates(result);
170 captureSession->ProcessAutoFocusUpdates(result);
171 }
172
UpdateSetting(std::shared_ptr<OHOS::Camera::CameraMetadata> changedMetadata)173 int32_t CameraInput::UpdateSetting(std::shared_ptr<OHOS::Camera::CameraMetadata> changedMetadata)
174 {
175 CAMERA_SYNC_TRACE;
176 int32_t ret = CAMERA_OK;
177 if (!OHOS::Camera::GetCameraMetadataItemCount(changedMetadata->get())) {
178 MEDIA_INFO_LOG("CameraInput::UpdateSetting No configuration to update");
179 return ret;
180 }
181
182 if (deviceObj_) {
183 ret = deviceObj_->UpdateSetting(changedMetadata);
184 } else {
185 MEDIA_ERR_LOG("CameraInput::UpdateSetting() deviceObj_ is nullptr");
186 }
187 if (ret != CAMERA_OK) {
188 MEDIA_ERR_LOG("CameraInput::UpdateSetting Failed to update settings");
189 return ret;
190 }
191
192 size_t length;
193 uint32_t count = changedMetadata->get()->item_count;
194 uint8_t* data = OHOS::Camera::GetMetadataData(changedMetadata->get());
195 camera_metadata_item_entry_t* itemEntry = OHOS::Camera::GetMetadataItems(changedMetadata->get());
196 std::shared_ptr<OHOS::Camera::CameraMetadata> baseMetadata = cameraObj_->GetMetadata();
197 for (uint32_t i = 0; i < count; i++, itemEntry++) {
198 bool status = false;
199 camera_metadata_item_t item;
200 length = OHOS::Camera::CalculateCameraMetadataItemDataSize(itemEntry->data_type, itemEntry->count);
201 ret = OHOS::Camera::FindCameraMetadataItem(baseMetadata->get(), itemEntry->item, &item);
202 if (ret == CAM_META_SUCCESS) {
203 status = baseMetadata->updateEntry(itemEntry->item,
204 (length == 0) ? itemEntry->data.value : (data + itemEntry->data.offset),
205 itemEntry->count);
206 } else if (ret == CAM_META_ITEM_NOT_FOUND) {
207 status = baseMetadata->addEntry(itemEntry->item,
208 (length == 0) ? itemEntry->data.value : (data + itemEntry->data.offset),
209 itemEntry->count);
210 }
211 if (!status) {
212 MEDIA_ERR_LOG("CameraInput::UpdateSetting Failed to add/update metadata item: %{public}d",
213 itemEntry->item);
214 }
215 }
216 return CAMERA_OK;
217 }
218
GetCameraSettings()219 std::string CameraInput::GetCameraSettings()
220 {
221 return OHOS::Camera::MetadataUtils::EncodeToString(cameraObj_->GetMetadata());
222 }
223
SetCameraSettings(std::string setting)224 int32_t CameraInput::SetCameraSettings(std::string setting)
225 {
226 std::shared_ptr<OHOS::Camera::CameraMetadata> metadata = OHOS::Camera::MetadataUtils::DecodeFromString(setting);
227 if (metadata == nullptr) {
228 MEDIA_ERR_LOG("CameraInput::SetCameraSettings Failed to decode metadata setting from string");
229 return CAMERA_INVALID_ARG;
230 }
231 return UpdateSetting(metadata);
232 }
233 } // CameraStandard
234 } // OHOS
235