• 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 "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