• 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 <sys/prctl.h>
28 
29 #include "sample_comm_ive.h"
30 #include "ivs_md.h"
31 
32 #define SAMPLE_IVE_MD_IMAGE_NUM              2
33 #define SAMPLE_IVE_MD_X_WEIGHT               32768
34 #define SAMPLE_IVE_MD_Y_WEIGHT               32768
35 #define SAMPLE_IVE_MD_SAD_THR                (100 * (1 << 1))
36 #define SAMPLE_IVE_MD_CAL_WIN_SIZE(mod)      (1 << (2 + (mod)))
37 #define SAMPLE_IVE_MD_AREA_THR_STEP           8
38 #define SAMPLE_IVE_MD_COLOR                   0x0000FF00
39 
40 typedef struct hiSAMPLE_IVE_MD_S {
41     IVE_SRC_IMAGE_S astImg[SAMPLE_IVE_MD_IMAGE_NUM];
42     IVE_DST_MEM_INFO_S stBlob;
43     MD_ATTR_S stMdAttr;
44     SAMPLE_RECT_ARRAY_S stRegion;
45 } SAMPLE_IVE_MD_S;
46 
47 static HI_BOOL s_bStopSignal = HI_FALSE;
48 static pthread_t s_hMdThread = 0;
49 static SAMPLE_IVE_MD_S s_stMd;
50 static SAMPLE_IVE_SWITCH_S s_stMdSwitch = { HI_FALSE, HI_TRUE };
51 static SAMPLE_VI_CONFIG_S s_stViConfig = { 0 };
52 
SAMPLE_IVE_Md_Uninit(SAMPLE_IVE_MD_S * pstMd)53 static HI_VOID SAMPLE_IVE_Md_Uninit(SAMPLE_IVE_MD_S *pstMd)
54 {
55     HI_S32 i;
56     HI_S32 s32Ret = HI_SUCCESS;
57 
58     for (i = 0; i < SAMPLE_IVE_MD_IMAGE_NUM; i++) {
59         IVE_MMZ_FREE(pstMd->astImg[i].au64PhyAddr[0], pstMd->astImg[i].au64VirAddr[0]);
60     }
61 
62     IVE_MMZ_FREE(pstMd->stBlob.u64PhyAddr, pstMd->stBlob.u64VirAddr);
63 
64     s32Ret = HI_IVS_MD_Exit();
65     if (s32Ret != HI_SUCCESS) {
66         SAMPLE_PRT("HI_IVS_MD_Exit fail,Error(%#x)\n", s32Ret);
67         return;
68     }
69 }
70 
SAMPLE_IVE_Md_Init(SAMPLE_IVE_MD_S * pstMd,HI_U32 u32Width,HI_U32 u32Height)71 static HI_S32 SAMPLE_IVE_Md_Init(SAMPLE_IVE_MD_S *pstMd, HI_U32 u32Width, HI_U32 u32Height)
72 {
73     HI_S32 s32Ret = HI_SUCCESS;
74     HI_S32 i;
75     HI_U32 u32Size;
76     HI_U8 u8WndSz;
77     HI_U8 u8SadMode = pstMd->stMdAttr.enSadMode;
78 
79     for (i = 0; i < SAMPLE_IVE_MD_IMAGE_NUM; i++) {
80         s32Ret = SAMPLE_COMM_IVE_CreateImage(&pstMd->astImg[i], IVE_IMAGE_TYPE_U8C1, u32Width, u32Height);
81         SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, MD_INIT_FAIL, "Error(%#x),Create img[%d] image failed!\n", s32Ret,
82             i);
83     }
84     u32Size = sizeof(IVE_CCBLOB_S);
85     s32Ret = SAMPLE_COMM_IVE_CreateMemInfo(&pstMd->stBlob, u32Size);
86     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, MD_INIT_FAIL, "Error(%#x),Create blob mem info failed!\n", s32Ret);
87 
88     // Set attr info
89     pstMd->stMdAttr.enAlgMode = MD_ALG_MODE_BG;
90     pstMd->stMdAttr.enSadMode = IVE_SAD_MODE_MB_4X4;
91     pstMd->stMdAttr.enSadOutCtrl = IVE_SAD_OUT_CTRL_THRESH;
92     pstMd->stMdAttr.u16SadThr = SAMPLE_IVE_MD_SAD_THR; // 100 * (1 << 2);
93     pstMd->stMdAttr.u32Width = u32Width;
94     pstMd->stMdAttr.u32Height = u32Height;
95     pstMd->stMdAttr.stAddCtrl.u0q16X = SAMPLE_IVE_MD_X_WEIGHT; // X: 32768
96     pstMd->stMdAttr.stAddCtrl.u0q16Y = SAMPLE_IVE_MD_Y_WEIGHT; // Y: 32768
97     pstMd->stMdAttr.stCclCtrl.enMode = IVE_CCL_MODE_4C;
98     u8WndSz = SAMPLE_IVE_MD_CAL_WIN_SIZE(u8SadMode);  // (2 + u8SadMode) bit
99     pstMd->stMdAttr.stCclCtrl.u16InitAreaThr = u8WndSz * u8WndSz;
100     pstMd->stMdAttr.stCclCtrl.u16Step = u8WndSz;
101 
102     s32Ret = HI_IVS_MD_Init();
103     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, MD_INIT_FAIL, "Error(%#x),HI_IVS_MD_Init failed!\n", s32Ret);
104 
105 MD_INIT_FAIL:
106 
107     if (s32Ret != HI_SUCCESS) {
108         SAMPLE_IVE_Md_Uninit(pstMd);
109     }
110     return s32Ret;
111 }
SAMPLE_IVE_MdProc(HI_VOID * pArgs)112 static HI_VOID *SAMPLE_IVE_MdProc(HI_VOID *pArgs)
113 {
114     HI_S32 s32Ret;
115     SAMPLE_IVE_MD_S *pstMd = NULL;
116     MD_ATTR_S *pstMdAttr = NULL;
117     VIDEO_FRAME_INFO_S stBaseFrmInfo;
118     VIDEO_FRAME_INFO_S stExtFrmInfo;
119     HI_S32 s32VpssGrp = 0;
120     HI_S32 as32VpssChn[] = {VPSS_CHN0, VPSS_CHN1};
121     HI_S32 s32MilliSec = SAMPLE_IVE_FRM_TIMEOUT;
122     MD_CHN MdChn = 0;
123     VO_LAYER voLayer = 0;
124     VO_CHN voChn = 0;
125     HI_BOOL bInstant = HI_TRUE;
126     HI_S32 s32CurIdx = 0;
127     HI_BOOL bFirstFrm = HI_TRUE;
128     pstMd = (SAMPLE_IVE_MD_S *)(pArgs);
129     pstMdAttr = &(pstMd->stMdAttr);
130     // Create chn
131     s32Ret = HI_IVS_MD_CreateChn(MdChn, &(pstMd->stMdAttr));
132     if (s32Ret != HI_SUCCESS) {
133         SAMPLE_PRT("HI_IVS_MD_CreateChn fail,Error(%#x)\n", s32Ret);
134         return NULL;
135     }
136 
137     while (HI_FALSE == s_bStopSignal) {
138         s32Ret = HI_MPI_VPSS_GetChnFrame(s32VpssGrp, as32VpssChn[1], &stExtFrmInfo, s32MilliSec);
139         if (s32Ret != HI_SUCCESS) {
140             SAMPLE_PRT("Error(%#x),HI_MPI_VPSS_GetChnFrame failed, VPSS_GRP(%d), VPSS_CHN(%d)!\n", s32Ret, s32VpssGrp,
141                 as32VpssChn[1]);
142             continue;
143         }
144 
145         s32Ret = HI_MPI_VPSS_GetChnFrame(s32VpssGrp, as32VpssChn[0], &stBaseFrmInfo, s32MilliSec);
146         SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, EXT_RELEASE,
147             "Error(%#x),HI_MPI_VPSS_GetChnFrame failed, VPSS_GRP(%d), VPSS_CHN(%d)!\n", s32Ret, s32VpssGrp,
148             as32VpssChn[0]);
149 
150         if (HI_TRUE != bFirstFrm) {
151             s32Ret = SAMPLE_COMM_IVE_DmaImage(&stExtFrmInfo, &pstMd->astImg[s32CurIdx], bInstant);
152             SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, BASE_RELEASE, "SAMPLE_COMM_IVE_DmaImage fail,Error(%#x)\n",
153                 s32Ret);
154         } else {
155             s32Ret = SAMPLE_COMM_IVE_DmaImage(&stExtFrmInfo, &pstMd->astImg[1 - s32CurIdx], bInstant);
156             SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, BASE_RELEASE, "SAMPLE_COMM_IVE_DmaImage fail,Error(%#x)\n",
157                 s32Ret);
158 
159             bFirstFrm = HI_FALSE;
160             goto CHANGE_IDX; // first frame just init reference frame
161         }
162 
163         s32Ret =
164             HI_IVS_MD_Process(MdChn, &pstMd->astImg[s32CurIdx], &pstMd->astImg[1 - s32CurIdx], NULL, &pstMd->stBlob);
165         SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, BASE_RELEASE, "HI_IVS_MD_Process fail,Error(%#x)\n", s32Ret);
166         SAMPLE_COMM_IVE_BlobToRect(SAMPLE_COMM_IVE_CONVERT_64BIT_ADDR(IVE_CCBLOB_S, pstMd->stBlob.u64VirAddr),
167             &(pstMd->stRegion), IVE_RECT_NUM, SAMPLE_IVE_MD_AREA_THR_STEP, pstMdAttr->u32Width, pstMdAttr->u32Height,
168             stBaseFrmInfo.stVFrame.u32Width, stBaseFrmInfo.stVFrame.u32Height);
169 
170         // Draw rect
171         s32Ret = SAMPLE_COMM_VGS_FillRect(&stBaseFrmInfo, &pstMd->stRegion, SAMPLE_IVE_MD_COLOR); // 0x0000FF00
172         SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, BASE_RELEASE, "SAMPLE_COMM_VGS_FillRect fail,Error(%#x)\n",
173             s32Ret);
174 
175         s32Ret = HI_MPI_VO_SendFrame(voLayer, voChn, &stBaseFrmInfo, s32MilliSec);
176         SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, BASE_RELEASE, "HI_MPI_VO_SendFrame fail,Error(%#x)\n", s32Ret);
177 
178     CHANGE_IDX:
179         // Change reference and current frame index
180         s32CurIdx = 1 - s32CurIdx;
181 
182     BASE_RELEASE:
183         s32Ret = HI_MPI_VPSS_ReleaseChnFrame(s32VpssGrp, as32VpssChn[0], &stBaseFrmInfo);
184         if (s32Ret != HI_SUCCESS) {
185             SAMPLE_PRT("Error(%#x),HI_MPI_VPSS_ReleaseChnFrame failed,Grp(%d) chn(%d)!\n", s32Ret, s32VpssGrp,
186                 as32VpssChn[0]);
187         }
188 
189     EXT_RELEASE:
190         s32Ret = HI_MPI_VPSS_ReleaseChnFrame(s32VpssGrp, as32VpssChn[1], &stExtFrmInfo);
191         if (s32Ret != HI_SUCCESS) {
192             SAMPLE_PRT("Error(%#x),HI_MPI_VPSS_ReleaseChnFrame failed,Grp(%d) chn(%d)!\n", s32Ret, s32VpssGrp,
193                 as32VpssChn[1]);
194         }
195     }
196 
197     // destroy
198     s32Ret = HI_IVS_MD_DestroyChn(MdChn);
199     if (s32Ret != HI_SUCCESS) {
200         SAMPLE_PRT("HI_IVS_MD_DestroyChn fail,Error(%#x)\n", s32Ret);
201     }
202 
203     return HI_NULL;
204 }
205 
SAMPLE_IVE_MdPause(HI_VOID)206 static HI_S32 SAMPLE_IVE_MdPause(HI_VOID)
207 {
208     printf("---------------press Enter key to exit!---------------\n");
209     if (s_bStopSignal == HI_TRUE) {
210         if (s_hMdThread != 0) {
211             pthread_join(s_hMdThread, HI_NULL);
212             s_hMdThread = 0;
213         }
214         SAMPLE_IVE_Md_Uninit(&(s_stMd));
215         (HI_VOID)memset_s(&s_stMd, sizeof(s_stMd), 0, sizeof(s_stMd));
216 
217         SAMPLE_COMM_IVE_StopViVpssVencVo(&s_stViConfig, &s_stMdSwitch);
218         printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
219         return HI_FAILURE;
220     }
221     (HI_VOID)getchar();
222     if (s_bStopSignal == HI_TRUE) {
223         if (s_hMdThread != 0) {
224             pthread_join(s_hMdThread, HI_NULL);
225             s_hMdThread = 0;
226         }
227         SAMPLE_IVE_Md_Uninit(&(s_stMd));
228         (HI_VOID)memset_s(&s_stMd, sizeof(s_stMd), 0, sizeof(s_stMd));
229 
230         SAMPLE_COMM_IVE_StopViVpssVencVo(&s_stViConfig, &s_stMdSwitch);
231         printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
232         return HI_FAILURE;
233     }
234     return HI_SUCCESS;
235 }
236 
SAMPLE_IVE_Md(HI_VOID)237 HI_VOID SAMPLE_IVE_Md(HI_VOID)
238 {
239     SIZE_S stSize;
240     PIC_SIZE_E enSize = PIC_D1_PAL;
241     HI_S32 s32Ret = HI_SUCCESS;
242 
243     (HI_VOID)memset_s(&s_stMd, sizeof(s_stMd), 0, sizeof(s_stMd));
244     /* step 1: start vi vpss venc vo */
245     s32Ret = SAMPLE_COMM_IVE_StartViVpssVencVo(&s_stViConfig, &s_stMdSwitch, &enSize);
246     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, END_MD_0, "Error(%#x),SAMPLE_COMM_IVE_StartViVpssVencVo failed!\n",
247         s32Ret);
248 
249     enSize = PIC_D1_PAL;
250     s32Ret = SAMPLE_COMM_SYS_GetPicSize(enSize, &stSize);
251     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, END_MD_0, "Error(%#x),SAMPLE_COMM_SYS_GetPicSize failed!\n", s32Ret);
252     /* step 2: Init Md */
253     s32Ret = SAMPLE_IVE_Md_Init(&s_stMd, stSize.u32Width, stSize.u32Height);
254     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, END_MD_0, " Error(%#x),SAMPLE_IVE_Md_Init failed!\n", s32Ret);
255     s_bStopSignal = HI_FALSE;
256     /* step 3: Create work thread */
257     s32Ret = prctl(PR_SET_NAME, "IVE_MdProc", 0, 0, 0);
258     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, END_MD_0, "thread set name failed!\n");
259     s32Ret = pthread_create(&s_hMdThread, 0, SAMPLE_IVE_MdProc, (HI_VOID *)&s_stMd);
260     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, END_MD_0, "thread create failed!\n");
261 
262     s32Ret = SAMPLE_IVE_MdPause();
263     SAMPLE_CHECK_EXPR_RET_VOID(s32Ret != HI_SUCCESS, "pause failed!\n");
264 
265     s_bStopSignal = HI_TRUE;
266     pthread_join(s_hMdThread, HI_NULL);
267     s_hMdThread = 0;
268 
269     SAMPLE_IVE_Md_Uninit(&(s_stMd));
270     (HI_VOID)memset_s(&s_stMd, sizeof(s_stMd), 0, sizeof(s_stMd));
271 
272 END_MD_0:
273     s_bStopSignal = HI_TRUE;
274     s_hMdThread = 0;
275     SAMPLE_COMM_IVE_StopViVpssVencVo(&s_stViConfig, &s_stMdSwitch);
276     return;
277 }
278 
279 /* function : Md sample signal handle */
SAMPLE_IVE_Md_HandleSig(HI_VOID)280 HI_VOID SAMPLE_IVE_Md_HandleSig(HI_VOID)
281 {
282     s_bStopSignal = HI_TRUE;
283 }
284