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  *
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 <vector>
17 
18 #include "ffrt_inner.h"
19 #include "common.h"
20 
FaceStory()21 void FaceStory()
22 {
23     PreHotFFRT();
24 
25     const int FACE_NUM = 3; // 假设图像上存在多少张人脸,可修改,实际业务可以支持1-10个人脸
26 
27     uint32_t inputImageInfo_ = 0; // 模拟输入图像
28     std::vector<uint32_t> faceBboxes_; // 模拟人脸检测框
29     std::vector<uint32_t> faceDegrees_; // 模拟人脸朝向
30     std::vector<uint32_t> faceLandmarks_; // 模拟人脸特征点
31     std::vector<uint32_t> faceAttrs_; // 模拟人脸属性
32     std::vector<uint32_t> faceMasks_; // 模拟人脸分割
33     std::vector<uint32_t> faceAngles_; // 模拟人脸角度
34 
35     TIME_BEGIN(t);
36     for (uint32_t r = 0; r < REPEAT; r++) {
37         for (uint64_t count = 0; count < 10; ++count) {
38             // 原图的预处理,输入原始图像,输出预处理图像
39             ffrt::submit(
40                 [&]() {
41                     // 下采样Y通道
42                     ffrt::submit([&]() { simulate_task_compute_time(COMPUTE_TIME_US); }, {}, {});
43 
44                     // 下采样UV通道
45                     ffrt::submit([&]() { simulate_task_compute_time(COMPUTE_TIME_US); }, {}, {});
46 
47                     ffrt::wait(); // 同步下采样结果
48 
49                     // FlushCache
50                     simulate_task_compute_time(COMPUTE_TIME_US);
51                 },
52                 {}, {&inputImageInfo_});
53 
54             // 人脸检测,输入预处理图像,输出人脸检测结果
55             ffrt::submit(
56                 [&]() {
57                     faceBboxes_.clear();
58                     simulate_task_compute_time(COMPUTE_TIME_US);
59                     for (auto i = 0; i < FACE_NUM; i++) {
60                         faceBboxes_.push_back(1);
61                     }
62                 },
63                 {&inputImageInfo_}, {&faceBboxes_});
64 
65             // Tracking的Init,对processImageInfo_和faceBboxes_是只读,不存在Rotation的情况下,直接丢出去并发就行,也不需要同步
66             ffrt::submit([&]() { simulate_task_compute_time(COMPUTE_TIME_US); }, {&faceBboxes_}, {});
67 
68             // 人脸朝向检测,输出人脸朝向结果(省略了根据朝向做旋转)
69             faceDegrees_ = std::vector<uint32_t>(FACE_NUM, 0);
70             for (auto j = 0; j < FACE_NUM; j++) { // 图像可能存在多个人脸,loop
71                 ffrt::submit(
72                     [&, j]() { // FaceDirectionProcess对于processImageInfo_是只读访问,多个人脸可以并发
73                         simulate_task_compute_time(COMPUTE_TIME_US);
74                         faceDegrees_[j] = 1;
75                     },
76                     {&faceBboxes_}, {&faceDegrees_[j]});
77             }
78 
79             // 人脸特征点检测,输入人脸旋转结果,输出人脸特征点结果
80             faceLandmarks_ = std::vector<uint32_t>(FACE_NUM, 0);
81             for (auto k = 0; k < FACE_NUM; k++) {
82                 ffrt::submit(
83                     [&, k]() {
84                         simulate_task_compute_time(COMPUTE_TIME_US);
85                         faceLandmarks_[k] = 1;
86                     },
87                     {&faceDegrees_[k]}, {&faceLandmarks_[k]});
88             }
89 
90             // 人脸属性检测,输入人脸旋转结果,输出人脸属性结果
91             faceAttrs_ = std::vector<uint32_t>(FACE_NUM, 0);
92             for (auto m = 0; m < FACE_NUM; m++) {
93                 ffrt::submit(
94                     [&, m]() {
95                         simulate_task_compute_time(COMPUTE_TIME_US);
96                         faceAttrs_[m] = 1;
97                     },
98                     {&faceDegrees_[m]}, {&faceAttrs_[m]});
99             }
100 
101             // 人脸分割,输入人脸旋转结果,输出人脸特征点结果
102             faceMasks_ = std::vector<uint32_t>(FACE_NUM, 0);
103             for (auto n = 0; n < 1; n++) { // 实际业务中分割当前只做一次
104                 ffrt::submit(
105                     [&, n]() {
106                         simulate_task_compute_time(COMPUTE_TIME_US);
107                         faceMasks_[n] = 1;
108                     },
109                     {&faceDegrees_[n]}, {&faceMasks_[n]});
110             }
111 
112             // 人脸角度检测,输入人脸特征点结果,输出人脸角度结果
113             faceAngles_ = std::vector<uint32_t>(FACE_NUM, 0);
114             for (auto q = 0; q < FACE_NUM; q++) { // 实际业务中分割当前只做一次
115                 ffrt::submit(
116                     [&, q]() {
117                         simulate_task_compute_time(COMPUTE_TIME_US);
118                         faceAngles_[q] = 1;
119                     },
120                     {&faceLandmarks_[q]}, {&faceAngles_[q]});
121             }
122 
123             ffrt::wait(); // 同步子任务完成
124         }
125     }
126     TIME_END_INFO(t, "face_story");
127 }
128 
main()129 int main()
130 {
131     GetEnvs();
132     FaceStory();
133 }