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