• 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 
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <unistd.h>
20 #include <pthread.h>
21 #include <signal.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25 #include <sys/ioctl.h>
26 #include <sys/prctl.h>
27 
28 #include "hi_mipi_tx.h"
29 #include "sdk.h"
30 #include "sample_comm.h"
31 #include "ai_infer_process.h"
32 #include "cnn_trash_classify.h"
33 #include "hand_classify.h"
34 #include "vgs_img.h"
35 #include "osd_img.h"
36 #include "posix_help.h"
37 #include "sample_media_ai.h"
38 
39 #ifdef __cplusplus
40 #if __cplusplus
41 extern "C" {
42 #endif
43 #endif /* End of #ifdef __cplusplus */
44 
45 static HI_BOOL g_bAiProcessStopSignal = HI_FALSE;
46 static HI_U32 g_num = 0;
47 AicMediaInfo g_aicMediaInfo = { 0 };
48 static pthread_t g_aiProcessThread = 0;
49 AiPlugLib g_workPlug = {0};
50 
51 #define HAND_FRM_WIDTH    640
52 #define HAND_FRM_HEIGHT   384
53 #define AI_SAMPLE_CFG_FILE      "./sample_ai.conf"
54 #define BUFFER_SIZE           16    // buffer size
55 
56 #define USLEEP_TIME   1000 // 1000: usleep time, in microseconds
57 #define G_MBUF_LENGTH 50 // 50: length of g_mbuf
58 #define ALIGN_DOWN_SIZE 2
59 
60 #define G_MBUF_ARRAY_SUBSCRIPT_0     0
61 #define G_MBUF_ARRAY_SUBSCRIPT_1     1
62 #define G_MBUF_ARRAY_SUBSCRIPT_2     2
63 #define G_MBUF_ARRAY_SUBSCRIPT_3     3
64 #define G_MBUF_ARRAY_SUBSCRIPT_4     4
65 #define G_MBUF_ARRAY_SUBSCRIPT_5     5
66 #define G_MBUF_ARRAY_SUBSCRIPT_6     6
67 #define G_MBUF_ARRAY_SUBSCRIPT_7     7
68 #define G_MBUF_ARRAY_SUBSCRIPT_8     8
69 #define G_MBUF_ARRAY_SUBSCRIPT_9     9
70 #define G_MBUF_ARRAY_SUBSCRIPT_10    10
71 #define G_MBUF_ARRAY_SUBSCRIPT_11    11
72 #define G_MBUF_ARRAY_SUBSCRIPT_12    12
73 #define G_MBUF_ARRAY_SUBSCRIPT_13    13
74 #define G_MBUF_ARRAY_SUBSCRIPT_14    14
75 #define G_MBUF_ARRAY_SUBSCRIPT_15    15
76 #define G_MBUF_ARRAY_SUBSCRIPT_16    16
77 
78 #define LANE_ID_SUBSCRIPT_0    0
79 #define LANE_ID_SUBSCRIPT_1    1
80 #define LANE_ID_SUBSCRIPT_2    2
81 #define LANE_ID_SUBSCRIPT_3    3
82 
83 static unsigned char g_mBuf[G_MBUF_LENGTH];
84 static SampleVoModeMux g_sampleVoModeMux = {0};
85 static VO_PUB_ATTR_S stVoPubAttr = {0};
86 static VO_VIDEO_LAYER_ATTR_S  stLayerAttr    = {0};
87 static VO_CSC_S               stVideoCSC     = {0};
88 static RECT_S stDefDispRect  = {0, 0, 800, 480};
89 static SIZE_S stDefImageSize = {800, 480};
90 
91 HI_CHAR acThreadName[16] = {0};
92 
93 typedef struct StSampleUserVoConfigs {
94     VO_SYNC_INFO_S stSyncInfo;
95     VO_USER_INTFSYNC_ATTR_S stUserIntfSyncAttr;
96     HI_U32 u32PreDiv;
97     HI_U32 u32DevDiv;
98     HI_U32 u32Framerate;
99     combo_dev_cfg_t stcombo_dev_cfgl;
100 } SAMPLE_USER_VO_CONFIG_S;
101 
SAMPLE_VOU_SYS_Exit(void)102 HI_VOID SAMPLE_VOU_SYS_Exit(void)
103 {
104     HI_MPI_SYS_Exit();
105     HI_MPI_VB_Exit();
106 }
107 
SAMPLE_VO_GetUserLayerAttr(VO_VIDEO_LAYER_ATTR_S * pstLayerAttr,SIZE_S * pstDevSize)108 HI_VOID SAMPLE_VO_GetUserLayerAttr(VO_VIDEO_LAYER_ATTR_S *pstLayerAttr, SIZE_S *pstDevSize)
109 {
110     pstLayerAttr->bClusterMode = HI_FALSE;
111     pstLayerAttr->bDoubleFrame = HI_FALSE;
112     pstLayerAttr->enDstDynamicRange = DYNAMIC_RANGE_SDR8;
113     pstLayerAttr->enPixFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420;
114 
115     pstLayerAttr->stDispRect.s32X = 0;
116     pstLayerAttr->stDispRect.s32Y = 0;
117     pstLayerAttr->stDispRect.u32Height = pstDevSize->u32Height;
118     pstLayerAttr->stDispRect.u32Width  = pstDevSize->u32Width;
119 
120     pstLayerAttr->stImageSize.u32Height = pstDevSize->u32Height;
121     pstLayerAttr->stImageSize.u32Width = pstDevSize->u32Width;
122 
123     return;
124 }
125 
SAMPLE_VO_GetUserChnAttr(VO_CHN_ATTR_S * pstChnAttr,SIZE_S * pstDevSize,HI_S32 VoChnNum)126 HI_VOID SAMPLE_VO_GetUserChnAttr(VO_CHN_ATTR_S *pstChnAttr, SIZE_S *pstDevSize, HI_S32 VoChnNum)
127 {
128     HI_S32 i;
129     for (i = 0; i < VoChnNum; i++) {
130         pstChnAttr[i].bDeflicker = HI_FALSE;
131         pstChnAttr[i].u32Priority = 0;
132         pstChnAttr[i].stRect.s32X = 0;
133         pstChnAttr[i].stRect.s32Y = 0;
134         pstChnAttr[i].stRect.u32Height = pstDevSize->u32Height;
135         pstChnAttr[i].stRect.u32Width = pstDevSize->u32Width;
136         }
137 
138     return;
139 }
140 
141 /*
142  * 打开MIPI Tx设备
143  * Open MIPI Tx device
144  */
SampleOpenMipiTxFd(HI_VOID)145 HI_S32 SampleOpenMipiTxFd(HI_VOID)
146 {
147     HI_S32 fd;
148 
149     fd = open("/dev/hi_mipi_tx", O_RDWR);
150     if (fd < 0) {
151         printf("open hi_mipi_tx dev failed\n");
152     }
153     return fd;
154 }
155 
156 /*
157  * 关闭MIPI Tx设备
158  * Close MIPI Tx device
159  */
SampleCloseMipiTxFd(HI_S32 fd)160 HI_VOID SampleCloseMipiTxFd(HI_S32 fd)
161 {
162     close(fd);
163     return;
164 }
165 
166 /*
167  * 获取MIPI Tx配置信息
168  * Get MIPI Tx config information
169  */
SAMPLE_GetMipiTxConfig(combo_dev_cfg_t * pstMipiTxConfig)170 HI_VOID SAMPLE_GetMipiTxConfig(combo_dev_cfg_t *pstMipiTxConfig)
171 {
172     /*
173      * 用户需要设置MIPI设备配置
174      * User need set MIPI device config
175      */
176     pstMipiTxConfig->devno = 0;
177     pstMipiTxConfig->lane_id[LANE_ID_SUBSCRIPT_0] = 0;
178     pstMipiTxConfig->lane_id[LANE_ID_SUBSCRIPT_1] = 1;
179     // -1: 2 lane mode configuration,lane_id[4] = {0, 1, -1, -1}
180     pstMipiTxConfig->lane_id[LANE_ID_SUBSCRIPT_2] = -1;
181     // -1: 2 lane mode configuration,lane_id[4] = {0, 1, -1, -1}
182     pstMipiTxConfig->lane_id[LANE_ID_SUBSCRIPT_3] = -1;
183     pstMipiTxConfig->output_mode = OUTPUT_MODE_DSI_VIDEO;
184     pstMipiTxConfig->output_format = OUT_FORMAT_RGB_24_BIT;
185     pstMipiTxConfig->video_mode = BURST_MODE;
186     pstMipiTxConfig->sync_info.vid_pkt_size = 480; // 480: received packet size
187     pstMipiTxConfig->sync_info.vid_hsa_pixels = 10; // 10: The number of pixels in the input line sync pulse area
188     pstMipiTxConfig->sync_info.vid_hbp_pixels = 50; // 50: Number of pixels in blanking area after input
189     pstMipiTxConfig->sync_info.vid_hline_pixels = 590; // 590: The total number of pixels detected per line
190     pstMipiTxConfig->sync_info.vid_vsa_lines = 4; // 4: Number of frame sync pulse lines detected
191     pstMipiTxConfig->sync_info.vid_vbp_lines = 20; // 20: Number of blanking area lines after frame sync pulse
192     pstMipiTxConfig->sync_info.vid_vfp_lines = 20; // 20: Number of blanking area lines before frame sync pulse
193     pstMipiTxConfig->sync_info.vid_active_lines = 800; // 800: VACTIVE rows
194     pstMipiTxConfig->sync_info.edpi_cmd_size = 0; // 0: Write memory command bytes
195     pstMipiTxConfig->phy_data_rate = 359; // 359: MIPI Tx output rate
196     pstMipiTxConfig->pixel_clk = 29878; // 29878: pixel clock. The unit is KHz
197 
198     return;
199 }
200 
201 /*
202  * 设置MIPI Tx配置信息
203  * Set MIPI Tx config information
204  */
SAMPLE_SetMipiTxConfig(HI_S32 fd,combo_dev_cfg_t * pstMipiTxConfig)205 HI_S32 SAMPLE_SetMipiTxConfig(HI_S32 fd, combo_dev_cfg_t *pstMipiTxConfig)
206 {
207     HI_S32 s32Ret = ioctl(fd, HI_MIPI_TX_SET_DEV_CFG, pstMipiTxConfig);
208     if (s32Ret != HI_SUCCESS) {
209         printf("MIPI_TX SET_DEV_CONFIG failed\n");
210         SampleCloseMipiTxFd(fd);
211         return s32Ret;
212     }
213     return s32Ret;
214 }
215 
216 /*
217  * 设置MIPI Tx设备属性
218  * Set MIPI Tx device attr
219  */
SampleSetMipiTxDevAttr(HI_S32 fd)220 HI_S32 SampleSetMipiTxDevAttr(HI_S32 fd)
221 {
222     HI_S32 s32Ret;
223     combo_dev_cfg_t stMipiTxConfig;
224 
225     SAMPLE_GetMipiTxConfig(&stMipiTxConfig);
226     s32Ret = SAMPLE_SetMipiTxConfig(fd, &stMipiTxConfig);
227 
228     return s32Ret;
229 }
230 
231 /*
232  * 初始化MIPI Tx设备
233  * Init MIPI Tx device
234  */
SAMPLE_USER_INIT_MIPITx(HI_S32 fd,cmd_info_t * pcmd_info)235 HI_S32 SAMPLE_USER_INIT_MIPITx(HI_S32 fd, cmd_info_t *pcmd_info)
236 {
237     HI_S32 s32Ret = ioctl(fd, HI_MIPI_TX_SET_CMD, pcmd_info);
238     if (s32Ret !=  HI_SUCCESS) {
239         printf("MIPI_TX SET CMD failed\n");
240         SampleCloseMipiTxFd(fd);
241         return s32Ret;
242     }
243 
244     return HI_SUCCESS;
245 }
246 
247 /*
248  * 配置MIPI Tx初始化序列
249  * Config MIPI Tx initialization sequence
250  */
SampleVoInitMipiTxScreen(HI_S32 fd)251 HI_S32 SampleVoInitMipiTxScreen(HI_S32 fd)
252 {
253     HI_S32 s32Ret;
254     cmd_info_t cmd_info;
255     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
256     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xFF;
257     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x77;
258     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0x01;
259     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_3] = 0x00;
260     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_4] = 0x00;
261     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_5] = 0x13;
262     cmd_info.devno = 0;
263     cmd_info.cmd_size = 6; // 6: command data size
264     cmd_info.data_type = 0x29;
265     cmd_info.cmd = g_mBuf;
266     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
267     if (s32Ret != HI_SUCCESS) {
268         return s32Ret;
269     }
270     usleep(USLEEP_TIME);
271 
272     cmd_info.devno = 0;
273     cmd_info.cmd_size = 0x08ef;
274     cmd_info.data_type = 0x23;
275     cmd_info.cmd = NULL;
276     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
277     if (s32Ret != HI_SUCCESS) {
278         return s32Ret;
279     }
280     usleep(USLEEP_TIME);
281 
282     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
283     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xFF;
284     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x77;
285     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0x01;
286     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_3] = 0x00;
287     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_4] = 0x00;
288     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_5] = 0x10;
289     cmd_info.devno = 0;
290     cmd_info.cmd_size = 6; // 6: command data size
291     cmd_info.data_type = 0x29;
292     cmd_info.cmd = g_mBuf;
293     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
294     if (s32Ret != HI_SUCCESS) {
295         return s32Ret;
296     }
297     usleep(USLEEP_TIME);
298 
299     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
300     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xC0;
301     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x63;
302     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0x00;
303     cmd_info.devno = 0;
304     cmd_info.cmd_size = 3; // 3: command data size
305     cmd_info.data_type = 0x29;
306     cmd_info.cmd = g_mBuf;
307     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
308     if (s32Ret != HI_SUCCESS) {
309         return s32Ret;
310     }
311     usleep(USLEEP_TIME);
312 
313     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
314     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xC1;
315     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x10;
316     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0x02;
317     cmd_info.devno = 0;
318     cmd_info.cmd_size = 3; // 3: command data size
319     cmd_info.data_type = 0x29;
320     cmd_info.cmd = g_mBuf;
321     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
322     if (s32Ret != HI_SUCCESS) {
323         return s32Ret;
324     }
325     usleep(USLEEP_TIME);
326 
327     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
328     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xC2;
329     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x01;
330     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0x08;
331     cmd_info.devno = 0;
332     cmd_info.cmd_size = 3; // 3: command data size
333     cmd_info.data_type = 0x29;
334     cmd_info.cmd = g_mBuf;
335     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
336     if (s32Ret != HI_SUCCESS) {
337         return s32Ret;
338     }
339     usleep(USLEEP_TIME);
340 
341     cmd_info.devno = 0;
342     cmd_info.cmd_size = 0x18CC;
343     cmd_info.data_type = 0x23;
344     cmd_info.cmd = NULL;
345     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
346     if (s32Ret != HI_SUCCESS) {
347         return s32Ret;
348     }
349     usleep(USLEEP_TIME);
350 
351     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
352     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xB0;
353     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x40;
354     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0xC9;
355     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_3] = 0x8F;
356     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_4] = 0x0D;
357     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_5] = 0x11;
358     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_6] = 0x07;
359     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_7] = 0x02;
360     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_8] = 0x09;
361     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_9] = 0x09;
362     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_10] = 0x1F;
363     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_11] = 0x04;
364     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_12] = 0x50;
365     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_13] = 0x0F;
366     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_14] = 0xE4;
367     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_15] = 0x29;
368     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_16] = 0xDF;
369     cmd_info.devno = 0;
370     cmd_info.cmd_size = 17; // 17: command data size
371     cmd_info.data_type = 0x29;
372     cmd_info.cmd = g_mBuf;
373     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
374     if (s32Ret != HI_SUCCESS) {
375         return s32Ret;
376     }
377     usleep(USLEEP_TIME);
378 
379     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
380     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xB1;
381     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x40;
382     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0xCB;
383     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_3] = 0xD3;
384     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_4] = 0x11;
385     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_5] = 0x8F;
386     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_6] = 0x04;
387     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_7] = 0x00;
388     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_8] = 0x08;
389     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_9] = 0x07;
390     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_10] = 0x1C;
391     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_11] = 0x06;
392     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_12] = 0x53;
393     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_13] = 0x12;
394     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_14] = 0x63;
395     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_15] = 0xEB;
396     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_16] = 0xDF;
397     cmd_info.devno = 0;
398     cmd_info.cmd_size = 17; // 17: command data size
399     cmd_info.data_type = 0x29;
400     cmd_info.cmd = g_mBuf;
401     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
402     if (s32Ret != HI_SUCCESS) {
403         return s32Ret;
404     }
405     usleep(USLEEP_TIME);
406 
407     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
408     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xFF;
409     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x77;
410     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0x01;
411     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_3] = 0x00;
412     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_4] = 0x00;
413     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_5] = 0x11;
414     cmd_info.devno = 0;
415     cmd_info.cmd_size = 6; // 6: command data size
416     cmd_info.data_type = 0x29;
417     cmd_info.cmd = g_mBuf;
418     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
419     if (s32Ret != HI_SUCCESS) {
420         return s32Ret;
421     }
422     usleep(USLEEP_TIME);
423 
424     cmd_info.devno = 0;
425     cmd_info.cmd_size = 0x65b0;
426     cmd_info.data_type = 0x23;
427     cmd_info.cmd = NULL;
428     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
429     if (s32Ret != HI_SUCCESS) {
430         return s32Ret;
431     }
432     usleep(USLEEP_TIME);
433 
434     cmd_info.devno = 0;
435     cmd_info.cmd_size = 0x34b1;
436     cmd_info.data_type = 0x23;
437     cmd_info.cmd = NULL;
438     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
439     if (s32Ret != HI_SUCCESS) {
440         return s32Ret;
441     }
442     usleep(USLEEP_TIME);
443 
444     cmd_info.devno = 0;
445     cmd_info.cmd_size = 0x87b2;
446     cmd_info.data_type = 0x23;
447     cmd_info.cmd = NULL;
448     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
449     if (s32Ret != HI_SUCCESS) {
450         return s32Ret;
451     }
452     usleep(USLEEP_TIME);
453 
454     cmd_info.devno = 0;
455     cmd_info.cmd_size = 0x80b3;
456     cmd_info.data_type = 0x23;
457     cmd_info.cmd = NULL;
458     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
459     if (s32Ret != HI_SUCCESS) {
460         return s32Ret;
461     }
462     usleep(USLEEP_TIME);
463 
464     cmd_info.devno = 0;
465     cmd_info.cmd_size = 0x49b5;
466     cmd_info.data_type = 0x23;
467     cmd_info.cmd = NULL;
468     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
469     if (s32Ret != HI_SUCCESS) {
470         return s32Ret;
471     }
472     usleep(USLEEP_TIME);
473 
474     cmd_info.devno = 0;
475     cmd_info.cmd_size = 0x85b7;
476     cmd_info.data_type = 0x23;
477     cmd_info.cmd = NULL;
478     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
479     if (s32Ret != HI_SUCCESS) {
480         return s32Ret;
481     }
482     usleep(USLEEP_TIME);
483 
484     cmd_info.devno = 0;
485     cmd_info.cmd_size = 0x20b8;
486     cmd_info.data_type = 0x23;
487     cmd_info.cmd = NULL;
488     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
489     if (s32Ret != HI_SUCCESS) {
490         return s32Ret;
491     }
492     usleep(USLEEP_TIME);
493 
494     cmd_info.devno = 0;
495     cmd_info.cmd_size = 0x10b9;
496     cmd_info.data_type = 0x23;
497     cmd_info.cmd = NULL;
498     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
499     if (s32Ret != HI_SUCCESS) {
500         return s32Ret;
501     }
502     usleep(USLEEP_TIME);
503 
504     cmd_info.devno = 0;
505     cmd_info.cmd_size = 0x78c1;
506     cmd_info.data_type = 0x23;
507     cmd_info.cmd = NULL;
508     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
509     if (s32Ret != HI_SUCCESS) {
510         return s32Ret;
511     }
512     usleep(USLEEP_TIME);
513 
514     cmd_info.devno = 0;
515     cmd_info.cmd_size = 0x78c2;
516     cmd_info.data_type = 0x23;
517     cmd_info.cmd = NULL;
518     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
519     if (s32Ret != HI_SUCCESS) {
520         return s32Ret;
521     }
522     usleep(USLEEP_TIME);
523 
524     cmd_info.devno = 0;
525     cmd_info.cmd_size = 0x88d0;
526     cmd_info.data_type = 0x23;
527     cmd_info.cmd = NULL;
528     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
529     if (s32Ret != HI_SUCCESS) {
530         return s32Ret;
531     }
532     usleep(USLEEP_TIME);
533     usleep(100000);  // 100000: The process hangs for a period of time, in microseconds
534 
535     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
536     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xE0;
537     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x00;
538     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0x19;
539     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_3] = 0x02;
540     cmd_info.devno = 0;
541     cmd_info.cmd_size = 4; // 4: command data size
542     cmd_info.data_type = 0x29;
543     cmd_info.cmd = g_mBuf;
544     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
545     if (s32Ret != HI_SUCCESS) {
546         return s32Ret;
547     }
548     usleep(USLEEP_TIME);
549     usleep(USLEEP_TIME);
550 
551     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
552     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xE1;
553     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x05;
554     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0xA0;
555     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_3] = 0x07;
556     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_4] = 0xA0;
557     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_5] = 0x04;
558     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_6] = 0xA0;
559     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_7] = 0x06;
560     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_8] = 0xA0;
561     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_9] = 0x00;
562     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_10] = 0x44;
563     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_11] = 0x44;
564     cmd_info.devno = 0;
565     cmd_info.cmd_size = 12; // 12: command data size
566     cmd_info.data_type = 0x29;
567     cmd_info.cmd = g_mBuf;
568     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
569     if (s32Ret != HI_SUCCESS) {
570         return s32Ret;
571     }
572     usleep(USLEEP_TIME);
573 
574     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
575     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xE2;
576     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x00;
577     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0x00;
578     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_3] = 0x00;
579     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_4] = 0x00;
580     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_5] = 0x00;
581     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_6] = 0x00;
582     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_7] = 0x00;
583     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_8] = 0x00;
584     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_9] = 0x00;
585     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_10] = 0x00;
586     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_11] = 0x00;
587     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_12] = 0x00;
588     cmd_info.devno = 0;
589     cmd_info.cmd_size = 13; // 13: command data size
590     cmd_info.data_type = 0x29;
591     cmd_info.cmd = g_mBuf;
592     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
593     if (s32Ret != HI_SUCCESS) {
594         return s32Ret;
595     }
596     usleep(USLEEP_TIME);
597 
598     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
599     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xE3;
600     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x00;
601     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0x00;
602     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_3] = 0x33;
603     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_4] = 0x33;
604     cmd_info.devno = 0;
605     cmd_info.cmd_size = 5; // 5: command data size
606     cmd_info.data_type = 0x29;
607     cmd_info.cmd = g_mBuf;
608     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
609     if (s32Ret != HI_SUCCESS) {
610         return s32Ret;
611     }
612     usleep(USLEEP_TIME);
613 
614     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
615     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xE4;
616     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x44;
617     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0x44;
618     cmd_info.devno = 0;
619     cmd_info.cmd_size = 3; // 3: command data size
620     cmd_info.data_type = 0x29;
621     cmd_info.cmd = g_mBuf;
622     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
623     if (s32Ret != HI_SUCCESS) {
624         return s32Ret;
625     }
626     usleep(USLEEP_TIME);
627 
628     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
629     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xE5;
630     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x0D;
631     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0x31;
632     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_3] = 0xC8;
633     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_4] = 0xAF;
634     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_5] = 0x0F;
635     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_6] = 0x33;
636     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_7] = 0xC8;
637     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_8] = 0xAF;
638     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_9] = 0x09;
639     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_10] = 0x2D;
640     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_11] = 0xC8;
641     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_12] = 0xAF;
642     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_13] = 0x0B;
643     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_14] = 0x2F;
644     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_15] = 0xC8;
645     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_16] = 0xAF;
646     cmd_info.devno = 0;
647     cmd_info.cmd_size = 17; // 17: command data size
648     cmd_info.data_type = 0x29;
649     cmd_info.cmd = g_mBuf;
650     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
651     if (s32Ret != HI_SUCCESS) {
652         return s32Ret;
653     }
654     usleep(USLEEP_TIME);
655 
656     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
657     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xE6;
658     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x00;
659     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0x00;
660     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_3] = 0x33;
661     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_4] = 0x33;
662     cmd_info.devno = 0;
663     cmd_info.cmd_size = 5; // 5: command data size
664     cmd_info.data_type = 0x29;
665     cmd_info.cmd = g_mBuf;
666     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
667     if (s32Ret != HI_SUCCESS) {
668         return s32Ret;
669     }
670     usleep(USLEEP_TIME);
671 
672     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
673     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xE7;
674     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x44;
675     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0x44;
676     cmd_info.devno = 0;
677     cmd_info.cmd_size = 3; // 3: command data size
678     cmd_info.data_type = 0x29;
679     cmd_info.cmd = g_mBuf;
680     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
681     if (s32Ret != HI_SUCCESS) {
682         return s32Ret;
683     }
684     usleep(USLEEP_TIME);
685 
686     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
687     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xE8;
688     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x0C;
689     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0x30;
690     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_3] = 0xC8;
691     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_4] = 0xAF;
692     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_5] = 0x0E;
693     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_6] = 0x32;
694     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_7] = 0xC8;
695     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_8] = 0xAF;
696     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_9] = 0x08;
697     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_10] = 0x2C;
698     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_11] = 0xC8;
699     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_12] = 0xAF;
700     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_13] = 0x0A;
701     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_14] = 0x2E;
702     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_15] = 0xC8;
703     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_16] = 0xAF;
704     cmd_info.devno = 0;
705     cmd_info.cmd_size = 17; // 17: command data size
706     cmd_info.data_type = 0x29;
707     cmd_info.cmd = g_mBuf;
708     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
709     if (s32Ret != HI_SUCCESS) {
710         return s32Ret;
711     }
712     usleep(USLEEP_TIME);
713 
714     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
715     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xEB;
716     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x02;
717     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0x00;
718     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_3] = 0xE4;
719     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_4] = 0xE4;
720     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_5] = 0x44;
721     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_6] = 0x00;
722     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_7] = 0x40;
723     cmd_info.devno = 0;
724     cmd_info.cmd_size = 8; // 8: command data size
725     cmd_info.data_type = 0x29;
726     cmd_info.cmd = g_mBuf;
727     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
728     if (s32Ret != HI_SUCCESS) {
729         return s32Ret;
730     }
731     usleep(USLEEP_TIME);
732 
733     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
734     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xEC;
735     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x3C;
736     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0x00;
737     cmd_info.devno = 0;
738     cmd_info.cmd_size = 3; // 3: command data size
739     cmd_info.data_type = 0x29;
740     cmd_info.cmd = g_mBuf;
741     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
742     if (s32Ret != HI_SUCCESS) {
743         return s32Ret;
744     }
745     usleep(USLEEP_TIME);
746 
747     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
748     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xED;
749     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0xAB;
750     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0x89;
751     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_3] = 0x76;
752     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_4] = 0x54;
753     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_5] = 0x01;
754     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_6] = 0xFF;
755     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_7] = 0xFF;
756     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_8] = 0xFF;
757     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_9] = 0xFF;
758     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_10] = 0xFF;
759     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_11] = 0xFF;
760     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_12] = 0x10;
761     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_13] = 0x45;
762     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_14] = 0x67;
763     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_15] = 0x98;
764     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_16] = 0xBA;
765     cmd_info.devno = 0;
766     cmd_info.cmd_size = 17; // 17: command data size
767     cmd_info.data_type = 0x29;
768     cmd_info.cmd = g_mBuf;
769     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
770     if (s32Ret != HI_SUCCESS) {
771         return s32Ret;
772     }
773     usleep(USLEEP_TIME);
774 
775     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
776     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xEF;
777     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x08;
778     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0x08;
779     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_3] = 0x08;
780     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_4] = 0x45;
781     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_5] = 0x3F;
782     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_6] = 0x54;
783     cmd_info.devno = 0;
784     cmd_info.cmd_size = 7; // 7: command data size
785     cmd_info.data_type = 0x29;
786     cmd_info.cmd = g_mBuf;
787     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
788     if (s32Ret != HI_SUCCESS) {
789         return s32Ret;
790     }
791     usleep(USLEEP_TIME);
792 
793     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
794     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xFF;
795     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x77;
796     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0x01;
797     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_3] = 0x00;
798     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_4] = 0x00;
799     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_5] = 0x00;
800     cmd_info.devno = 0;
801     cmd_info.cmd_size = 6; // 6: command data size
802     cmd_info.data_type = 0x29;
803     cmd_info.cmd = g_mBuf;
804     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
805     if (s32Ret != HI_SUCCESS) {
806         return s32Ret;
807     }
808     usleep(USLEEP_TIME);
809 
810     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
811     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xFF;
812     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x77;
813     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0x01;
814     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_3] = 0x00;
815     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_4] = 0x00;
816     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_5] = 0x13;
817     cmd_info.devno = 0;
818     cmd_info.cmd_size = 6; // 6: command data size
819     cmd_info.data_type = 0x29;
820     cmd_info.cmd = g_mBuf;
821     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
822     if (s32Ret != HI_SUCCESS) {
823         return s32Ret;
824     }
825     usleep(USLEEP_TIME);
826 
827     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
828     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xE8;
829     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x00;
830     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0x0E;
831     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_3] = 0x11;
832     cmd_info.devno = 0;
833     cmd_info.cmd_size = 4; // 4: command data size
834     cmd_info.data_type = 0x29;
835     cmd_info.cmd = g_mBuf;
836     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
837     if (s32Ret != HI_SUCCESS) {
838         return s32Ret;
839     }
840     usleep(USLEEP_TIME);
841     usleep(120000); // 120000: The process hangs for a period of time, in microseconds
842 
843     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
844     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xE8;
845     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x00;
846     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0x0C;
847     cmd_info.devno = 0;
848     cmd_info.cmd_size = 3; // 3: command data size
849     cmd_info.data_type = 0x29;
850     cmd_info.cmd = g_mBuf;
851     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
852     if (s32Ret != HI_SUCCESS) {
853         return s32Ret;
854     }
855     usleep(USLEEP_TIME);
856     usleep(10000); // 10000: The process hangs for a period of time, in microseconds
857 
858     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
859     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xE8;
860     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x00;
861     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0x00;
862     cmd_info.devno = 0;
863     cmd_info.cmd_size = 3; // 3: command data size
864     cmd_info.data_type = 0x29;
865     cmd_info.cmd = g_mBuf;
866     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
867     if (s32Ret != HI_SUCCESS) {
868         return s32Ret;
869     }
870     usleep(USLEEP_TIME);
871     usleep(10000); // 10000: The process hangs for a period of time, in microseconds
872 
873     memset_s(g_mBuf, G_MBUF_LENGTH, 0, G_MBUF_LENGTH);
874     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_0] = 0xFF;
875     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_1] = 0x77;
876     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_2] = 0x01;
877     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_3] = 0x00;
878     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_4] = 0x00;
879     g_mBuf[G_MBUF_ARRAY_SUBSCRIPT_5] = 0x00;
880     cmd_info.devno = 0;
881     cmd_info.cmd_size = 6; // 6: command data size
882     cmd_info.data_type = 0x29;
883     cmd_info.cmd = g_mBuf;
884     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
885     if (s32Ret != HI_SUCCESS) {
886         return s32Ret;
887     }
888     usleep(USLEEP_TIME);
889     usleep(10000); // 10000: The process hangs for a period of time, in microseconds
890 
891     cmd_info.devno = 0;
892     cmd_info.cmd_size = 0x11;
893     cmd_info.data_type = 0x05;
894     cmd_info.cmd = NULL;
895     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
896     if (s32Ret != HI_SUCCESS) {
897         return s32Ret;
898     }
899     usleep(USLEEP_TIME);
900     usleep(150000); // 150000: The process hangs for a period of time, in microseconds
901 
902     cmd_info.devno = 0;
903     cmd_info.cmd_size = 0x29;
904     cmd_info.data_type = 0x05;
905     cmd_info.cmd = NULL;
906     s32Ret = SAMPLE_USER_INIT_MIPITx(fd, &cmd_info);
907     if (s32Ret != HI_SUCCESS) {
908         return s32Ret;
909     }
910     usleep(USLEEP_TIME);
911     usleep(50000); // 50000: The process hangs for a period of time, in microseconds
912 
913     return HI_SUCCESS;
914 }
915 
916 /*
917  * 启用MIPI Tx设备
918  * Enable MIPI Tx device
919  */
SAMPLE_VO_ENABLE_MIPITx(HI_S32 fd)920 HI_S32 SAMPLE_VO_ENABLE_MIPITx(HI_S32 fd)
921 {
922     HI_S32 s32Ret = ioctl(fd, HI_MIPI_TX_ENABLE);
923     if (s32Ret != HI_SUCCESS) {
924         printf("MIPI_TX enable failed\n");
925         return s32Ret;
926     }
927 
928     return s32Ret;
929 }
930 
931 /*
932  * 禁用MIPI Tx设备
933  * Disable MIPI Tx device
934  */
SAMPLE_VO_DISABLE_MIPITx(HI_S32 fd)935 HI_S32 SAMPLE_VO_DISABLE_MIPITx(HI_S32 fd)
936 {
937     HI_S32 s32Ret = ioctl(fd, HI_MIPI_TX_DISABLE);
938     if (s32Ret != HI_SUCCESS) {
939         printf("MIPI_TX disable failed\n");
940         return s32Ret;
941     }
942 
943     return s32Ret;
944 }
945 
946 /*
947  * 设置VO至MIPI通路,获取MIPI设备
948  * Set VO config to MIPI, get MIPI device
949  */
SAMPLE_VO_CONFIG_MIPI(HI_S32 * mipiFD)950 HI_S32 SAMPLE_VO_CONFIG_MIPI(HI_S32* mipiFD)
951 {
952     HI_S32 s32Ret;
953     HI_S32  fd;
954 
955     /*
956      * 打开MIPI FD
957      * Open MIPI FD
958      */
959     fd = SampleOpenMipiTxFd();
960     if (fd < 0) {
961         return HI_FAILURE;
962     }
963 	*mipiFD = fd;
964 
965     /*
966      * 设置MIPI Tx设备属性
967      * Set MIPI Tx device attribution
968      */
969     s32Ret = SampleSetMipiTxDevAttr(fd);
970     if (s32Ret != HI_SUCCESS) {
971         return s32Ret;
972     }
973 
974     usleep(10000); // 10000: The process hangs for a period of time, in microseconds
975     system("cd /sys/class/gpio/;echo 5 > export;echo out > gpio5/direction;echo 1 > gpio5/value");
976     usleep(200000); // 200000: The process hangs for a period of time, in microseconds
977     system("echo 0 > /sys/class/gpio/gpio5/value");
978     usleep(200000); // 200000: The process hangs for a period of time, in microseconds
979     system("echo 1 > /sys/class/gpio/gpio5/value");
980     usleep(20000); // 20000: The process hangs for a period of time, in microseconds
981 
982     /*
983      * 配置MIPI Tx初始化序列
984      * Config MIPI Tx initialization sequence
985      */
986     s32Ret = SampleVoInitMipiTxScreen(fd);
987     if (s32Ret != HI_SUCCESS) {
988         return s32Ret;
989     }
990 
991     /*
992      * 启用MIPI Tx设备
993      * Enable MIPI Tx device
994      */
995     s32Ret = SAMPLE_VO_ENABLE_MIPITx(fd);
996     if (s32Ret != HI_SUCCESS) {
997         return s32Ret;
998     }
999 
1000     return s32Ret;
1001 }
1002 
1003 /*
1004  * 获得mipi设备的宽和高
1005  * Get mipi device Height and width
1006  */
SampleCommVoGetWhMipi(VO_INTF_SYNC_E enIntfSync,HI_U32 * pu32W,HI_U32 * pu32H,HI_U32 * pu32Frm)1007 HI_S32 SampleCommVoGetWhMipi(VO_INTF_SYNC_E enIntfSync, HI_U32* pu32W, HI_U32* pu32H, HI_U32* pu32Frm)
1008 {
1009     switch (enIntfSync) {
1010         case VO_OUTPUT_1080P24:
1011             *pu32W = 1920; // 1920: VO_OUTPUT_1080P24-Width
1012             *pu32H = 1080; // 1080: VO_OUTPUT_1080P24-Height
1013             *pu32Frm = 24; // 24: VO_OUTPUT_1080P24-Frame rate
1014             break;
1015         case VO_OUTPUT_1080P25:
1016             *pu32W = 1920; // 1920: VO_OUTPUT_1080P25-Width
1017             *pu32H = 1080; // 1080: VO_OUTPUT_1080P25-Height
1018             *pu32Frm = 25; // 25: VO_OUTPUT_1080P25-Frame rate
1019             break;
1020         case VO_OUTPUT_1080P30:
1021             *pu32W = 1920; // 1920: VO_OUTPUT_1080P30-Width
1022             *pu32H = 1080; // 1080: VO_OUTPUT_1080P30-Height
1023             *pu32Frm = 30; // 30: VO_OUTPUT_1080P30-Frame rate
1024             break;
1025         case VO_OUTPUT_720P50:
1026             *pu32W = 1280; // 1280: VO_OUTPUT_720P50-Width
1027             *pu32H = 720; // 720: VO_OUTPUT_720P50-Height
1028             *pu32Frm = 50; // 50: VO_OUTPUT_720P50-Frame rate
1029             break;
1030         case VO_OUTPUT_720P60:
1031             *pu32W = 1280; // 1280: VO_OUTPUT_720P60-Width
1032             *pu32H = 720; // 720: VO_OUTPUT_720P60-Height
1033             *pu32Frm = 60; // 60: VO_OUTPUT_720P60-Frame rate
1034             break;
1035         case VO_OUTPUT_1080P50:
1036             *pu32W = 1920; // 1920: VO_OUTPUT_1080P50-Width
1037             *pu32H = 1080; // 1080: VO_OUTPUT_1080P50-Height
1038             *pu32Frm = 50; // 50: VO_OUTPUT_1080P50-Frame rate
1039             break;
1040         case VO_OUTPUT_1080P60:
1041             *pu32W = 1920; // 1920: VO_OUTPUT_1080P60-Width
1042             *pu32H = 1080; // 1080: VO_OUTPUT_1080P60-Height
1043             *pu32Frm = 60; // 60: VO_OUTPUT_1080P60-Frame rate
1044             break;
1045         case VO_OUTPUT_USER:
1046             *pu32W = 800; // 800: VO_OUTPUT_USER-Width
1047             *pu32H = 480; // 480: VO_OUTPUT_USER-Height
1048             *pu32Frm = 60; // 60: VO_OUTPUT_USER-Frame rate
1049             break;
1050         default:
1051             SAMPLE_PRT("vo enIntfSync %d not support, please config self!\n", enIntfSync);
1052             return HI_FAILURE;
1053     }
1054 
1055     return HI_SUCCESS;
1056 }
1057 
SampleCommVoStartDevMipi(VO_DEV VoDev,VO_PUB_ATTR_S * pstPubAttr)1058 HI_S32 SampleCommVoStartDevMipi(VO_DEV VoDev, VO_PUB_ATTR_S* pstPubAttr)
1059 {
1060     HI_S32 s32Ret;
1061     VO_USER_INTFSYNC_INFO_S stUserInfo = {0};
1062 
1063     stUserInfo.bClkReverse = HI_TRUE;
1064     stUserInfo.u32DevDiv = 1;
1065     stUserInfo.u32PreDiv = 1;
1066     stUserInfo.stUserIntfSyncAttr.enClkSource = VO_CLK_SOURCE_PLL;
1067     stUserInfo.stUserIntfSyncAttr.stUserSyncPll.u32Fbdiv = 244; // 244: PLL integer frequency multiplier coefficient
1068     stUserInfo.stUserIntfSyncAttr.stUserSyncPll.u32Frac = 0x1A36;
1069     stUserInfo.stUserIntfSyncAttr.stUserSyncPll.u32Refdiv = 4; // 4: PLL reference clock frequency division coefficient
1070     // 7: PLL first stage output frequency division coefficient
1071     stUserInfo.stUserIntfSyncAttr.stUserSyncPll.u32Postdiv1 = 7;
1072     // 7: PLL second stage output frequency division coefficient
1073     stUserInfo.stUserIntfSyncAttr.stUserSyncPll.u32Postdiv2 = 7;
1074     HI_U32 u32Framerate = 60; // 60: device frame rate
1075 
1076     /*
1077      * 配置视频输出设备的公共属性
1078      * Set the common properties of the video output device
1079      */
1080     s32Ret = HI_MPI_VO_SetPubAttr(VoDev, pstPubAttr);
1081     if (s32Ret != HI_SUCCESS) {
1082         SAMPLE_PRT("failed with %#x!\n", s32Ret);
1083         return HI_FAILURE;
1084     }
1085 
1086     /*
1087      * 设置设备用户时序下设备帧率
1088      * Set the device frame rate under the device user timing
1089      */
1090     s32Ret = HI_MPI_VO_SetDevFrameRate(VoDev, u32Framerate);
1091     if (s32Ret != HI_SUCCESS) {
1092         SAMPLE_PRT("failed with %#x!\n", s32Ret);
1093         return HI_FAILURE;
1094     }
1095 
1096     /*
1097      * 设置用户接口时序信息,用于配置时钟源、时钟大小和时钟分频比
1098      *
1099      * Set user interface timing information, used to configure clock source,
1100      * clock size and clock frequency division ratio
1101      */
1102     s32Ret = HI_MPI_VO_SetUserIntfSyncInfo(VoDev, &stUserInfo);
1103     if (s32Ret != HI_SUCCESS) {
1104         SAMPLE_PRT("failed with %#x!\n", s32Ret);
1105         return HI_FAILURE;
1106     }
1107 
1108     /*
1109      * 启用视频输出设备
1110      * Enable video output device
1111      */
1112     s32Ret = HI_MPI_VO_Enable(VoDev);
1113     if (s32Ret != HI_SUCCESS) {
1114         SAMPLE_PRT("failed with %#x!\n", s32Ret);
1115         return HI_FAILURE;
1116     }
1117 
1118     return s32Ret;
1119 }
1120 
SampleCommVoStartChnModeMux(SAMPLE_VO_MODE_E enMode)1121 HI_S32 SampleCommVoStartChnModeMux(SAMPLE_VO_MODE_E enMode)
1122 {
1123     int s32Ret;
1124     switch (enMode) {
1125         case VO_MODE_1MUX:
1126             g_sampleVoModeMux.u32WndNum = 1;
1127             g_sampleVoModeMux.u32Square = 1;
1128             break;
1129         case VO_MODE_2MUX:
1130             g_sampleVoModeMux.u32WndNum = 2; // 2: 2MUX-WndNum
1131             g_sampleVoModeMux.u32Square = 2; // 2: 2MUX-Square
1132             break;
1133         case VO_MODE_4MUX:
1134             g_sampleVoModeMux.u32WndNum = 4; // 4: 4MUX-WndNum
1135             g_sampleVoModeMux.u32Square = 2; // 2: 4MUX-Square
1136             break;
1137         case VO_MODE_8MUX:
1138             g_sampleVoModeMux.u32WndNum = 8; // 8: 8MUX-WndNum
1139             g_sampleVoModeMux.u32Square = 3; // 3: 8MUX-Square
1140             break;
1141         case VO_MODE_9MUX:
1142             g_sampleVoModeMux.u32WndNum = 9; // 9: 9MUX-WndNum
1143             g_sampleVoModeMux.u32Square = 3; // 3: 9MUX-Square
1144             break;
1145         case VO_MODE_16MUX:
1146             g_sampleVoModeMux.u32WndNum = 16; // 16: 16MUX-WndNum
1147             g_sampleVoModeMux.u32Square = 4; // 4: 16MUX-Square
1148             break;
1149         case VO_MODE_25MUX:
1150             g_sampleVoModeMux.u32WndNum = 25; // 25: 25MUX-WndNum
1151             g_sampleVoModeMux.u32Square = 5; // 5: 25MUX-Square
1152             break;
1153         case VO_MODE_36MUX:
1154             g_sampleVoModeMux.u32WndNum = 36; // 36: 36MUX-WndNum
1155             g_sampleVoModeMux.u32Square = 6; // 6: 36MUX-Square
1156             break;
1157         case VO_MODE_49MUX:
1158             g_sampleVoModeMux.u32WndNum = 49; // 49: 49MUX-WndNum
1159             g_sampleVoModeMux.u32Square = 7; // 7: 49MUX-Square
1160             break;
1161         case VO_MODE_2X4:
1162             g_sampleVoModeMux.u32WndNum = 8; // 8: 2X4-WndNum
1163             g_sampleVoModeMux.u32Square = 3; // 3: 2X4-Square
1164             g_sampleVoModeMux.u32Row    = 4; // 4: 2X4-Row
1165             g_sampleVoModeMux.u32Col    = 2; // 2: 2X4-Col
1166             break;
1167         default:
1168             SAMPLE_PRT("failed with %#x!\n", s32Ret);
1169             return HI_FAILURE;
1170     }
1171 
1172     return HI_SUCCESS;
1173 }
1174 
SampleCommVoStartChnMipi(VO_LAYER VoLayer,SAMPLE_VO_MODE_E enMode)1175 HI_S32 SampleCommVoStartChnMipi(VO_LAYER VoLayer, SAMPLE_VO_MODE_E enMode)
1176 {
1177     HI_S32 i;
1178     HI_S32 s32Ret    = HI_SUCCESS;
1179     HI_U32 u32Width  = 0;
1180     HI_U32 u32Height = 0;
1181     VO_CHN_ATTR_S         stChnAttr;
1182     VO_VIDEO_LAYER_ATTR_S stLayerAttr;
1183 
1184     s32Ret = SampleCommVoStartChnModeMux(enMode);
1185     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "for SampleCommVoStartChnModeMux FAIL, s32Ret=%x\n", s32Ret);
1186 
1187     /*
1188      * 获取视频层属性
1189      * Get video layer properties
1190      */
1191     s32Ret = HI_MPI_VO_GetVideoLayerAttr(VoLayer, &stLayerAttr);
1192     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "for HI_MPI_VO_GetVideoLayerAttr FAIL, s32Ret=%x\n", s32Ret);
1193     u32Width  = stLayerAttr.stImageSize.u32Width;
1194     u32Height = stLayerAttr.stImageSize.u32Height;
1195     SAMPLE_PRT("enMode:%d, u32Width:%d, u32Height:%d, u32Square:%d\n", enMode,
1196         u32Width, u32Height, g_sampleVoModeMux.u32Square);
1197 
1198     for (i = 0; i < g_sampleVoModeMux.u32WndNum; i++) {
1199         if (enMode == VO_MODE_1MUX  || enMode == VO_MODE_2MUX  || enMode == VO_MODE_4MUX  ||
1200             enMode == VO_MODE_8MUX  || enMode == VO_MODE_9MUX  || enMode == VO_MODE_16MUX ||
1201             enMode == VO_MODE_25MUX || enMode == VO_MODE_36MUX || enMode == VO_MODE_49MUX) {
1202             stChnAttr.stRect.s32X       = HI_ALIGN_DOWN((u32Width / g_sampleVoModeMux.u32Square) *
1203                 (i % g_sampleVoModeMux.u32Square), ALIGN_DOWN_SIZE);
1204             stChnAttr.stRect.s32Y       = HI_ALIGN_DOWN((u32Height / g_sampleVoModeMux.u32Square) *
1205                 (i / g_sampleVoModeMux.u32Square), ALIGN_DOWN_SIZE);
1206             stChnAttr.stRect.u32Width   = HI_ALIGN_DOWN(u32Width / g_sampleVoModeMux.u32Square, ALIGN_DOWN_SIZE);
1207             stChnAttr.stRect.u32Height  = HI_ALIGN_DOWN(u32Height / g_sampleVoModeMux.u32Square, ALIGN_DOWN_SIZE);
1208             stChnAttr.u32Priority       = 0;
1209             stChnAttr.bDeflicker        = HI_FALSE;
1210         } else if (enMode == VO_MODE_2X4) {
1211             stChnAttr.stRect.s32X       = HI_ALIGN_DOWN((u32Width / g_sampleVoModeMux.u32Col) *
1212                 (i % g_sampleVoModeMux.u32Col), ALIGN_DOWN_SIZE);
1213             stChnAttr.stRect.s32Y       = HI_ALIGN_DOWN((u32Height / g_sampleVoModeMux.u32Row) *
1214                 (i / g_sampleVoModeMux.u32Col), ALIGN_DOWN_SIZE);
1215             stChnAttr.stRect.u32Width   = HI_ALIGN_DOWN(u32Width / g_sampleVoModeMux.u32Col, ALIGN_DOWN_SIZE);
1216             stChnAttr.stRect.u32Height  = HI_ALIGN_DOWN(u32Height / g_sampleVoModeMux.u32Row, ALIGN_DOWN_SIZE);
1217             stChnAttr.u32Priority       = 0;
1218             stChnAttr.bDeflicker        = HI_FALSE;
1219         }
1220 
1221         /*
1222          * 配置指定视频输出通道的属性
1223          * Set properties for the specified video output channel
1224          */
1225         s32Ret = HI_MPI_VO_SetChnAttr(VoLayer, i, &stChnAttr);
1226         SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "for HI_MPI_VO_SetChnAttr FAIL, s32Ret=%x\n", s32Ret);
1227 
1228         /*
1229          * 设置指定视频输出通道的旋转角度
1230          * Set video output channel rotation angle
1231          */
1232         s32Ret = HI_MPI_VO_SetChnRotation(VoLayer, i, ROTATION_90);
1233         SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "for HI_MPI_VO_SetChnRotation FAIL, s32Ret=%x\n", s32Ret);
1234 
1235         /*
1236          * 启用指定的视频输出通道
1237          * Enables the specified video output channel
1238          */
1239         s32Ret = HI_MPI_VO_EnableChn(VoLayer, i);
1240         SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "for HI_MPI_VO_EnableChn FAIL, s32Ret=%x\n", s32Ret);
1241     }
1242 
1243     return HI_SUCCESS;
1244 }
1245 
StVoPubAttrCfg(SAMPLE_VO_CONFIG_S * pstVoConfig)1246 static HI_VOID StVoPubAttrCfg(SAMPLE_VO_CONFIG_S *pstVoConfig)
1247 {
1248     HI_ASSERT(pstVoConfig);
1249     /*
1250      * 定义视频输出公共属性结构体
1251      * Define the video output public attribute structure
1252      */
1253     stVoPubAttr.enIntfType  = VO_INTF_MIPI;
1254     stVoPubAttr.enIntfSync  = VO_OUTPUT_USER;
1255     stVoPubAttr.stSyncInfo.bSynm = 0;
1256     stVoPubAttr.stSyncInfo.bIop = 1;
1257     stVoPubAttr.stSyncInfo.u8Intfb = 0;
1258 
1259     stVoPubAttr.stSyncInfo.u16Hmid = 1;
1260     stVoPubAttr.stSyncInfo.u16Bvact = 1;
1261     stVoPubAttr.stSyncInfo.u16Bvbb = 1;
1262     stVoPubAttr.stSyncInfo.u16Bvfb = 1;
1263 
1264     stVoPubAttr.stSyncInfo.bIdv = 0;
1265     stVoPubAttr.stSyncInfo.bIhs = 0;
1266     stVoPubAttr.stSyncInfo.bIvs = 0;
1267 
1268     stVoPubAttr.stSyncInfo.u16Hact = 480; // 480: Horizontal effective area. Unit: pixel
1269     stVoPubAttr.stSyncInfo.u16Hbb = 60; // 60: Horizontal blanking of the rear shoulder. Unit: pixel
1270     stVoPubAttr.stSyncInfo.u16Hfb = 50; // 50: Horizontal blanking of the front shoulder. Unit: pixel
1271     stVoPubAttr.stSyncInfo.u16Hpw = 10; // 10: The width of the horizontal sync signal. Unit: pixel
1272     stVoPubAttr.stSyncInfo.u16Vact = 800; // 800: Vertical effective area. Unit: line
1273     stVoPubAttr.stSyncInfo.u16Vbb = 24; // 24: Vertical blanking of the rear shoulder.  Unit: line
1274     stVoPubAttr.stSyncInfo.u16Vfb = 20; // 20: Vertical blanking of the front shoulder.  Unit: line
1275     stVoPubAttr.stSyncInfo.u16Vpw = 4; // 4: The width of the vertical sync signal. Unit: line
1276     stVoPubAttr.u32BgColor  = pstVoConfig->u32BgColor;
1277 }
1278 
StLayerAttrCfg(SAMPLE_VO_CONFIG_S * pstVoConfig)1279 static HI_VOID StLayerAttrCfg(SAMPLE_VO_CONFIG_S *pstVoConfig)
1280 {
1281     HI_ASSERT(pstVoConfig);
1282     stLayerAttr.bClusterMode     = HI_FALSE;
1283     stLayerAttr.bDoubleFrame    = HI_FALSE;
1284     stLayerAttr.enPixFormat       = pstVoConfig->enPixFormat;
1285 
1286     stLayerAttr.stDispRect.s32X = 0;
1287     stLayerAttr.stDispRect.s32Y = 0;
1288     stLayerAttr.enDstDynamicRange     = pstVoConfig->enDstDynamicRange;
1289 }
1290 
1291 /*
1292  * 启动VO到MIPI lcd通路
1293  * Start VO to MIPI lcd
1294  */
SampleCommVoStartMipi(SAMPLE_VO_CONFIG_S * pstVoConfig)1295 HI_S32 SampleCommVoStartMipi(SAMPLE_VO_CONFIG_S *pstVoConfig)
1296 {
1297     HI_S32 s32Ret;
1298 
1299     HI_ASSERT(pstVoConfig);
1300     StVoPubAttrCfg(pstVoConfig);
1301     s32Ret = SampleCommVoStartDevMipi(pstVoConfig->VoDev, &stVoPubAttr);
1302     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "StartDevMipi FAIL, ret=%x\n", s32Ret);
1303     /*
1304      * 获得MIPI设备的宽和高
1305      * Get MIPI device Height and width
1306      */
1307     s32Ret = SampleCommVoGetWhMipi(stVoPubAttr.enIntfSync,
1308         &stLayerAttr.stDispRect.u32Width, &stLayerAttr.stDispRect.u32Height, &stLayerAttr.u32DispFrmRt);
1309     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, FAIL, "VoGetWhMipi fail, err(%#x)\n", s32Ret);
1310 
1311     StLayerAttrCfg(pstVoConfig);
1312 
1313     /*
1314      * 如果存在变化,设置显示矩形框
1315      * Set display rectangle if changed
1316      */
1317     if (memcmp(&pstVoConfig->stDispRect, &stDefDispRect, sizeof(RECT_S)) != 0) {
1318         memcpy_s(&stLayerAttr.stDispRect, sizeof(stLayerAttr.stDispRect),
1319             &pstVoConfig->stDispRect, sizeof(RECT_S));
1320     }
1321 
1322     /*
1323      * 如果存在变化,设置图片大小
1324      * Set image size if changed
1325      */
1326     if (memcmp(&pstVoConfig->stImageSize, &stDefImageSize, sizeof(SIZE_S)) != 0) {
1327         memcpy_s(&stLayerAttr.stImageSize, sizeof(stLayerAttr.stImageSize),
1328             &pstVoConfig->stImageSize, sizeof(SIZE_S));
1329     }
1330     stLayerAttr.stImageSize.u32Width  = stLayerAttr.stDispRect.u32Width = 480; // 480: video layer canvas Width
1331     stLayerAttr.stImageSize.u32Height = stLayerAttr.stDispRect.u32Height = 800; // 800: video layer canvas Height
1332 
1333     if (pstVoConfig->u32DisBufLen) {
1334         /*
1335          * 设置显示缓冲的长度
1336          * Set buffer length
1337          */
1338         s32Ret = HI_MPI_VO_SetDisplayBufLen(pstVoConfig->VoDev, pstVoConfig->u32DisBufLen);
1339         SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, FAIL, "HI_MPI_VO_SetDisplayBufLen fail, err(%#x)\n", s32Ret);
1340     }
1341     if (VO_PART_MODE_MULTI == pstVoConfig->enVoPartMode) {
1342         /*
1343          * 设置视频层的分割模式
1344          * Set the segmentation mode of the video layer
1345          */
1346         s32Ret = HI_MPI_VO_SetVideoLayerPartitionMode(pstVoConfig->VoDev, pstVoConfig->enVoPartMode);
1347         SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, FAIL, "SetVideoLayerMode fail, err(%#x)\n", s32Ret);
1348     }
1349 
1350     s32Ret = SAMPLE_COMM_VO_StartLayer(pstVoConfig->VoDev, &stLayerAttr); // start layer
1351     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, FAIL, "VO_StartLayer fail, err(%#x)\n", s32Ret);
1352 
1353     if (VO_INTF_MIPI == pstVoConfig->enVoIntfType) {
1354         s32Ret = HI_MPI_VO_GetVideoLayerCSC(pstVoConfig->VoDev, &stVideoCSC); // get video layerCSC
1355         SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, FAIL, "GetVideoLayerCSC fail, err(%#x)\n", s32Ret);
1356         stVideoCSC.enCscMatrix = VO_CSC_MATRIX_BT709_TO_RGB_PC;
1357         s32Ret = HI_MPI_VO_SetVideoLayerCSC(pstVoConfig->VoDev, &stVideoCSC); // Set video layer CSC
1358         SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, FAIL, "SetVideoLayerCSC fail, err(%#x)\n", s32Ret);
1359     }
1360 
1361     s32Ret = SampleCommVoStartChnMipi(pstVoConfig->VoDev, pstVoConfig->enVoMode); // start vo channels
1362     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, FAIL1, "VoStartChnMipi fail, err(%#x)\n", s32Ret);
1363     return HI_SUCCESS;
1364 
1365 FAIL1:
1366     SAMPLE_COMM_VO_StopLayer(pstVoConfig->VoDev);
1367 FAIL:
1368     SAMPLE_COMM_VO_StopDev(pstVoConfig->VoDev);
1369     return s32Ret;
1370 }
1371 
1372 /*
1373  * 初始化vi配置
1374  * Init ViCfg
1375  */
ViCfgInit(ViCfg * self)1376 void ViCfgInit(ViCfg* self)
1377 {
1378     HI_ASSERT(self);
1379     if (memset_s(self, sizeof(*self), 0, sizeof(*self)) != EOK) {
1380         HI_ASSERT(0);
1381     }
1382 
1383     SAMPLE_COMM_VI_GetSensorInfo(self);
1384     self->s32WorkingViNum = 1;
1385     self->as32WorkingViId[0] = 0;
1386 
1387     self->astViInfo[0].stSnsInfo.MipiDev =
1388         SAMPLE_COMM_VI_GetComboDevBySensor(self->astViInfo[0].stSnsInfo.enSnsType, 0);
1389     self->astViInfo[0].stSnsInfo.s32BusId = 0;
1390 }
1391 
1392 /*
1393  * 设置VI设备信息
1394  * Set VI device information
1395  */
ViCfgSetDev(ViCfg * self,int devId,WDR_MODE_E wdrMode)1396 void ViCfgSetDev(ViCfg* self, int devId, WDR_MODE_E wdrMode)
1397 {
1398     HI_ASSERT(self);
1399     HI_ASSERT((int)wdrMode < WDR_MODE_BUTT);
1400 
1401     self->astViInfo[0].stDevInfo.ViDev = devId;
1402     self->astViInfo[0].stDevInfo.enWDRMode = (int)wdrMode < 0 ? WDR_MODE_NONE : wdrMode;
1403 }
1404 
1405 /*
1406  * 设置VI的PIPE信息
1407  * Set the PIPE information of the VI
1408  */
ViCfgSetPipe(ViCfg * self,int pipe0Id,int pipe1Id,int pipe2Id,int pipe3Id)1409 void ViCfgSetPipe(ViCfg* self, int pipe0Id, int pipe1Id, int pipe2Id, int pipe3Id)
1410 {
1411     HI_ASSERT(self);
1412 
1413     self->astViInfo[0].stPipeInfo.aPipe[APIPE0] = pipe0Id;
1414     self->astViInfo[0].stPipeInfo.aPipe[APIPE1] = pipe1Id;
1415     self->astViInfo[0].stPipeInfo.aPipe[APIPE2] = pipe2Id;
1416     self->astViInfo[0].stPipeInfo.aPipe[APIPE3] = pipe3Id;
1417 }
1418 
1419 /*
1420  * 设置VI通道
1421  * Set up the VI channel
1422  */
ViCfgSetChn(ViCfg * self,int chnId,PIXEL_FORMAT_E pixFormat,VIDEO_FORMAT_E videoFormat,DYNAMIC_RANGE_E dynamicRange)1423 void ViCfgSetChn(ViCfg* self, int chnId, PIXEL_FORMAT_E pixFormat,
1424     VIDEO_FORMAT_E videoFormat, DYNAMIC_RANGE_E dynamicRange)
1425 {
1426     HI_ASSERT(self);
1427     HI_ASSERT((int)pixFormat < PIXEL_FORMAT_BUTT);
1428     HI_ASSERT((int)videoFormat < VIDEO_FORMAT_BUTT);
1429     HI_ASSERT((int)dynamicRange < DYNAMIC_RANGE_BUTT);
1430 
1431     self->astViInfo[0].stChnInfo.ViChn = chnId;
1432     self->astViInfo[0].stChnInfo.enPixFormat =
1433         (int)pixFormat < 0 ? PIXEL_FORMAT_YVU_SEMIPLANAR_420 : pixFormat;
1434     self->astViInfo[0].stChnInfo.enVideoFormat =
1435         (int)videoFormat < 0 ? VIDEO_FORMAT_LINEAR : videoFormat;
1436     self->astViInfo[0].stChnInfo.enDynamicRange =
1437         (int)dynamicRange < 0 ? DYNAMIC_RANGE_SDR8 : dynamicRange;
1438 }
1439 
1440 /*
1441  * 初始化VPSS配置
1442  * Init VpssCfg
1443  */
VpssCfgInit(VpssCfg * self)1444 void VpssCfgInit(VpssCfg* self)
1445 {
1446     HI_ASSERT(self);
1447     if (memset_s(self, sizeof(*self), 0, sizeof(*self)) != EOK) {
1448         HI_ASSERT(0);
1449     }
1450     self->grpId = -1;
1451     self->chnNum = 0;
1452 }
1453 
1454 /*
1455  * 设置VPSS组
1456  * Set up VPSS Group
1457  */
VpssCfgSetGrp(VpssCfg * self,int grpId,const VPSS_GRP_ATTR_S * grpAttr,int maxWidth,int maxHeight)1458 void VpssCfgSetGrp(VpssCfg* self,
1459     int grpId, const VPSS_GRP_ATTR_S* grpAttr, int maxWidth, int maxHeight)
1460 {
1461     HI_ASSERT(self);
1462     HI_ASSERT(grpId >= 0);
1463 
1464     self->grpId = grpId;
1465 
1466     if (grpAttr) {
1467         self->grpAttr = *grpAttr;
1468     } else { // Set as default
1469         self->grpAttr.u32MaxW = maxWidth < 0 ? 0 : maxWidth;
1470         self->grpAttr.u32MaxH = maxHeight < 0 ? 0 : maxHeight;
1471         self->grpAttr.enPixelFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420;
1472         self->grpAttr.enDynamicRange = DYNAMIC_RANGE_SDR8;
1473         self->grpAttr.stFrameRate.s32SrcFrameRate = -1;
1474         self->grpAttr.stFrameRate.s32DstFrameRate = -1;
1475         self->grpAttr.bNrEn = HI_TRUE;
1476     }
1477 }
1478 
1479 /*
1480  * 增加一个VPSS通道
1481  * Add a VPSS channel
1482  */
VpssCfgAddChn(VpssCfg * self,int chnId,const VPSS_CHN_ATTR_S * chnAttr,int width,int height)1483 VPSS_CHN_ATTR_S* VpssCfgAddChn(VpssCfg* self,
1484     int chnId, const VPSS_CHN_ATTR_S* chnAttr, int width, int height)
1485 {
1486     HI_ASSERT(self);
1487     HI_ASSERT(self->chnNum < (sizeof(self->chnCfgs) / sizeof((self->chnCfgs)[0])));
1488     static const uint32_t depthDef = 2;
1489     VpssChnCfg *chnCfg = &self->chnCfgs[self->chnNum];
1490 
1491     if (chnAttr) {
1492         chnCfg->attr = *chnAttr;
1493     } else { // Set as default
1494         chnCfg->attr.u32Width = width < 0 ? 0 : width;
1495         chnCfg->attr.u32Height = height < 0 ? 0 : height;
1496         chnCfg->attr.enChnMode = VPSS_CHN_MODE_USER;
1497         chnCfg->attr.enVideoFormat = VIDEO_FORMAT_LINEAR;
1498         chnCfg->attr.enPixelFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420;
1499         chnCfg->attr.enDynamicRange = DYNAMIC_RANGE_SDR8;
1500         chnCfg->attr.enCompressMode = COMPRESS_MODE_NONE;
1501         chnCfg->attr.stFrameRate.s32SrcFrameRate = -1;
1502         chnCfg->attr.stFrameRate.s32DstFrameRate = -1;
1503         chnCfg->attr.u32Depth = depthDef;
1504         chnCfg->attr.bMirror = HI_FALSE;
1505         chnCfg->attr.bFlip = HI_FALSE;
1506         chnCfg->attr.stAspectRatio.enMode = ASPECT_RATIO_NONE;
1507     }
1508     chnCfg->id = chnId;
1509 
1510     self->chnNum++;
1511     return &chnCfg->attr;
1512 }
1513 
1514 /*
1515  * 根据VPSS配置来启动VPSS
1516  * Start VPSS according to VPSS config
1517  */
VpssStart(const VpssCfg * cfg)1518 int VpssStart(const VpssCfg* cfg)
1519 {
1520     HI_ASSERT(cfg);
1521     VPSS_GRP grpId = cfg->grpId;
1522     HI_S32 ret;
1523 
1524     /*
1525      * 创建一个VPSS GROUP
1526      * Create a VPSS GROUP
1527      */
1528     ret = HI_MPI_VPSS_CreateGrp(grpId, &cfg->grpAttr);
1529     if (ret != 0) {
1530         SAMPLE_PRT("HI_MPI_VPSS_CreateGrp(%d) FAIL, ret=%#x\n", grpId, ret);
1531         return ret;
1532     }
1533 
1534     for (int i = 0; i < cfg->chnNum; i++) {
1535         /*
1536          * 设置VPSS通道属性
1537          * Set VPSS channel properties
1538          */
1539         ret = HI_MPI_VPSS_SetChnAttr(grpId, cfg->chnCfgs[i].id, &cfg->chnCfgs[i].attr);
1540         if (ret != 0) {
1541             SAMPLE_PRT("HI_MPI_VPSS_SetChnAttr(%d) FAIL, ret=%#x\n", cfg->chnCfgs[i].id, ret);
1542             return ret;
1543         }
1544 
1545         /*
1546          * 启用VPSS通道
1547          * Enable VPSS channel
1548          */
1549         ret = HI_MPI_VPSS_EnableChn(grpId, cfg->chnCfgs[i].id);
1550         if (ret != 0) {
1551             SAMPLE_PRT("HI_MPI_VPSS_EnableChn(%d) FAIL, ret=%#x\n", cfg->chnCfgs[i].id, ret);
1552             return ret;
1553         }
1554     }
1555 
1556     /*
1557      * 启用VPSS GROUP
1558      * Enable VPSS GROUP
1559      */
1560     ret = HI_MPI_VPSS_StartGrp(grpId);
1561     if (ret != 0) {
1562         SAMPLE_PRT("HI_MPI_VPSS_StartGrp(%d) FAIL, ret=%#x\n", grpId, ret);
1563         return ret;
1564     }
1565     return HI_SUCCESS;
1566 }
1567 
1568 /*
1569  * 终止使用ViCfg启动的VI
1570  * Terminate VI started with ViCfg
1571  */
ViStop(const ViCfg * viCfg)1572 int ViStop(const ViCfg* viCfg)
1573 {
1574     return SAMPLE_COMM_VI_StopVi((ViCfg*)viCfg);
1575 }
1576 
1577 /*
1578  * 停止使用VpssCfg启动的VPSS
1579  * Terminate VPSS started with VpssCfg
1580  */
VpssStop(const VpssCfg * cfg)1581 int VpssStop(const VpssCfg* cfg)
1582 {
1583     HI_ASSERT(cfg);
1584     VPSS_GRP grpId = cfg->grpId;
1585     HI_S32 ret;
1586 
1587     for (int i = 0; i < cfg->chnNum; i++) {
1588         /*
1589          * 禁用VPSS通道
1590          * Disable VPSS channel
1591          */
1592         ret = HI_MPI_VPSS_DisableChn(grpId, cfg->chnCfgs[i].id);
1593         if (ret != 0) {
1594             SAMPLE_PRT("HI_MPI_VPSS_DisableChn(%d, %d) FAIL, ret=%#x\n", grpId, cfg->chnCfgs[i].id, ret);
1595             return ret;
1596         }
1597     }
1598 
1599     /*
1600      * 禁用VPSS GROUP
1601      * Stop VPSS GROUP
1602      */
1603     ret = HI_MPI_VPSS_StopGrp(grpId);
1604     if (ret != 0) {
1605         SAMPLE_PRT("HI_MPI_VPSS_StopGrp(%d) FAIL, ret=%#x\n", grpId, ret);
1606         return ret;
1607     }
1608 
1609     /*
1610      * 销毁一个VPSS GROUP
1611      * Destroy a VPSS GROUP
1612      */
1613     ret = HI_MPI_VPSS_DestroyGrp(grpId);
1614     if (ret != 0) {
1615         SAMPLE_PRT("HI_MPI_VPSS_DestroyGrp(%d) FAIL, ret=%#x\n", grpId, ret);
1616         return ret;
1617     }
1618     return HI_SUCCESS;
1619 }
1620 
1621 /*
1622  * 根据VI配置来启动VI
1623  * Start VI according to ViCfg
1624  */
ViStart(const ViCfg * viCfg)1625 int ViStart(const ViCfg* viCfg)
1626 {
1627     static const uint32_t frmRateDef = 30;
1628     SAMPLE_SNS_TYPE_E snsType = viCfg->astViInfo[0].stSnsInfo.enSnsType;
1629     ISP_CTRL_PARAM_S ispCtrlParam;
1630     HI_U32 frmRate;
1631     HI_S32 ret;
1632 
1633     ret = SAMPLE_COMM_VI_SetParam((ViCfg*)viCfg);
1634     if (ret != 0) {
1635         SAMPLE_PRT("SAMPLE_COMM_VI_SetParam FAIL, ret=%#x\n", ret);
1636         return ret;
1637     }
1638 
1639     /*
1640      * 通过Sensor型号来获取帧率
1641      * Get the frame rate through the Sensor model
1642      */
1643     SAMPLE_COMM_VI_GetFrameRateBySensor(snsType, &frmRate);
1644     ret = HI_MPI_ISP_GetCtrlParam(viCfg->astViInfo[0].stPipeInfo.aPipe[0], &ispCtrlParam);
1645     if (ret != 0) {
1646         SAMPLE_PRT("HI_MPI_ISP_GetCtrlParam FAIL, ret=%#x\n", ret);
1647         return ret;
1648     }
1649 
1650     ispCtrlParam.u32StatIntvl = frmRate / frmRateDef;
1651     ret = HI_MPI_ISP_SetCtrlParam(viCfg->astViInfo[0].stPipeInfo.aPipe[0], &ispCtrlParam);
1652     if (ret != 0) {
1653         SAMPLE_PRT("HI_MPI_ISP_SetCtrlParam FAIL, ret=%#x\n", ret);
1654         return ret;
1655     }
1656 
1657     ret = SAMPLE_COMM_VI_StartVi((ViCfg*)viCfg);
1658     if (ret != 0) {
1659         SAMPLE_PRT("SAMPLE_COMM_VI_StartVi FAIL, ret=%#x\n", ret);
1660         return ret;
1661     }
1662 
1663     return HI_SUCCESS;
1664 }
1665 
1666 /*
1667  * 将VI绑定到VPSS
1668  * Bind VI to VPSS
1669  */
ViBindVpss(VI_PIPE viPipe,VI_CHN viChn,VPSS_GRP vpssGrp)1670 int ViBindVpss(VI_PIPE viPipe, VI_CHN viChn, VPSS_GRP vpssGrp)
1671 {
1672     MPP_CHN_S srcChn;
1673     MPP_CHN_S dstChn;
1674 
1675     srcChn.enModId = HI_ID_VI;
1676     srcChn.s32DevId = viPipe;
1677     srcChn.s32ChnId = viChn;
1678 
1679     dstChn.enModId = HI_ID_VPSS;
1680     dstChn.s32DevId = vpssGrp;
1681     dstChn.s32ChnId = 0;
1682 
1683     int ret = HI_MPI_SYS_Bind(&srcChn, &dstChn);
1684     if (ret != 0) {
1685         SAMPLE_PRT("HI_MPI_SYS_Bind(VI:%d, VPSS:%d) FAIL, ret=%#x\n", viChn, vpssGrp, ret);
1686         return ret;
1687     }
1688 
1689     return ret;
1690 }
1691 
1692 /*
1693  * 新的MppSess
1694  * New MppSess
1695  */
MppSessNew(void)1696 static MppSess* MppSessNew(void)
1697 {
1698     MppSess *sess = (MppSess*)malloc(sizeof(*sess));
1699     if (sess == NULL) {
1700         SAMPLE_PRT("%s: malloc failed!\n", __FUNCTION__);
1701         HI_ASSERT(sess);
1702     }
1703 
1704     if (memset_s(sess, sizeof(*sess), 0, sizeof(*sess)) != EOK) {
1705         HI_ASSERT(0);
1706     }
1707 
1708     sess->vpssGrp = -1;
1709     sess->vpssChn0 = -1;
1710     sess->vpssChn1 = -1;
1711 
1712     return sess;
1713 }
1714 
1715 /*
1716  * 创建并启动{VI->VPSS}MppSess
1717  * Create and start {VI->VPSS}MppSess
1718  */
ViVpssCreate(MppSess ** sess,const ViCfg * viCfg,const VpssCfg * vpssCfg)1719 int ViVpssCreate(MppSess** sess, const ViCfg* viCfg, const VpssCfg* vpssCfg)
1720 {
1721     HI_ASSERT(sess && viCfg && vpssCfg);
1722     *sess = NULL;
1723     int res;
1724     int ret;
1725 
1726     ret = ViStart(viCfg);
1727     SAMPLE_CHECK_EXPR_GOTO(ret != HI_SUCCESS, FAIL1,
1728         "vi start fail, err(%#x)\n", ret);
1729 
1730     ret = VpssStart(vpssCfg);
1731     SAMPLE_CHECK_EXPR_GOTO(ret != HI_SUCCESS, FAIL2,
1732         "vpss start fail, err(%#x)\n", ret);
1733 
1734     VI_PIPE pipeId = viCfg->astViInfo[0].stPipeInfo.aPipe[0];
1735     VI_CHN chnId = viCfg->astViInfo[0].stChnInfo.ViChn;
1736     ret = ViBindVpss(pipeId, chnId, vpssCfg->grpId);
1737     SAMPLE_CHECK_EXPR_GOTO(ret != HI_SUCCESS, FAIL3,
1738         "vi bind vpss fail, err(%#x)\n", ret);
1739 
1740     MppSess *self = MppSessNew(); // todo:realease malloc
1741     *sess = self;
1742     self->viCfg = *viCfg;
1743     self->vpssCfg = *vpssCfg;
1744     self->used |= MPP_VI;
1745     self->used |= MPP_VPSS;
1746     self->vpssGrp = vpssCfg->grpId;
1747     self->vpssChn0 = vpssCfg->chnCfgs[0].id;
1748     self->vpssChn1 = vpssCfg->chnNum > 1 ? vpssCfg->chnCfgs[1].id : -1;
1749     return 0;
1750 
1751     FAIL3:
1752         res = VpssStop(vpssCfg);
1753         SAMPLE_PRT("ViVpssCreate\n");
1754         if (res != 0) {
1755             SAMPLE_PRT("VpssStop FAIL, ret=%#x\n", res);
1756         }
1757     FAIL2:
1758         ViStop(viCfg);
1759     FAIL1:
1760         return ret;
1761 }
1762 
CnnTrashClassifyAiProcess(VIDEO_FRAME_INFO_S frm)1763 static HI_VOID CnnTrashClassifyAiProcess(VIDEO_FRAME_INFO_S frm)
1764 {
1765     int ret;
1766     if (GetCfgBool("trash_classify_switch:support_trash_classify", true)) {
1767         if (g_workPlug.model == 0) {
1768             HI_ASSERT(!g_aicMediaInfo.osds);
1769             g_aicMediaInfo.osds = OsdsCreate(HI_OSD_BINDMOD_VPSS, g_aicMediaInfo.vpssGrp, g_aicMediaInfo.vpssChn0);
1770             HI_ASSERT(g_aicMediaInfo.osds);
1771             ret = CnnTrashClassifyLoadModel(&g_workPlug.model, g_aicMediaInfo.osds);
1772             if (ret < 0) {
1773                 g_workPlug.model = 0;
1774                 SAMPLE_CHECK_EXPR_GOTO(ret < 0, TRASH_RELEASE,
1775                     "load cnn trash classify model err(%#x)\n", ret);
1776             }
1777         }
1778         VIDEO_FRAME_INFO_S *resFrm = NULL;
1779         ret = CnnTrashClassifyCal(g_workPlug.model, &frm, resFrm);
1780         SAMPLE_CHECK_EXPR_GOTO(ret < 0, TRASH_RELEASE,
1781             "trash classify plug cal FAIL, ret=%#x\n", ret);
1782     }
1783 
1784     TRASH_RELEASE:
1785         ret = HI_MPI_VPSS_ReleaseChnFrame(g_aicMediaInfo.vpssGrp, g_aicMediaInfo.vpssChn0, &frm);
1786         if (ret != HI_SUCCESS) {
1787             SAMPLE_PRT("Error(%#x),HI_MPI_VPSS_ReleaseChnFrame failed,Grp(%d) chn(%d)!\n",
1788                 ret, g_aicMediaInfo.vpssGrp, g_aicMediaInfo.vpssChn0);
1789         }
1790 }
1791 
GetVpssChnFrameCnnTrashClassify(HI_VOID * arg)1792 static HI_VOID* GetVpssChnFrameCnnTrashClassify(HI_VOID* arg)
1793 {
1794     int ret;
1795     VIDEO_FRAME_INFO_S frm;
1796     HI_S32 s32MilliSec = 20000;
1797 
1798     while (HI_FALSE == g_bAiProcessStopSignal) {
1799         ret = HI_MPI_VPSS_GetChnFrame(g_aicMediaInfo.vpssGrp, g_aicMediaInfo.vpssChn0, &frm, s32MilliSec);
1800         if (ret != 0) {
1801             SAMPLE_PRT("HI_MPI_VPSS_GetChnFrame FAIL, err=%#x, grp=%d, chn=%d\n",
1802                 ret, g_aicMediaInfo.vpssGrp, g_aicMediaInfo.vpssChn0);
1803             ret = HI_MPI_VPSS_ReleaseChnFrame(g_aicMediaInfo.vpssGrp, g_aicMediaInfo.vpssChn0, &frm);
1804             if (ret != HI_SUCCESS) {
1805                 SAMPLE_PRT("Error(%#x),HI_MPI_VPSS_ReleaseChnFrame failed,Grp(%d) chn(%d)!\n",
1806                     ret, g_aicMediaInfo.vpssGrp, g_aicMediaInfo.vpssChn0);
1807             }
1808             continue;
1809         }
1810         SAMPLE_PRT("get vpss frame success, weight:%d, height:%d\n", frm.stVFrame.u32Width, frm.stVFrame.u32Height);
1811 
1812         if (g_num == 0) {
1813             ConfBaseInit(AI_SAMPLE_CFG_FILE);
1814             g_num++;
1815         }
1816         CnnTrashClassifyAiProcess(frm);
1817     }
1818 
1819     return HI_NULL;
1820 }
1821 
HandClassifyAiProcess(VIDEO_FRAME_INFO_S frm,VO_LAYER voLayer,VO_CHN voChn)1822 static HI_VOID HandClassifyAiProcess(VIDEO_FRAME_INFO_S frm, VO_LAYER voLayer, VO_CHN voChn)
1823 {
1824     int ret;
1825     if (GetCfgBool("hand_classify_switch:support_hand_classify", true)) {
1826         if (g_workPlug.model == 0) {
1827             ret = Yolo2HandDetectResnetClassifyLoad(&g_workPlug.model);
1828             if (ret < 0) {
1829                 g_workPlug.model = 0;
1830                 SAMPLE_CHECK_EXPR_GOTO(ret < 0, HAND_RELEASE,
1831                     "load hand classify model err, ret=%#x\n", ret);
1832             }
1833         }
1834 
1835         VIDEO_FRAME_INFO_S resizeFrm;
1836         ret = MppFrmResize(&frm, &resizeFrm, HAND_FRM_WIDTH, HAND_FRM_HEIGHT);
1837         ret = Yolo2HandDetectResnetClassifyCal(g_workPlug.model, &resizeFrm, &frm);
1838         SAMPLE_CHECK_EXPR_GOTO(ret < 0, HAND_RELEASE,
1839             "hand classify plug cal FAIL, ret=%#x\n", ret);
1840 
1841         ret = HI_MPI_VO_SendFrame(voLayer, voChn, &frm, 0);
1842         SAMPLE_CHECK_EXPR_GOTO(ret != HI_SUCCESS, HAND_RELEASE,
1843             "HI_MPI_VO_SendFrame fail, Error(%#x)\n", ret);
1844 
1845         MppFrmDestroy(&resizeFrm);
1846     }
1847 
1848     HAND_RELEASE:
1849         ret = HI_MPI_VPSS_ReleaseChnFrame(g_aicMediaInfo.vpssGrp, g_aicMediaInfo.vpssChn0, &frm);
1850         if (ret != HI_SUCCESS) {
1851             SAMPLE_PRT("Error(%#x),HI_MPI_VPSS_ReleaseChnFrame failed,Grp(%d) chn(%d)!\n",
1852                 ret, g_aicMediaInfo.vpssGrp, g_aicMediaInfo.vpssChn0);
1853         }
1854 }
1855 
GetVpssChnFrameHandClassify(HI_VOID * arg)1856 static HI_VOID* GetVpssChnFrameHandClassify(HI_VOID* arg)
1857 {
1858     int ret;
1859     VIDEO_FRAME_INFO_S frm;
1860     HI_S32 s32MilliSec = 2000;
1861     VO_LAYER voLayer = 0;
1862     VO_CHN voChn = 0;
1863 
1864     SAMPLE_PRT("vpssGrp:%d, vpssChn0:%d\n", g_aicMediaInfo.vpssGrp, g_aicMediaInfo.vpssChn0);
1865 
1866     while (HI_FALSE == g_bAiProcessStopSignal) {
1867         ret = HI_MPI_VPSS_GetChnFrame(g_aicMediaInfo.vpssGrp, g_aicMediaInfo.vpssChn0, &frm, s32MilliSec);
1868         if (ret != 0) {
1869             SAMPLE_PRT("HI_MPI_VPSS_GetChnFrame FAIL, err=%#x, grp=%d, chn=%d\n",
1870                 ret, g_aicMediaInfo.vpssGrp, g_aicMediaInfo.vpssChn0);
1871             ret = HI_MPI_VPSS_ReleaseChnFrame(g_aicMediaInfo.vpssGrp, g_aicMediaInfo.vpssChn0, &frm);
1872             if (ret != HI_SUCCESS) {
1873                 SAMPLE_PRT("Error(%#x),HI_MPI_VPSS_ReleaseChnFrame failed,Grp(%d) chn(%d)!\n",
1874                     ret, g_aicMediaInfo.vpssGrp, g_aicMediaInfo.vpssChn0);
1875             }
1876             continue;
1877         }
1878         SAMPLE_PRT("get vpss frame success, weight:%d, height:%d\n", frm.stVFrame.u32Width, frm.stVFrame.u32Height);
1879 
1880         if (g_num == 0) {
1881             ConfBaseInit(AI_SAMPLE_CFG_FILE);
1882             g_num++;
1883         }
1884         HandClassifyAiProcess(frm, voLayer, voChn);
1885     }
1886 
1887     return HI_NULL;
1888 }
1889 
Pause(HI_VOID)1890 static HI_VOID Pause(HI_VOID)
1891 {
1892     printf("---------------press Enter key to exit!---------------\n");
1893     (void)getchar();
1894 }
1895 
ViPramCfg(HI_VOID)1896 HI_VOID ViPramCfg(HI_VOID)
1897 {
1898     ViCfgInit(&g_aicMediaInfo.viCfg);
1899     ViCfgSetDev(&g_aicMediaInfo.viCfg, 0, -1);
1900     ViCfgSetPipe(&g_aicMediaInfo.viCfg, 0, -1, -1, -1);
1901     g_aicMediaInfo.viCfg.astViInfo[0].stPipeInfo.enMastPipeMode = 0;
1902     ViCfgSetChn(&g_aicMediaInfo.viCfg, 0, -1, -1, -1);
1903     g_aicMediaInfo.viCfg.astViInfo[0].stChnInfo.enCompressMode = 1;
1904 }
1905 
StVbParamCfg(VbCfg * self)1906 static HI_VOID StVbParamCfg(VbCfg *self)
1907 {
1908     memset_s(&g_aicMediaInfo.vbCfg, sizeof(VB_CONFIG_S), 0, sizeof(VB_CONFIG_S));
1909     // 2: The number of buffer pools that can be accommodated in the entire system
1910     self->u32MaxPoolCnt              = 2;
1911 
1912     /*
1913      * 获取一帧图片的buffer大小
1914      * Get picture buffer size
1915      */
1916     g_aicMediaInfo.u32BlkSize = COMMON_GetPicBufferSize(g_aicMediaInfo.stSize.u32Width, g_aicMediaInfo.stSize.u32Height,
1917         SAMPLE_PIXEL_FORMAT, DATA_BITWIDTH_8, COMPRESS_MODE_SEG, DEFAULT_ALIGN);
1918     self->astCommPool[0].u64BlkSize  = g_aicMediaInfo.u32BlkSize;
1919     // 10: Number of cache blocks per cache pool. Value range: (0, 10240]
1920     self->astCommPool[0].u32BlkCnt   = 10;
1921 
1922     /*
1923      * 获取raw buffer的大小
1924      * Get raw buffer size
1925      */
1926     g_aicMediaInfo.u32BlkSize = VI_GetRawBufferSize(g_aicMediaInfo.stSize.u32Width, g_aicMediaInfo.stSize.u32Height,
1927         PIXEL_FORMAT_RGB_BAYER_16BPP, COMPRESS_MODE_NONE, DEFAULT_ALIGN);
1928     self->astCommPool[1].u64BlkSize  = g_aicMediaInfo.u32BlkSize;
1929     // 4: Number of cache blocks per cache pool. Value range: (0, 10240]
1930     self->astCommPool[1].u32BlkCnt   = 4;
1931 }
1932 
StVoParamCfg(VoCfg * self)1933 static HI_VOID StVoParamCfg(VoCfg *self)
1934 {
1935     SAMPLE_COMM_VO_GetDefConfig(self);
1936     self->enDstDynamicRange = DYNAMIC_RANGE_SDR8;
1937 
1938     self->enVoIntfType = VO_INTF_MIPI; /* set VO int type */
1939     self->enIntfSync = VO_OUTPUT_USER; /* set VO output information */
1940 
1941     self->enPicSize = g_aicMediaInfo.enPicSize;
1942 }
1943 
VpssParamCfg(HI_VOID)1944 static HI_VOID VpssParamCfg(HI_VOID)
1945 {
1946     VpssCfgInit(&g_aicMediaInfo.vpssCfg);
1947     VpssCfgSetGrp(&g_aicMediaInfo.vpssCfg, AIC_VPSS_GRP, NULL,
1948         g_aicMediaInfo.stSize.u32Width, g_aicMediaInfo.stSize.u32Width);
1949     g_aicMediaInfo.vpssCfg.grpAttr.enPixelFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420;
1950     VpssCfgAddChn(&g_aicMediaInfo.vpssCfg, AIC_VPSS_ZOUT_CHN, NULL, AICSTART_VI_OUTWIDTH, AICSTART_VI_OUTHEIGHT);
1951     HI_ASSERT(!g_aicMediaInfo.viSess);
1952 }
1953 
CnnTrashAiThreadProcess(HI_VOID)1954 static HI_S32 CnnTrashAiThreadProcess(HI_VOID)
1955 {
1956     HI_S32 s32Ret;
1957     if (snprintf_s(acThreadName, BUFFER_SIZE, BUFFER_SIZE - 1, "AIProcess") < 0) {
1958         HI_ASSERT(0);
1959     }
1960     prctl(PR_SET_NAME, (unsigned long)acThreadName, 0, 0, 0);
1961     s32Ret = pthread_create(&g_aiProcessThread, NULL, GetVpssChnFrameCnnTrashClassify, NULL);
1962 
1963     return s32Ret;
1964 }
1965 
HandClassifyAiThreadProcess(HI_VOID)1966 static HI_S32 HandClassifyAiThreadProcess(HI_VOID)
1967 {
1968     HI_S32 s32Ret;
1969     if (snprintf_s(acThreadName, BUFFER_SIZE, BUFFER_SIZE - 1, "AIProcess") < 0) {
1970         HI_ASSERT(0);
1971     }
1972     prctl(PR_SET_NAME, (unsigned long)acThreadName, 0, 0, 0);
1973     s32Ret = pthread_create(&g_aiProcessThread, NULL, GetVpssChnFrameHandClassify, NULL);
1974 
1975     return s32Ret;
1976 }
1977 
PauseDoUnloadCnnModel(HI_VOID)1978 static HI_S32 PauseDoUnloadCnnModel(HI_VOID)
1979 {
1980     HI_S32 s32Ret = HI_SUCCESS;
1981 
1982     if (GetCfgBool("trash_classify_switch:support_trash_classify", true)) {
1983         if (memset_s(&g_workPlug, sizeof(g_workPlug), 0x00, sizeof(g_workPlug)) != EOK) {
1984             HI_ASSERT(0);
1985         }
1986         /*
1987          * 退出运行时,应卸载模型
1988          * When exiting the operation, the model should be unloaded
1989          */
1990         s32Ret = CnnTrashClassifyUnloadModel(g_workPlug.model);
1991         SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "unload cnn trash classify model err:%x\n", s32Ret);
1992         ConfBaseExt();
1993         g_num = 0;
1994         OsdsClear(g_aicMediaInfo.osds);
1995         OsdsDestroy(g_aicMediaInfo.osds);
1996     }
1997 
1998     return s32Ret;
1999 }
2000 
PauseDoUnloadHandClassifyModel(HI_VOID)2001 static HI_S32 PauseDoUnloadHandClassifyModel(HI_VOID)
2002 {
2003     HI_S32 s32Ret = HI_SUCCESS;
2004 
2005     if (GetCfgBool("hand_classify_switch:support_hand_classify", true)) {
2006         if (memset_s(&g_workPlug, sizeof(g_workPlug), 0x00, sizeof(g_workPlug)) != EOK) {
2007             HI_ASSERT(0);
2008         }
2009         /*
2010          * 退出运行时,应卸载模型
2011          * When exiting the operation, the model should be unloaded
2012          */
2013         s32Ret = Yolo2HandDetectResnetClassifyUnload(g_workPlug.model);
2014         SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "unload hand model err:%x\n", s32Ret);
2015         ConfBaseExt();
2016         g_num = 0;
2017     }
2018 
2019     return s32Ret;
2020 }
2021 
2022 /*
2023  * 将sensor采集到数据显示到液晶屏上,同时创建线程运行垃圾分类推理计算
2024  * 视频输入->视频处理子系统->视频输出->显示屏
2025  *
2026  * Display the data collected by the sensor on the LCD screen,
2027  * and at the same time create a thread to run trash classification reasoning calculations
2028  * VI->VPSS->VO->MIPI
2029  */
SAMPLE_MEDIA_CNN_TRASH_CLASSIFY(HI_VOID)2030 HI_S32 SAMPLE_MEDIA_CNN_TRASH_CLASSIFY(HI_VOID)
2031 {
2032     HI_S32             s32Ret;
2033     HI_S32             fd = 0;
2034 
2035     /*
2036      * 配置VI参数
2037      * Config VI parameter
2038      */
2039     ViPramCfg();
2040 
2041     /*
2042      * 通过Sensor型号获取enPicSize
2043      * Obtain enPicSize through the Sensor type
2044      */
2045     s32Ret = SAMPLE_COMM_VI_GetSizeBySensor(g_aicMediaInfo.viCfg.astViInfo[0].stSnsInfo.enSnsType,
2046         &g_aicMediaInfo.enPicSize);
2047     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "get pic size by sensor fail, s32Ret=%#x\n", s32Ret);
2048 
2049     /*
2050      * 根据enPicSize,得到图片的宽高
2051      * Get picture size(w*h), according enPicSize
2052      */
2053     s32Ret = SAMPLE_COMM_SYS_GetPicSize(g_aicMediaInfo.enPicSize, &g_aicMediaInfo.stSize);
2054     SAMPLE_PRT("AIC: snsMaxSize=%ux%u\n", g_aicMediaInfo.stSize.u32Width, g_aicMediaInfo.stSize.u32Height);
2055     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "get picture size failed, s32Ret=%#x\n", s32Ret);
2056 
2057     /*
2058      * 配置VB参数
2059      * Config VB parameter
2060      */
2061     StVbParamCfg(&g_aicMediaInfo.vbCfg);
2062 
2063     /*
2064      * 视频缓存池初始化以及MPI系统初始化
2065      * VB init & MPI system init
2066      */
2067     s32Ret = SAMPLE_COMM_SYS_Init(&g_aicMediaInfo.vbCfg);
2068     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "system init failed, s32Ret=%#x\n", s32Ret);
2069 
2070     /*
2071      * 设置VO至MIPI通路,获取MIPI设备
2072      * Set VO config to MIPI, get MIPI device
2073      */
2074     s32Ret = SAMPLE_VO_CONFIG_MIPI(&fd);
2075     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, EXIT, "CONFIG MIPI FAIL.s32Ret:0x%x\n", s32Ret);
2076 
2077     /*
2078      * 配置VPSS参数
2079      * Config VPSS parameter
2080      */
2081     VpssParamCfg();
2082     s32Ret = ViVpssCreate(&g_aicMediaInfo.viSess, &g_aicMediaInfo.viCfg, &g_aicMediaInfo.vpssCfg);
2083     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, EXIT1, "ViVpss Sess create FAIL, ret=%#x\n", s32Ret);
2084     g_aicMediaInfo.vpssGrp = AIC_VPSS_GRP;
2085     g_aicMediaInfo.vpssChn0 = AIC_VPSS_ZOUT_CHN;
2086 
2087     /*
2088      * 配置VO参数
2089      * Config VO parameter
2090      */
2091     StVoParamCfg(&g_aicMediaInfo.voCfg);
2092 
2093     /*
2094      * 启动VO到MIPI lcd通路
2095      * Start VO to MIPI lcd
2096      */
2097     s32Ret = SampleCommVoStartMipi(&g_aicMediaInfo.voCfg);
2098     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, EXIT1, "start vo FAIL. s32Ret: 0x%x\n", s32Ret);
2099 
2100     /*
2101      * VPSS绑定VO
2102      * VPSS bind VO
2103      */
2104     s32Ret = SAMPLE_COMM_VPSS_Bind_VO(g_aicMediaInfo.vpssGrp, g_aicMediaInfo.vpssChn0, g_aicMediaInfo.voCfg.VoDev, 0);
2105     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, EXIT2, "vo bind vpss FAIL. s32Ret: 0x%x\n", s32Ret);
2106     SAMPLE_PRT("vpssGrp:%d, vpssChn:%d\n", g_aicMediaInfo.vpssGrp, g_aicMediaInfo.vpssChn0);
2107 
2108     /*
2109      * 创建工作线程运行ai
2110      * Create work thread to run ai
2111      */
2112     s32Ret = CnnTrashAiThreadProcess();
2113     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "ai proccess thread creat fail:%s\n", strerror(s32Ret));
2114     Pause();
2115     g_bAiProcessStopSignal = HI_TRUE;
2116     /*
2117      * 等待一个线程结束,线程间同步的操作
2118      * Waiting for the end of a thread, the operation of synchronization between threads
2119      */
2120     pthread_join(g_aiProcessThread, NULL);
2121     g_aiProcessThread = 0;
2122     PauseDoUnloadCnnModel();
2123 
2124     SAMPLE_COMM_VPSS_UnBind_VO(g_aicMediaInfo.vpssGrp, g_aicMediaInfo.vpssChn0, g_aicMediaInfo.voCfg.VoDev, 0);
2125     SAMPLE_VO_DISABLE_MIPITx(fd);
2126     SampleCloseMipiTxFd(fd);
2127     system("echo 0 > /sys/class/gpio/gpio55/value");
2128 
2129 EXIT2:
2130     SAMPLE_COMM_VO_StopVO(&g_aicMediaInfo.voCfg);
2131 EXIT1:
2132     VpssStop(&g_aicMediaInfo.vpssCfg);
2133     SAMPLE_COMM_VI_UnBind_VPSS(g_aicMediaInfo.viCfg.astViInfo[0].stPipeInfo.aPipe[0],
2134         g_aicMediaInfo.viCfg.astViInfo[0].stChnInfo.ViChn, g_aicMediaInfo.vpssGrp);
2135     ViStop(&g_aicMediaInfo.viCfg);
2136     free(g_aicMediaInfo.viSess);
2137 EXIT:
2138     SAMPLE_COMM_SYS_Exit();
2139     return s32Ret;
2140 }
2141 
2142 /*
2143  * 将sensor采集到数据显示到液晶屏上,同时创建线程运行手部检测和手势分类推理计算
2144  * 视频输入->视频处理子系统->视频输出->显示屏
2145  *
2146  * Display the data collected by the sensor on the LCD screen,
2147  * and create threads to run hand detection and gesture classification reasoning calculations
2148  * VI->VPSS->VO->MIPI
2149  */
SAMPLE_MEDIA_HAND_CLASSIFY(HI_VOID)2150 HI_S32 SAMPLE_MEDIA_HAND_CLASSIFY(HI_VOID)
2151 {
2152     HI_S32             s32Ret;
2153     HI_S32             fd = 0;
2154 
2155     /*
2156      * 配置VI参数
2157      * Config VI parameter
2158      */
2159     ViPramCfg();
2160 
2161     /*
2162      * 通过Sensor型号获取enPicSize
2163      * Obtain enPicSize through the Sensor type
2164      */
2165     s32Ret = SAMPLE_COMM_VI_GetSizeBySensor(g_aicMediaInfo.viCfg.astViInfo[0].stSnsInfo.enSnsType,
2166         &g_aicMediaInfo.enPicSize);
2167     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "get pic size by sensor fail, s32Ret=%#x\n", s32Ret);
2168 
2169     /*
2170      * 根据enPicSize,得到图片的宽高
2171      * Get picture size(w*h), according enPicSize
2172      */
2173     s32Ret = SAMPLE_COMM_SYS_GetPicSize(g_aicMediaInfo.enPicSize, &g_aicMediaInfo.stSize);
2174     SAMPLE_PRT("AIC: snsMaxSize=%ux%u\n", g_aicMediaInfo.stSize.u32Width, g_aicMediaInfo.stSize.u32Height);
2175     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "get picture size failed, s32Ret=%#x\n", s32Ret);
2176 
2177     /*
2178      * 配置VB参数
2179      * Config VB parameter
2180      */
2181     StVbParamCfg(&g_aicMediaInfo.vbCfg);
2182 
2183     /*
2184      * 视频缓存池初始化以及MPI系统初始化
2185      * VB init & MPI system init
2186      */
2187     s32Ret = SAMPLE_COMM_SYS_Init(&g_aicMediaInfo.vbCfg);
2188     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "system init failed, s32Ret=%#x\n", s32Ret);
2189 
2190     /*
2191      * 设置VO至MIPI通路,获取MIPI设备
2192      * Set VO config to MIPI, get MIPI device
2193      */
2194     s32Ret = SAMPLE_VO_CONFIG_MIPI(&fd);
2195     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, EXIT, "CONFIG MIPI FAIL.s32Ret:0x%x\n", s32Ret);
2196 
2197     /*
2198      * 配置VPSS参数
2199      * Config VPSS parameter
2200      */
2201     VpssParamCfg();
2202     s32Ret = ViVpssCreate(&g_aicMediaInfo.viSess, &g_aicMediaInfo.viCfg, &g_aicMediaInfo.vpssCfg);
2203     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, EXIT1, "ViVpss Sess create FAIL, ret=%#x\n", s32Ret);
2204     g_aicMediaInfo.vpssGrp = AIC_VPSS_GRP;
2205     g_aicMediaInfo.vpssChn0 = AIC_VPSS_ZOUT_CHN;
2206 
2207     /*
2208      * 配置VO参数
2209      * Config VO parameter
2210      */
2211     StVoParamCfg(&g_aicMediaInfo.voCfg);
2212 
2213     /*
2214      * 启动VO到MIPI lcd通路
2215      * Start VO to MIPI lcd
2216      */
2217     s32Ret = SampleCommVoStartMipi(&g_aicMediaInfo.voCfg);
2218     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, EXIT1, "start vo FAIL. s32Ret: 0x%x\n", s32Ret);
2219 
2220     /*
2221      * VPSS绑定VO
2222      * VPSS bind VO
2223      */
2224     s32Ret = SAMPLE_COMM_VPSS_Bind_VO(g_aicMediaInfo.vpssGrp, g_aicMediaInfo.vpssChn0, g_aicMediaInfo.voCfg.VoDev, 0);
2225     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, EXIT2, "vo bind vpss FAIL. s32Ret: 0x%x\n", s32Ret);
2226     SAMPLE_PRT("vpssGrp:%d, vpssChn:%d\n", g_aicMediaInfo.vpssGrp, g_aicMediaInfo.vpssChn0);
2227 
2228     /*
2229      * 创建工作线程运行ai
2230      * Create work thread to run ai
2231      */
2232     s32Ret = HandClassifyAiThreadProcess();
2233     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "ai proccess thread creat fail:%s\n", strerror(s32Ret));
2234 
2235     Pause();
2236     g_bAiProcessStopSignal = HI_TRUE;
2237     /*
2238      * 等待一个线程结束,线程间同步的操作
2239      * Waiting for the end of a thread, the operation of synchronization between threads
2240      */
2241     pthread_join(g_aiProcessThread, NULL);
2242     g_aiProcessThread = 0;
2243     PauseDoUnloadHandClassifyModel();
2244 
2245     SAMPLE_COMM_VPSS_UnBind_VO(g_aicMediaInfo.vpssGrp, g_aicMediaInfo.vpssChn0, g_aicMediaInfo.voCfg.VoDev, 0);
2246     SAMPLE_VO_DISABLE_MIPITx(fd);
2247     SampleCloseMipiTxFd(fd);
2248     system("echo 0 > /sys/class/gpio/gpio55/value");
2249 
2250 EXIT2:
2251     SAMPLE_COMM_VO_StopVO(&g_aicMediaInfo.voCfg);
2252 EXIT1:
2253     VpssStop(&g_aicMediaInfo.vpssCfg);
2254     SAMPLE_COMM_VI_UnBind_VPSS(g_aicMediaInfo.viCfg.astViInfo[0].stPipeInfo.aPipe[0],
2255         g_aicMediaInfo.viCfg.astViInfo[0].stChnInfo.ViChn, g_aicMediaInfo.vpssGrp);
2256     ViStop(&g_aicMediaInfo.viCfg);
2257     free(g_aicMediaInfo.viSess);
2258 EXIT:
2259     SAMPLE_COMM_SYS_Exit();
2260     return s32Ret;
2261 }
2262 
2263 #ifdef __cplusplus
2264 #if __cplusplus
2265 }
2266 #endif
2267 #endif /* End of #ifdef __cplusplus */
2268