• 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 <string.h>
17 #include <sys/prctl.h>
18 #include <pthread.h>
19 #include <errno.h>
20 #include <unistd.h>
21 #include "mpi_vi.h"
22 #include "mpi_vpss.h"
23 #include "mpi_venc.h"
24 #include "mpi_vo.h"
25 #include "mpi_region.h"
26 #include "sample_comm_ive.h"
27 #include "sample_media_ai.h"
28 #include "vgs_img.h"
29 #include "osd_img.h"
30 
31 /* OSD font library */
32 static const HI_U8 G_FONT_LIB[] __attribute__((aligned(4))) = {
33 #include "simsunb_16x32.txt"
34 };
35 
36 #ifdef __cplusplus
37 #if __cplusplus
38 extern "C" {
39 #endif
40 #endif /* End of #ifdef __cplusplus */
41 
42 #define OSD_FONT_WIDTH_DEF      40 // Default font width
43 #define OSD_FONT_HEIGHT_DEF     40 // The default font height
44 #define NOASCII_CHARACTER_BYTES  (2) /* Number of bytes occupied by each Chinese character */
45 #define BYTE_BITS (8)
46 
47 #define OSD_FONT_ASC
48 #define OSD_FONT_MOD_W          16
49 #define OSD_FONT_MOD_H          32
50 #define X_COORDINATE            100
51 #define Y_COORDINATE            100
52 #define BASE_YAER               1900
53 #define MULTIPLE_NUM            100
54 
55 /*
56  * Global object.
57  * Multiple OsdSet instances will allocate ids from the global pool.
58  */
59 static void* g_osdHndPool[HI_OSD_MAX_CNT]; // Used to identify whether the index handle is used
60 static pthread_mutex_t g_osdMutex; // pool access lock
61 /* OSD Parameter Array */
62 static OSD_PARAM_S s_stOSDParam[HI_OSD_MAX_CNT];
63 
64 /* OSD Module Init Flag
65  * Canbe modified only by HI_PDT_OSD_Init/HI_PDT_OSD_DeInit
66  */
67 static HI_BOOL s_bOSDInitFlg = HI_FALSE;
68 
69 /* OSD Fonts Lib, inited by HI_PDT_OSD_Init */
70 static HI_OSD_FONTS_S s_stOSDFonts;
71 
72 /** OSD Time Update Runing Flag
73       Canbe modified only by HI_PDT_OSD_Init/HI_PDT_OSD_DeInit */
74 static HI_BOOL s_bOSDTimeRun = HI_FALSE;
75 
76 /* Time OSD Update Task Thread ID, created by HI_PDT_OSD_Init, destroyed by HI_OSD_DeInit */
77 static pthread_t s_OSDTimeTskId = 0;
78 
79 static HI_OSD_TEXTBITMAP_S s_stOSDTextBitMap;
80 
81 static HI_U8* FontMod = NULL;
82 static HI_S32 FontModLen = 0;
83 
84 /* Bitmap Row/Col Index */
85 static HI_S32 s32BmRow;
86 static HI_S32 s32BmCol;
87 struct tm stTime = {0};
88 
89 /* OSD Font Step In Lib, in bytes */
90 #define OSD_LIB_FONT_W (s_stOSDFonts.u32FontWidth)
91 #define OSD_LIB_FONT_H (s_stOSDFonts.u32FontHeight)
92 #define OSD_LIB_FONT_STEP (OSD_LIB_FONT_W * OSD_LIB_FONT_H / BYTE_BITS)
93 
94 /* Value Align */
HiAppcommAlign(HI_S32 value,HI_S32 base)95 HI_S32 HiAppcommAlign(HI_S32 value, HI_S32 base)
96 {
97     return (((value) + (base)-1) / (base) * (base));
98 }
99 
max(HI_U32 a,HI_U32 b)100 HI_U32 max(HI_U32 a, HI_U32 b)
101 {
102     return (((a) < (b)) ? (b) : (a));
103 }
104 
min(HI_U32 a,HI_U32 b)105 HI_U32 min(HI_U32 a, HI_U32 b)
106 {
107     return (((a) > (b)) ? (b) : (a));
108 }
109 
IsAscii(HI_S32 a)110 HI_S32 IsAscii(HI_S32 a)
111 {
112     return (((a) >= 0x00 && (a) <= 0x7F) ? 1 : 0);
113 }
114 
OSD_GetNonASCNum(HI_CHAR * string,HI_S32 len)115 static HI_S32 OSD_GetNonASCNum(HI_CHAR* string, HI_S32 len)
116 {
117     HI_S32 i;
118     HI_S32 n = 0;
119     for (i = 0; i < len; i++) {
120         if (string[i] == '\0') {
121             break;
122         }
123         if (!IsAscii(string[i])) {
124             i++;
125             n++;
126         }
127     }
128     return n;
129 }
130 
131 /* Creat OsdSet */
OsdsCreate(HI_OSD_BIND_MOD_E bindMod,HI_U32 modHnd,HI_U32 chnHnd)132 OsdSet* OsdsCreate(HI_OSD_BIND_MOD_E bindMod, HI_U32 modHnd, HI_U32 chnHnd)
133 {
134     OsdSet *self = NULL;
135 
136     self = (OsdSet*)malloc(sizeof(*self));
137     if (!self) {
138         HI_ASSERT(0);
139     }
140     if (memset_s(self, sizeof(*self), 0, sizeof(*self)) != EOK) {
141         HI_ASSERT(0);
142     }
143 
144     self->bindMod = bindMod;
145     self->modHnd = modHnd;
146     self->chnHnd = chnHnd;
147     return self;
148 }
149 
150 /*
151  * @brief   get time string with given format
152  * @param[in]pstTime : time struct, get current system time if null
153  * @param[out]pazStr : time string buffer
154  * @param[in]s32Len : time string buffer length
155  */
OSD_GetTimeStr(struct tm * pstTime,HI_CHAR * pazStr,HI_S32 s32Len)156 static HI_VOID OSD_GetTimeStr(struct tm* pstTime, HI_CHAR* pazStr, HI_S32 s32Len)
157 {
158     /* Get Time */
159     time_t nowTime;
160 
161     if (!pstTime) {
162         time(&nowTime);
163         localtime_r(&nowTime, pstTime);
164     }
165 
166     /* Generate Time String */
167     if (snprintf_s(pazStr, s32Len, s32Len - 1, "%04d-%02d-%02d %02d:%02d:%02d",
168         pstTime->tm_year + BASE_YAER, pstTime->tm_mon + 1, pstTime->tm_mday,
169         pstTime->tm_hour, pstTime->tm_min, pstTime->tm_sec) < 0) {
170         HI_ASSERT(0);
171     }
172 
173     return;
174 }
175 
OSD_RGNDetach(RGN_HANDLE RgnHdl,const HI_OSD_DISP_ATTR_S * pstDispAttr)176 static HI_S32 OSD_RGNDetach(RGN_HANDLE RgnHdl, const HI_OSD_DISP_ATTR_S* pstDispAttr)
177 {
178     HI_S32 s32Ret = HI_SUCCESS;
179     MPP_CHN_S stChn;
180 
181     stChn.s32DevId = pstDispAttr->ModHdl;
182     stChn.s32ChnId = pstDispAttr->ChnHdl;
183     switch (pstDispAttr->enBindedMod) {
184         case HI_OSD_BINDMOD_VI:
185             stChn.enModId = HI_ID_VI;
186             break;
187         case HI_OSD_BINDMOD_VPSS:
188             stChn.enModId = HI_ID_VPSS;
189             break;
190         case HI_OSD_BINDMOD_AVS:
191             stChn.enModId = HI_ID_AVS;
192             break;
193         case HI_OSD_BINDMOD_VENC:
194             stChn.s32DevId = 0;
195             stChn.enModId = HI_ID_VENC;
196             break;
197         case HI_OSD_BINDMOD_VO:
198             stChn.enModId = HI_ID_VO;
199             break;
200         default:
201             SAMPLE_PRT("RgnHdl[%d] invalide bind mode [%d]\n", RgnHdl, pstDispAttr->enBindedMod);
202             return HI_EINVAL;
203     }
204 
205     s32Ret = HI_MPI_RGN_DetachFromChn(RgnHdl, &stChn);
206     if (s32Ret != HI_SUCCESS) {
207         SAMPLE_PRT("HI_MPI_RGN_DetachFromChn fail,RgnHdl[%d] stChn[%d,%d,%d] Error Code: [0x%08X]\n",
208             RgnHdl, stChn.enModId, stChn.s32DevId, stChn.s32ChnId, s32Ret);
209         return s32Ret;
210     }
211 
212     return HI_SUCCESS;
213 }
214 
OSD_DestroyRGN(RGN_HANDLE RgnHdl,const HI_OSD_ATTR_S * pstAttr)215 static HI_S32 OSD_DestroyRGN(RGN_HANDLE RgnHdl, const HI_OSD_ATTR_S* pstAttr)
216 {
217     HI_S32 s32Ret = HI_SUCCESS;
218     HI_S32 s32DispIdx = 0;
219 
220     for (s32DispIdx = 0; s32DispIdx < pstAttr->u32DispNum ; ++s32DispIdx) {
221         if (pstAttr->astDispAttr[s32DispIdx].bShow) {
222             OSD_RGNDetach(RgnHdl, &pstAttr->astDispAttr[s32DispIdx]);
223         }
224     }
225 
226     s32Ret = HI_MPI_RGN_Destroy(RgnHdl);
227     if (s32Ret != HI_SUCCESS) {
228         SAMPLE_PRT("HI_MPI_RGN_Destroy fail, RgnHdl[%d] Error Code: [0x%08X]\n", RgnHdl, s32Ret);
229         return s32Ret;
230     }
231 
232     return HI_SUCCESS;
233 }
234 
235 /* Create a region in OsdSet */
OsdsCreateRgn(OsdSet * self)236 int OsdsCreateRgn(OsdSet* self)
237 {
238     HI_ASSERT(self);
239     int ret = -1;
240 
241     MutexLock(&g_osdMutex);
242     for (int i = 0; i < HI_OSD_MAX_CNT; i++) {
243         if (!g_osdHndPool[i]) {
244             g_osdHndPool[i] = self;
245             ret = i;
246             break;
247         }
248     }
249     MutexUnlock(&g_osdMutex);
250     return ret;
251 }
252 
OSD_Stop(HI_S32 s32OsdIdx)253 static HI_S32 OSD_Stop(HI_S32 s32OsdIdx)
254 {
255     HI_S32 s32Ret = HI_SUCCESS;
256     OSD_PARAM_S* pstOsdParam = &s_stOSDParam[s32OsdIdx];
257 
258     if (!pstOsdParam->bOn) {
259         return HI_SUCCESS;
260     }
261 
262     s32Ret = OSD_DestroyRGN(s32OsdIdx, &pstOsdParam->stAttr);
263     if (s32Ret != HI_SUCCESS) {
264         SAMPLE_PRT("OSD_DestroyRGN s32OsdIdx[%d] failed:[0x%08X]\n", s32OsdIdx, s32Ret);
265         return s32Ret;
266     }
267 
268     pstOsdParam->bOn = HI_FALSE;
269     return HI_SUCCESS;
270 }
271 
272 /*
273  * @brief    stop osd by index.
274  * @param[in] s32OsdIdx:osd index, range[0,HI_OSD_MAX_CNT)
275  * @return 0 success,non-zero error code.
276  */
HI_OSD_Stop(HI_S32 s32OsdIdx)277 HI_S32 HI_OSD_Stop(HI_S32 s32OsdIdx)
278 {
279     /* Check Module Init or not */
280     HI_ASSERT(HI_TRUE == s_bOSDInitFlg);
281     /* Check Input Param */
282     HI_ASSERT(s32OsdIdx >= 0);
283     HI_ASSERT(HI_OSD_MAX_CNT > s32OsdIdx);
284 
285     HI_S32 s32Ret = HI_SUCCESS;
286     OSD_PARAM_S* pstOsdParam = &s_stOSDParam[s32OsdIdx];
287 
288     pthread_mutex_lock(&pstOsdParam->mutexLock);
289 
290     /* Check OSD Attrbute init or not */
291     if (!pstOsdParam->bInit) {
292         pthread_mutex_unlock(&pstOsdParam->mutexLock);
293         return HI_SUCCESS;
294     }
295 
296     /* Check OSD stop or not */
297     if (!pstOsdParam->bOn) {
298         pthread_mutex_unlock(&pstOsdParam->mutexLock);
299         return HI_SUCCESS;
300     }
301 
302     s32Ret = OSD_Stop(s32OsdIdx);
303     pstOsdParam->stMaxSize.u32Width = 0;
304     pstOsdParam->stMaxSize.u32Height= 0;
305     pthread_mutex_unlock(&pstOsdParam->mutexLock);
306     return s32Ret;
307 }
308 
309 /* Destroy the region specified in the OsdSet */
OsdsDestroyRgn(OsdSet * self,int rgnHnd)310 void OsdsDestroyRgn(OsdSet* self, int rgnHnd)
311 {
312     HI_ASSERT(self);
313     HI_ASSERT(rgnHnd >= 0 && rgnHnd < HI_OSD_MAX_CNT);
314 
315     MutexLock(&g_osdMutex);
316     HI_ASSERT(g_osdHndPool[rgnHnd] && g_osdHndPool[rgnHnd] == (void*)self);
317     g_osdHndPool[rgnHnd] = NULL;
318     MutexUnlock(&g_osdMutex);
319 
320     HI_OSD_Stop(rgnHnd);
321 }
322 
323 /* Destroy all regions in OsdSet */
OsdsClear(OsdSet * self)324 void OsdsClear(OsdSet* self)
325 {
326     MutexLock(&g_osdMutex);
327     for (int i = 0; i < HI_OSD_MAX_CNT; i++) {
328         if (g_osdHndPool[i] && g_osdHndPool[i] == (void*)self) {
329             OsdsDestroyRgn(self, i);
330         }
331     }
332     MutexUnlock(&g_osdMutex);
333 }
334 
335 /* Destory OsdSet */
OsdsDestroy(OsdSet * self)336 void OsdsDestroy(OsdSet* self)
337 {
338     HI_ASSERT(self);
339     OsdsClear(self);
340     free(self);
341 }
342 
343 /* Set the attribute value of the text region */
TxtRgnInit(HI_OSD_ATTR_S * rgnAttr,const char * str,uint32_t begX,uint32_t begY,uint32_t color)344 int TxtRgnInit(HI_OSD_ATTR_S* rgnAttr, const char* str, uint32_t begX, uint32_t begY, uint32_t color)
345 {
346     HI_ASSERT(rgnAttr);
347     if (!str) {
348         HI_ASSERT(0);
349     }
350     // 64:[0,128], the transparency of the text background block, the larger the background block color,
351     // the darker the background block color, 0 means no background block, that is, completely transparent
352     static const uint32_t bgAlpha = 64;
353     // 128:[0,128], the brightness of the text, the larger the value, the brighter the text
354     static const uint32_t fgAlpha = 128;
355 
356     if (memset_s(rgnAttr, sizeof(*rgnAttr), 0, sizeof(*rgnAttr)) != EOK) {
357         HI_ASSERT(0);
358     }
359     rgnAttr->u32DispNum = 1;
360     rgnAttr->astDispAttr[0].bShow = (str && *str) ? HI_TRUE : HI_FALSE;
361     rgnAttr->astDispAttr[0].enBindedMod = HI_OSD_BINDMOD_BUTT;
362     rgnAttr->astDispAttr[0].ChnHdl = UINT32_MAX;
363     rgnAttr->astDispAttr[0].u32BgAlpha = bgAlpha;
364     rgnAttr->astDispAttr[0].u32FgAlpha = fgAlpha;
365     rgnAttr->astDispAttr[0].enCoordinate = HI_OSD_COORDINATE_ABS_COOR;
366     rgnAttr->astDispAttr[0].stStartPos.s32X = begX;
367     rgnAttr->astDispAttr[0].stStartPos.s32Y = begY;
368     rgnAttr->astDispAttr[0].enAttachDest = ATTACH_JPEG_MAIN;
369     rgnAttr->stContent.enType = HI_OSD_TYPE_STRING;
370     rgnAttr->stContent.u32Color = color; // ARGB #FFFF0000 Red
371     HiStrxfrm(rgnAttr->stContent.szStr, str, sizeof(rgnAttr->stContent.szStr));
372     rgnAttr->stContent.stFontSize.u32Width = OSD_FONT_WIDTH_DEF;
373     rgnAttr->stContent.stFontSize.u32Height = OSD_FONT_HEIGHT_DEF;
374     return 0;
375 }
376 
OSD_Ratio2Absolute(MPP_CHN_S stChn,const POINT_S * pstRatioCoor,POINT_S * pstAbsCoor)377 static HI_S32 OSD_Ratio2Absolute(MPP_CHN_S stChn, const POINT_S* pstRatioCoor, POINT_S* pstAbsCoor)
378 {
379     HI_S32 s32Ret = HI_SUCCESS;
380     SIZE_S stImageSize;
381 
382     if (pstRatioCoor->s32X < 0 || pstRatioCoor->s32X > X_COORDINATE ||
383         pstRatioCoor->s32Y < 0 || pstRatioCoor->s32Y > Y_COORDINATE) {
384         SAMPLE_PRT("invalide Ratio coordinate(%d,%d)\n", pstRatioCoor->s32X, pstRatioCoor->s32Y);
385         return HI_EINVAL;
386     }
387     switch (stChn.enModId) {
388         case HI_ID_VI: {
389             VI_CHN_ATTR_S stChnAttr;
390             s32Ret = HI_MPI_VI_GetChnAttr(stChn.s32DevId, stChn.s32ChnId, &stChnAttr);
391             if (s32Ret != HI_SUCCESS) {
392                 SAMPLE_PRT("HI_MPI_VI_GetChnAttr(%d,%d) fail,Error Code: [0x%08X]\n",
393                     stChn.s32DevId, stChn.s32ChnId, s32Ret);
394                 return s32Ret;
395             }
396             stImageSize = stChnAttr.stSize;
397             break;
398         }
399         case HI_ID_VPSS: {
400             VPSS_CHN_ATTR_S stChnAttr;
401             s32Ret = HI_MPI_VPSS_GetChnAttr(stChn.s32DevId, stChn.s32ChnId, &stChnAttr);
402             if (s32Ret != HI_SUCCESS) {
403                 SAMPLE_PRT("HI_MPI_VPSS_GetChnAttr(%d,%d) fail, Error Code: [0x%08X]\n",
404                     stChn.s32DevId, stChn.s32ChnId, s32Ret);
405                 return s32Ret;
406             }
407             stImageSize.u32Width = stChnAttr.u32Width;
408             stImageSize.u32Height = stChnAttr.u32Height;
409             break;
410         }
411         case HI_ID_VO: {
412             VO_CHN_ATTR_S stChnAttr;
413             s32Ret = HI_MPI_VO_GetChnAttr(stChn.s32DevId, stChn.s32ChnId, &stChnAttr);
414             if (s32Ret != HI_SUCCESS) {
415                 SAMPLE_PRT("HI_MPI_VO_GetChnAttr(%d,%d) fail,Error Code: [0x%08X]\n",
416                     stChn.s32DevId, stChn.s32ChnId, s32Ret);
417                 return s32Ret;
418             }
419             stImageSize.u32Width = stChnAttr.stRect.u32Width;
420             stImageSize.u32Height = stChnAttr.stRect.u32Height;
421             break;
422         }
423         default:
424             SAMPLE_PRT("invalide mode id [%d]\n", stChn.enModId);
425             return HI_EINVAL;
426     }
427 
428     // 2: HiAppcommAlign api base param
429     pstAbsCoor->s32X = HiAppcommAlign(stImageSize.u32Width * pstRatioCoor->s32X / MULTIPLE_NUM, 2);
430     // 2: HiAppcommAlign api base param
431     pstAbsCoor->s32Y = HiAppcommAlign(stImageSize.u32Height * pstRatioCoor->s32Y / MULTIPLE_NUM, 2);
432     return HI_SUCCESS;
433 }
434 
OSD_Update(RGN_HANDLE RgnHdl,const HI_OSD_ATTR_S * pstAttr)435 static HI_S32 OSD_Update(RGN_HANDLE RgnHdl, const HI_OSD_ATTR_S* pstAttr)
436 {
437     HI_S32 s32Ret = HI_SUCCESS;
438     HI_S32 s32DispIdx = 0;
439     RGN_CHN_ATTR_S stRgnChnAttr;
440     MPP_CHN_S stChn;
441 
442     for (s32DispIdx = 0; s32DispIdx < pstAttr->u32DispNum ; ++s32DispIdx) {
443         if (!pstAttr->astDispAttr[s32DispIdx].bShow) {
444             /* not no show,no need to update */
445             continue;
446         }
447 
448         stChn.s32DevId = pstAttr->astDispAttr[s32DispIdx].ModHdl;
449         stChn.s32ChnId = pstAttr->astDispAttr[s32DispIdx].ChnHdl;
450         switch (pstAttr->astDispAttr[s32DispIdx].enBindedMod) {
451             case HI_OSD_BINDMOD_VI:
452                 stChn.enModId = HI_ID_VI;
453                 break;
454             case HI_OSD_BINDMOD_VPSS:
455                 stChn.enModId = HI_ID_VPSS;
456                 break;
457             case HI_OSD_BINDMOD_VO:
458                 stChn.enModId = HI_ID_VO;
459                 break;
460             default:
461                 SAMPLE_PRT("invalide bind mode [%d]\n", pstAttr->astDispAttr[s32DispIdx].enBindedMod);
462                 return HI_EINVAL;
463         }
464 
465         s32Ret = HI_MPI_RGN_GetDisplayAttr(RgnHdl, &stChn, &stRgnChnAttr);
466         SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "GetDisplayAttr fail, s32Ret:[0x%08X]\n", s32Ret);
467 
468         stRgnChnAttr.bShow = pstAttr->astDispAttr[s32DispIdx].bShow;
469         POINT_S stStartPos;
470         if (pstAttr->astDispAttr[s32DispIdx].enCoordinate == HI_OSD_COORDINATE_RATIO_COOR) {
471             s32Ret = OSD_Ratio2Absolute(stChn, &pstAttr->astDispAttr[s32DispIdx].stStartPos, &stStartPos);
472             SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Ratio2Absolute fail, s32Ret:[0x%08X]\n", s32Ret);
473         } else {
474             stStartPos = pstAttr->astDispAttr[s32DispIdx].stStartPos;
475         }
476 
477         if (stRgnChnAttr.enType == OVERLAYEX_RGN) {
478             stRgnChnAttr.unChnAttr.stOverlayExChn.stPoint.s32X = stStartPos.s32X;
479             stRgnChnAttr.unChnAttr.stOverlayExChn.stPoint.s32Y = stStartPos.s32Y;
480             stRgnChnAttr.unChnAttr.stOverlayExChn.u32BgAlpha = pstAttr->astDispAttr[s32DispIdx].u32BgAlpha;
481             stRgnChnAttr.unChnAttr.stOverlayExChn.u32FgAlpha = pstAttr->astDispAttr[s32DispIdx].u32FgAlpha;
482         } else {
483             stRgnChnAttr.unChnAttr.stOverlayChn.stPoint.s32X = stStartPos.s32X;
484             stRgnChnAttr.unChnAttr.stOverlayChn.stPoint.s32Y = stStartPos.s32Y;
485             stRgnChnAttr.unChnAttr.stOverlayChn.u32BgAlpha = pstAttr->astDispAttr[s32DispIdx].u32BgAlpha;
486             stRgnChnAttr.unChnAttr.stOverlayChn.u32FgAlpha = pstAttr->astDispAttr[s32DispIdx].u32FgAlpha;
487         }
488 
489         s32Ret = HI_MPI_RGN_SetDisplayAttr(RgnHdl, &stChn, &stRgnChnAttr);
490         SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "SetDisplayAttr fail, s32Ret:[0x%08X]\n", s32Ret);
491     }
492 
493     return HI_SUCCESS;
494 }
495 
OSD_PuBmData_Cal(HI_OSD_CONTENT_S * pstContent,HI_U16 * puBmData,HI_S32 s32HexOffset,HI_S32 s32BmDataIdx,HI_S32 s32BitOffset)496 HI_VOID OSD_PuBmData_Cal(HI_OSD_CONTENT_S* pstContent, HI_U16* puBmData, HI_S32 s32HexOffset,
497     HI_S32 s32BmDataIdx, HI_S32 s32BitOffset)
498 {
499     HI_U8 temp = FontMod[s32HexOffset];
500     if ((temp >> ((BYTE_BITS - 1) - s32BitOffset)) & 0x1) {
501         puBmData[s32BmDataIdx] = (HI_U16)pstContent->u32Color;
502     } else {
503         puBmData[s32BmDataIdx] = (HI_U16)pstContent->u32BgColor;
504     }
505 
506     return;
507 }
508 
OSD_Bitmap_Cal(HI_OSD_CONTENT_S * pstContent,HI_S32 NonASCNum,HI_U16 * puBmData)509 HI_S32 OSD_Bitmap_Cal(HI_OSD_CONTENT_S* pstContent, HI_S32 NonASCNum, HI_U16* puBmData)
510 {
511     HI_S32 NonASCShow = 0;
512     for (s32BmCol = 0; s32BmCol < pstContent->stBitmap.u32Width; ++s32BmCol) {
513         /* Bitmap Data Offset for the point */
514         HI_S32 s32BmDataIdx = s32BmRow * s_stOSDTextBitMap.stCanvasInfo.u32Stride / 2 + s32BmCol;
515         /* Character Index in Text String */
516         HI_S32 s32CharIdx = s32BmCol / pstContent->stFontSize.u32Width;
517         HI_S32 s32StringIdx = s32CharIdx+NonASCShow * (NOASCII_CHARACTER_BYTES - 1);
518         if (NonASCNum > 0 && s32CharIdx > 0) {
519             NonASCShow = OSD_GetNonASCNum(pstContent->szStr, s32StringIdx);
520             s32StringIdx = s32CharIdx+NonASCShow * (NOASCII_CHARACTER_BYTES - 1);
521         }
522         /* Point Row/Col Index in Character */
523         HI_S32 s32CharCol = (s32BmCol - (pstContent->stFontSize.u32Width * s32CharIdx)) *
524             OSD_LIB_FONT_W / pstContent->stFontSize.u32Width;
525         HI_S32 s32CharRow = s32BmRow * OSD_LIB_FONT_H / pstContent->stFontSize.u32Height;
526         HI_S32 s32HexOffset = s32CharRow * OSD_LIB_FONT_W / BYTE_BITS + s32CharCol / BYTE_BITS;
527         HI_S32 s32BitOffset = s32CharCol % BYTE_BITS;
528 
529         if (s_stOSDFonts.pfnGetFontMod(&pstContent->szStr[s32StringIdx], &FontMod, &FontModLen)
530             == HI_SUCCESS) {
531             if (FontMod != NULL && s32HexOffset < FontModLen) {
532                 OSD_PuBmData_Cal(pstContent, puBmData, s32HexOffset, s32BmDataIdx, s32BitOffset);
533                 continue;
534             }
535         }
536         SAMPLE_PRT("GetFontMod Fail\n");
537         return HI_FAILURE;
538     }
539 }
540 
OSD_Generate_Bitmap(RGN_HANDLE RgnHdl,HI_OSD_CONTENT_S * pstContent)541 HI_S32 OSD_Generate_Bitmap(RGN_HANDLE RgnHdl, HI_OSD_CONTENT_S* pstContent)
542 {
543     HI_S32 s32Ret;
544     HI_S32 s32StrLen = strnlen(pstContent->szStr, HI_OSD_MAX_STR_LEN);
545     HI_S32 NonASCNum = OSD_GetNonASCNum(pstContent->szStr, s32StrLen);
546 
547     s32Ret = HI_MPI_RGN_GetCanvasInfo(RgnHdl, &s_stOSDTextBitMap.stCanvasInfo);
548     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "RGN_GetCanvasInfo FAIL, s32Ret=%x\n", s32Ret);
549 
550     /* Generate Bitmap */
551     pstContent->stBitmap.u32Width = pstContent->stFontSize.u32Width *
552         (s32StrLen - NonASCNum * (NOASCII_CHARACTER_BYTES - 1));
553     pstContent->stBitmap.u32Height = pstContent->stFontSize.u32Height;
554     HI_U16* puBmData = (HI_U16*)(HI_UL)s_stOSDTextBitMap.stCanvasInfo.u64VirtAddr;
555 
556     for (s32BmRow = 0; s32BmRow < pstContent->stBitmap.u32Height; ++s32BmRow) {
557         OSD_Bitmap_Cal(pstContent, NonASCNum, puBmData);
558         for (s32BmCol = pstContent->stBitmap.u32Width;
559             s32BmCol < s_stOSDParam[RgnHdl].stMaxSize.u32Width; ++s32BmCol) {
560             HI_S32 s32BmDataIdx = s32BmRow * s_stOSDTextBitMap.stCanvasInfo.u32Stride / 2 + s32BmCol;
561             puBmData[s32BmDataIdx] = 0;
562         }
563     }
564 
565     for (s32BmRow = pstContent->stBitmap.u32Height;
566         s32BmRow < s_stOSDParam[RgnHdl].stMaxSize.u32Height; ++s32BmRow) {
567         for (s32BmCol = 0; s32BmCol < s_stOSDParam[RgnHdl].stMaxSize.u32Width; ++s32BmCol) {
568             HI_S32 s32BmDataIdx = s32BmRow * s_stOSDTextBitMap.stCanvasInfo.u32Stride / 2 + s32BmCol;
569             puBmData[s32BmDataIdx] = 0;
570         }
571     }
572 
573     return s32Ret;
574 }
575 
OSD_UpdateTextBitmap(RGN_HANDLE RgnHdl,HI_OSD_CONTENT_S * pstContent)576 static HI_S32 OSD_UpdateTextBitmap(RGN_HANDLE RgnHdl, HI_OSD_CONTENT_S* pstContent)
577 {
578     HI_S32 s32Ret = HI_SUCCESS;
579 
580     OSD_Generate_Bitmap(RgnHdl, pstContent);
581     s_stOSDTextBitMap.stCanvasInfo.enPixelFmt = PIXEL_FORMAT_ARGB_1555;
582     s_stOSDTextBitMap.stCanvasInfo.stSize.u32Width = pstContent->stBitmap.u32Width;
583     s_stOSDTextBitMap.stCanvasInfo.stSize.u32Height = pstContent->stBitmap.u32Height;
584 
585     s32Ret = HI_MPI_RGN_UpdateCanvas(RgnHdl);
586     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "RGN_UpdateCanvas FAIL, s32Ret=%x\n", s32Ret);
587 
588     return s32Ret;
589 }
590 
OSD_RGNAttach(RGN_HANDLE RgnHdl,const HI_OSD_DISP_ATTR_S * pstDispAttr)591 static HI_S32 OSD_RGNAttach(RGN_HANDLE RgnHdl, const HI_OSD_DISP_ATTR_S* pstDispAttr)
592 {
593     HI_S32 s32Ret = HI_SUCCESS;
594     RGN_CHN_ATTR_S stRgnChnAttr;
595     MPP_CHN_S stChn;
596 
597     stChn.s32DevId = pstDispAttr->ModHdl;
598     stChn.s32ChnId = pstDispAttr->ChnHdl;
599     memset_s(&stRgnChnAttr, sizeof(RGN_CHN_ATTR_S), 0x0, sizeof(RGN_CHN_ATTR_S));
600     stRgnChnAttr.bShow = pstDispAttr->bShow;
601     stRgnChnAttr.enType = OVERLAYEX_RGN;
602     switch (pstDispAttr->enBindedMod) {
603         case HI_OSD_BINDMOD_VI:
604             stChn.enModId = HI_ID_VI;
605             break;
606         case HI_OSD_BINDMOD_VPSS:
607             stChn.enModId = HI_ID_VPSS;
608             break;
609         case HI_OSD_BINDMOD_VO:
610             stChn.enModId = HI_ID_VO;
611             break;
612         default:
613             SAMPLE_PRT("RgnHdl[%d] invalide bind mode [%d]\n", RgnHdl, pstDispAttr->enBindedMod);
614             return HI_EINVAL;
615     }
616 
617     POINT_S stStartPos;
618     if (pstDispAttr->enCoordinate == HI_OSD_COORDINATE_RATIO_COOR) {
619         s32Ret = OSD_Ratio2Absolute(stChn, &pstDispAttr->stStartPos, &stStartPos);
620         SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Ratio2Absolute FAIL, s32Ret=%x\n", s32Ret);
621     } else {
622         stStartPos = pstDispAttr->stStartPos;
623     }
624 
625     if (stRgnChnAttr.enType == OVERLAYEX_RGN) {
626         stRgnChnAttr.unChnAttr.stOverlayExChn.stPoint.s32X = stStartPos.s32X;
627         stRgnChnAttr.unChnAttr.stOverlayExChn.stPoint.s32Y = stStartPos.s32Y;
628         stRgnChnAttr.unChnAttr.stOverlayExChn.u32BgAlpha = pstDispAttr->u32BgAlpha;
629         stRgnChnAttr.unChnAttr.stOverlayExChn.u32FgAlpha = pstDispAttr->u32FgAlpha;
630         stRgnChnAttr.unChnAttr.stOverlayExChn.u32Layer = 0;
631     } else {
632         stRgnChnAttr.unChnAttr.stOverlayChn.stPoint.s32X = stStartPos.s32X;
633         stRgnChnAttr.unChnAttr.stOverlayChn.stPoint.s32Y = stStartPos.s32Y;
634         stRgnChnAttr.unChnAttr.stOverlayChn.u32BgAlpha = pstDispAttr->u32BgAlpha;
635         stRgnChnAttr.unChnAttr.stOverlayChn.u32FgAlpha = pstDispAttr->u32FgAlpha;
636         stRgnChnAttr.unChnAttr.stOverlayChn.u32Layer = 0;
637     }
638 
639     s32Ret = HI_MPI_RGN_AttachToChn(RgnHdl, &stChn, &stRgnChnAttr);
640     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "RGN_AttachToChn FAIL, s32Ret=%x\n", s32Ret);
641 
642     return HI_SUCCESS;
643 }
644 
OSD_CreateRGN(RGN_HANDLE RgnHdl,const HI_OSD_ATTR_S * pstAttr)645 static HI_S32 OSD_CreateRGN(RGN_HANDLE RgnHdl, const HI_OSD_ATTR_S* pstAttr)
646 {
647     HI_S32 s32Ret = HI_SUCCESS;
648     HI_S32 s32DispIdx = 0;
649     RGN_ATTR_S stRgnAttr;
650     stRgnAttr.enType = OVERLAY_RGN;
651 
652     for (s32DispIdx = 0; s32DispIdx < pstAttr->u32DispNum ; ++s32DispIdx) {
653         if (pstAttr->astDispAttr[s32DispIdx].enBindedMod != HI_OSD_BINDMOD_VENC) {
654             stRgnAttr.enType = OVERLAYEX_RGN;
655             break;
656         }
657     }
658 
659     if (stRgnAttr.enType == OVERLAYEX_RGN) {
660         stRgnAttr.unAttr.stOverlayEx.enPixelFmt = PIXEL_FORMAT_ARGB_1555;
661         stRgnAttr.unAttr.stOverlayEx.u32BgColor = pstAttr->stContent.u32Color;
662         stRgnAttr.unAttr.stOverlayEx.stSize.u32Width = pstAttr->stContent.stBitmap.u32Width;
663         stRgnAttr.unAttr.stOverlayEx.stSize.u32Height = pstAttr->stContent.stBitmap.u32Height;
664         stRgnAttr.unAttr.stOverlayEx.u32CanvasNum =
665             (HI_OSD_TYPE_BITMAP == pstAttr->stContent.enType) ? 1 : 2; // 2: u32CanvasNum
666     } else {
667         stRgnAttr.unAttr.stOverlay.enPixelFmt = PIXEL_FORMAT_ARGB_1555;
668         stRgnAttr.unAttr.stOverlay.u32BgColor = pstAttr->stContent.u32Color;
669         stRgnAttr.unAttr.stOverlay.stSize.u32Width = pstAttr->stContent.stBitmap.u32Width;
670         stRgnAttr.unAttr.stOverlay.stSize.u32Height = pstAttr->stContent.stBitmap.u32Height;
671         stRgnAttr.unAttr.stOverlay.u32CanvasNum =
672             (HI_OSD_TYPE_BITMAP == pstAttr->stContent.enType) ? 1 : 2; // 2: u32CanvasNum
673     }
674 
675     s32Ret = HI_MPI_RGN_Create(RgnHdl, &stRgnAttr);
676     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret,
677         "HI_MPI_RGN_Create fail,RgnHdl[%d] Error Code: [0x%08X]\n", RgnHdl, s32Ret);
678 
679     if (pstAttr->stContent.enType == HI_OSD_TYPE_BITMAP) {
680         BITMAP_S stBitmap;
681         stBitmap.enPixelFormat = PIXEL_FORMAT_ARGB_1555;
682         stBitmap.u32Width = pstAttr->stContent.stBitmap.u32Width;
683         stBitmap.u32Height = pstAttr->stContent.stBitmap.u32Height;
684         stBitmap.pData = pstAttr->stContent.stBitmap.pvData;
685         s32Ret = HI_MPI_RGN_SetBitMap(RgnHdl, &stBitmap);
686         SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret,
687             "HI_MPI_RGN_SetBitMap fail,RgnHdl[%d] Error Code: [0x%08X]\n", RgnHdl, s32Ret);
688     } else {
689         s32Ret = OSD_UpdateTextBitmap(RgnHdl, (HI_OSD_CONTENT_S*)&pstAttr->stContent);
690         SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "UpdateTextBitmap fail, ret=%x\n", s32Ret);
691     }
692 
693     for (s32DispIdx = 0; s32DispIdx < pstAttr->u32DispNum; ++s32DispIdx) {
694         if (pstAttr->astDispAttr[s32DispIdx].bShow) {
695             OSD_RGNAttach(RgnHdl, &pstAttr->astDispAttr[s32DispIdx]);
696         }
697     }
698 
699     return HI_SUCCESS;
700 }
701 
OSD_Update_Relate_Info(HI_S32 s32OsdIdx)702 HI_VOID OSD_Update_Relate_Info(HI_S32 s32OsdIdx)
703 {
704     HI_S32 s32Ret = 0;
705 
706     for (s32OsdIdx = 0; s32OsdIdx < HI_OSD_MAX_CNT; ++s32OsdIdx) {
707         pthread_mutex_lock(&s_stOSDParam[s32OsdIdx].mutexLock);
708         if (s_stOSDParam[s32OsdIdx].stAttr.stContent.enType ==
709             HI_OSD_TYPE_TIME && s_stOSDParam[s32OsdIdx].bOn) {
710             /* Update OSD Time String */
711             OSD_GetTimeStr(&stTime,
712                 s_stOSDParam[s32OsdIdx].stAttr.stContent.szStr, HI_OSD_MAX_STR_LEN);
713             /* Update OSD Text Bitmap */
714             s32Ret = OSD_UpdateTextBitmap(s32OsdIdx, &s_stOSDParam[s32OsdIdx].stAttr.stContent);
715             if (HI_SUCCESS != s32Ret) {
716                 pthread_mutex_unlock(&s_stOSDParam[s32OsdIdx].mutexLock);
717                 SAMPLE_PRT("Update Text Bitmap failed\n");
718                 continue;
719             }
720             /* Update OSD Attribute */
721             s32Ret = OSD_Update(s32OsdIdx, &s_stOSDParam[s32OsdIdx].stAttr);
722             if (HI_SUCCESS != s32Ret) {
723                 SAMPLE_PRT("Update Attribute failed\n");
724             }
725         }
726         pthread_mutex_unlock(&s_stOSDParam[s32OsdIdx].mutexLock);
727     }
728 
729     return;
730 }
731 
732 /**
733  * @brief   time osd update task
734  * @param[in]pvParam : nonuse
735  * @return 0 success,non-zero error code.
736  */
OSD_TimeUpdate(HI_VOID * pvParam)737 static HI_VOID* OSD_TimeUpdate(HI_VOID* pvParam)
738 {
739     HI_S32 s32Ret = 0;
740     HI_S32 s32OsdIdx = 0;
741     time_t nowTime = 0;
742     time_t lastTime = 0;
743     prctl(PR_SET_NAME, __FUNCTION__, 0, 0, 0);
744 
745     while (s_bOSDTimeRun) {
746         nowTime = time(NULL); // also means time(&nowTime)
747         if (nowTime == lastTime) {
748             usleep(10000); // 10000:usleep time
749             continue;
750         } else {
751             localtime_r(&nowTime, &stTime);
752             OSD_Update_Relate_Info(s32OsdIdx);
753             lastTime = nowTime; /* update time */
754         }
755         usleep(500000); // 500000: usleep time
756     }
757 
758     return NULL;
759 }
760 
761 /**
762  * @brief    osd module initialization, eg. create time osd update task.
763  * @param[in] pstFonts:osd fonts lib
764  * @return 0 success,non-zero error code.
765  */
HI_OSD_Init(const HI_OSD_FONTS_S * pstFonts)766 HI_S32 HI_OSD_Init(const HI_OSD_FONTS_S* pstFonts)
767 {
768     if (!(HI_TRUE != s_bOSDInitFlg)) {
769         return HI_EINITIALIZED;
770     }
771     if (pstFonts != NULL) {
772         if (!pstFonts->pfnGetFontMod) {
773             return HI_EINVAL;
774         }
775         if (pstFonts->u32FontWidth % BYTE_BITS) {
776             SAMPLE_PRT("FontWidth must be a multiple of %d.", BYTE_BITS);
777             return HI_EINVAL;
778         }
779         memcpy_s(&s_stOSDFonts, sizeof(HI_OSD_FONTS_S), pstFonts, sizeof(HI_OSD_FONTS_S));
780     } else {
781         memset_s(&s_stOSDFonts, sizeof(HI_OSD_FONTS_S), 0, sizeof(HI_OSD_FONTS_S));
782     }
783     HI_S32 s32Idx = 0;
784     HI_S32 s32Ret = HI_SUCCESS;
785 
786     /* Init OSD Param */
787     for (s32Idx = 0; s32Idx < HI_OSD_MAX_CNT; ++s32Idx) {
788         pthread_mutex_init(&s_stOSDParam[s32Idx].mutexLock, NULL);
789         pthread_mutex_lock(&s_stOSDParam[s32Idx].mutexLock);
790         memset_s(&s_stOSDParam[s32Idx], sizeof(OSD_PARAM_S), 0, sizeof(OSD_PARAM_S));
791         pthread_mutex_unlock(&s_stOSDParam[s32Idx].mutexLock);
792     }
793 
794     if (pstFonts != NULL) {
795         /* Create Time OSD Update Thread */
796         s_bOSDTimeRun = HI_TRUE;
797         s32Ret = pthread_create(&s_OSDTimeTskId, NULL, OSD_TimeUpdate, NULL);
798         if (HI_SUCCESS != s32Ret) {
799             SAMPLE_PRT("create OSD_TimeUpdate failed:%s\n", strerror(errno));
800             return HI_ENORES;
801         }
802     }
803 
804     s_bOSDInitFlg = HI_TRUE;
805     return HI_SUCCESS;
806 }
807 
808 /* Initialize OSD font */
OsdInitFont(HI_CHAR * character,HI_U8 ** fontMod,HI_S32 * fontModLen)809 static int OsdInitFont(HI_CHAR *character, HI_U8 **fontMod, HI_S32 *fontModLen)
810 {
811     static const HI_CHAR baseChar = 0x20;
812 
813     // Get Font Mod in ASCII Fontlib
814     if (!character || !fontMod || !fontModLen) {
815         return HI_FAILURE;
816     }
817     // Return true if the parameter is an ASCII character, otherwise NULL (0)
818     if (!IsAscii(character[0])) {
819         return HI_FAILURE;
820     }
821     HI_U32 offset = (character[0] - baseChar) * (OSD_FONT_MOD_H * OSD_FONT_MOD_W / HI_BYTE_BITS);
822     *fontMod = (HI_U8 *)G_FONT_LIB + offset;
823     *fontModLen = OSD_FONT_MOD_H * OSD_FONT_MOD_W / HI_BYTE_BITS;
824     return HI_SUCCESS;
825 }
826 
827 /* Initialize OsdSet lib */
OsdLibInit(void)828 int OsdLibInit(void)
829 {
830     RecurMutexInit(&g_osdMutex);
831 
832 #   if defined(OSD_FONT_HZK) || defined(OSD_FONT_ASC)
833     SAMPLE_PRT("==================success=================\n");
834     HI_OSD_FONTS_S stOsdFonts;
835     stOsdFonts.u32FontWidth = OSD_FONT_MOD_W;
836     stOsdFonts.u32FontHeight = OSD_FONT_MOD_H;
837     stOsdFonts.pfnGetFontMod = OsdInitFont;
838     return HI_OSD_Init(&stOsdFonts);
839 #   else
840     SAMPLE_PRT("##################success##################\n");
841     return HI_OSD_Init(NULL);
842 #   endif
843 }
844 
Osd_Param_Config(const HI_OSD_ATTR_S * pstAttr,OSD_PARAM_S * pstOsdParam)845 HI_VOID Osd_Param_Config(const HI_OSD_ATTR_S* pstAttr, OSD_PARAM_S* pstOsdParam)
846 {
847     /* Update Attribute */
848     pstOsdParam->stAttr.stContent.u32Color = pstAttr->stContent.u32Color;
849     pstOsdParam->stAttr.stContent.u32BgColor = pstAttr->stContent.u32BgColor;
850 
851     if (HI_OSD_TYPE_BITMAP != pstAttr->stContent.enType) {
852         if (HI_OSD_TYPE_TIME == pstAttr->stContent.enType) {
853             /* Time Type: Update time string */
854             pstOsdParam->stAttr.stContent.enTimeFmt = pstAttr->stContent.enTimeFmt;
855             OSD_GetTimeStr(NULL, ((HI_OSD_ATTR_S*)pstAttr)->stContent.szStr, HI_OSD_MAX_STR_LEN);
856         }
857 
858         /* Update string */
859         if (snprintf_s(pstOsdParam->stAttr.stContent.szStr, HI_OSD_MAX_STR_LEN,
860             HI_OSD_MAX_STR_LEN - 1, "%s", pstAttr->stContent.szStr) < 0) {
861             HI_ASSERT(0);
862         }
863 
864         pstOsdParam->stAttr.stContent.stBitmap.enPixelFormat = PIXEL_FORMAT_ARGB_1555;
865         ((HI_OSD_ATTR_S*)pstAttr)->stContent.stBitmap.u32Width =
866             pstAttr->stContent.stFontSize.u32Width * strnlen(pstOsdParam->stAttr.stContent.szStr, HI_OSD_MAX_STR_LEN);
867         ((HI_OSD_ATTR_S*)pstAttr)->stContent.stBitmap.u32Height= pstAttr->stContent.stFontSize.u32Height;
868         pstOsdParam->stAttr.stContent.stFontSize = pstAttr->stContent.stFontSize;
869     } else {
870         pstOsdParam->stAttr.stContent.stBitmap.enPixelFormat = pstAttr->stContent.stBitmap.enPixelFormat;
871         pstOsdParam->stAttr.stContent.stBitmap.u64PhyAddr = pstAttr->stContent.stBitmap.u64PhyAddr;
872         pstOsdParam->stAttr.stContent.stBitmap.pvData = pstAttr->stContent.stBitmap.pvData;
873     }
874     pstOsdParam->stAttr.stContent.stBitmap.u32Width = pstAttr->stContent.stBitmap.u32Width;
875     pstOsdParam->stAttr.stContent.stBitmap.u32Height = pstAttr->stContent.stBitmap.u32Height;
876     pstOsdParam->stAttr.stContent.enType = pstAttr->stContent.enType;
877 
878     return;
879 }
880 
OSD_Update_RGN_Content(const HI_OSD_ATTR_S * pstAttr,OSD_PARAM_S * pstOsdParam,HI_S32 s32OsdIdx)881 static HI_S32 OSD_Update_RGN_Content(const HI_OSD_ATTR_S* pstAttr, OSD_PARAM_S* pstOsdParam, HI_S32 s32OsdIdx)
882 {
883     HI_S32 s32Ret = HI_SUCCESS;
884     /* Update RGN Content */
885     if (pstAttr->stContent.enType == HI_OSD_TYPE_BITMAP) {
886         BITMAP_S stBitmap;
887         stBitmap.enPixelFormat = PIXEL_FORMAT_ARGB_1555;
888         stBitmap.u32Width = pstAttr->stContent.stBitmap.u32Width;
889         stBitmap.u32Height = pstAttr->stContent.stBitmap.u32Height;
890         stBitmap.pData = pstAttr->stContent.stBitmap.pvData;
891         s32Ret = HI_MPI_RGN_SetBitMap(s32OsdIdx, &stBitmap);
892         SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, FAIL, "HI_MPI_RGN_SetBitMap. s32Ret: 0x%x\n", s32Ret);
893     } else {
894         /* Time/String Type: Update text bitmap */
895         s32Ret = OSD_UpdateTextBitmap(s32OsdIdx, (HI_OSD_CONTENT_S*)&pstOsdParam->stAttr.stContent);
896         SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, FAIL, "OSD_UpdateTextBitmap fail, err(%#x)\n", s32Ret);
897     }
898 
899     HI_S32 s32DispIdx = 0;
900     for (s32DispIdx = 0; s32DispIdx < pstAttr->u32DispNum ; ++s32DispIdx) {
901         if (HI_TRUE == pstAttr->astDispAttr[s32DispIdx].bShow && HI_FALSE ==
902             pstOsdParam->stAttr.astDispAttr[s32DispIdx].bShow) {
903             OSD_RGNAttach(s32OsdIdx, &pstAttr->astDispAttr[s32DispIdx]);
904         } else if (HI_FALSE == pstAttr->astDispAttr[s32DispIdx].bShow && HI_TRUE ==
905             pstOsdParam->stAttr.astDispAttr[s32DispIdx].bShow) {
906             OSD_RGNDetach(s32OsdIdx, &pstOsdParam->stAttr.astDispAttr[s32DispIdx]);
907         }
908     }
909     s32Ret = OSD_Update(s32OsdIdx, pstAttr);
910     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, FAIL, "OSD_Update fail, err(%#x)\n", s32Ret);
911 
912     return s32Ret;
913 
914 FAIL:
915     pthread_mutex_unlock(&pstOsdParam->mutexLock);
916     return s32Ret;
917 }
918 
919 /*
920  * @brief    set osd attribute.
921  * @param[in] s32OsdIdx:osd index, range[0,HI_OSD_MAX_CNT)
922  * @param[in] pstAttr:osd configure attribute
923  * @return 0 success,non-zero error code.
924  */
HI_OSD_SetAttr(HI_S32 s32OsdIdx,const HI_OSD_ATTR_S * pstAttr)925 HI_S32 HI_OSD_SetAttr(HI_S32 s32OsdIdx, const HI_OSD_ATTR_S* pstAttr)
926 {
927     /* Check Module Init or not */
928     HI_ASSERT(HI_TRUE == s_bOSDInitFlg);
929     /* Check Input Param */
930     HI_ASSERT(s32OsdIdx >= 0);
931     HI_ASSERT(HI_OSD_MAX_CNT > s32OsdIdx);
932     HI_ASSERT(pstAttr);
933     HI_ASSERT(HI_OSD_MAX_DISP_CNT >= pstAttr->u32DispNum);
934 
935     if (HI_OSD_TYPE_BITMAP == pstAttr->stContent.enType) {
936         if (!pstAttr->stContent.stBitmap.pvData) {
937             return HI_FAILURE;
938         }
939     } else {
940         if (s_stOSDFonts.pfnGetFontMod == NULL) {
941             SAMPLE_PRT("The font library is not registered,only support bitmaps OSD\n");
942             return HI_FAILURE;
943         }
944     }
945 
946     HI_S32 s32Ret = HI_SUCCESS;
947     OSD_PARAM_S* pstOsdParam = &s_stOSDParam[s32OsdIdx];
948     pthread_mutex_lock(&pstOsdParam->mutexLock);
949     HI_BOOL bOn = pstOsdParam->bOn;
950 
951     /* Update Attribute */
952     Osd_Param_Config(pstAttr, pstOsdParam);
953     if (bOn) {
954         if (pstOsdParam->stMaxSize.u32Width < pstOsdParam->stAttr.stContent.stBitmap.u32Width
955             || pstOsdParam->stMaxSize.u32Height < pstOsdParam->stAttr.stContent.stBitmap.u32Height) {
956             SAMPLE_PRT("RGN(%d) size increase[%d,%d->%d,%d], rebuild\n", s32OsdIdx,
957                 pstOsdParam->stMaxSize.u32Width, pstOsdParam->stMaxSize.u32Height,
958                 pstAttr->stContent.stBitmap.u32Width, pstAttr->stContent.stBitmap.u32Height);
959             /* rebuild RGN */
960             s32Ret = OSD_DestroyRGN(s32OsdIdx, &pstOsdParam->stAttr);
961             if (s32Ret != HI_SUCCESS) {
962                 pthread_mutex_unlock(&pstOsdParam->mutexLock);
963                 return s32Ret;
964             }
965 
966             s32Ret = OSD_CreateRGN(s32OsdIdx, pstAttr);
967             if (s32Ret != HI_SUCCESS) {
968                 pthread_mutex_unlock(&pstOsdParam->mutexLock);
969                 return s32Ret;
970             }
971         } else {
972             OSD_Update_RGN_Content(pstAttr, pstOsdParam, s32OsdIdx);
973         }
974     }
975 
976     memcpy_s(pstOsdParam->stAttr.astDispAttr, sizeof(HI_OSD_DISP_ATTR_S) * HI_OSD_MAX_DISP_CNT,
977         pstAttr->astDispAttr, sizeof(HI_OSD_DISP_ATTR_S) * HI_OSD_MAX_DISP_CNT);
978     pstOsdParam->stAttr.u32DispNum = pstAttr->u32DispNum;
979     pstOsdParam->stMaxSize.u32Width =
980         max(pstOsdParam->stMaxSize.u32Width, pstOsdParam->stAttr.stContent.stBitmap.u32Width);
981     pstOsdParam->stMaxSize.u32Height=
982         max(pstOsdParam->stMaxSize.u32Height, pstOsdParam->stAttr.stContent.stBitmap.u32Height);
983     pstOsdParam->bInit = HI_TRUE;
984     pthread_mutex_unlock(&pstOsdParam->mutexLock);
985 
986     return HI_SUCCESS;
987 }
988 
OSD_Start(HI_S32 s32OsdIdx)989 static HI_S32 OSD_Start(HI_S32 s32OsdIdx)
990 {
991     HI_S32 s32Ret = HI_SUCCESS;
992     OSD_PARAM_S* pstOsdParam = &s_stOSDParam[s32OsdIdx];
993 
994     /* Time OSD: Update time string and bitmap */
995     if (HI_OSD_TYPE_TIME == pstOsdParam->stAttr.stContent.enType) {
996         OSD_GetTimeStr(NULL, pstOsdParam->stAttr.stContent.szStr, HI_OSD_MAX_STR_LEN);
997     }
998 
999     s32Ret = OSD_CreateRGN(s32OsdIdx, &pstOsdParam->stAttr);
1000     if (HI_SUCCESS != s32Ret) {
1001         SAMPLE_PRT("OSD_CreateRGN s32OsdIdx[%d] failed:[0x%08X]\n", s32OsdIdx, s32Ret);
1002         return s32Ret;
1003     }
1004     pstOsdParam->bOn = HI_TRUE;
1005     return HI_SUCCESS;
1006 }
1007 
1008 /*
1009  * @brief    start osd by index.
1010  * @param[in] s32OsdIdx:osd index, range[0,HI_OSD_MAX_CNT)
1011  * @return 0 success,non-zero error code.
1012  */
HI_OSD_Start(HI_S32 s32OsdIdx)1013 HI_S32 HI_OSD_Start(HI_S32 s32OsdIdx)
1014 {
1015     /* Check Module Init or not */
1016     HI_ASSERT(HI_TRUE == s_bOSDInitFlg);
1017     /* Check Input Param */
1018     HI_ASSERT(s32OsdIdx >= 0);
1019     HI_ASSERT(HI_OSD_MAX_CNT > s32OsdIdx);
1020 
1021     HI_S32 s32Ret = HI_SUCCESS;
1022     OSD_PARAM_S* pstOsdParam = &s_stOSDParam[s32OsdIdx];
1023 
1024     pthread_mutex_lock(&pstOsdParam->mutexLock);
1025 
1026     /* Check OSD Attrbute init or not */
1027     if (!pstOsdParam->bInit) {
1028         pthread_mutex_unlock(&pstOsdParam->mutexLock);
1029         SAMPLE_PRT("OSD[%d] not init yet!\n", s32OsdIdx);
1030         return HI_EINVAL;
1031     }
1032 
1033     /* Check OSD stop or not */
1034     if (pstOsdParam->bOn) {
1035         pthread_mutex_unlock(&pstOsdParam->mutexLock);
1036         SAMPLE_PRT("OSD[%d] has already started!\n", s32OsdIdx);
1037         return HI_SUCCESS;
1038     }
1039 
1040     s32Ret = OSD_Start(s32OsdIdx);
1041     pthread_mutex_unlock(&pstOsdParam->mutexLock);
1042     return s32Ret;
1043 }
1044 
1045 /* Set attributes for the specified region in OsdSet */
OsdsSetRgn(OsdSet * self,int rgnHnd,const HI_OSD_ATTR_S * rgnAttr)1046 int OsdsSetRgn(OsdSet* self, int rgnHnd, const HI_OSD_ATTR_S* rgnAttr)
1047 {
1048     HI_ASSERT(self);
1049     HI_ASSERT(rgnHnd >= 0 && rgnHnd < HI_OSD_MAX_CNT);
1050     HI_ASSERT(g_osdHndPool[rgnHnd] && g_osdHndPool[rgnHnd] == (void*)self); // not need lock
1051     HI_OSD_ATTR_S attr;
1052     int ret;
1053 
1054     if (!rgnAttr) { // hidden the region
1055         if (memset_s(&attr, sizeof(attr), 0, sizeof(attr)) != EOK) {
1056             HI_ASSERT(0);
1057         }
1058         attr.u32DispNum = 1;
1059         attr.astDispAttr[0].bShow = HI_FALSE;
1060     } else {
1061         attr = *rgnAttr;
1062     }
1063 
1064     attr.astDispAttr[0].enBindedMod = self->bindMod;
1065     attr.astDispAttr[0].ModHdl = self->modHnd;
1066     attr.astDispAttr[0].ChnHdl = self->chnHnd;
1067 
1068     ret = HI_OSD_SetAttr(rgnHnd, &attr);
1069     SAMPLE_CHECK_EXPR_RET(ret, "HI_OSD_SetAttr FAIL, ret=%d\n", ret);
1070 
1071     ret = HI_OSD_Start(rgnHnd);
1072     SAMPLE_CHECK_EXPR_RET(ret, "HI_OSD_Start FAIL, ret=%d\n", ret);
1073     return 0;
1074 }
1075 
1076 #ifdef __cplusplus
1077 #if __cplusplus
1078 }
1079 #endif
1080 #endif /* End of #ifdef __cplusplus */