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