1 /*
2  * Copyright (c) 2023 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  *     http://www.apache.org/licenses/LICENSE-2.0
7  * Unless required by applicable law or agreed to in writing, software
8  * distributed under the License is distributed on an "AS IS" BASIS,
9  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10  * See the License for the specific language governing permissions and
11  * limitations under the License.
12  */
13 
14 #include "face_node.h"
15 #include <securec.h>
16 #include "camera_dump.h"
17 #include "camera_hal_hisysevent.h"
18 
19 namespace OHOS::Camera {
FaceNode(const std::string & name,const std::string & type,const std::string & cameraId)20 FaceNode::FaceNode(const std::string &name, const std::string &type, const std::string &cameraId)
21     : NodeBase(name, type, cameraId), metaDataSize_(0)
22 {
23     CAMERA_LOGV("%{public}s enter, type(%{public}s)\n", name_.c_str(), type_.c_str());
24 }
25 
~FaceNode()26 FaceNode::~FaceNode()
27 {
28     CAMERA_LOGI("~FaceNode Node exit.");
29 }
30 
Start(const int32_t streamId)31 RetCode FaceNode::Start(const int32_t streamId)
32 {
33     CAMERA_LOGI("FaceNode::Start streamId = %{public}d\n", streamId);
34     CreateMetadataInfo();
35     return RC_OK;
36 }
37 
Stop(const int32_t streamId)38 RetCode FaceNode::Stop(const int32_t streamId)
39 {
40     CAMERA_LOGI("FaceNode::Stop streamId = %{public}d\n", streamId);
41     std::unique_lock <std::mutex> lock(mLock_);
42     metaDataSize_ = 0;
43     return RC_OK;
44 }
45 
Flush(const int32_t streamId)46 RetCode FaceNode::Flush(const int32_t streamId)
47 {
48     CAMERA_LOGI("FaceNode::Flush streamId = %{public}d\n", streamId);
49     return RC_OK;
50 }
51 
DeliverBuffer(std::shared_ptr<IBuffer> & buffer)52 void FaceNode::DeliverBuffer(std::shared_ptr<IBuffer>& buffer)
53 {
54     if (buffer == nullptr) {
55         CAMERA_LOGE("FaceNode::DeliverBuffer frameSpec is null");
56         return;
57     }
58     if (buffer->GetBufferStatus() != CAMERA_BUFFER_STATUS_OK) {
59         CAMERA_LOGE("BufferStatus() != CAMERA_BUFFER_STATUS_OK");
60         return NodeBase::DeliverBuffer(buffer);
61     }
62 
63     CameraDumper& dumper = CameraDumper::GetInstance();
64     dumper.DumpBuffer("FaceNode", ENABLE_FACE_NODE_CONVERTED, buffer);
65 
66     NodeBase::DeliverBuffer(buffer);
67 }
68 
Config(const int32_t streamId,const CaptureMeta & meta)69 RetCode FaceNode::Config(const int32_t streamId, const CaptureMeta& meta)
70 {
71     (void)meta;
72     if (meta == nullptr || meta->get() == nullptr) {
73         CAMERA_LOGE("FaceNode::Config meta is invalid");
74         return RC_ERROR;
75     }
76     CAMERA_LOGD("FaceNode::Config streamId = %{public}d", streamId);
77     return RC_OK;
78 }
79 
Capture(const int32_t streamId,const int32_t captureId)80 RetCode FaceNode::Capture(const int32_t streamId, const int32_t captureId)
81 {
82     CAMERA_LOGV("FaceNode::Capture streamId = %{public}d and captureId = %{public}d", streamId, captureId);
83     return RC_OK;
84 }
85 
CancelCapture(const int32_t streamId)86 RetCode FaceNode::CancelCapture(const int32_t streamId)
87 {
88     CAMERA_LOGI("FaceNode::CancelCapture streamid = %{public}d", streamId);
89     return RC_OK;
90 }
91 
GetFaceDetectMetaData(std::shared_ptr<CameraMetadata> & metadata)92 RetCode FaceNode::GetFaceDetectMetaData(std::shared_ptr<CameraMetadata> &metadata)
93 {
94     GetCameraFaceDetectSwitch(metadata);
95     GetCameraFaceRectangles(metadata);
96     GetCameraFaceIds(metadata);
97     return RC_OK;
98 }
99 
GetCameraFaceDetectSwitch(std::shared_ptr<CameraMetadata> & metadata)100 RetCode FaceNode::GetCameraFaceDetectSwitch(std::shared_ptr<CameraMetadata> &metadata)
101 {
102     uint8_t faceDetectSwitch = OHOS_CAMERA_FACE_DETECT_MODE_SIMPLE;
103     metadata->addEntry(OHOS_STATISTICS_FACE_DETECT_SWITCH, &faceDetectSwitch, sizeof(uint8_t));
104     return RC_OK;
105 }
106 
GetCameraFaceRectangles(std::shared_ptr<CameraMetadata> & metadata)107 RetCode FaceNode::GetCameraFaceRectangles(std::shared_ptr<CameraMetadata> &metadata)
108 {
109     constexpr int32_t row = 3;
110     constexpr int32_t col = 4;
111     constexpr float rectOneX = 0.0; // dummy data: faceRectangles data
112     constexpr float rectOneY = 0.0;
113     constexpr float rectOneWidth = 0.2;
114     constexpr float rectOneHeight = 0.3;
115 
116     constexpr float rectTwoX = 0.3; // dummy data: faceRectangles data
117     constexpr float rectTwoY = 0.3;
118     constexpr float rectTwoWidth = 0.2;
119     constexpr float rectTwoHeight = 0.3;
120 
121     constexpr float rectThreeX = 0.6; // dummy data: faceRectangles data
122     constexpr float rectThreeY = 0.6;
123     constexpr float rectThreeWidth = 0.2;
124     constexpr float rectThreeHeight = 0.3;
125 
126     float faceRectangles[row][col];
127     faceRectangles[INDEX_0][INDEX_0] = rectOneX;
128     faceRectangles[INDEX_0][INDEX_1] = rectOneY;
129     faceRectangles[INDEX_0][INDEX_2] = rectOneWidth;
130     faceRectangles[INDEX_0][INDEX_3] = rectOneHeight;
131 
132     faceRectangles[INDEX_1][INDEX_0] = rectTwoX;
133     faceRectangles[INDEX_1][INDEX_1] = rectTwoY;
134     faceRectangles[INDEX_1][INDEX_2] = rectTwoWidth;
135     faceRectangles[INDEX_1][INDEX_3] = rectTwoHeight;
136 
137     faceRectangles[INDEX_2][INDEX_0] = rectThreeX;
138     faceRectangles[INDEX_2][INDEX_1] = rectThreeY;
139     faceRectangles[INDEX_2][INDEX_2] = rectThreeWidth;
140     faceRectangles[INDEX_2][INDEX_3] = rectThreeHeight;
141     metadata->addEntry(OHOS_STATISTICS_FACE_RECTANGLES, static_cast<void*>(&faceRectangles[0]),
142         row * col);
143     return RC_OK;
144 }
145 
GetCameraFaceIds(std::shared_ptr<CameraMetadata> & metadata)146 RetCode FaceNode::GetCameraFaceIds(std::shared_ptr<CameraMetadata> &metadata)
147 {
148     std::vector<int32_t> vFaceIds;
149     constexpr int32_t idZero = 0;
150     constexpr int32_t idOne = 1;
151     constexpr int32_t idTwo = 2;
152     vFaceIds.push_back(idZero);
153     vFaceIds.push_back(idOne);
154     vFaceIds.push_back(idTwo);
155     metadata->addEntry(OHOS_STATISTICS_FACE_IDS, vFaceIds.data(), vFaceIds.size());
156     return RC_OK;
157 }
158 
CopyMetadataBuffer(std::shared_ptr<CameraMetadata> & metadata,std::shared_ptr<IBuffer> & outPutBuffer,int32_t dataSize)159 RetCode FaceNode::CopyMetadataBuffer(std::shared_ptr<CameraMetadata> &metadata,
160     std::shared_ptr<IBuffer>& outPutBuffer, int32_t dataSize)
161 {
162     int bufferSize = outPutBuffer->GetSize();
163     int metadataSize = metadata->get()->size;
164     CAMERA_LOGI("outPutBuffer.size = %{public}d dataSize = %{public}d and metadataSize = %{public}d",
165         bufferSize, dataSize, metadataSize);
166     int ret = 0;
167     ret = memset_s(outPutBuffer->GetVirAddress(),  bufferSize, 0,  bufferSize);
168     if (ret != RC_OK) {
169         CAMERA_LOGE("memset_s failed");
170         return RC_ERROR;
171     }
172 
173     if (memcpy_s(outPutBuffer->GetVirAddress(), metadataSize, static_cast<void*>(metadata->get()),
174         metadataSize) != 0) {
175         CameraHalHisysevent::WriteFaultHisysEvent(CameraHalHisysevent::GetEventName(COPY_BUFFER_ERROR),
176             CameraHalHisysevent::CreateMsg("streamId:%d CopyMetadataBuffer failed", outPutBuffer->GetStreamId()));
177         CAMERA_LOGE("memcpy_s failed");
178         return RC_ERROR;
179     }
180     outPutBuffer->SetEsFrameSize(metadataSize);
181     return RC_OK;
182 }
183 
CopyBuffer(uint8_t * sourceBuffer,std::shared_ptr<IBuffer> & outPutBuffer,int32_t dataSize)184 RetCode FaceNode::CopyBuffer(uint8_t *sourceBuffer, std::shared_ptr<IBuffer>& outPutBuffer, int32_t dataSize)
185 {
186     if (memcpy_s(outPutBuffer->GetVirAddress(), dataSize, sourceBuffer, dataSize) != 0) {
187         CameraHalHisysevent::WriteFaultHisysEvent(CameraHalHisysevent::GetEventName(COPY_BUFFER_ERROR),
188             CameraHalHisysevent::CreateMsg("streamId:%d CopyBuffer failed", outPutBuffer->GetStreamId()));
189         CAMERA_LOGE("copy buffer memcpy_s failed");
190         return RC_ERROR;
191     }
192     outPutBuffer->SetEsFrameSize(dataSize);
193     return RC_OK;
194 }
195 
CreateMetadataInfo()196 RetCode FaceNode::CreateMetadataInfo()
197 {
198     const int entryCapacity = 30; // 30:entry capacity
199     const int dataCapacity = 2000; // 2000:data capacity
200     std::unique_lock <std::mutex> lock(mLock_);
201     metaData_ = std::make_shared<CameraMetadata>(entryCapacity, dataCapacity);
202     RetCode result = GetFaceDetectMetaData(metaData_);
203     if (result  != RC_OK) {
204         CAMERA_LOGE("GetFaceDetectMetaData failed\n");
205         return RC_ERROR;
206     }
207     return RC_OK;
208 }
209 
210 REGISTERNODE(FaceNode, {"Face"})
211 } // namespace OHOS::Camera
212