1 /*
2 * Copyright (c) 2021-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 "dcamera_handler.h"
17
18 #include <functional>
19
20 #include "anonymous_string.h"
21 #include "avcodec_info.h"
22 #include "avcodec_list.h"
23 #include "dcamera_manager_callback.h"
24 #include "dcamera_utils_tools.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 {
32 IMPLEMENT_SINGLE_INSTANCE(DCameraHandler);
33
34 const int32_t MAXWIDTHSIZE = 65535;
35
~DCameraHandler()36 DCameraHandler::~DCameraHandler()
37 {
38 DHLOGI("~DCameraHandler");
39 }
40
Initialize()41 int32_t DCameraHandler::Initialize()
42 {
43 DHLOGI("start");
44 cameraManager_ = CameraStandard::CameraManager::GetInstance();
45 if (cameraManager_ == nullptr) {
46 DHLOGE("cameraManager getInstance failed");
47 return DCAMERA_INIT_ERR;
48 }
49 std::shared_ptr<DCameraManagerCallback> cameraMgrCallback = std::make_shared<DCameraManagerCallback>();
50 cameraManager_->SetCallback(cameraMgrCallback);
51 DHLOGI("success");
52 return DCAMERA_OK;
53 }
54
Query()55 std::vector<DHItem> DCameraHandler::Query()
56 {
57 std::vector<DHItem> itemList;
58 std::vector<sptr<CameraStandard::CameraDevice>> cameraList = cameraManager_->GetSupportedCameras();
59 DHLOGI("get %d cameras", cameraList.size());
60 if (cameraList.empty()) {
61 DHLOGE("no camera device");
62 return itemList;
63 }
64 for (auto& info : cameraList) {
65 if (info->GetConnectionType() != CameraStandard::ConnectionType::CAMERA_CONNECTION_BUILT_IN) {
66 DHLOGI("connection type: %d", info->GetConnectionType());
67 continue;
68 }
69 DHLOGI("get %s, position: %d, cameraType: %d",
70 GetAnonyString(info->GetID()).c_str(), info->GetPosition(), info->GetCameraType());
71 DHItem item;
72 if (CreateDHItem(info, item) == DCAMERA_OK) {
73 itemList.emplace_back(item);
74 }
75 }
76 DHLOGI("success, get %d items", itemList.size());
77 return itemList;
78 }
79
QueryExtraInfo()80 std::map<std::string, std::string> DCameraHandler::QueryExtraInfo()
81 {
82 DHLOGI("enter");
83 std::map<std::string, std::string> extraInfo;
84 return extraInfo;
85 }
86
IsSupportPlugin()87 bool DCameraHandler::IsSupportPlugin()
88 {
89 DHLOGI("enter");
90 return false;
91 }
92
RegisterPluginListener(std::shared_ptr<PluginListener> listener)93 void DCameraHandler::RegisterPluginListener(std::shared_ptr<PluginListener> listener)
94 {
95 DHLOGI("enter");
96 if (listener == nullptr) {
97 DHLOGE("DCameraHandler unregistering plugin listener");
98 }
99 pluginListener_ = listener;
100 }
101
UnRegisterPluginListener()102 void DCameraHandler::UnRegisterPluginListener()
103 {
104 DHLOGI("enter");
105 pluginListener_ = nullptr;
106 }
107
GetCameras()108 std::vector<std::string> DCameraHandler::GetCameras()
109 {
110 std::vector<std::string> cameras;
111 std::vector<sptr<CameraStandard::CameraDevice>> cameraList = cameraManager_->GetSupportedCameras();
112 DHLOGI("get %d cameras", cameraList.size());
113 if (cameraList.empty()) {
114 DHLOGE("no camera device");
115 return cameras;
116 }
117 for (auto& info : cameraList) {
118 sptr<CameraStandard::CameraOutputCapability> capability = cameraManager_->GetSupportedOutputCapability(info);
119 if (capability == nullptr) {
120 DHLOGI("get supported capability is null");
121 continue;
122 }
123 if (info->GetConnectionType() != CameraStandard::ConnectionType::CAMERA_CONNECTION_BUILT_IN) {
124 DHLOGI("connection type: %d", info->GetConnectionType());
125 continue;
126 }
127 DHLOGI("get %s, position: %d, cameraType: %d",
128 GetAnonyString(info->GetID()).c_str(), info->GetPosition(), info->GetCameraType());
129 std::string dhId = CAMERA_ID_PREFIX + info->GetID();
130 cameras.emplace_back(dhId);
131 }
132 DHLOGI("success, get %d items", cameras.size());
133 return cameras;
134 }
135
CreateAVCodecList(Json::Value & root)136 int32_t DCameraHandler::CreateAVCodecList(Json::Value& root)
137 {
138 DHLOGI("Create avCodecList start");
139 std::shared_ptr<MediaAVCodec::AVCodecList> avCodecList = MediaAVCodec::AVCodecListFactory::CreateAVCodecList();
140 if (avCodecList == nullptr) {
141 DHLOGI("Create avCodecList failed");
142 return DCAMERA_BAD_VALUE;
143 }
144 const std::vector<std::string> encoderName = {std::string(MediaAVCodec::CodecMimeType::VIDEO_AVC),
145 std::string(MediaAVCodec::CodecMimeType::VIDEO_HEVC)};
146 for (auto &coder : encoderName) {
147 MediaAVCodec::CapabilityData *capData = avCodecList->GetCapability(coder, true,
148 MediaAVCodec::AVCodecCategory::AVCODEC_HARDWARE);
149 if (capData == nullptr) {
150 DHLOGI("capData is nullptr");
151 return DCAMERA_BAD_VALUE;
152 }
153 std::string mimeType = capData->mimeType;
154 root[CAMERA_CODEC_TYPE_KEY].append(mimeType);
155 DHLOGI("codec name: %s, mimeType: %s", coder.c_str(), mimeType.c_str());
156 }
157 return DCAMERA_OK;
158 }
159
CreateDHItem(sptr<CameraStandard::CameraDevice> & info,DHItem & item)160 int32_t DCameraHandler::CreateDHItem(sptr<CameraStandard::CameraDevice>& info, DHItem& item)
161 {
162 std::string id = info->GetID();
163 item.dhId = CAMERA_ID_PREFIX + id;
164 item.subtype = "camera";
165 DHLOGI("camera id: %s", GetAnonyString(id).c_str());
166
167 Json::Value root;
168 root[CAMERA_PROTOCOL_VERSION_KEY] = Json::Value(CAMERA_PROTOCOL_VERSION_VALUE);
169 root[CAMERA_POSITION_KEY] = Json::Value(GetCameraPosition(info->GetPosition()));
170 int32_t ret = CreateAVCodecList(root);
171 if (ret != DCAMERA_OK) {
172 DHLOGI("CreateAVCodecList failed");
173 return DCAMERA_BAD_VALUE;
174 }
175 sptr<CameraStandard::CameraOutputCapability> capability = cameraManager_->GetSupportedOutputCapability(info);
176 if (capability == nullptr) {
177 DHLOGI("get supported capability is null");
178 return DCAMERA_BAD_VALUE;
179 }
180 std::vector<CameraStandard::Profile> photoProfiles = capability->GetPhotoProfiles();
181 ConfigFormatAndResolution(SNAPSHOT_FRAME, root, photoProfiles);
182
183 std::vector<CameraStandard::Profile> previewProfiles = capability->GetPreviewProfiles();
184 ConfigFormatAndResolution(CONTINUOUS_FRAME, root, previewProfiles);
185
186 sptr<CameraStandard::CameraInput> cameraInput = nullptr;
187 int rv = cameraManager_->CreateCameraInput(info, &cameraInput);
188 if (rv != DCAMERA_OK) {
189 DHLOGE("create cameraInput failed");
190 return DCAMERA_BAD_VALUE;
191 }
192
193 std::hash<std::string> h;
194 std::string abilityString = cameraInput->GetCameraSettings();
195 DHLOGI("abilityString hash: %zu, length: %zu", h(abilityString), abilityString.length());
196
197 std::string encodeString = Base64Encode(reinterpret_cast<const unsigned char *>(abilityString.c_str()),
198 abilityString.length());
199 DHLOGI("encodeString hash: %zu, length: %zu", h(encodeString), encodeString.length());
200 root[CAMERA_METADATA_KEY] = Json::Value(encodeString);
201
202 item.attrs = root.toStyledString();
203 if (cameraInput->Release() != DCAMERA_OK) {
204 DHLOGE("cameraInput Release failed");
205 }
206 return DCAMERA_OK;
207 }
208
GetCameraPosition(CameraStandard::CameraPosition position)209 std::string DCameraHandler::GetCameraPosition(CameraStandard::CameraPosition position)
210 {
211 DHLOGI("position: %d", position);
212 std::string ret = "";
213 switch (position) {
214 case CameraStandard::CameraPosition::CAMERA_POSITION_BACK: {
215 ret = CAMERA_POSITION_BACK;
216 break;
217 }
218 case CameraStandard::CameraPosition::CAMERA_POSITION_FRONT: {
219 ret = CAMERA_POSITION_FRONT;
220 break;
221 }
222 case CameraStandard::CameraPosition::CAMERA_POSITION_UNSPECIFIED: {
223 ret = CAMERA_POSITION_UNSPECIFIED;
224 break;
225 }
226 default: {
227 DHLOGE("unknown camera position");
228 break;
229 }
230 }
231 DHLOGI("success ret: %s", ret.c_str());
232 return ret;
233 }
234
ConfigFormatAndResolution(const DCStreamType type,Json::Value & root,std::vector<CameraStandard::Profile> & profileList)235 void DCameraHandler::ConfigFormatAndResolution(const DCStreamType type, Json::Value& root,
236 std::vector<CameraStandard::Profile>& profileList)
237 {
238 DHLOGI("type: %d, size: %d", type, profileList.size());
239 std::set<int32_t> formatSet;
240 for (auto& profile : profileList) {
241 CameraStandard::CameraFormat format = profile.GetCameraFormat();
242 CameraStandard::Size picSize = profile.GetSize();
243 int32_t dformat = CovertToDcameraFormat(format);
244 if (dformat == INVALID_FORMAT) {
245 continue;
246 }
247 formatSet.insert(dformat);
248 DHLOGI("width: %d, height: %d, format: %d", picSize.width, picSize.height, dformat);
249 std::string formatName = std::to_string(dformat);
250 if (IsValid(type, picSize)) {
251 std::string resolutionValue = std::to_string(picSize.width) + "*" + std::to_string(picSize.height);
252 if (type == SNAPSHOT_FRAME) {
253 root[CAMERA_FORMAT_PHOTO][CAMERA_RESOLUTION_KEY][formatName].append(resolutionValue);
254 } else if (type == CONTINUOUS_FRAME) {
255 root[CAMERA_FORMAT_PREVIEW][CAMERA_RESOLUTION_KEY][formatName].append(resolutionValue);
256 root[CAMERA_FORMAT_VIDEO][CAMERA_RESOLUTION_KEY][formatName].append(resolutionValue);
257 }
258 }
259 }
260
261 for (auto format : formatSet) {
262 if (type == SNAPSHOT_FRAME) {
263 root[CAMERA_FORMAT_PHOTO][CAMERA_FORMAT_KEY].append(format);
264 } else if (type == CONTINUOUS_FRAME) {
265 root[CAMERA_FORMAT_PREVIEW][CAMERA_FORMAT_KEY].append(format);
266 root[CAMERA_FORMAT_VIDEO][CAMERA_FORMAT_KEY].append(format);
267 }
268 }
269 }
270
CovertToDcameraFormat(CameraStandard::CameraFormat format)271 int32_t DCameraHandler::CovertToDcameraFormat(CameraStandard::CameraFormat format)
272 {
273 DHLOGI("format: %d", format);
274 int32_t ret = INVALID_FORMAT;
275 switch (format) {
276 case CameraStandard::CameraFormat::CAMERA_FORMAT_RGBA_8888:
277 ret = camera_format_t::OHOS_CAMERA_FORMAT_RGBA_8888;
278 break;
279 case CameraStandard::CameraFormat::CAMERA_FORMAT_YCBCR_420_888:
280 ret = camera_format_t::OHOS_CAMERA_FORMAT_YCBCR_420_888;
281 break;
282 case CameraStandard::CameraFormat::CAMERA_FORMAT_YUV_420_SP:
283 ret = camera_format_t::OHOS_CAMERA_FORMAT_YCRCB_420_SP;
284 break;
285 case CameraStandard::CameraFormat::CAMERA_FORMAT_JPEG:
286 ret = camera_format_t::OHOS_CAMERA_FORMAT_JPEG;
287 break;
288 case CameraStandard::CameraFormat::CAMERA_FORMAT_YCBCR_P010:
289 ret = camera_format_t::OHOS_CAMERA_FORMAT_YCBCR_P010;
290 break;
291 case CameraStandard::CameraFormat::CAMERA_FORMAT_YCRCB_P010:
292 ret = camera_format_t::OHOS_CAMERA_FORMAT_YCRCB_P010;
293 break;
294 default:
295 DHLOGE("invalid camera format");
296 break;
297 }
298 return ret;
299 }
300
IsValid(const DCStreamType type,const CameraStandard::Size & size)301 bool DCameraHandler::IsValid(const DCStreamType type, const CameraStandard::Size& size)
302 {
303 bool ret = false;
304 switch (type) {
305 case CONTINUOUS_FRAME: {
306 ret = (size.width >= RESOLUTION_MIN_WIDTH) &&
307 (size.height >= RESOLUTION_MIN_HEIGHT) &&
308 (size.width <= RESOLUTION_MAX_WIDTH_CONTINUOUS) &&
309 (size.height <= RESOLUTION_MAX_HEIGHT_CONTINUOUS);
310 break;
311 }
312 case SNAPSHOT_FRAME: {
313 if (size.width > MAXWIDTHSIZE) {
314 DHLOGE("size width out of range.");
315 return ret;
316 }
317 uint64_t dcResolution = static_cast<uint64_t>(size.width * size.width);
318 uint64_t dcMaxResolution = static_cast<uint64_t>(RESOLUTION_MAX_WIDTH_SNAPSHOT *
319 RESOLUTION_MAX_HEIGHT_SNAPSHOT);
320 uint64_t dcMinResolution = static_cast<uint64_t>(RESOLUTION_MIN_WIDTH *
321 RESOLUTION_MIN_HEIGHT);
322 ret = (dcResolution >= dcMinResolution) && (dcResolution <= dcMaxResolution);
323 break;
324 }
325 default: {
326 DHLOGE("unknown stream type");
327 break;
328 }
329 }
330 return ret;
331 }
332
GetHardwareHandler()333 IHardwareHandler* GetHardwareHandler()
334 {
335 DHLOGI("DCameraHandler::GetHardwareHandler");
336 return &DCameraHandler::GetInstance();
337 }
338 } // namespace DistributedHardware
339 } // namespace OHOS