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