1 /*
2 * Copyright (c) 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 "output/metadata_output.h"
17
18 #include <algorithm>
19 #include <cinttypes>
20 #include <cstddef>
21 #include <cstdint>
22
23 #include "camera_device_ability_items.h"
24 #include "camera_error_code.h"
25 #include "camera_log.h"
26 #include "camera_manager.h"
27 #include "camera_security_utils.h"
28 #include "camera_util.h"
29 #include "session/capture_session.h"
30
31 namespace OHOS {
32 namespace CameraStandard {
33 sptr<MetadataObjectFactory> MetadataObjectFactory::metaFactoryInstance_;
34 std::mutex MetadataObjectFactory::instanceMutex_;
35
36 const std::unordered_map<uint32_t, MetadataObjectType> g_HALResultToFwCameraMetaDetect_ = {
37 {OHOS_STATISTICS_DETECT_HUMAN_FACE_INFOS, MetadataObjectType::FACE},
38 {OHOS_STATISTICS_DETECT_HUMAN_BODY_INFOS, MetadataObjectType::HUMAN_BODY},
39 {OHOS_STATISTICS_DETECT_CAT_FACE_INFOS, MetadataObjectType::CAT_FACE},
40 {OHOS_STATISTICS_DETECT_CAT_BODY_INFOS, MetadataObjectType::CAT_BODY},
41 {OHOS_STATISTICS_DETECT_DOG_FACE_INFOS, MetadataObjectType::DOG_FACE},
42 {OHOS_STATISTICS_DETECT_DOG_BODY_INFOS, MetadataObjectType::DOG_BODY},
43 {OHOS_STATISTICS_DETECT_SALIENT_INFOS, MetadataObjectType::SALIENT_DETECTION},
44 {OHOS_STATISTICS_DETECT_BAR_CODE_INFOS, MetadataObjectType::BAR_CODE_DETECTION},
45 {OHOS_STATISTICS_DETECT_BASE_FACE_INFO, MetadataObjectType::BASE_FACE_DETECTION},
46 };
47
MetadataObject(const MetadataObjectType type,const int32_t timestamp,const Rect rect,const int32_t objectId,const int32_t confidence)48 MetadataObject::MetadataObject(const MetadataObjectType type, const int32_t timestamp, const Rect rect,
49 const int32_t objectId, const int32_t confidence)
50 : type_(type),
51 timestamp_(timestamp),
52 box_(rect),
53 objectId_(objectId),
54 confidence_(confidence)
55 {}
56
MetadataObject(const MetaObjectParms & parms)57 MetadataObject::MetadataObject(const MetaObjectParms &parms)
58 {
59 type_ = parms.type;
60 timestamp_ = parms.timestamp;
61 box_ = parms.box;
62 objectId_ = parms.objectId;
63 confidence_ = parms.confidence;
64 }
65
MetadataFaceObject(const MetaObjectParms & parms,const Rect leftEyeBoundingBox,const Rect rightEyeBoundingBox,const Emotion emotion,const int32_t emotionConfidence,const int32_t pitchAngle,const int32_t yawAngle,const int32_t rollAngle)66 MetadataFaceObject::MetadataFaceObject(const MetaObjectParms &parms, const Rect leftEyeBoundingBox,
67 const Rect rightEyeBoundingBox, const Emotion emotion,
68 const int32_t emotionConfidence, const int32_t pitchAngle,
69 const int32_t yawAngle, const int32_t rollAngle)
70 : MetadataObject(parms),
71 leftEyeBoundingBox_(leftEyeBoundingBox),
72 rightEyeBoundingBox_(rightEyeBoundingBox),
73 emotion_(emotion),
74 emotionConfidence_(emotionConfidence),
75 pitchAngle_(pitchAngle),
76 yawAngle_(yawAngle),
77 rollAngle_(rollAngle)
78 {}
79
MetadataHumanBodyObject(const MetaObjectParms & parms)80 MetadataHumanBodyObject::MetadataHumanBodyObject(const MetaObjectParms &parms) : MetadataObject(parms) {}
81
MetadataCatFaceObject(const MetaObjectParms & parms,const Rect leftEyeBoundingBox,const Rect rightEyeBoundingBox)82 MetadataCatFaceObject::MetadataCatFaceObject(const MetaObjectParms &parms, const Rect leftEyeBoundingBox,
83 const Rect rightEyeBoundingBox)
84 : MetadataObject(parms),
85 leftEyeBoundingBox_(leftEyeBoundingBox),
86 rightEyeBoundingBox_(rightEyeBoundingBox)
87 {}
88
MetadataCatBodyObject(const MetaObjectParms & parms)89 MetadataCatBodyObject::MetadataCatBodyObject(const MetaObjectParms &parms) : MetadataObject(parms) {}
90
MetadataDogFaceObject(const MetaObjectParms & parms,const Rect leftEyeBoundingBox,const Rect rightEyeBoundingBox)91 MetadataDogFaceObject::MetadataDogFaceObject(const MetaObjectParms &parms, const Rect leftEyeBoundingBox,
92 const Rect rightEyeBoundingBox)
93 : MetadataObject(parms),
94 leftEyeBoundingBox_(leftEyeBoundingBox),
95 rightEyeBoundingBox_(rightEyeBoundingBox)
96 {}
97
MetadataDogBodyObject(const MetaObjectParms & parms)98 MetadataDogBodyObject::MetadataDogBodyObject(const MetaObjectParms &parms) : MetadataObject(parms) {}
99
MetadataSalientDetectionObject(const MetaObjectParms & parms)100 MetadataSalientDetectionObject::MetadataSalientDetectionObject(const MetaObjectParms &parms) : MetadataObject(parms) {}
101
MetadataBarCodeDetectionObject(const MetaObjectParms & parms)102 MetadataBarCodeDetectionObject::MetadataBarCodeDetectionObject(const MetaObjectParms &parms) : MetadataObject(parms) {}
103
MetadataOutput(sptr<IConsumerSurface> surface,sptr<IStreamMetadata> & streamMetadata)104 MetadataOutput::MetadataOutput(sptr<IConsumerSurface> surface, sptr<IStreamMetadata> &streamMetadata)
105 : CaptureOutput(CAPTURE_OUTPUT_TYPE_METADATA, StreamType::METADATA, surface->GetProducer(), nullptr),
106 surface_(surface)
107 {
108 MEDIA_DEBUG_LOG("MetadataOutput::MetadataOutput construct enter");
109 }
110
~MetadataOutput()111 MetadataOutput::~MetadataOutput()
112 {
113 ReleaseSurface();
114 }
115
GetAppObjectCallback()116 std::shared_ptr<MetadataObjectCallback> MetadataOutput::GetAppObjectCallback()
117 {
118 std::lock_guard<std::mutex> lock(outputCallbackMutex_);
119 return appObjectCallback_;
120 }
121
GetAppStateCallback()122 std::shared_ptr<MetadataStateCallback> MetadataOutput::GetAppStateCallback()
123 {
124 MEDIA_DEBUG_LOG("CameraDeviceServiceCallback::GetAppStateCallback");
125 std::lock_guard<std::mutex> lock(outputCallbackMutex_);
126 return appStateCallback_;
127 }
128
GetSupportedMetadataObjectTypes()129 std::vector<MetadataObjectType> MetadataOutput::GetSupportedMetadataObjectTypes()
130 {
131 auto session = GetSession();
132 CHECK_ERROR_RETURN_RET(session == nullptr, {});
133 auto inputDevice = session->GetInputDevice();
134 CHECK_ERROR_RETURN_RET(inputDevice == nullptr, {});
135 sptr<CameraDevice> cameraObj = inputDevice->GetCameraDeviceInfo();
136 CHECK_ERROR_RETURN_RET(cameraObj == nullptr, {});
137 std::shared_ptr<Camera::CameraMetadata> metadata = cameraObj->GetCachedMetadata();
138 CHECK_ERROR_RETURN_RET(metadata == nullptr, {});
139 camera_metadata_item_t item;
140 int ret = Camera::FindCameraMetadataItem(metadata->get(), OHOS_STATISTICS_FACE_DETECT_MODE, &item);
141 CHECK_ERROR_RETURN_RET(ret, {});
142 std::vector<MetadataObjectType> objectTypes;
143 for (size_t index = 0; index < item.count; index++) {
144 CHECK_EXECUTE(item.data.u8[index] == OHOS_CAMERA_FACE_DETECT_MODE_SIMPLE,
145 objectTypes.emplace_back(MetadataObjectType::FACE));
146 }
147 return objectTypes;
148 }
149
SetCapturingMetadataObjectTypes(std::vector<MetadataObjectType> metadataObjectTypes)150 void MetadataOutput::SetCapturingMetadataObjectTypes(std::vector<MetadataObjectType> metadataObjectTypes)
151 {
152 auto session = GetSession();
153 CHECK_ERROR_RETURN((session == nullptr) || (session->GetInputDevice() == nullptr));
154 std::set<camera_face_detect_mode_t> objectTypes;
155 for (const auto& type : metadataObjectTypes) {
156 CHECK_EXECUTE(type == MetadataObjectType::FACE, objectTypes.insert(OHOS_CAMERA_FACE_DETECT_MODE_SIMPLE));
157 }
158 CHECK_EXECUTE(objectTypes.empty(), objectTypes.insert(OHOS_CAMERA_FACE_DETECT_MODE_OFF));
159
160 session->SetCaptureMetadataObjectTypes(objectTypes);
161 }
162
AddMetadataObjectTypes(std::vector<MetadataObjectType> metadataObjectTypes)163 int32_t MetadataOutput::AddMetadataObjectTypes(std::vector<MetadataObjectType> metadataObjectTypes)
164 {
165 const size_t maxSize4NonSystemApp = 1;
166 if (!CameraSecurity::CheckSystemApp()) {
167 MEDIA_DEBUG_LOG("public calling for metadataOutput");
168 if (metadataObjectTypes.size() > maxSize4NonSystemApp ||
169 std::any_of(metadataObjectTypes.begin(), metadataObjectTypes.end(),
170 [](MetadataObjectType type) { return type != MetadataObjectType::FACE; })) {
171 return CameraErrorCode::INVALID_ARGUMENT;
172 }
173 }
174 auto session = GetSession();
175 CHECK_ERROR_RETURN_RET_LOG(session == nullptr || !session->IsSessionCommited(), CameraErrorCode::SESSION_NOT_CONFIG,
176 "MetadataOutput Failed to AddMetadataObjectTypes!, session not commited");
177
178 auto inputDevice = session->GetInputDevice();
179 CHECK_ERROR_RETURN_RET_LOG(inputDevice == nullptr, CameraErrorCode::SESSION_NOT_CONFIG,
180 "MetadataOutput Failed to AddMetadataObjectTypes!, inputDevice is null");
181
182 sptr<CameraDevice> cameraObj = inputDevice->GetCameraDeviceInfo();
183 CHECK_ERROR_RETURN_RET_LOG(cameraObj == nullptr, CameraErrorCode::SESSION_NOT_CONFIG,
184 "MetadataOutput Failed to AddMetadataObjectTypes!, cameraObj is null");
185
186 auto outoputCapability = CameraManager::GetInstance()->GetSupportedOutputCapability(cameraObj, session->GetMode());
187 CHECK_ERROR_RETURN_RET_LOG(outoputCapability == nullptr, CameraErrorCode::SESSION_NOT_CONFIG,
188 "MetadataOutput Failed to AddMetadataObjectTypes!, outoputCapability is null");
189
190 std::vector<MetadataObjectType> supportMetadataType = outoputCapability->GetSupportedMetadataObjectType();
191 for (const auto &type : supportMetadataType) {
192 MEDIA_DEBUG_LOG("MetadataOutput::AddMetadataObjectTypes, support type: %{public}d", type);
193 }
194 CHECK_ERROR_RETURN_RET_LOG(!checkValidType(metadataObjectTypes, supportMetadataType),
195 CameraErrorCode::INVALID_ARGUMENT,
196 "MetadataOutput::AddMetadataObjectTypes, unsupported type!");
197
198 auto stream = GetStream();
199 CHECK_ERROR_RETURN_RET_LOG(stream == nullptr, CameraErrorCode::SESSION_NOT_CONFIG,
200 "MetadataOutput Failed to AddMetadataObjectTypes!, GetStream is nullptr");
201 std::vector<int32_t> numberOfTypes = convert(metadataObjectTypes);
202 int32_t errCode = static_cast<IStreamMetadata *>(stream.GetRefPtr())->EnableMetadataType(numberOfTypes);
203 CHECK_ERROR_RETURN_RET_LOG(
204 errCode != CAMERA_OK, CameraErrorCode::SERVICE_FATL_ERROR,
205 "MetadataOutput Failed to AddMetadataObjectTypes!, EnableMetadataType failed ret: %{public}d", errCode);
206 return CameraErrorCode::SUCCESS;
207 }
208
RemoveMetadataObjectTypes(std::vector<MetadataObjectType> metadataObjectTypes)209 int32_t MetadataOutput::RemoveMetadataObjectTypes(std::vector<MetadataObjectType> metadataObjectTypes)
210 {
211 const size_t maxSize4NonSystemApp = 1;
212 if (!CameraSecurity::CheckSystemApp()) {
213 MEDIA_DEBUG_LOG("public calling for metadataOutput");
214 if (metadataObjectTypes.size() > maxSize4NonSystemApp ||
215 std::any_of(metadataObjectTypes.begin(), metadataObjectTypes.end(),
216 [](MetadataObjectType type) { return type != MetadataObjectType::FACE; })) {
217 return CameraErrorCode::INVALID_ARGUMENT;
218 }
219 }
220 auto session = GetSession();
221 CHECK_ERROR_RETURN_RET_LOG(session == nullptr || !session->IsSessionCommited(), CameraErrorCode::SESSION_NOT_CONFIG,
222 "MetadataOutput Failed to RemoveMetadataObjectTypes!, session not commited");
223
224 auto stream = GetStream();
225 CHECK_ERROR_RETURN_RET_LOG(stream == nullptr, CameraErrorCode::SESSION_NOT_CONFIG,
226 "MetadataOutput Failed to AddMetadataObjectTypes!, GetStream is nullptr");
227
228 std::vector<int32_t> numberOfTypes = convert(metadataObjectTypes);
229 int32_t errCode = static_cast<IStreamMetadata *>(stream.GetRefPtr())->DisableMetadataType(numberOfTypes);
230 CHECK_ERROR_RETURN_RET_LOG(
231 errCode != CAMERA_OK, CameraErrorCode::SERVICE_FATL_ERROR,
232 "MetadataOutput Failed to AddMetadataObjectTypes!, EnableMetadataType failed ret: %{public}d", errCode);
233 return CameraErrorCode::SUCCESS;
234 }
235
checkValidType(const std::vector<MetadataObjectType> & typeAdded,const std::vector<MetadataObjectType> & supportedType)236 bool MetadataOutput::checkValidType(const std::vector<MetadataObjectType> &typeAdded,
237 const std::vector<MetadataObjectType> &supportedType)
238 {
239 return std::all_of(typeAdded.begin(), typeAdded.end(), [&supportedType](MetadataObjectType type) {
240 return std::find(supportedType.begin(), supportedType.end(), type) != supportedType.end();
241 });
242 }
243
convert(const std::vector<MetadataObjectType> & typesOfMetadata)244 std::vector<int32_t> MetadataOutput::convert(const std::vector<MetadataObjectType> &typesOfMetadata)
245 {
246 std::vector<int32_t> result(typesOfMetadata.size());
247 std::transform(typesOfMetadata.begin(), typesOfMetadata.end(), result.begin(),
248 [](MetadataObjectType obj) { return static_cast<int32_t>(obj); });
249 return result;
250 }
251
SetCallback(std::shared_ptr<MetadataObjectCallback> metadataObjectCallback)252 void MetadataOutput::SetCallback(std::shared_ptr<MetadataObjectCallback> metadataObjectCallback)
253 {
254 std::lock_guard<std::mutex> lock(outputCallbackMutex_);
255 appObjectCallback_ = metadataObjectCallback;
256 if (appObjectCallback_ != nullptr) {
257 if (cameraMetadataCallback_ == nullptr) {
258 cameraMetadataCallback_ = new HStreamMetadataCallbackImpl(this);
259 }
260 }
261 auto stream = GetStream();
262 sptr<IStreamMetadata> itemStream = static_cast<IStreamMetadata*>(stream.GetRefPtr());
263 int32_t errorCode = CAMERA_OK;
264 if (itemStream) {
265 errorCode = itemStream->SetCallback(cameraMetadataCallback_);
266 } else {
267 MEDIA_ERR_LOG("MetadataOutput::SetCallback() itemStream is nullptr");
268 }
269 if (errorCode != CAMERA_OK) {
270 MEDIA_ERR_LOG("MetadataOutput::SetCallback(): Failed to register callback, errorCode: %{public}d", errorCode);
271 cameraMetadataCallback_ = nullptr;
272 appObjectCallback_ = nullptr;
273 }
274 }
275
SetCallback(std::shared_ptr<MetadataStateCallback> metadataStateCallback)276 void MetadataOutput::SetCallback(std::shared_ptr<MetadataStateCallback> metadataStateCallback)
277 {
278 std::lock_guard<std::mutex> lock(outputCallbackMutex_);
279 appStateCallback_ = metadataStateCallback;
280 }
281
CreateStream()282 int32_t MetadataOutput::CreateStream()
283 {
284 return CameraErrorCode::SUCCESS;
285 }
286
Start()287 int32_t MetadataOutput::Start()
288 {
289 MEDIA_DEBUG_LOG("MetadataOutput::Start is called");
290 auto session = GetSession();
291 CHECK_ERROR_RETURN_RET_LOG(session == nullptr || !session->IsSessionCommited(), CameraErrorCode::SUCCESS,
292 "MetadataOutput Failed to Start!, session not commited");
293 auto stream = GetStream();
294 CHECK_ERROR_RETURN_RET_LOG(stream == nullptr, CameraErrorCode::SUCCESS,
295 "MetadataOutput Failed to Start!, GetStream is nullptr");
296 int32_t errCode = static_cast<IStreamMetadata *>(stream.GetRefPtr())->Start();
297 CHECK_ERROR_PRINT_LOG(errCode != CAMERA_OK, "Failed to Start MetadataOutput!, errCode: %{public}d", errCode);
298 return CameraErrorCode::SUCCESS;
299 }
300
CameraServerDied(pid_t pid)301 void MetadataOutput::CameraServerDied(pid_t pid)
302 {
303 MEDIA_ERR_LOG("camera server has died, pid:%{public}d!", pid);
304 std::lock_guard<std::mutex> lock(outputCallbackMutex_);
305 if (appStateCallback_ != nullptr) {
306 MEDIA_DEBUG_LOG("appCallback not nullptr");
307 int32_t serviceErrorType = ServiceToCameraError(CAMERA_INVALID_STATE);
308 appStateCallback_->OnError(serviceErrorType);
309 }
310 }
311
Stop()312 int32_t MetadataOutput::Stop()
313 {
314 MEDIA_DEBUG_LOG("MetadataOutput::Stop");
315 auto stream = GetStream();
316 CHECK_ERROR_RETURN_RET_LOG(stream == nullptr, CameraErrorCode::SERVICE_FATL_ERROR,
317 "MetadataOutput Failed to Stop!, GetStream is nullptr");
318 int32_t errCode = static_cast<IStreamMetadata*>(stream.GetRefPtr())->Stop();
319 CHECK_ERROR_PRINT_LOG(errCode != CAMERA_OK, "Failed to Stop MetadataOutput!, errCode: %{public}d", errCode);
320 return ServiceToCameraError(errCode);
321 }
322
Release()323 int32_t MetadataOutput::Release()
324 {
325 {
326 std::lock_guard<std::mutex> lock(outputCallbackMutex_);
327 appObjectCallback_ = nullptr;
328 appStateCallback_ = nullptr;
329 cameraMetadataCallback_ = nullptr;
330 }
331 auto stream = GetStream();
332 CHECK_ERROR_RETURN_RET_LOG(stream == nullptr, CameraErrorCode::SERVICE_FATL_ERROR,
333 "MetadataOutput Failed to Release!, GetStream is nullptr");
334 int32_t errCode = static_cast<IStreamMetadata *>(stream.GetRefPtr())->Release();
335 CHECK_ERROR_PRINT_LOG(errCode != CAMERA_OK, "Failed to Release MetadataOutput!, errCode: %{public}d", errCode);
336 ReleaseSurface();
337 CaptureOutput::Release();
338 return ServiceToCameraError(errCode);
339 }
340
ReleaseSurface()341 void MetadataOutput::ReleaseSurface()
342 {
343 std::lock_guard<std::mutex> lock(surfaceMutex_);
344 if (surface_ != nullptr) {
345 SurfaceError ret = surface_->UnregisterConsumerListener();
346 CHECK_ERROR_PRINT_LOG(ret != SURFACE_ERROR_OK, "Failed to unregister surface consumer listener");
347 surface_ = nullptr;
348 }
349 }
350
GetSurface()351 sptr<IConsumerSurface> MetadataOutput::GetSurface()
352 {
353 std::lock_guard<std::mutex> lock(surfaceMutex_);
354 return surface_;
355 }
356
ProcessMetadata(const int32_t streamId,const std::shared_ptr<OHOS::Camera::CameraMetadata> & result,std::vector<sptr<MetadataObject>> & metaObjects,bool isNeedMirror,bool isNeedFlip)357 void MetadataOutput::ProcessMetadata(const int32_t streamId,
358 const std::shared_ptr<OHOS::Camera::CameraMetadata> &result,
359 std::vector<sptr<MetadataObject>> &metaObjects, bool isNeedMirror, bool isNeedFlip)
360 {
361 CHECK_ERROR_RETURN(result == nullptr);
362 // camera_metadata_item_t metadataItem;
363 common_metadata_header_t *metadata = result->get();
364 std::vector<camera_metadata_item_t> metadataResults;
365 std::vector<uint32_t> metadataTypes;
366 GetMetadataResults(metadata, metadataResults, metadataTypes);
367 if (metadataResults.size() == 0) {
368 reportLastFaceResults_ = false;
369 if (reportFaceResults_) {
370 reportLastFaceResults_ = true;
371 reportFaceResults_ = false;
372 }
373 metaObjects.clear();
374 MEDIA_ERR_LOG("Camera not ProcessFaceRectangles");
375 return;
376 }
377 int32_t ret = ProcessMetaObjects(streamId, metaObjects, metadataResults, metadataTypes, isNeedMirror, isNeedFlip);
378 reportFaceResults_ = true;
379 CHECK_ERROR_RETURN_LOG(ret != CameraErrorCode::SUCCESS, "MetadataOutput::ProcessFaceRectangles() is failed.");
380 return;
381 }
382
ProcessMetaObjects(const int32_t streamId,std::vector<sptr<MetadataObject>> & metaObjects,const std::vector<camera_metadata_item_t> & metadataItem,const std::vector<uint32_t> & metadataTypes,bool isNeedMirror,bool isNeedFlip)383 int32_t MetadataOutput::ProcessMetaObjects(const int32_t streamId, std::vector<sptr<MetadataObject>>& metaObjects,
384 const std::vector<camera_metadata_item_t>& metadataItem,
385 const std::vector<uint32_t>& metadataTypes,
386 bool isNeedMirror, bool isNeedFlip)
387 {
388 for (size_t i = 0; i < metadataItem.size(); ++i) {
389 auto itr = g_HALResultToFwCameraMetaDetect_.find(metadataTypes[i]);
390 if (itr != g_HALResultToFwCameraMetaDetect_.end()) {
391 GenerateObjects(metadataItem[i], itr->second, metaObjects, isNeedMirror, isNeedFlip);
392 } else {
393 MEDIA_ERR_LOG("MetadataOutput::ProcessMetaObjects() unsupported type: %{public}d", metadataTypes[i]);
394 }
395 }
396 return CameraErrorCode::SUCCESS;
397 }
398
GenerateObjects(const camera_metadata_item_t & metadataItem,MetadataObjectType type,std::vector<sptr<MetadataObject>> & metaObjects,bool isNeedMirror,bool isNeedFlip)399 void MetadataOutput::GenerateObjects(const camera_metadata_item_t &metadataItem, MetadataObjectType type,
400 std::vector<sptr<MetadataObject>> &metaObjects, bool isNeedMirror, bool isNeedFlip)
401 {
402 int32_t index = 0;
403 int32_t countOfObject = 0;
404 auto iteratorOfLengthMap = mapLengthOfType.find(type);
405 if (iteratorOfLengthMap != mapLengthOfType.end()) {
406 countOfObject = metadataItem.count / iteratorOfLengthMap->second;
407 }
408 for (int32_t itr = 0; itr < countOfObject; ++itr) {
409 sptr<MetadataObjectFactory> objectFactoryPtr = MetadataObjectFactory::GetInstance();
410 MetadataObjectType typeFromHal = static_cast<MetadataObjectType>(metadataItem.data.i32[index]);
411 index++;
412 ProcessBaseInfo(objectFactoryPtr, metadataItem, index, typeFromHal, isNeedMirror, isNeedFlip);
413 ProcessExternInfo(objectFactoryPtr, metadataItem, index, typeFromHal, isNeedMirror, isNeedFlip);
414 metaObjects.push_back(objectFactoryPtr->createMetadataObject(type));
415 }
416 }
417
GetMetadataResults(const common_metadata_header_t * metadata,std::vector<camera_metadata_item_t> & metadataResults,std::vector<uint32_t> & metadataTypes)418 void MetadataOutput::GetMetadataResults(const common_metadata_header_t *metadata,
419 std::vector<camera_metadata_item_t>& metadataResults, std::vector<uint32_t>& metadataTypes)
420 {
421 for (auto itr : typesOfMetadata_) {
422 camera_metadata_item_t item;
423 int ret = Camera::FindCameraMetadataItem(metadata, itr, &item);
424 if (ret == CAM_META_SUCCESS) {
425 metadataResults.emplace_back(std::move(item));
426 metadataTypes.emplace_back(itr);
427 }
428 }
429 }
430
ProcessRectBox(int32_t offsetTopLeftX,int32_t offsetTopLeftY,int32_t offsetBottomRightX,int32_t offsetBottomRightY,bool isNeedMirror,bool isNeedFlip)431 Rect MetadataOutput::ProcessRectBox(int32_t offsetTopLeftX, int32_t offsetTopLeftY,
432 int32_t offsetBottomRightX, int32_t offsetBottomRightY, bool isNeedMirror, bool isNeedFlip)
433 {
434 constexpr int32_t scale = 1000000;
435 double topLeftX = 0;
436 double topLeftY = 0;
437 double width = 0;
438 double height = 0;
439 if (isNeedMirror) {
440 topLeftX = scale - offsetBottomRightY;
441 topLeftY = scale - offsetBottomRightX;
442 width = offsetBottomRightY - offsetTopLeftY;
443 height = offsetBottomRightX - offsetTopLeftX;
444 } else if (isNeedFlip) {
445 topLeftX = offsetTopLeftY;
446 topLeftY = offsetTopLeftX;
447 width = offsetBottomRightY - offsetTopLeftY;
448 height = offsetBottomRightX - offsetTopLeftX;
449 } else {
450 topLeftX = scale - offsetBottomRightY;
451 topLeftY = offsetTopLeftX;
452 width = offsetBottomRightY - offsetTopLeftY;
453 height = offsetBottomRightX - offsetTopLeftX;
454 }
455 topLeftX = topLeftX < 0 ? 0 : topLeftX;
456 topLeftX = topLeftX > scale ? scale : topLeftX;
457 topLeftY = topLeftY < 0 ? 0 : topLeftY;
458 topLeftY = topLeftY > scale ? scale : topLeftY;
459
460 return (Rect){ topLeftX / scale, topLeftY / scale, width / scale, height / scale};
461 }
462
ProcessBaseInfo(sptr<MetadataObjectFactory> factoryPtr,const camera_metadata_item_t & metadataItem,int32_t & index,MetadataObjectType typeFromHal,bool isNeedMirror,bool isNeedFlip)463 void MetadataOutput::ProcessBaseInfo(sptr<MetadataObjectFactory> factoryPtr, const camera_metadata_item_t &metadataItem,
464 int32_t &index, MetadataObjectType typeFromHal, bool isNeedMirror, bool isNeedFlip)
465 {
466 const int32_t rectLength = 4;
467 const int32_t offsetOne = 1;
468 const int32_t offsetTwo = 2;
469 const int32_t offsetThree = 3;
470 factoryPtr->SetType(typeFromHal)
471 ->SetObjectId(metadataItem.data.i32[index]);
472 index++;
473 factoryPtr->SetTimestamp(metadataItem.data.i32[index]);
474 index++;
475 factoryPtr->SetBox(ProcessRectBox(metadataItem.data.i32[index], metadataItem.data.i32[index + offsetOne],
476 metadataItem.data.i32[index + offsetTwo],
477 metadataItem.data.i32[index + offsetThree], isNeedMirror, isNeedFlip));
478 index += rectLength;
479 factoryPtr->SetConfidence(metadataItem.data.i32[index]);
480 index++;
481 int32_t externalLength = metadataItem.data.i32[index];
482 index++;
483 MEDIA_DEBUG_LOG("MetadataOutput::GenerateObjects, type: %{public}d, externalLength: %{public}d", typeFromHal,
484 externalLength);
485 }
486
ProcessExternInfo(sptr<MetadataObjectFactory> factoryPtr,const camera_metadata_item_t & metadataItem,int32_t & index,MetadataObjectType typeFromHal,bool isNeedMirror,bool isNeedFlip)487 void MetadataOutput::ProcessExternInfo(sptr<MetadataObjectFactory> factoryPtr,
488 const camera_metadata_item_t &metadataItem, int32_t &index,
489 MetadataObjectType typeFromHal, bool isNeedMirror, bool isNeedFlip)
490 {
491 switch (typeFromHal) {
492 case MetadataObjectType::FACE:
493 ProcessHumanFaceDetectInfo(factoryPtr, metadataItem, index, isNeedMirror, isNeedFlip);
494 break;
495 case MetadataObjectType::CAT_FACE:
496 ProcessCatFaceDetectInfo(factoryPtr, metadataItem, index, isNeedMirror, isNeedFlip);
497 break;
498 case MetadataObjectType::DOG_FACE:
499 ProcessDogFaceDetectInfo(factoryPtr, metadataItem, index, isNeedMirror, isNeedFlip);
500 break;
501 default:
502 break;
503 }
504 }
505
ProcessHumanFaceDetectInfo(sptr<MetadataObjectFactory> factoryPtr,const camera_metadata_item_t & metadataItem,int32_t & index,bool isNeedMirror,bool isNeedFlip)506 void MetadataOutput::ProcessHumanFaceDetectInfo(sptr<MetadataObjectFactory> factoryPtr,
507 const camera_metadata_item_t &metadataItem, int32_t &index,
508 bool isNeedMirror, bool isNeedFlip)
509 {
510 int32_t version = metadataItem.data.i32[index++];
511 MEDIA_DEBUG_LOG("isNeedMirror: %{public}d, isNeedFlip: %{public}d, version: %{public}d",
512 isNeedMirror, isNeedFlip, version);
513 const int32_t rectLength = 4;
514 const int32_t offsetOne = 1;
515 const int32_t offsetTwo = 2;
516 const int32_t offsetThree = 3;
517 factoryPtr->SetLeftEyeBoundingBox(ProcessRectBox(
518 metadataItem.data.i32[index], metadataItem.data.i32[index + offsetOne],
519 metadataItem.data.i32[index + offsetTwo],
520 metadataItem.data.i32[index + offsetThree], isNeedMirror, isNeedFlip));
521 index += rectLength;
522 factoryPtr->SetRightEyeBoundingBoxd(ProcessRectBox(
523 metadataItem.data.i32[index], metadataItem.data.i32[index + offsetOne],
524 metadataItem.data.i32[index + offsetTwo],
525 metadataItem.data.i32[index + offsetThree], isNeedMirror, isNeedFlip));
526 index += rectLength;
527 factoryPtr->SetEmotion(static_cast<Emotion>(metadataItem.data.i32[index]));
528 index++;
529 factoryPtr->SetEmotionConfidence(static_cast<Emotion>(metadataItem.data.i32[index]));
530 index++;
531 factoryPtr->SetPitchAngle(metadataItem.data.i32[index]);
532 index++;
533 factoryPtr->SetYawAngle(metadataItem.data.i32[index]);
534 index++;
535 factoryPtr->SetRollAngle(metadataItem.data.i32[index]);
536 index++;
537 }
538
ProcessCatFaceDetectInfo(sptr<MetadataObjectFactory> factoryPtr,const camera_metadata_item_t & metadataItem,int32_t & index,bool isNeedMirror,bool isNeedFlip)539 void MetadataOutput::ProcessCatFaceDetectInfo(sptr<MetadataObjectFactory> factoryPtr,
540 const camera_metadata_item_t &metadataItem, int32_t &index,
541 bool isNeedMirror, bool isNeedFlip)
542 {
543 int32_t version = metadataItem.data.i32[index++];
544 MEDIA_DEBUG_LOG("isNeedMirror: %{public}d, isNeedFlip: %{public}d, version: %{public}d",
545 isNeedMirror, isNeedFlip, version);
546 const int32_t rectLength = 4;
547 const int32_t offsetOne = 1;
548 const int32_t offsetTwo = 2;
549 const int32_t offsetThree = 3;
550 factoryPtr->SetLeftEyeBoundingBox(ProcessRectBox(
551 metadataItem.data.i32[index], metadataItem.data.i32[index + offsetOne],
552 metadataItem.data.i32[index + offsetTwo],
553 metadataItem.data.i32[index + offsetThree], isNeedMirror, isNeedFlip));
554 index += rectLength;
555 factoryPtr->SetRightEyeBoundingBoxd(ProcessRectBox(
556 metadataItem.data.i32[index], metadataItem.data.i32[index + offsetOne],
557 metadataItem.data.i32[index + offsetTwo],
558 metadataItem.data.i32[index + offsetThree], isNeedMirror, isNeedFlip));
559 index += rectLength;
560 }
561
ProcessDogFaceDetectInfo(sptr<MetadataObjectFactory> factoryPtr,const camera_metadata_item_t & metadataItem,int32_t & index,bool isNeedMirror,bool isNeedFlip)562 void MetadataOutput::ProcessDogFaceDetectInfo(sptr<MetadataObjectFactory> factoryPtr,
563 const camera_metadata_item_t &metadataItem, int32_t &index,
564 bool isNeedMirror, bool isNeedFlip)
565 {
566 int32_t version = metadataItem.data.i32[index++];
567 MEDIA_DEBUG_LOG("isNeedMirror: %{public}d, isNeedFlip: %{public}d, version: %{public}d",
568 isNeedMirror, isNeedFlip, version);
569 const int32_t rectLength = 4;
570 const int32_t offsetOne = 1;
571 const int32_t offsetTwo = 2;
572 const int32_t offsetThree = 3;
573 factoryPtr->SetLeftEyeBoundingBox(ProcessRectBox(
574 metadataItem.data.i32[index], metadataItem.data.i32[index + offsetOne],
575 metadataItem.data.i32[index + offsetTwo],
576 metadataItem.data.i32[index + offsetThree], isNeedMirror, isNeedFlip));
577 index += rectLength;
578 factoryPtr->SetRightEyeBoundingBoxd(ProcessRectBox(
579 metadataItem.data.i32[index], metadataItem.data.i32[index + offsetOne],
580 metadataItem.data.i32[index + offsetTwo],
581 metadataItem.data.i32[index + offsetThree], isNeedMirror, isNeedFlip));
582 index += rectLength;
583 }
584
MetadataObjectListener(sptr<MetadataOutput> metadata)585 MetadataObjectListener::MetadataObjectListener(sptr<MetadataOutput> metadata) : metadata_(metadata) {}
586
ProcessMetadataBuffer(void * buffer,int64_t timestamp)587 int32_t MetadataObjectListener::ProcessMetadataBuffer(void *buffer, int64_t timestamp)
588 {
589 return CameraErrorCode::SUCCESS;
590 }
591
OnBufferAvailable()592 void MetadataObjectListener::OnBufferAvailable()
593 {
594 MEDIA_INFO_LOG("MetadataOutput::OnBufferAvailable() is Called");
595 // metaoutput adapte later
596 bool adapterLater = true;
597 CHECK_ERROR_RETURN(adapterLater);
598 auto metadataOutput = metadata_.promote();
599 CHECK_ERROR_RETURN_LOG(metadataOutput == nullptr, "OnBufferAvailable metadataOutput is null");
600 auto surface = metadataOutput->GetSurface();
601 CHECK_ERROR_RETURN_LOG(surface == nullptr, "OnBufferAvailable Metadata surface is null");
602 int32_t fence = -1;
603 int64_t timestamp;
604 OHOS::Rect damage;
605 sptr<SurfaceBuffer> buffer = nullptr;
606 SurfaceError surfaceRet = surface->AcquireBuffer(buffer, fence, timestamp, damage);
607 CHECK_ERROR_RETURN_LOG(surfaceRet != SURFACE_ERROR_OK, "OnBufferAvailable Failed to acquire surface buffer");
608 int32_t ret = ProcessMetadataBuffer(buffer->GetVirAddr(), timestamp);
609 if (ret) {
610 std::shared_ptr<MetadataStateCallback> appStateCallback = metadataOutput->GetAppStateCallback();
611 CHECK_EXECUTE(appStateCallback, appStateCallback->OnError(ret));
612 }
613 surface->ReleaseBuffer(buffer, -1);
614 }
615
OnMetadataResult(const int32_t streamId,const std::shared_ptr<OHOS::Camera::CameraMetadata> & result)616 int32_t HStreamMetadataCallbackImpl::OnMetadataResult(const int32_t streamId,
617 const std::shared_ptr<OHOS::Camera::CameraMetadata> &result)
618 {
619 auto metadataOutput = GetMetadataOutput();
620 CHECK_ERROR_RETURN_RET_LOG(metadataOutput == nullptr, CAMERA_OK,
621 "HStreamMetadataCallbackImpl::OnMetadataResult metadataOutput is nullptr");
622 auto session = metadataOutput->GetSession();
623 CHECK_ERROR_RETURN_RET_LOG(session == nullptr, SESSION_NOT_RUNNING,
624 "HStreamMetadataCallbackImpl OnMetadataResult error!, session is nullptr");
625 auto inputDevice = session->GetInputDevice();
626 bool isNeedMirror = false;
627 bool isNeedFlip = false;
628 if (inputDevice) {
629 auto inputDeviceInfo = inputDevice->GetCameraDeviceInfo();
630 isNeedMirror = (inputDeviceInfo->GetPosition() == CAMERA_POSITION_FRONT ||
631 inputDeviceInfo->GetPosition() == CAMERA_POSITION_FOLD_INNER);
632 isNeedFlip = inputDeviceInfo->GetUsedAsPosition() == CAMERA_POSITION_FRONT;
633 }
634 std::vector<sptr<MetadataObject>> metaObjects;
635 metadataOutput->ProcessMetadata(streamId, result, metaObjects, isNeedMirror, isNeedFlip);
636 auto objectCallback = metadataOutput->GetAppObjectCallback();
637 CHECK_ERROR_RETURN_RET(objectCallback == nullptr, INVALID_ARGUMENT);
638 CHECK_EXECUTE((metadataOutput->reportFaceResults_ || metadataOutput->reportLastFaceResults_) && objectCallback,
639 objectCallback->OnMetadataObjectsAvailable(metaObjects));
640 return SUCCESS;
641 }
642
MetadataObjectFactory()643 MetadataObjectFactory::MetadataObjectFactory() {}
644
GetInstance()645 sptr<MetadataObjectFactory> &MetadataObjectFactory::GetInstance()
646 {
647 if (metaFactoryInstance_ == nullptr) {
648 std::lock_guard<std::mutex> lock(instanceMutex_);
649 if (metaFactoryInstance_ == nullptr) {
650 MEDIA_INFO_LOG("Initializing MetadataObjectFactory instance");
651 metaFactoryInstance_ = new MetadataObjectFactory();
652 }
653 }
654 return metaFactoryInstance_;
655 }
656
createMetadataObject(MetadataObjectType type)657 sptr<MetadataObject> MetadataObjectFactory::createMetadataObject(MetadataObjectType type)
658 {
659 MetaObjectParms baseMetaParms = { type_, timestamp_, box_, objectId_, confidence_ };
660 sptr<MetadataObject> metadataObject;
661 switch (type) {
662 case MetadataObjectType::FACE:
663 metadataObject = new MetadataFaceObject(baseMetaParms, leftEyeBoundingBox_, rightEyeBoundingBox_, emotion_,
664 emotionConfidence_, pitchAngle_, yawAngle_, rollAngle_);
665 break;
666 case MetadataObjectType::HUMAN_BODY:
667 metadataObject = new MetadataHumanBodyObject(baseMetaParms);
668 break;
669 case MetadataObjectType::CAT_FACE:
670 metadataObject = new MetadataCatFaceObject(baseMetaParms, leftEyeBoundingBox_, rightEyeBoundingBox_);
671 break;
672 case MetadataObjectType::CAT_BODY:
673 metadataObject = new MetadataCatBodyObject(baseMetaParms);
674 break;
675 case MetadataObjectType::DOG_FACE:
676 metadataObject = new MetadataDogFaceObject(baseMetaParms, leftEyeBoundingBox_, rightEyeBoundingBox_);
677 break;
678 case MetadataObjectType::DOG_BODY:
679 metadataObject = new MetadataDogBodyObject(baseMetaParms);
680 break;
681 case MetadataObjectType::SALIENT_DETECTION:
682 metadataObject = new MetadataSalientDetectionObject(baseMetaParms);
683 break;
684 case MetadataObjectType::BAR_CODE_DETECTION:
685 metadataObject = new MetadataBarCodeDetectionObject(baseMetaParms);
686 break;
687 default:
688 metadataObject = new MetadataObject(baseMetaParms);
689 }
690 ResetParameters();
691 return metadataObject;
692 }
693
ResetParameters()694 void MetadataObjectFactory::ResetParameters()
695 {
696 type_ = MetadataObjectType::INVALID;
697 timestamp_ = 0;
698 box_ = { 0, 0, 0, 0 };
699 objectId_ = 0;
700 confidence_ = 0.0f;
701 leftEyeBoundingBox_ = { 0, 0, 0, 0 };
702 rightEyeBoundingBox_ = { 0, 0, 0, 0 };
703 emotion_ = Emotion::NEUTRAL;
704 emotionConfidence_ = 0;
705 pitchAngle_ = 0;
706 yawAngle_ = 0;
707 rollAngle_ = 0;
708 }
709 } // namespace CameraStandard
710 } // namespace OHOS
711