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 #define SAMPLE_IVE_PSP_WIDTH_250 250
31 #define SAMPLE_IVE_PSP_HEIGHT_250 250
32 #define SAMPLE_IVE_PSP_WIDTH_96 96
33 #define SAMPLE_IVE_PSP_HEIGHT_112 112
34 #define SAMPLE_IVE_PSP_POINT_PAIR_NUM_68 68
35 #define SAMPLE_IVE_PSP_POINT_PAIR_NUM_5 5
36 #define SAMPLE_IVE_PSP_POINT_FIX_BIT 2
37 #define SAMPLE_IVE_PSP_IDX_1 1
38 #define SAMPLE_IVE_PSP_IDX_2 2
39 #define SAMPLE_IVE_PSP_IDX_3 3
40 #define SAMPLE_IVE_PSP_LAND_MASK_OFFSET 4
41 #define SAMPLE_IVE_PSP_MAX_ROI 64
42 #define SAMPLE_IVE_PSP_MAX_POINT_PAIR 64
43
44 typedef struct hiSAMPLE_IVE_PERSP_TRANS_S {
45 IVE_SRC_IMAGE_S stSrc;
46 IVE_RECT_U32_S astRoi[SAMPLE_IVE_PSP_MAX_ROI];
47 HI_U16 u16RoiNum;
48 IVE_DST_IMAGE_S astDst[SAMPLE_IVE_PSP_MAX_ROI];
49 IVE_SRC_MEM_INFO_S astPointPair[SAMPLE_IVE_PSP_MAX_POINT_PAIR];
50 IVE_PERSP_TRANS_CTRL_S stPerspTransCtrl;
51
52 FILE *pFpSrc;
53 FILE *pFpDst;
54 } SAMPLE_IVE_PERSP_TRANS_S;
55
56 static SAMPLE_IVE_PERSP_TRANS_S s_stPerspTrans;
57 static HI_BOOL s_bStopSignal = HI_FALSE;
58
SAMPLE_IVE_PerspTrans_Uninit(SAMPLE_IVE_PERSP_TRANS_S * pstPerspTrans)59 static HI_VOID SAMPLE_IVE_PerspTrans_Uninit(SAMPLE_IVE_PERSP_TRANS_S *pstPerspTrans)
60 {
61 HI_U16 i;
62
63 IVE_MMZ_FREE(pstPerspTrans->stSrc.au64PhyAddr[0], pstPerspTrans->stSrc.au64VirAddr[0]);
64
65 for (i = 0; i < pstPerspTrans->u16RoiNum; i++) {
66 IVE_MMZ_FREE(pstPerspTrans->astDst[i].au64PhyAddr[0], pstPerspTrans->astDst[i].au64VirAddr[0]);
67 IVE_MMZ_FREE(pstPerspTrans->astPointPair[i].u64PhyAddr, pstPerspTrans->astPointPair[i].u64VirAddr);
68 }
69
70 IVE_CLOSE_FILE(pstPerspTrans->pFpSrc);
71 IVE_CLOSE_FILE(pstPerspTrans->pFpDst);
72 }
73
SAMPLE_IVE_PerspTrans_Init(SAMPLE_IVE_PERSP_TRANS_S * pstPerspTrans,HI_U32 u32SrcWidth,HI_U32 u32SrcHeight,HI_U32 u32DstWidth,HI_U32 u32DstHeight,IVE_RECT_U32_S astRoi[],HI_U16 u16RoiNum,HI_U16 u16MaxPointPairNum,HI_CHAR * pchSrcFileName,HI_CHAR * pchDstFileName)74 static HI_S32 SAMPLE_IVE_PerspTrans_Init(SAMPLE_IVE_PERSP_TRANS_S *pstPerspTrans, HI_U32 u32SrcWidth,
75 HI_U32 u32SrcHeight, HI_U32 u32DstWidth, HI_U32 u32DstHeight, IVE_RECT_U32_S astRoi[], HI_U16 u16RoiNum,
76 HI_U16 u16MaxPointPairNum, HI_CHAR *pchSrcFileName, HI_CHAR *pchDstFileName)
77 {
78 HI_S32 s32Ret = HI_SUCCESS;
79 HI_U32 u32Size;
80 HI_U16 i, j;
81 HI_U16 au16LandMark[] = {107, 109, 30, 52,
82 149, 117, 66, 52,
83 123, 135, 48, 72,
84 99, 157, 34, 92,
85 144, 157, 63, 92
86 };
87 IVE_PERSP_TRANS_POINT_PAIR_S *pstTmp = NULL;
88
89 s32Ret =
90 memcpy_s(pstPerspTrans->astRoi, sizeof(IVE_RECT_U32_S) * u16RoiNum, astRoi, sizeof(IVE_RECT_U32_S) * u16RoiNum);
91 SAMPLE_CHECK_EXPR_RET(s32Ret != EOK, HI_ERR_IVE_ILLEGAL_PARAM, "memcpy_s failed!\n");
92
93 s32Ret = SAMPLE_COMM_IVE_CreateImage(&(pstPerspTrans->stSrc), IVE_IMAGE_TYPE_YUV420SP, u32SrcWidth, u32SrcHeight);
94 SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, PERSP_TRANS_INIT_FAIL, "Error(%#x),Create src image failed!\n",
95 s32Ret);
96
97 for (i = 0; i < u16RoiNum; i++) {
98 s32Ret = SAMPLE_COMM_IVE_CreateImage(&(pstPerspTrans->astDst[i]), IVE_IMAGE_TYPE_YUV420SP, u32DstWidth,
99 u32DstHeight);
100 SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, PERSP_TRANS_INIT_FAIL, "Error(%#x),Create src image failed!\n",
101 s32Ret);
102 }
103
104 u32Size = sizeof(IVE_PERSP_TRANS_POINT_PAIR_S) * u16MaxPointPairNum;
105 for (i = 0; i < u16RoiNum; i++) {
106 s32Ret = SAMPLE_COMM_IVE_CreateMemInfo(&(pstPerspTrans->astPointPair[i]), u32Size);
107 SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, PERSP_TRANS_INIT_FAIL, "Error(%#x),Create src image failed!\n",
108 s32Ret);
109 }
110
111 pstPerspTrans->stPerspTransCtrl.enAlgMode = IVE_PERSP_TRANS_ALG_MODE_AFFINE;
112 pstPerspTrans->stPerspTransCtrl.enCscMode = IVE_PERSP_TRANS_CSC_MODE_NONE;
113 pstPerspTrans->stPerspTransCtrl.u16RoiNum = u16RoiNum;
114 pstPerspTrans->stPerspTransCtrl.u16PointPairNum = SAMPLE_IVE_PSP_POINT_PAIR_NUM_5; /* point pair num: 5 */
115 pstPerspTrans->u16RoiNum = u16RoiNum;
116
117 for (i = 0; i < u16RoiNum; i++) {
118 pstTmp = (IVE_PERSP_TRANS_POINT_PAIR_S *)(HI_UINTPTR_T)pstPerspTrans->astPointPair[i].u64VirAddr;
119 for (j = 0; j < pstPerspTrans->stPerspTransCtrl.u16PointPairNum; j++) {
120 /* x: au16LandMark[j * 4] << 2 */
121 pstTmp->stSrcPoint.u14q2X = au16LandMark[j * SAMPLE_IVE_PSP_LAND_MASK_OFFSET] <<
122 SAMPLE_IVE_PSP_POINT_FIX_BIT;
123 /* y: au16LandMark[j * 4 + 1] << 2 */
124 pstTmp->stSrcPoint.u14q2Y = au16LandMark[j * SAMPLE_IVE_PSP_LAND_MASK_OFFSET + SAMPLE_IVE_PSP_IDX_1] <<
125 SAMPLE_IVE_PSP_POINT_FIX_BIT;
126 /* x: au16LandMark[j * 4 + 2] << 2 */
127 pstTmp->stDstPoint.u14q2X = au16LandMark[j * SAMPLE_IVE_PSP_LAND_MASK_OFFSET + SAMPLE_IVE_PSP_IDX_2] <<
128 SAMPLE_IVE_PSP_POINT_FIX_BIT;
129 /* y: au16LandMark[j * 4 + 3] << 2 */
130 pstTmp->stDstPoint.u14q2Y = au16LandMark[j * SAMPLE_IVE_PSP_LAND_MASK_OFFSET + SAMPLE_IVE_PSP_IDX_3] <<
131 SAMPLE_IVE_PSP_POINT_FIX_BIT;
132
133 pstTmp++;
134 }
135 }
136
137 s32Ret = HI_FAILURE;
138 pstPerspTrans->pFpSrc = fopen(pchSrcFileName, "rb");
139 SAMPLE_CHECK_EXPR_GOTO(pstPerspTrans->pFpSrc == NULL, PERSP_TRANS_INIT_FAIL, "Error,Open file %s failed!\n",
140 pchSrcFileName);
141
142 pstPerspTrans->pFpDst = fopen(pchDstFileName, "wb");
143 SAMPLE_CHECK_EXPR_GOTO(pstPerspTrans->pFpDst == NULL, PERSP_TRANS_INIT_FAIL, "Error,Open file %s failed!\n",
144 pchDstFileName);
145 s32Ret = HI_SUCCESS;
146
147 return s32Ret;
148
149 PERSP_TRANS_INIT_FAIL:
150 SAMPLE_IVE_PerspTrans_Uninit(pstPerspTrans);
151
152 return s32Ret;
153 }
154
SAMPLE_IVE_PerspTransProc(SAMPLE_IVE_PERSP_TRANS_S * pstPerspTrans)155 static HI_S32 SAMPLE_IVE_PerspTransProc(SAMPLE_IVE_PERSP_TRANS_S *pstPerspTrans)
156 {
157 HI_S32 s32Ret = HI_FAILURE;
158 IVE_HANDLE IveHandle;
159 HI_BOOL bFinish = HI_FALSE;
160 HI_BOOL bBlock = HI_TRUE;
161 HI_BOOL bInstant = HI_TRUE;
162
163 s32Ret = SAMPLE_COMM_IVE_ReadFile(&(pstPerspTrans->stSrc), pstPerspTrans->pFpSrc);
164 SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),Read src file failed!\n", s32Ret);
165
166 s32Ret = HI_MPI_IVE_PerspTrans(&IveHandle, &pstPerspTrans->stSrc, pstPerspTrans->astRoi,
167 pstPerspTrans->astPointPair, pstPerspTrans->astDst, &pstPerspTrans->stPerspTransCtrl, bInstant);
168 SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),HI_MPI_IVE_PerspTrans failed!\n", s32Ret);
169
170 s32Ret = HI_MPI_IVE_Query(IveHandle, &bFinish, bBlock);
171 while (s32Ret == HI_ERR_IVE_QUERY_TIMEOUT) {
172 usleep(IVE_QUERY_SLEEP_TIME);
173 s32Ret = HI_MPI_IVE_Query(IveHandle, &bFinish, bBlock);
174 }
175 SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),HI_MPI_IVE_Query failed!\n", s32Ret);
176
177 s32Ret = SAMPLE_COMM_IVE_WriteFile(&pstPerspTrans->astDst[0], pstPerspTrans->pFpDst);
178 SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Error(%#x),Read src file failed!\n", s32Ret);
179
180 return s32Ret;
181 }
182
SAMPLE_IVE_PerspTransStop(HI_VOID)183 static HI_VOID SAMPLE_IVE_PerspTransStop(HI_VOID)
184 {
185 SAMPLE_IVE_PerspTrans_Uninit(&s_stPerspTrans);
186 (HI_VOID)memset_s(&s_stPerspTrans, sizeof(s_stPerspTrans), 0, sizeof(s_stPerspTrans));
187 SAMPLE_COMM_IVE_IveMpiExit();
188 printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
189 }
SAMPLE_IVE_PerspTrans(HI_VOID)190 HI_VOID SAMPLE_IVE_PerspTrans(HI_VOID)
191 {
192 HI_S32 s32Ret;
193 HI_U32 u32SrcWidth = SAMPLE_IVE_PSP_WIDTH_250;
194 HI_U32 u32SrcHeight = SAMPLE_IVE_PSP_HEIGHT_250;
195 HI_U32 u32DstWidth = SAMPLE_IVE_PSP_WIDTH_96;
196 HI_U32 u32DstHeight = SAMPLE_IVE_PSP_HEIGHT_112;
197 HI_CHAR *pchSrcFileName = "./data/input/psp/src/Amelia_Vega_250x250_420sp.yuv";
198 HI_CHAR achDstFileName[PATH_MAX] = {0};
199 HI_CHAR achSrcFileName[PATH_MAX] = {0};
200 IVE_RECT_U32_S astRoi[2] = {0};
201 HI_U16 u16RoiNum = 1;
202 HI_U16 u16MaxPointPairNum = SAMPLE_IVE_PSP_POINT_PAIR_NUM_68;
203 s_bStopSignal = HI_FALSE;
204
205 (HI_VOID)memset_s(&s_stPerspTrans, sizeof(s_stPerspTrans), 0, sizeof(s_stPerspTrans));
206 SAMPLE_COMM_IVE_CheckIveMpiInit();
207
208 SAMPLE_CHECK_EXPR_RET_VOID(realpath(pchSrcFileName, achSrcFileName) == NULL, "invalid path");
209 SAMPLE_CHECK_EXPR_RET_VOID(strlen(achSrcFileName) > PATH_MAX, "psp src file path is invalid!\n");
210
211 SAMPLE_CHECK_EXPR_RET_VOID(realpath("./data/output/psp", achDstFileName) == NULL, "invalid path");
212 s32Ret = strcat_s(achDstFileName, PATH_MAX, "/Amelia_Vega_Affine_96x112_420sp.yuv");
213 SAMPLE_CHECK_EXPR_RET_VOID(s32Ret < 0, "invali param");
214 SAMPLE_CHECK_EXPR_RET_VOID(strlen(achDstFileName) > PATH_MAX, "psp dst file path is invalid!\n");
215
216 astRoi[0].u32X = 0;
217 astRoi[0].u32Y = 0;
218 astRoi[0].u32Width = SAMPLE_IVE_PSP_WIDTH_250;
219 astRoi[0].u32Height = SAMPLE_IVE_PSP_HEIGHT_250;
220 s32Ret = SAMPLE_IVE_PerspTrans_Init(&s_stPerspTrans, u32SrcWidth, u32SrcHeight, u32DstWidth, u32DstHeight, astRoi,
221 u16RoiNum, u16MaxPointPairNum, achSrcFileName, achDstFileName);
222 SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, PERSP_TRANS_FAIL, "Error(%#x),SAMPLE_IVE_PerspTrans_Init failed!\n",
223 s32Ret);
224
225 if (s_bStopSignal == HI_TRUE) {
226 SAMPLE_IVE_PerspTransStop();
227 return;
228 }
229
230 s32Ret = SAMPLE_IVE_PerspTransProc(&s_stPerspTrans);
231 if (s32Ret == HI_SUCCESS) {
232 SAMPLE_PRT("Process success!\n");
233 }
234 if (s_bStopSignal == HI_TRUE) {
235 SAMPLE_IVE_PerspTransStop();
236 return;
237 }
238 SAMPLE_IVE_PerspTrans_Uninit(&s_stPerspTrans);
239 (HI_VOID)memset_s(&s_stPerspTrans, sizeof(s_stPerspTrans), 0, sizeof(s_stPerspTrans));
240
241 PERSP_TRANS_FAIL:
242 SAMPLE_COMM_IVE_IveMpiExit();
243 }
244
245 /* function : PerspTrans sample signal handle */
SAMPLE_IVE_PerspTrans_HandleSig(HI_VOID)246 HI_VOID SAMPLE_IVE_PerspTrans_HandleSig(HI_VOID)
247 {
248 s_bStopSignal = HI_TRUE;
249 }
250