• 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 
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