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