• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
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 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <sys/mman.h>
21 #include <sys/stat.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24 #include <signal.h>
25 #include <semaphore.h>
26 #include <pthread.h>
27 #include <math.h>
28 
29 #include "sample_comm_ive.h"
30 
31 #define SAMPLE_IVE_CANNY_HYS_EDGE_HIGH_THR 150
32 #define SAMPLE_IVE_CANNY_HYS_EDGE_LOW_THR  50
33 #define SAMPLE_IVE_CANNY_THR_U16_HIGH_THR  100
34 #define SAMPLE_IVE_CANNY_THR_U16_LOW_THR   100
35 #define SAMPLE_IVE_CANNY_THR_U16_MAX_VAL   255
36 #define SAMPLE_IVE_CANNY_THR_U16_MID_VAL   0
37 #define SAMPLE_IVE_CANNY_THR_U16_MIN_VAL   0
38 
39 typedef struct hiSAMPLE_IVE_CANNY_INFO_S {
40     IVE_SRC_IMAGE_S stSrc;
41     IVE_DST_IMAGE_S stEdge;
42     IVE_DST_IMAGE_S stMag;
43     IVE_MEM_INFO_S stStack;
44     IVE_CANNY_HYS_EDGE_CTRL_S stCannyHysEdgeCtrl;
45     IVE_MAG_AND_ANG_CTRL_S stMagAndAngCtrl;
46     IVE_THRESH_U16_CTRL_S stThrU16Ctrl;
47     FILE *pFpSrc;
48     FILE *pFpDst;
49 } SAMPLE_IVE_CANNY_INFO_S;
50 
51 static SAMPLE_IVE_CANNY_INFO_S s_stCannyInfo;
52 static HI_BOOL s_bStopSignal = HI_FALSE;
53 
SAMPLE_IVE_Canny_Uninit(SAMPLE_IVE_CANNY_INFO_S * pstCannyInfo)54 static HI_VOID SAMPLE_IVE_Canny_Uninit(SAMPLE_IVE_CANNY_INFO_S *pstCannyInfo)
55 {
56     IVE_MMZ_FREE(pstCannyInfo->stSrc.au64PhyAddr[0], pstCannyInfo->stSrc.au64VirAddr[0]);
57     IVE_MMZ_FREE(pstCannyInfo->stEdge.au64PhyAddr[0], pstCannyInfo->stEdge.au64VirAddr[0]);
58     IVE_MMZ_FREE(pstCannyInfo->stMag.au64PhyAddr[0], pstCannyInfo->stMag.au64VirAddr[0]);
59     IVE_MMZ_FREE(pstCannyInfo->stStack.u64PhyAddr, pstCannyInfo->stStack.u64VirAddr);
60     IVE_MMZ_FREE(pstCannyInfo->stCannyHysEdgeCtrl.stMem.u64PhyAddr, pstCannyInfo->stCannyHysEdgeCtrl.stMem.u64VirAddr);
61 
62     IVE_CLOSE_FILE(pstCannyInfo->pFpSrc);
63     IVE_CLOSE_FILE(pstCannyInfo->pFpDst);
64 }
65 
SAMPLE_IVE_Canny_Init(SAMPLE_IVE_CANNY_INFO_S * pstCannyInfo,HI_CHAR * pchSrcFileName,HI_CHAR * pchDstFileName,HI_U32 u32Width,HI_U32 u32Height)66 static HI_S32 SAMPLE_IVE_Canny_Init(SAMPLE_IVE_CANNY_INFO_S *pstCannyInfo, HI_CHAR *pchSrcFileName,
67     HI_CHAR *pchDstFileName, HI_U32 u32Width, HI_U32 u32Height)
68 {
69     HI_S32 s32Ret = HI_SUCCESS;
70     HI_U32 u32Size;
71     /* canny filter mask 5x5 */
72     HI_S8 as8Mask[IVE_MASK_NUM_25] = {
73         0, 0, 0, 0, 0,
74         0, -1, 0, 1, 0,
75         0, -2, 0, 2, 0,
76         0, -1, 0, 1, 0,
77         0, 0, 0, 0, 0};
78 
79     (HI_VOID)memset_s(pstCannyInfo, sizeof(SAMPLE_IVE_CANNY_INFO_S), 0, sizeof(SAMPLE_IVE_CANNY_INFO_S));
80     (HI_VOID)memcpy_s(pstCannyInfo->stCannyHysEdgeCtrl.as8Mask, IVE_MASK_NUM_25, as8Mask, IVE_MASK_NUM_25);
81     (HI_VOID)memcpy_s(pstCannyInfo->stMagAndAngCtrl.as8Mask, IVE_MASK_NUM_25, as8Mask, IVE_MASK_NUM_25);
82     pstCannyInfo->stCannyHysEdgeCtrl.u16HighThr = SAMPLE_IVE_CANNY_HYS_EDGE_HIGH_THR;
83     pstCannyInfo->stCannyHysEdgeCtrl.u16LowThr = SAMPLE_IVE_CANNY_HYS_EDGE_LOW_THR;
84     pstCannyInfo->stMagAndAngCtrl.enOutCtrl = IVE_MAG_AND_ANG_OUT_CTRL_MAG;
85     pstCannyInfo->stMagAndAngCtrl.u16Thr = 0;
86     pstCannyInfo->stThrU16Ctrl.enMode = IVE_THRESH_U16_MODE_U16_TO_U8_MIN_MID_MAX;
87     pstCannyInfo->stThrU16Ctrl.u16HighThr = SAMPLE_IVE_CANNY_THR_U16_HIGH_THR;
88     pstCannyInfo->stThrU16Ctrl.u16LowThr = SAMPLE_IVE_CANNY_THR_U16_LOW_THR;
89     pstCannyInfo->stThrU16Ctrl.u8MaxVal = SAMPLE_IVE_CANNY_THR_U16_MAX_VAL;
90     pstCannyInfo->stThrU16Ctrl.u8MidVal = SAMPLE_IVE_CANNY_THR_U16_MID_VAL;
91     pstCannyInfo->stThrU16Ctrl.u8MinVal = SAMPLE_IVE_CANNY_THR_U16_MIN_VAL;
92 
93     s32Ret = SAMPLE_COMM_IVE_CreateImage(&pstCannyInfo->stSrc, IVE_IMAGE_TYPE_U8C1, u32Width, u32Height);
94     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, CANNY_INIT_FAIL, "Error(%#x),Create Src Image failed!\n", s32Ret);
95     s32Ret = SAMPLE_COMM_IVE_CreateImage(&pstCannyInfo->stEdge, IVE_IMAGE_TYPE_U8C1, u32Width, u32Height);
96     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, CANNY_INIT_FAIL, "Error(%#x),Create edge Image failed!\n", s32Ret);
97     s32Ret = SAMPLE_COMM_IVE_CreateImage(&pstCannyInfo->stMag, IVE_IMAGE_TYPE_U16C1, u32Width, u32Height);
98     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, CANNY_INIT_FAIL, "Error(%#x),Create Mag Image failed!\n", s32Ret);
99     u32Size = (HI_U32)sizeof(HI_U16) + (HI_U32)sizeof(HI_U16);
100     u32Size = pstCannyInfo->stSrc.au32Stride[0] * pstCannyInfo->stSrc.u32Height * u32Size +
101         sizeof(IVE_CANNY_STACK_SIZE_S);
102     s32Ret = SAMPLE_COMM_IVE_CreateMemInfo(&pstCannyInfo->stStack, u32Size);
103     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, CANNY_INIT_FAIL, "Error(%#x),Create Stack Mem info failed!\n", s32Ret);
104     u32Size = (HI_U32)sizeof(HI_U16) + (HI_U32)sizeof(HI_U8);
105     u32Size = pstCannyInfo->stSrc.au32Stride[0] * pstCannyInfo->stSrc.u32Height * u32Size;
106     s32Ret = SAMPLE_COMM_IVE_CreateMemInfo(&pstCannyInfo->stCannyHysEdgeCtrl.stMem, u32Size);
107     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, CANNY_INIT_FAIL,
108         "Error(%#x),Create CannyHysEdgeCtrl.stMem Mem info failed!\n", s32Ret);
109 
110     s32Ret = HI_FAILURE;
111     pstCannyInfo->pFpSrc = fopen(pchSrcFileName, "rb");
112     SAMPLE_CHECK_EXPR_GOTO(pstCannyInfo->pFpSrc == HI_NULL, CANNY_INIT_FAIL, "Error,Open file %s failed!\n",
113         pchSrcFileName);
114     pstCannyInfo->pFpDst = fopen(pchDstFileName, "wb");
115     SAMPLE_CHECK_EXPR_GOTO(pstCannyInfo->pFpDst == HI_NULL, CANNY_INIT_FAIL, "Error,Open file %s failed!\n",
116         pchDstFileName);
117 
118     s32Ret = HI_SUCCESS;
119 
120 CANNY_INIT_FAIL:
121     if (s32Ret != HI_SUCCESS) {
122         SAMPLE_IVE_Canny_Uninit(pstCannyInfo);
123     }
124     return s32Ret;
125 }
126 
SAMPLE_IVE_Complete_Canny(SAMPLE_IVE_CANNY_INFO_S * pstCannyInfo)127 static HI_S32 SAMPLE_IVE_Complete_Canny(SAMPLE_IVE_CANNY_INFO_S *pstCannyInfo)
128 {
129     HI_S32 s32Ret = HI_SUCCESS;
130     HI_BOOL bInstant = HI_TRUE;
131     HI_BOOL bBlock = HI_TRUE;
132     HI_BOOL bFinish = HI_FALSE;
133     IVE_HANDLE IveHandle;
134 
135     s32Ret = SAMPLE_COMM_IVE_ReadFile(&(pstCannyInfo->stSrc), pstCannyInfo->pFpSrc);
136     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),Read src file failed!\n", s32Ret);
137 
138     s32Ret = HI_MPI_IVE_CannyHysEdge(&IveHandle, &pstCannyInfo->stSrc, &pstCannyInfo->stEdge, &pstCannyInfo->stStack,
139         &pstCannyInfo->stCannyHysEdgeCtrl, bInstant);
140     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),HI_MPI_IVE_CannyHysEdge failed!\n", s32Ret);
141 
142     s32Ret = HI_MPI_IVE_Query(IveHandle, &bFinish, bBlock);
143     while (s32Ret == HI_ERR_IVE_QUERY_TIMEOUT) {
144         usleep(IVE_QUERY_SLEEP_TIME);
145         s32Ret = HI_MPI_IVE_Query(IveHandle, &bFinish, bBlock);
146     }
147     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),HI_MPI_IVE_Query failed!\n", s32Ret);
148     s32Ret = HI_MPI_IVE_CannyEdge(&pstCannyInfo->stEdge, &pstCannyInfo->stStack);
149     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),HI_MPI_IVE_CannyEdge failed!\n", s32Ret);
150     s32Ret = SAMPLE_COMM_IVE_WriteFile(&pstCannyInfo->stEdge, pstCannyInfo->pFpDst);
151     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),Write edge file failed!\n", s32Ret);
152 
153     return s32Ret;
154 }
155 
SAMPLE_IVE_Part_Canny(SAMPLE_IVE_CANNY_INFO_S * pstCannyInfo)156 static HI_S32 SAMPLE_IVE_Part_Canny(SAMPLE_IVE_CANNY_INFO_S *pstCannyInfo)
157 {
158     HI_S32 s32Ret = HI_SUCCESS;
159     HI_BOOL bInstant = HI_TRUE;
160     HI_BOOL bBlock = HI_TRUE;
161     HI_BOOL bFinish = HI_FALSE;
162     IVE_HANDLE IveHandle;
163 
164     s32Ret = SAMPLE_COMM_IVE_ReadFile(&pstCannyInfo->stSrc, pstCannyInfo->pFpSrc);
165     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),Read src file failed!\n", s32Ret);
166 
167     bInstant = HI_FALSE;
168     s32Ret = HI_MPI_IVE_MagAndAng(&IveHandle, &pstCannyInfo->stSrc, &pstCannyInfo->stMag, HI_NULL,
169         &pstCannyInfo->stMagAndAngCtrl, bInstant);
170     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),HI_MPI_IVE_MagAndAng failed!\n", s32Ret);
171 
172     bInstant = HI_TRUE;
173     s32Ret = HI_MPI_IVE_Thresh_U16(&IveHandle, &pstCannyInfo->stMag, &pstCannyInfo->stEdge, &pstCannyInfo->stThrU16Ctrl,
174         bInstant);
175     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),HI_MPI_IVE_Thresh_U16 failed!\n", s32Ret);
176 
177     s32Ret = HI_MPI_IVE_Query(IveHandle, &bFinish, bBlock);
178     while (s32Ret == HI_ERR_IVE_QUERY_TIMEOUT) {
179         usleep(IVE_QUERY_SLEEP_TIME);
180         s32Ret = HI_MPI_IVE_Query(IveHandle, &bFinish, bBlock);
181     }
182     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),HI_MPI_IVE_Query failed!\n", s32Ret);
183 
184     s32Ret = SAMPLE_COMM_IVE_WriteFile(&pstCannyInfo->stEdge, pstCannyInfo->pFpDst);
185     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),Write edge file failed!\n", s32Ret);
186 
187     return s32Ret;
188 }
189 
SAMPLE_IVE_CannyStop(HI_VOID)190 static HI_VOID SAMPLE_IVE_CannyStop(HI_VOID)
191 {
192     SAMPLE_IVE_Canny_Uninit(&s_stCannyInfo);
193     (HI_VOID)memset_s(&s_stCannyInfo, sizeof(s_stCannyInfo), 0, sizeof(s_stCannyInfo));
194     SAMPLE_COMM_IVE_IveMpiExit();
195     printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
196 }
197 
SAMPLE_IVE_Canny(HI_CHAR chComplete)198 HI_VOID SAMPLE_IVE_Canny(HI_CHAR chComplete)
199 {
200     HI_U16 u32Width = IVE_D1_WIDTH;
201     HI_U16 u32Height = IVE_D1_HEIGHT;
202     HI_CHAR *pchSrcFileName = "./data/input/canny/canny.yuv";
203     HI_CHAR *pchDstFileName = "./data/output/canny";
204 
205     HI_CHAR achSrcFileName[PATH_MAX] = {0};
206     HI_CHAR achDstFileName[PATH_MAX] = {0};
207     HI_CHAR tmpFile[PATH_MAX] = {0};
208     HI_S32 s32Ret;
209     s_bStopSignal = HI_FALSE;
210 
211     SAMPLE_CHECK_EXPR_RET_VOID((strlen(pchSrcFileName) > PATH_MAX) ||
212         (realpath(pchSrcFileName, achSrcFileName) == NULL),
213         "invalid input file\n");
214 
215     SAMPLE_CHECK_EXPR_RET_VOID((strlen(pchDstFileName) > PATH_MAX) ||
216         (realpath(pchDstFileName, achDstFileName) == NULL),
217         "invalid input file\n");
218 
219     s32Ret = snprintf_s(tmpFile, sizeof(tmpFile), sizeof(tmpFile) - 1, "/cannyout_complete_%c.yuv", chComplete);
220     SAMPLE_CHECK_EXPR_RET_VOID(s32Ret < 0, "invalid param!\n");
221 
222     s32Ret = strcat_s(achDstFileName, PATH_MAX, tmpFile);
223     SAMPLE_CHECK_EXPR_RET_VOID(s32Ret < 0, "invalid param!\n");
224 
225     (HI_VOID)memset_s(&s_stCannyInfo, sizeof(s_stCannyInfo), 0, sizeof(s_stCannyInfo));
226     SAMPLE_COMM_IVE_CheckIveMpiInit();
227 
228     s32Ret = SAMPLE_IVE_Canny_Init(&s_stCannyInfo, achSrcFileName, achDstFileName, u32Width, u32Height);
229     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, CANNY_FAIL, "Error(%#x),SAMPLE_IVE_Canny_Init failed!\n", s32Ret);
230     if (s_bStopSignal == HI_TRUE) {
231         SAMPLE_IVE_CannyStop();
232         return;
233     }
234 
235     if (chComplete == '0') {
236         s32Ret = SAMPLE_IVE_Part_Canny(&s_stCannyInfo);
237     } else {
238         s32Ret = SAMPLE_IVE_Complete_Canny(&s_stCannyInfo);
239     }
240 
241     if (s_bStopSignal == HI_TRUE) {
242         SAMPLE_IVE_CannyStop();
243         return;
244     }
245 
246     if (s32Ret == HI_SUCCESS) {
247         SAMPLE_PRT("Process success!\n");
248     }
249 
250     s_bStopSignal = HI_TRUE;
251     SAMPLE_IVE_Canny_Uninit(&s_stCannyInfo);
252     (HI_VOID)memset_s(&s_stCannyInfo, sizeof(s_stCannyInfo), 0, sizeof(s_stCannyInfo));
253 
254 CANNY_FAIL:
255     s_bStopSignal = HI_TRUE;
256     SAMPLE_COMM_IVE_IveMpiExit();
257 }
258 
SAMPLE_IVE_Canny_HandleSig(HI_VOID)259 HI_VOID SAMPLE_IVE_Canny_HandleSig(HI_VOID)
260 {
261     s_bStopSignal = HI_TRUE;
262 }
263