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
28 #include "sample_comm_ive.h"
29
30 typedef struct hiSAMPLE_IVE_SOBEL_S {
31 IVE_SRC_IMAGE_S stSrc1;
32 IVE_SRC_IMAGE_S stSrc2;
33 IVE_DST_IMAGE_S stDstH1;
34 IVE_DST_IMAGE_S stDstH2;
35 IVE_DST_IMAGE_S stDstV1;
36 IVE_DST_IMAGE_S stDstV2;
37 IVE_SOBEL_CTRL_S stSobelCtrl;
38 FILE *pFpSrc;
39 FILE *pFpDstH1;
40 FILE *pFpDstH2;
41 FILE *pFpDstV1;
42 FILE *pFpDstV2;
43 } SAMPLE_IVE_SOBEL_S;
44
45 static HI_BOOL s_bFlushCached = HI_TRUE;
46 static SAMPLE_IVE_SOBEL_S s_stSobel;
47 static HI_BOOL s_bStopSignal = HI_FALSE;
48
49 /* function : show Sobel uninit */
SAMPLE_IVE_Sobel_Uninit(SAMPLE_IVE_SOBEL_S * pstSobel)50 static HI_VOID SAMPLE_IVE_Sobel_Uninit(SAMPLE_IVE_SOBEL_S *pstSobel)
51 {
52 IVE_MMZ_FREE(pstSobel->stSrc1.au64PhyAddr[0], pstSobel->stSrc1.au64VirAddr[0]);
53 IVE_MMZ_FREE(pstSobel->stSrc2.au64PhyAddr[0], pstSobel->stSrc2.au64VirAddr[0]);
54 IVE_MMZ_FREE(pstSobel->stDstH1.au64PhyAddr[0], pstSobel->stDstH1.au64VirAddr[0]);
55 IVE_MMZ_FREE(pstSobel->stDstH2.au64PhyAddr[0], pstSobel->stDstH2.au64VirAddr[0]);
56 IVE_MMZ_FREE(pstSobel->stDstV1.au64PhyAddr[0], pstSobel->stDstV1.au64VirAddr[0]);
57 IVE_MMZ_FREE(pstSobel->stDstV2.au64PhyAddr[0], pstSobel->stDstV2.au64VirAddr[0]);
58
59 IVE_CLOSE_FILE(pstSobel->pFpSrc);
60 IVE_CLOSE_FILE(pstSobel->pFpDstH1);
61 IVE_CLOSE_FILE(pstSobel->pFpDstH2);
62 IVE_CLOSE_FILE(pstSobel->pFpDstV1);
63 IVE_CLOSE_FILE(pstSobel->pFpDstV2);
64 }
65 /* function : show Sobel init */
SAMPLE_IVE_Sobel_Init(SAMPLE_IVE_SOBEL_S * pstSobel,HI_CHAR * pchSrcFileName,HI_U32 u32Width,HI_U32 u32Height)66 static HI_S32 SAMPLE_IVE_Sobel_Init(SAMPLE_IVE_SOBEL_S *pstSobel, HI_CHAR *pchSrcFileName, HI_U32 u32Width,
67 HI_U32 u32Height)
68 {
69 HI_S32 s32Ret = HI_SUCCESS;
70 HI_CHAR path[PATH_MAX] = {0};
71 HI_CHAR *file = "./data/output/sobel";
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
80 (HI_VOID)memset_s(pstSobel, sizeof(SAMPLE_IVE_SOBEL_S), 0, sizeof(SAMPLE_IVE_SOBEL_S));
81
82 s32Ret = SAMPLE_COMM_IVE_CreateImageByCached(&(pstSobel->stSrc1), IVE_IMAGE_TYPE_U8C1, u32Width, u32Height);
83 SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, SOBEL_INIT_FAIL, "Error(%#x),Create src1 image failed!\n", s32Ret);
84
85 s32Ret = SAMPLE_COMM_IVE_CreateImageByCached(&(pstSobel->stSrc2), IVE_IMAGE_TYPE_U8C1, u32Width, u32Height);
86 SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, SOBEL_INIT_FAIL, "Error(%#x),Create src2 image failed!\n", s32Ret);
87
88 s32Ret = SAMPLE_COMM_IVE_CreateImage(&(pstSobel->stDstH1), IVE_IMAGE_TYPE_S16C1, u32Width, u32Height);
89 SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, SOBEL_INIT_FAIL, "Error(%#x),Create dstH1 image failed!\n", s32Ret);
90
91 s32Ret = SAMPLE_COMM_IVE_CreateImage(&(pstSobel->stDstH2), IVE_IMAGE_TYPE_S16C1, u32Width, u32Height);
92 SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, SOBEL_INIT_FAIL, "Error(%#x),Create dstH2 image failed!\n", s32Ret);
93
94 s32Ret = SAMPLE_COMM_IVE_CreateImage(&(pstSobel->stDstV1), IVE_IMAGE_TYPE_S16C1, u32Width, u32Height);
95 SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, SOBEL_INIT_FAIL, "Error(%#x),Create dstV1 image failed!\n", s32Ret);
96
97 s32Ret = SAMPLE_COMM_IVE_CreateImage(&(pstSobel->stDstV2), IVE_IMAGE_TYPE_S16C1, u32Width, u32Height);
98 SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, SOBEL_INIT_FAIL, "Error(%#x),Create dstV2 image failed!\n", s32Ret);
99
100 pstSobel->stSobelCtrl.enOutCtrl = IVE_SOBEL_OUT_CTRL_BOTH;
101 (HI_VOID)memcpy_s(pstSobel->stSobelCtrl.as8Mask, sizeof(as8Mask), as8Mask, sizeof(as8Mask));
102 s32Ret = HI_FAILURE;
103 pstSobel->pFpSrc = fopen(pchSrcFileName, "rb");
104 SAMPLE_CHECK_EXPR_GOTO(pstSobel->pFpSrc == HI_NULL, SOBEL_INIT_FAIL, "Error,Open file %s failed!\n",
105 pchSrcFileName);
106
107 SAMPLE_CHECK_EXPR_GOTO(realpath(file, path) == NULL, SOBEL_INIT_FAIL, "invalid path!\n");
108 s32Ret = strcat_s(path, PATH_MAX, "/sobelh1.dat");
109 SAMPLE_CHECK_EXPR_GOTO(s32Ret != EOK, SOBEL_INIT_FAIL, "stract_s failed!\n");
110 s32Ret = HI_FAILURE;
111 pstSobel->pFpDstH1 = fopen(path, "wb");
112 SAMPLE_CHECK_EXPR_GOTO(pstSobel->pFpDstH1 == HI_NULL, SOBEL_INIT_FAIL, "Error,Open file %s failed!\n", path);
113
114 SAMPLE_CHECK_EXPR_GOTO(realpath(file, path) == NULL, SOBEL_INIT_FAIL, "invalid path!\n");
115 s32Ret = strcat_s(path, PATH_MAX, "/sobelh2.dat");
116 SAMPLE_CHECK_EXPR_GOTO(s32Ret != EOK, SOBEL_INIT_FAIL, "stract_s failed!\n");
117 s32Ret = HI_FAILURE;
118 pstSobel->pFpDstH2 = fopen(path, "wb");
119 SAMPLE_CHECK_EXPR_GOTO(pstSobel->pFpDstH2 == HI_NULL, SOBEL_INIT_FAIL, "Error,Open file %s failed!\n", path);
120 SAMPLE_CHECK_EXPR_GOTO(realpath(file, path) == NULL, SOBEL_INIT_FAIL, "invalid path!\n");
121 s32Ret = strcat_s(path, PATH_MAX, "/sobelv1.dat");
122 SAMPLE_CHECK_EXPR_GOTO(s32Ret != EOK, SOBEL_INIT_FAIL, "stract_s failed!\n");
123 s32Ret = HI_FAILURE;
124 pstSobel->pFpDstV1 = fopen(path, "wb");
125 SAMPLE_CHECK_EXPR_GOTO(pstSobel->pFpDstV1 == HI_NULL, SOBEL_INIT_FAIL, "Error,Open file %s failed!\n", path);
126 SAMPLE_CHECK_EXPR_GOTO(realpath(file, path) == NULL, SOBEL_INIT_FAIL, "invalid path!\n");
127 s32Ret = strcat_s(path, PATH_MAX, "/sobelv2.dat");
128 SAMPLE_CHECK_EXPR_GOTO(s32Ret != EOK, SOBEL_INIT_FAIL, "stract_s failed!\n");
129 s32Ret = HI_FAILURE;
130 pstSobel->pFpDstV2 = fopen(path, "wb");
131 SAMPLE_CHECK_EXPR_GOTO(pstSobel->pFpDstV2 == HI_NULL, SOBEL_INIT_FAIL, "Error,Open file %s failed!\n", path);
132 s32Ret = HI_SUCCESS;
133
134 SOBEL_INIT_FAIL:
135 if (s32Ret != HI_SUCCESS) {
136 SAMPLE_IVE_Sobel_Uninit(pstSobel);
137 }
138 return s32Ret;
139 }
140
141 /* function : show Sobel proc */
SAMPLE_IVE_SobelProc(SAMPLE_IVE_SOBEL_S * pstSobel)142 static HI_S32 SAMPLE_IVE_SobelProc(SAMPLE_IVE_SOBEL_S *pstSobel)
143 {
144 HI_S32 s32Ret = HI_SUCCESS;
145 HI_BOOL bInstant = HI_TRUE;
146 IVE_HANDLE IveHandle;
147 HI_BOOL bBlock = HI_TRUE;
148 HI_BOOL bFinish = HI_FALSE;
149
150 s32Ret = SAMPLE_COMM_IVE_ReadFile(&(pstSobel->stSrc1), pstSobel->pFpSrc);
151 SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),Read src file failed!\n", s32Ret);
152 /* src1 address and src2 address can not be overlap */
153 (HI_VOID)memcpy_s(SAMPLE_COMM_IVE_CONVERT_64BIT_ADDR(HI_VOID, pstSobel->stSrc2.au64VirAddr[0]),
154 pstSobel->stSrc2.au32Stride[0] * pstSobel->stSrc2.u32Height,
155 SAMPLE_COMM_IVE_CONVERT_64BIT_ADDR(HI_VOID, pstSobel->stSrc1.au64VirAddr[0]),
156 pstSobel->stSrc2.au32Stride[0] * pstSobel->stSrc2.u32Height);
157 s32Ret = HI_MPI_SYS_MmzFlushCache(pstSobel->stSrc1.au64PhyAddr[0],
158 SAMPLE_COMM_IVE_CONVERT_64BIT_ADDR(HI_VOID, pstSobel->stSrc1.au64VirAddr[0]),
159 pstSobel->stSrc1.au32Stride[0] * pstSobel->stSrc1.u32Height);
160 SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),HI_MPI_SYS_MmzFlushCache failed!\n", s32Ret);
161
162 s32Ret = HI_MPI_IVE_Sobel(&IveHandle, &pstSobel->stSrc1, &pstSobel->stDstH1, &pstSobel->stDstV1,
163 &pstSobel->stSobelCtrl, bInstant);
164 SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),HI_MPI_IVE_Sobel failed!\n", s32Ret);
165
166 s32Ret = HI_MPI_IVE_Query(IveHandle, &bFinish, bBlock);
167 while (s32Ret == HI_ERR_IVE_QUERY_TIMEOUT) {
168 usleep(IVE_QUERY_SLEEP_TIME); /* sleep 100 us */
169 s32Ret = HI_MPI_IVE_Query(IveHandle, &bFinish, bBlock);
170 }
171
172 SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),HI_MPI_IVE_Query failed!\n", s32Ret);
173 s32Ret = SAMPLE_COMM_IVE_WriteFile(&pstSobel->stDstH1, pstSobel->pFpDstH1);
174 SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),Write dstH1 failed!\n", s32Ret);
175 s32Ret = SAMPLE_COMM_IVE_WriteFile(&pstSobel->stDstV1, pstSobel->pFpDstV1);
176 SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),Write dstV1 failed!\n", s32Ret);
177
178 // Second sobel
179 // The result of sobel my be error,if you do not call HI_MPI_SYS_MmzFlushCache to flush cache
180 if (s_bFlushCached == HI_TRUE) {
181 s32Ret = HI_MPI_SYS_MmzFlushCache(pstSobel->stSrc2.au64PhyAddr[0],
182 SAMPLE_COMM_IVE_CONVERT_64BIT_ADDR(HI_VOID, pstSobel->stSrc2.au64VirAddr[0]),
183 pstSobel->stSrc2.au32Stride[0] * pstSobel->stSrc2.u32Height);
184 SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),HI_MPI_SYS_MmzFlushCache failed!\n", s32Ret);
185 }
186
187 s32Ret = HI_MPI_IVE_Sobel(&IveHandle, &pstSobel->stSrc2, &pstSobel->stDstH2, &pstSobel->stDstV2,
188 &pstSobel->stSobelCtrl, bInstant);
189 SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),HI_MPI_IVE_Sobel failed!\n", s32Ret);
190
191 s32Ret = HI_MPI_IVE_Query(IveHandle, &bFinish, bBlock);
192 while (s32Ret == HI_ERR_IVE_QUERY_TIMEOUT) {
193 usleep(IVE_QUERY_SLEEP_TIME); /* sleep 100 us */
194 s32Ret = HI_MPI_IVE_Query(IveHandle, &bFinish, bBlock);
195 }
196 SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),HI_MPI_IVE_Query failed!\n", s32Ret);
197 s32Ret = SAMPLE_COMM_IVE_WriteFile(&pstSobel->stDstH2, pstSobel->pFpDstH2);
198 SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),Write dstH2 failed!\n", s32Ret);
199 s32Ret = SAMPLE_COMM_IVE_WriteFile(&pstSobel->stDstV2, pstSobel->pFpDstV2);
200 SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),Write dstV2 failed!\n", s32Ret);
201 return s32Ret;
202 }
203
SAMPLE_IVE_SobelPause(HI_VOID)204 static HI_VOID SAMPLE_IVE_SobelPause(HI_VOID)
205 {
206 SAMPLE_IVE_Sobel_Uninit(&s_stSobel);
207 (HI_VOID)memset_s(&s_stSobel, sizeof(s_stSobel), 0, sizeof(s_stSobel));
208 SAMPLE_COMM_IVE_IveMpiExit();
209 printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
210 }
211
212 /* function : show Sobel sample */
SAMPLE_IVE_Sobel(HI_VOID)213 HI_VOID SAMPLE_IVE_Sobel(HI_VOID)
214 {
215 HI_S32 s32Ret;
216 HI_U32 u32Width = IVE_D1_WIDTH;
217 HI_U32 u32Height = IVE_D1_HEIGHT;
218 HI_CHAR *pchSrcFileName = "./data/input/sobel/sobel.yuv";
219 HI_CHAR achSrcFileName[PATH_MAX] = {0};
220 s_bStopSignal = HI_FALSE;
221
222 SAMPLE_CHECK_EXPR_RET_VOID(
223 (strlen(pchSrcFileName) > PATH_MAX) || (realpath(pchSrcFileName, achSrcFileName) == NULL), "invalid path!\n");
224 (HI_VOID)memset_s(&s_stSobel, sizeof(s_stSobel), 0, sizeof(s_stSobel));
225 SAMPLE_COMM_IVE_CheckIveMpiInit();
226 s32Ret = SAMPLE_IVE_Sobel_Init(&s_stSobel, achSrcFileName, u32Width, u32Height);
227 SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, SOBEL_FAIL, "Error(%#x),SAMPLE_IVE_Sobel_Init failed!\n", s32Ret);
228 if (s_bStopSignal == HI_TRUE) {
229 SAMPLE_IVE_SobelPause();
230 return;
231 }
232
233 s32Ret = SAMPLE_IVE_SobelProc(&s_stSobel);
234 if (s32Ret == HI_SUCCESS) {
235 SAMPLE_PRT("Process success!\n");
236 }
237 if (s_bStopSignal == HI_TRUE) {
238 SAMPLE_IVE_SobelPause();
239 return;
240 }
241
242 s_bStopSignal = HI_TRUE;
243 SAMPLE_IVE_Sobel_Uninit(&s_stSobel);
244 (HI_VOID)memset_s(&s_stSobel, sizeof(s_stSobel), 0, sizeof(s_stSobel));
245
246 SOBEL_FAIL:
247 s_bStopSignal = HI_TRUE;
248 SAMPLE_COMM_IVE_IveMpiExit();
249 }
250
251 /* function : Sobel sample signal handle */
SAMPLE_IVE_Sobel_HandleSig(HI_VOID)252 HI_VOID SAMPLE_IVE_Sobel_HandleSig(HI_VOID)
253 {
254 s_bStopSignal = HI_TRUE;
255 }
256