• 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  * 全局对象
57  * 多个OsdSet实例将从全局池中分配id
58  *
59  * Global object.
60  * Multiple OsdSet instances will allocate ids from the global pool.
61  */
62 static void* g_osdHndPool[HI_OSD_MAX_CNT]; // Used to identify whether the index handle is used
63 static pthread_mutex_t g_osdMutex; // pool access lock
64 
65 /*
66  * OSD参数数组
67  * OSD Parameter Array、
68  */
69 static OSD_PARAM_S s_stOSDParam[HI_OSD_MAX_CNT];
70 
71 /*
72  * OSD 模块初始化标志
73  * 只能被HI_PDT_OSD_Init/HI_PDT_OSD_DeInit修改
74  *
75  * OSD Module Init Flag
76  * Only modified by HI_PDT_OSD_Init/HI_PDT_OSD_DeInit
77  */
78 static HI_BOOL s_bOSDInitFlg = HI_FALSE;
79 
80 /*
81  * OSD 字体库,由 HI_PDT_OSD_Init 初始化
82  * OSD Fonts Lib, inited by HI_PDT_OSD_Init
83  */
84 static HI_OSD_FONTS_S s_stOSDFonts;
85 
86 /*
87  * OSD 时间更新运行标志
88  * 只能被HI_PDT_OSD_Init/HI_PDT_OSD_DeInit修改
89  *
90  * OSD Time Update Runing Flag
91  * Only modified by HI_PDT_OSD_Init/HI_PDT_OSD_DeInit
92  */
93 static HI_BOOL s_bOSDTimeRun = HI_FALSE;
94 
95 /*
96  * 时间OSD更新任务线程ID,由HI_PDT_OSD_Init创建,由HI_OSD_DeInit销毁
97  * Time OSD Update Task Thread ID, created by HI_PDT_OSD_Init, destroyed by HI_OSD_DeInit
98  */
99 static pthread_t s_OSDTimeTskId = 0;
100 
101 static HI_OSD_TEXTBITMAP_S s_stOSDTextBitMap;
102 
103 static HI_U8* FontMod = NULL;
104 static HI_S32 FontModLen = 0;
105 
106 /*
107  * 位图行/列索引
108  * Bitmap Row/Col Index
109  */
110 static HI_S32 s32BmRow;
111 static HI_S32 s32BmCol;
112 struct tm stTime = {0};
113 
114 /*
115  * OSD Font Step In Lib,以字节为单位
116  * OSD Font Step In Lib, in bytes
117  */
118 #define OSD_LIB_FONT_W (s_stOSDFonts.u32FontWidth)
119 #define OSD_LIB_FONT_H (s_stOSDFonts.u32FontHeight)
120 #define OSD_LIB_FONT_STEP (OSD_LIB_FONT_W * OSD_LIB_FONT_H / BYTE_BITS)
121 
122 /*
123  * 数据对齐
124  * Value Align
125  */
HiAppcommAlign(HI_S32 value,HI_S32 base)126 HI_S32 HiAppcommAlign(HI_S32 value, HI_S32 base)
127 {
128     return (((value) + (base)-1) / (base) * (base));
129 }
130 
max(HI_U32 a,HI_U32 b)131 HI_U32 max(HI_U32 a, HI_U32 b)
132 {
133     return (((a) < (b)) ? (b) : (a));
134 }
135 
min(HI_U32 a,HI_U32 b)136 HI_U32 min(HI_U32 a, HI_U32 b)
137 {
138     return (((a) > (b)) ? (b) : (a));
139 }
140 
IsAscii(HI_S32 a)141 HI_S32 IsAscii(HI_S32 a)
142 {
143     return (((a) >= 0x00 && (a) <= 0x7F) ? 1 : 0);
144 }
145 
OSD_GetNonASCNum(HI_CHAR * string,HI_S32 len)146 static HI_S32 OSD_GetNonASCNum(HI_CHAR* string, HI_S32 len)
147 {
148     HI_S32 i;
149     HI_S32 n = 0;
150     for (i = 0; i < len; i++) {
151         if (string[i] == '\0') {
152             break;
153         }
154         if (!IsAscii(string[i])) {
155             i++;
156             n++;
157         }
158     }
159     return n;
160 }
161 
162 /*
163  * 创建OsdSet
164  * Creat OsdSet
165  */
OsdsCreate(HI_OSD_BIND_MOD_E bindMod,HI_U32 modHnd,HI_U32 chnHnd)166 OsdSet* OsdsCreate(HI_OSD_BIND_MOD_E bindMod, HI_U32 modHnd, HI_U32 chnHnd)
167 {
168     OsdSet *self = NULL;
169 
170     self = (OsdSet*)malloc(sizeof(*self));
171     if (!self) {
172         HI_ASSERT(0);
173     }
174     if (memset_s(self, sizeof(*self), 0, sizeof(*self)) != EOK) {
175         HI_ASSERT(0);
176     }
177 
178     self->bindMod = bindMod;
179     self->modHnd = modHnd;
180     self->chnHnd = chnHnd;
181     return self;
182 }
183 
184 /*
185  * @brief 获取给定格式的时间字符串
186  * @param[in]pstTime : 时间结构,如果为空则获取当前系统时间
187  * @param[out]pazStr : 时间字符串缓冲区
188  * @param[in]s32Len : 时间字符串缓冲区长度
189  *
190  * @brief get time string with given format
191  * @param[in]pstTime : time struct, get current system time if null
192  * @param[out]pazStr : time string buffer
193  * @param[in]s32Len : time string buffer length
194  */
OSD_GetTimeStr(struct tm * pstTime,HI_CHAR * pazStr,HI_S32 s32Len)195 static HI_VOID OSD_GetTimeStr(struct tm* pstTime, HI_CHAR* pazStr, HI_S32 s32Len)
196 {
197     /*
198      * 获取时间
199      * Get Time
200      */
201     time_t nowTime;
202 
203     if (!pstTime) {
204         time(&nowTime);
205         localtime_r(&nowTime, pstTime);
206     }
207 
208     /*
209      * 生成时间字符串
210      * Generate Time String
211      */
212     if (snprintf_s(pazStr, s32Len, s32Len - 1, "%04d-%02d-%02d %02d:%02d:%02d",
213         pstTime->tm_year + BASE_YAER, pstTime->tm_mon + 1, pstTime->tm_mday,
214         pstTime->tm_hour, pstTime->tm_min, pstTime->tm_sec) < 0) {
215         HI_ASSERT(0);
216     }
217 
218     return;
219 }
220 
OSD_RGNDetach(RGN_HANDLE RgnHdl,const HI_OSD_DISP_ATTR_S * pstDispAttr)221 static HI_S32 OSD_RGNDetach(RGN_HANDLE RgnHdl, const HI_OSD_DISP_ATTR_S* pstDispAttr)
222 {
223     HI_S32 s32Ret = HI_SUCCESS;
224     MPP_CHN_S stChn;
225 
226     stChn.s32DevId = pstDispAttr->ModHdl;
227     stChn.s32ChnId = pstDispAttr->ChnHdl;
228     switch (pstDispAttr->enBindedMod) {
229         case HI_OSD_BINDMOD_VI:
230             stChn.enModId = HI_ID_VI;
231             break;
232         case HI_OSD_BINDMOD_VPSS:
233             stChn.enModId = HI_ID_VPSS;
234             break;
235         case HI_OSD_BINDMOD_AVS:
236             stChn.enModId = HI_ID_AVS;
237             break;
238         case HI_OSD_BINDMOD_VENC:
239             stChn.s32DevId = 0;
240             stChn.enModId = HI_ID_VENC;
241             break;
242         case HI_OSD_BINDMOD_VO:
243             stChn.enModId = HI_ID_VO;
244             break;
245         default:
246             SAMPLE_PRT("RgnHdl[%d] invalide bind mode [%d]\n", RgnHdl, pstDispAttr->enBindedMod);
247             return HI_EINVAL;
248     }
249 
250     s32Ret = HI_MPI_RGN_DetachFromChn(RgnHdl, &stChn);
251     if (s32Ret != HI_SUCCESS) {
252         SAMPLE_PRT("HI_MPI_RGN_DetachFromChn fail,RgnHdl[%d] stChn[%d,%d,%d] Error Code: [0x%08X]\n",
253             RgnHdl, stChn.enModId, stChn.s32DevId, stChn.s32ChnId, s32Ret);
254         return s32Ret;
255     }
256 
257     return HI_SUCCESS;
258 }
259 
OSD_DestroyRGN(RGN_HANDLE RgnHdl,const HI_OSD_ATTR_S * pstAttr)260 static HI_S32 OSD_DestroyRGN(RGN_HANDLE RgnHdl, const HI_OSD_ATTR_S* pstAttr)
261 {
262     HI_S32 s32Ret = HI_SUCCESS;
263     HI_S32 s32DispIdx = 0;
264 
265     for (s32DispIdx = 0; s32DispIdx < pstAttr->u32DispNum ; ++s32DispIdx) {
266         if (pstAttr->astDispAttr[s32DispIdx].bShow) {
267             OSD_RGNDetach(RgnHdl, &pstAttr->astDispAttr[s32DispIdx]);
268         }
269     }
270 
271     s32Ret = HI_MPI_RGN_Destroy(RgnHdl);
272     if (s32Ret != HI_SUCCESS) {
273         SAMPLE_PRT("HI_MPI_RGN_Destroy fail, RgnHdl[%d] Error Code: [0x%08X]\n", RgnHdl, s32Ret);
274         return s32Ret;
275     }
276 
277     return HI_SUCCESS;
278 }
279 
280 /*
281  * 在OsdSet中创建区域
282  * Create a region in OsdSet
283  */
OsdsCreateRgn(OsdSet * self)284 int OsdsCreateRgn(OsdSet* self)
285 {
286     HI_ASSERT(self);
287     int ret = -1;
288 
289     MutexLock(&g_osdMutex);
290     for (int i = 0; i < HI_OSD_MAX_CNT; i++) {
291         if (!g_osdHndPool[i]) {
292             g_osdHndPool[i] = self;
293             ret = i;
294             break;
295         }
296     }
297     MutexUnlock(&g_osdMutex);
298     return ret;
299 }
300 
OSD_Stop(HI_S32 s32OsdIdx)301 static HI_S32 OSD_Stop(HI_S32 s32OsdIdx)
302 {
303     HI_S32 s32Ret = HI_SUCCESS;
304     OSD_PARAM_S* pstOsdParam = &s_stOSDParam[s32OsdIdx];
305 
306     if (!pstOsdParam->bOn) {
307         return HI_SUCCESS;
308     }
309 
310     s32Ret = OSD_DestroyRGN(s32OsdIdx, &pstOsdParam->stAttr);
311     if (s32Ret != HI_SUCCESS) {
312         SAMPLE_PRT("OSD_DestroyRGN s32OsdIdx[%d] failed:[0x%08X]\n", s32OsdIdx, s32Ret);
313         return s32Ret;
314     }
315 
316     pstOsdParam->bOn = HI_FALSE;
317     return HI_SUCCESS;
318 }
319 
320 /*
321  * @brief 按索引停止osd
322  * @param[in] s32OsdIdx:osd 索引,范围[0,HI_OSD_MAX_CNT)
323  * @return 0 成功,非零错误码
324  *
325  * @brief    stop osd by index.
326  * @param[in] s32OsdIdx:osd index, range[0,HI_OSD_MAX_CNT)
327  * @return 0 success,non-zero error code.
328  */
HI_OSD_Stop(HI_S32 s32OsdIdx)329 HI_S32 HI_OSD_Stop(HI_S32 s32OsdIdx)
330 {
331     /*
332      * 检查模块初始化与否
333      * Check Module Init or not
334      */
335     HI_ASSERT(HI_TRUE == s_bOSDInitFlg);
336     /*
337      * 检查输入参数
338      * Check Input Param
339      */
340     HI_ASSERT(s32OsdIdx >= 0);
341     HI_ASSERT(HI_OSD_MAX_CNT > s32OsdIdx);
342 
343     HI_S32 s32Ret = HI_SUCCESS;
344     OSD_PARAM_S* pstOsdParam = &s_stOSDParam[s32OsdIdx];
345 
346     pthread_mutex_lock(&pstOsdParam->mutexLock);
347 
348     /*
349      * 检查OSD Attrbute是否初始化
350      * Check OSD Attrbute init or not
351      */
352     if (!pstOsdParam->bInit) {
353         pthread_mutex_unlock(&pstOsdParam->mutexLock);
354         return HI_SUCCESS;
355     }
356 
357     /*
358      * 检查OSD是否停止
359      * Check OSD stop or not
360      */
361     if (!pstOsdParam->bOn) {
362         pthread_mutex_unlock(&pstOsdParam->mutexLock);
363         return HI_SUCCESS;
364     }
365 
366     s32Ret = OSD_Stop(s32OsdIdx);
367     pstOsdParam->stMaxSize.u32Width = 0;
368     pstOsdParam->stMaxSize.u32Height= 0;
369     pthread_mutex_unlock(&pstOsdParam->mutexLock);
370     return s32Ret;
371 }
372 
373 /*
374  * 销毁OsdSet中指定的区域
375  * Destroy the region specified in the OsdSet
376  */
OsdsDestroyRgn(OsdSet * self,int rgnHnd)377 void OsdsDestroyRgn(OsdSet* self, int rgnHnd)
378 {
379     HI_ASSERT(self);
380     HI_ASSERT(rgnHnd >= 0 && rgnHnd < HI_OSD_MAX_CNT);
381 
382     MutexLock(&g_osdMutex);
383     HI_ASSERT(g_osdHndPool[rgnHnd] && g_osdHndPool[rgnHnd] == (void*)self);
384     g_osdHndPool[rgnHnd] = NULL;
385     MutexUnlock(&g_osdMutex);
386 
387     HI_OSD_Stop(rgnHnd);
388 }
389 
390 /*
391  * 销毁OsdSet中的所有区域
392  * Destroy all regions in OsdSet
393  */
OsdsClear(OsdSet * self)394 void OsdsClear(OsdSet* self)
395 {
396     MutexLock(&g_osdMutex);
397     for (int i = 0; i < HI_OSD_MAX_CNT; i++) {
398         if (g_osdHndPool[i] && g_osdHndPool[i] == (void*)self) {
399             OsdsDestroyRgn(self, i);
400         }
401     }
402     MutexUnlock(&g_osdMutex);
403 }
404 
405 /*
406  * 销毁OsdSet
407  * Destory OsdSet
408  */
OsdsDestroy(OsdSet * self)409 void OsdsDestroy(OsdSet* self)
410 {
411     HI_ASSERT(self);
412     OsdsClear(self);
413     free(self);
414 }
415 
416 /*
417  * 设置文本区域的属性值
418  * Set the attribute value of the text region
419  */
TxtRgnInit(HI_OSD_ATTR_S * rgnAttr,const char * str,uint32_t begX,uint32_t begY,uint32_t color)420 int TxtRgnInit(HI_OSD_ATTR_S* rgnAttr, const char* str, uint32_t begX, uint32_t begY, uint32_t color)
421 {
422     HI_ASSERT(rgnAttr);
423     if (!str) {
424         HI_ASSERT(0);
425     }
426     // 64:[0,128], the transparency of the text background block, the larger the background block color,
427     // the darker the background block color, 0 means no background block, that is, completely transparent
428     static const uint32_t bgAlpha = 64;
429     // 128:[0,128], the brightness of the text, the larger the value, the brighter the text
430     static const uint32_t fgAlpha = 128;
431 
432     if (memset_s(rgnAttr, sizeof(*rgnAttr), 0, sizeof(*rgnAttr)) != EOK) {
433         HI_ASSERT(0);
434     }
435     rgnAttr->u32DispNum = 1;
436     rgnAttr->astDispAttr[0].bShow = (str && *str) ? HI_TRUE : HI_FALSE;
437     rgnAttr->astDispAttr[0].enBindedMod = HI_OSD_BINDMOD_BUTT;
438     rgnAttr->astDispAttr[0].ChnHdl = UINT32_MAX;
439     rgnAttr->astDispAttr[0].u32BgAlpha = bgAlpha;
440     rgnAttr->astDispAttr[0].u32FgAlpha = fgAlpha;
441     rgnAttr->astDispAttr[0].enCoordinate = HI_OSD_COORDINATE_ABS_COOR;
442     rgnAttr->astDispAttr[0].stStartPos.s32X = begX;
443     rgnAttr->astDispAttr[0].stStartPos.s32Y = begY;
444     rgnAttr->astDispAttr[0].enAttachDest = ATTACH_JPEG_MAIN;
445     rgnAttr->stContent.enType = HI_OSD_TYPE_STRING;
446     rgnAttr->stContent.u32Color = color; // ARGB #FFFF0000 Red
447     HiStrxfrm(rgnAttr->stContent.szStr, str, sizeof(rgnAttr->stContent.szStr));
448     rgnAttr->stContent.stFontSize.u32Width = OSD_FONT_WIDTH_DEF;
449     rgnAttr->stContent.stFontSize.u32Height = OSD_FONT_HEIGHT_DEF;
450     return 0;
451 }
452 
OSD_Ratio2Absolute(MPP_CHN_S stChn,const POINT_S * pstRatioCoor,POINT_S * pstAbsCoor)453 static HI_S32 OSD_Ratio2Absolute(MPP_CHN_S stChn, const POINT_S* pstRatioCoor, POINT_S* pstAbsCoor)
454 {
455     HI_S32 s32Ret = HI_SUCCESS;
456     SIZE_S stImageSize;
457 
458     if (pstRatioCoor->s32X < 0 || pstRatioCoor->s32X > X_COORDINATE ||
459         pstRatioCoor->s32Y < 0 || pstRatioCoor->s32Y > Y_COORDINATE) {
460         SAMPLE_PRT("invalide Ratio coordinate(%d,%d)\n", pstRatioCoor->s32X, pstRatioCoor->s32Y);
461         return HI_EINVAL;
462     }
463     switch (stChn.enModId) {
464         case HI_ID_VI: {
465             VI_CHN_ATTR_S stChnAttr;
466             s32Ret = HI_MPI_VI_GetChnAttr(stChn.s32DevId, stChn.s32ChnId, &stChnAttr);
467             if (s32Ret != HI_SUCCESS) {
468                 SAMPLE_PRT("HI_MPI_VI_GetChnAttr(%d,%d) fail,Error Code: [0x%08X]\n",
469                     stChn.s32DevId, stChn.s32ChnId, s32Ret);
470                 return s32Ret;
471             }
472             stImageSize = stChnAttr.stSize;
473             break;
474         }
475         case HI_ID_VPSS: {
476             VPSS_CHN_ATTR_S stChnAttr;
477             s32Ret = HI_MPI_VPSS_GetChnAttr(stChn.s32DevId, stChn.s32ChnId, &stChnAttr);
478             if (s32Ret != HI_SUCCESS) {
479                 SAMPLE_PRT("HI_MPI_VPSS_GetChnAttr(%d,%d) fail, Error Code: [0x%08X]\n",
480                     stChn.s32DevId, stChn.s32ChnId, s32Ret);
481                 return s32Ret;
482             }
483             stImageSize.u32Width = stChnAttr.u32Width;
484             stImageSize.u32Height = stChnAttr.u32Height;
485             break;
486         }
487         case HI_ID_VO: {
488             VO_CHN_ATTR_S stChnAttr;
489             s32Ret = HI_MPI_VO_GetChnAttr(stChn.s32DevId, stChn.s32ChnId, &stChnAttr);
490             if (s32Ret != HI_SUCCESS) {
491                 SAMPLE_PRT("HI_MPI_VO_GetChnAttr(%d,%d) fail,Error Code: [0x%08X]\n",
492                     stChn.s32DevId, stChn.s32ChnId, s32Ret);
493                 return s32Ret;
494             }
495             stImageSize.u32Width = stChnAttr.stRect.u32Width;
496             stImageSize.u32Height = stChnAttr.stRect.u32Height;
497             break;
498         }
499         default:
500             SAMPLE_PRT("invalide mode id [%d]\n", stChn.enModId);
501             return HI_EINVAL;
502     }
503 
504     // 2: HiAppcommAlign api base param
505     pstAbsCoor->s32X = HiAppcommAlign(stImageSize.u32Width * pstRatioCoor->s32X / MULTIPLE_NUM, 2);
506     // 2: HiAppcommAlign api base param
507     pstAbsCoor->s32Y = HiAppcommAlign(stImageSize.u32Height * pstRatioCoor->s32Y / MULTIPLE_NUM, 2);
508     return HI_SUCCESS;
509 }
510 
OSD_Update(RGN_HANDLE RgnHdl,const HI_OSD_ATTR_S * pstAttr)511 static HI_S32 OSD_Update(RGN_HANDLE RgnHdl, const HI_OSD_ATTR_S* pstAttr)
512 {
513     HI_S32 s32Ret = HI_SUCCESS;
514     HI_S32 s32DispIdx = 0;
515     RGN_CHN_ATTR_S stRgnChnAttr;
516     MPP_CHN_S stChn;
517 
518     for (s32DispIdx = 0; s32DispIdx < pstAttr->u32DispNum ; ++s32DispIdx) {
519         if (!pstAttr->astDispAttr[s32DispIdx].bShow) {
520             continue;
521         }
522 
523         stChn.s32DevId = pstAttr->astDispAttr[s32DispIdx].ModHdl;
524         stChn.s32ChnId = pstAttr->astDispAttr[s32DispIdx].ChnHdl;
525         switch (pstAttr->astDispAttr[s32DispIdx].enBindedMod) {
526             case HI_OSD_BINDMOD_VI:
527                 stChn.enModId = HI_ID_VI;
528                 break;
529             case HI_OSD_BINDMOD_VPSS:
530                 stChn.enModId = HI_ID_VPSS;
531                 break;
532             case HI_OSD_BINDMOD_VO:
533                 stChn.enModId = HI_ID_VO;
534                 break;
535             default:
536                 SAMPLE_PRT("invalide bind mode [%d]\n", pstAttr->astDispAttr[s32DispIdx].enBindedMod);
537                 return HI_EINVAL;
538         }
539         /*
540          * 获取区域的通道显示属性
541          * Get the channel display properties of the zone
542          */
543         s32Ret = HI_MPI_RGN_GetDisplayAttr(RgnHdl, &stChn, &stRgnChnAttr);
544         SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "GetDisplayAttr fail, s32Ret:[0x%08X]\n", s32Ret);
545 
546         stRgnChnAttr.bShow = pstAttr->astDispAttr[s32DispIdx].bShow;
547         POINT_S stStartPos;
548         if (pstAttr->astDispAttr[s32DispIdx].enCoordinate == HI_OSD_COORDINATE_RATIO_COOR) {
549             s32Ret = OSD_Ratio2Absolute(stChn, &pstAttr->astDispAttr[s32DispIdx].stStartPos, &stStartPos);
550             SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Ratio2Absolute fail, s32Ret:[0x%08X]\n", s32Ret);
551         } else {
552             stStartPos = pstAttr->astDispAttr[s32DispIdx].stStartPos;
553         }
554 
555         if (stRgnChnAttr.enType == OVERLAYEX_RGN) {
556             stRgnChnAttr.unChnAttr.stOverlayExChn.stPoint.s32X = stStartPos.s32X;
557             stRgnChnAttr.unChnAttr.stOverlayExChn.stPoint.s32Y = stStartPos.s32Y;
558             stRgnChnAttr.unChnAttr.stOverlayExChn.u32BgAlpha = pstAttr->astDispAttr[s32DispIdx].u32BgAlpha;
559             stRgnChnAttr.unChnAttr.stOverlayExChn.u32FgAlpha = pstAttr->astDispAttr[s32DispIdx].u32FgAlpha;
560         } else {
561             stRgnChnAttr.unChnAttr.stOverlayChn.stPoint.s32X = stStartPos.s32X;
562             stRgnChnAttr.unChnAttr.stOverlayChn.stPoint.s32Y = stStartPos.s32Y;
563             stRgnChnAttr.unChnAttr.stOverlayChn.u32BgAlpha = pstAttr->astDispAttr[s32DispIdx].u32BgAlpha;
564             stRgnChnAttr.unChnAttr.stOverlayChn.u32FgAlpha = pstAttr->astDispAttr[s32DispIdx].u32FgAlpha;
565         }
566         /*
567          * 设置区域的通道显示属性
568          * Sets the channel display properties for the zone
569          */
570         s32Ret = HI_MPI_RGN_SetDisplayAttr(RgnHdl, &stChn, &stRgnChnAttr);
571         SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "SetDisplayAttr fail, s32Ret:[0x%08X]\n", s32Ret);
572     }
573 
574     return HI_SUCCESS;
575 }
576 
OSD_PuBmData_Cal(HI_OSD_CONTENT_S * pstContent,HI_U16 * puBmData,HI_S32 s32HexOffset,HI_S32 s32BmDataIdx,HI_S32 s32BitOffset)577 HI_VOID OSD_PuBmData_Cal(HI_OSD_CONTENT_S* pstContent, HI_U16* puBmData, HI_S32 s32HexOffset,
578     HI_S32 s32BmDataIdx, HI_S32 s32BitOffset)
579 {
580     HI_U8 temp = FontMod[s32HexOffset];
581     if ((temp >> ((BYTE_BITS - 1) - s32BitOffset)) & 0x1) {
582         puBmData[s32BmDataIdx] = (HI_U16)pstContent->u32Color;
583     } else {
584         puBmData[s32BmDataIdx] = (HI_U16)pstContent->u32BgColor;
585     }
586 
587     return;
588 }
589 
OSD_Bitmap_Cal(HI_OSD_CONTENT_S * pstContent,HI_S32 NonASCNum,HI_U16 * puBmData)590 HI_S32 OSD_Bitmap_Cal(HI_OSD_CONTENT_S* pstContent, HI_S32 NonASCNum, HI_U16* puBmData)
591 {
592     HI_S32 NonASCShow = 0;
593     for (s32BmCol = 0; s32BmCol < pstContent->stBitmap.u32Width; ++s32BmCol) {
594         /*
595          * 点的位图数据偏移
596          * Bitmap Data Offset for the point
597          */
598         HI_S32 s32BmDataIdx = s32BmRow * s_stOSDTextBitMap.stCanvasInfo.u32Stride / 2 + s32BmCol;
599         /*
600          * 文本字符串中的字符索引
601          * Character Index in Text String
602          */
603         HI_S32 s32CharIdx = s32BmCol / pstContent->stFontSize.u32Width;
604         HI_S32 s32StringIdx = s32CharIdx+NonASCShow * (NOASCII_CHARACTER_BYTES - 1);
605         if (NonASCNum > 0 && s32CharIdx > 0) {
606             NonASCShow = OSD_GetNonASCNum(pstContent->szStr, s32StringIdx);
607             s32StringIdx = s32CharIdx+NonASCShow * (NOASCII_CHARACTER_BYTES - 1);
608         }
609         /*
610          * 字符中的点行/列索引
611          * Point Row/Col Index in Character
612          */
613         HI_S32 s32CharCol = (s32BmCol - (pstContent->stFontSize.u32Width * s32CharIdx)) *
614             OSD_LIB_FONT_W / pstContent->stFontSize.u32Width;
615         HI_S32 s32CharRow = s32BmRow * OSD_LIB_FONT_H / pstContent->stFontSize.u32Height;
616         HI_S32 s32HexOffset = s32CharRow * OSD_LIB_FONT_W / BYTE_BITS + s32CharCol / BYTE_BITS;
617         HI_S32 s32BitOffset = s32CharCol % BYTE_BITS;
618 
619         if (s_stOSDFonts.pfnGetFontMod(&pstContent->szStr[s32StringIdx], &FontMod, &FontModLen)
620             == HI_SUCCESS) {
621             if (FontMod != NULL && s32HexOffset < FontModLen) {
622                 OSD_PuBmData_Cal(pstContent, puBmData, s32HexOffset, s32BmDataIdx, s32BitOffset);
623                 continue;
624             }
625         }
626         SAMPLE_PRT("GetFontMod Fail\n");
627         return HI_FAILURE;
628     }
629 }
630 
OSD_Generate_Bitmap(RGN_HANDLE RgnHdl,HI_OSD_CONTENT_S * pstContent)631 HI_S32 OSD_Generate_Bitmap(RGN_HANDLE RgnHdl, HI_OSD_CONTENT_S* pstContent)
632 {
633     HI_S32 s32Ret;
634     HI_S32 s32StrLen = strnlen(pstContent->szStr, HI_OSD_MAX_STR_LEN);
635     HI_S32 NonASCNum = OSD_GetNonASCNum(pstContent->szStr, s32StrLen);
636 
637     s32Ret = HI_MPI_RGN_GetCanvasInfo(RgnHdl, &s_stOSDTextBitMap.stCanvasInfo);
638     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "RGN_GetCanvasInfo FAIL, s32Ret=%x\n", s32Ret);
639 
640     /*
641      * 生成位图
642      * Generate Bitmap
643      */
644     pstContent->stBitmap.u32Width = pstContent->stFontSize.u32Width *
645         (s32StrLen - NonASCNum * (NOASCII_CHARACTER_BYTES - 1));
646     pstContent->stBitmap.u32Height = pstContent->stFontSize.u32Height;
647     HI_U16* puBmData = (HI_U16*)(HI_UL)s_stOSDTextBitMap.stCanvasInfo.u64VirtAddr;
648 
649     for (s32BmRow = 0; s32BmRow < pstContent->stBitmap.u32Height; ++s32BmRow) {
650         OSD_Bitmap_Cal(pstContent, NonASCNum, puBmData);
651         for (s32BmCol = pstContent->stBitmap.u32Width;
652             s32BmCol < s_stOSDParam[RgnHdl].stMaxSize.u32Width; ++s32BmCol) {
653             HI_S32 s32BmDataIdx = s32BmRow * s_stOSDTextBitMap.stCanvasInfo.u32Stride / 2 + s32BmCol;
654             puBmData[s32BmDataIdx] = 0;
655         }
656     }
657 
658     for (s32BmRow = pstContent->stBitmap.u32Height;
659         s32BmRow < s_stOSDParam[RgnHdl].stMaxSize.u32Height; ++s32BmRow) {
660         for (s32BmCol = 0; s32BmCol < s_stOSDParam[RgnHdl].stMaxSize.u32Width; ++s32BmCol) {
661             HI_S32 s32BmDataIdx = s32BmRow * s_stOSDTextBitMap.stCanvasInfo.u32Stride / 2 + s32BmCol;
662             puBmData[s32BmDataIdx] = 0;
663         }
664     }
665 
666     return s32Ret;
667 }
668 
OSD_UpdateTextBitmap(RGN_HANDLE RgnHdl,HI_OSD_CONTENT_S * pstContent)669 static HI_S32 OSD_UpdateTextBitmap(RGN_HANDLE RgnHdl, HI_OSD_CONTENT_S* pstContent)
670 {
671     HI_S32 s32Ret = HI_SUCCESS;
672 
673     OSD_Generate_Bitmap(RgnHdl, pstContent);
674     s_stOSDTextBitMap.stCanvasInfo.enPixelFmt = PIXEL_FORMAT_ARGB_1555;
675     s_stOSDTextBitMap.stCanvasInfo.stSize.u32Width = pstContent->stBitmap.u32Width;
676     s_stOSDTextBitMap.stCanvasInfo.stSize.u32Height = pstContent->stBitmap.u32Height;
677 
678     s32Ret = HI_MPI_RGN_UpdateCanvas(RgnHdl);
679     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "RGN_UpdateCanvas FAIL, s32Ret=%x\n", s32Ret);
680 
681     return s32Ret;
682 }
683 
OSD_RGNAttach(RGN_HANDLE RgnHdl,const HI_OSD_DISP_ATTR_S * pstDispAttr)684 static HI_S32 OSD_RGNAttach(RGN_HANDLE RgnHdl, const HI_OSD_DISP_ATTR_S* pstDispAttr)
685 {
686     HI_S32 s32Ret = HI_SUCCESS;
687     RGN_CHN_ATTR_S stRgnChnAttr;
688     MPP_CHN_S stChn;
689 
690     stChn.s32DevId = pstDispAttr->ModHdl;
691     stChn.s32ChnId = pstDispAttr->ChnHdl;
692     memset_s(&stRgnChnAttr, sizeof(RGN_CHN_ATTR_S), 0x0, sizeof(RGN_CHN_ATTR_S));
693     stRgnChnAttr.bShow = pstDispAttr->bShow;
694     stRgnChnAttr.enType = OVERLAYEX_RGN;
695     switch (pstDispAttr->enBindedMod) {
696         case HI_OSD_BINDMOD_VI:
697             stChn.enModId = HI_ID_VI;
698             break;
699         case HI_OSD_BINDMOD_VPSS:
700             stChn.enModId = HI_ID_VPSS;
701             break;
702         case HI_OSD_BINDMOD_VO:
703             stChn.enModId = HI_ID_VO;
704             break;
705         default:
706             SAMPLE_PRT("RgnHdl[%d] invalide bind mode [%d]\n", RgnHdl, pstDispAttr->enBindedMod);
707             return HI_EINVAL;
708     }
709 
710     POINT_S stStartPos;
711     if (pstDispAttr->enCoordinate == HI_OSD_COORDINATE_RATIO_COOR) {
712         s32Ret = OSD_Ratio2Absolute(stChn, &pstDispAttr->stStartPos, &stStartPos);
713         SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Ratio2Absolute FAIL, s32Ret=%x\n", s32Ret);
714     } else {
715         stStartPos = pstDispAttr->stStartPos;
716     }
717 
718     if (stRgnChnAttr.enType == OVERLAYEX_RGN) {
719         stRgnChnAttr.unChnAttr.stOverlayExChn.stPoint.s32X = stStartPos.s32X;
720         stRgnChnAttr.unChnAttr.stOverlayExChn.stPoint.s32Y = stStartPos.s32Y;
721         stRgnChnAttr.unChnAttr.stOverlayExChn.u32BgAlpha = pstDispAttr->u32BgAlpha;
722         stRgnChnAttr.unChnAttr.stOverlayExChn.u32FgAlpha = pstDispAttr->u32FgAlpha;
723         stRgnChnAttr.unChnAttr.stOverlayExChn.u32Layer = 0;
724     } else {
725         stRgnChnAttr.unChnAttr.stOverlayChn.stPoint.s32X = stStartPos.s32X;
726         stRgnChnAttr.unChnAttr.stOverlayChn.stPoint.s32Y = stStartPos.s32Y;
727         stRgnChnAttr.unChnAttr.stOverlayChn.u32BgAlpha = pstDispAttr->u32BgAlpha;
728         stRgnChnAttr.unChnAttr.stOverlayChn.u32FgAlpha = pstDispAttr->u32FgAlpha;
729         stRgnChnAttr.unChnAttr.stOverlayChn.u32Layer = 0;
730     }
731 
732     s32Ret = HI_MPI_RGN_AttachToChn(RgnHdl, &stChn, &stRgnChnAttr);
733     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "RGN_AttachToChn FAIL, s32Ret=%x\n", s32Ret);
734 
735     return HI_SUCCESS;
736 }
737 
OSD_CreateRGN(RGN_HANDLE RgnHdl,const HI_OSD_ATTR_S * pstAttr)738 static HI_S32 OSD_CreateRGN(RGN_HANDLE RgnHdl, const HI_OSD_ATTR_S* pstAttr)
739 {
740     HI_S32 s32Ret = HI_SUCCESS;
741     HI_S32 s32DispIdx = 0;
742     RGN_ATTR_S stRgnAttr;
743     stRgnAttr.enType = OVERLAY_RGN;
744 
745     for (s32DispIdx = 0; s32DispIdx < pstAttr->u32DispNum ; ++s32DispIdx) {
746         if (pstAttr->astDispAttr[s32DispIdx].enBindedMod != HI_OSD_BINDMOD_VENC) {
747             stRgnAttr.enType = OVERLAYEX_RGN;
748             break;
749         }
750     }
751 
752     if (stRgnAttr.enType == OVERLAYEX_RGN) {
753         stRgnAttr.unAttr.stOverlayEx.enPixelFmt = PIXEL_FORMAT_ARGB_1555;
754         stRgnAttr.unAttr.stOverlayEx.u32BgColor = pstAttr->stContent.u32Color;
755         stRgnAttr.unAttr.stOverlayEx.stSize.u32Width = pstAttr->stContent.stBitmap.u32Width;
756         stRgnAttr.unAttr.stOverlayEx.stSize.u32Height = pstAttr->stContent.stBitmap.u32Height;
757         stRgnAttr.unAttr.stOverlayEx.u32CanvasNum =
758             (HI_OSD_TYPE_BITMAP == pstAttr->stContent.enType) ? 1 : 2; // 2: u32CanvasNum
759     } else {
760         stRgnAttr.unAttr.stOverlay.enPixelFmt = PIXEL_FORMAT_ARGB_1555;
761         stRgnAttr.unAttr.stOverlay.u32BgColor = pstAttr->stContent.u32Color;
762         stRgnAttr.unAttr.stOverlay.stSize.u32Width = pstAttr->stContent.stBitmap.u32Width;
763         stRgnAttr.unAttr.stOverlay.stSize.u32Height = pstAttr->stContent.stBitmap.u32Height;
764         stRgnAttr.unAttr.stOverlay.u32CanvasNum =
765             (HI_OSD_TYPE_BITMAP == pstAttr->stContent.enType) ? 1 : 2; // 2: u32CanvasNum
766     }
767 
768     s32Ret = HI_MPI_RGN_Create(RgnHdl, &stRgnAttr);
769     SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret,
770         "HI_MPI_RGN_Create fail,RgnHdl[%d] Error Code: [0x%08X]\n", RgnHdl, s32Ret);
771 
772     if (pstAttr->stContent.enType == HI_OSD_TYPE_BITMAP) {
773         BITMAP_S stBitmap;
774         stBitmap.enPixelFormat = PIXEL_FORMAT_ARGB_1555;
775         stBitmap.u32Width = pstAttr->stContent.stBitmap.u32Width;
776         stBitmap.u32Height = pstAttr->stContent.stBitmap.u32Height;
777         stBitmap.pData = pstAttr->stContent.stBitmap.pvData;
778         s32Ret = HI_MPI_RGN_SetBitMap(RgnHdl, &stBitmap);
779         SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret,
780             "HI_MPI_RGN_SetBitMap fail,RgnHdl[%d] Error Code: [0x%08X]\n", RgnHdl, s32Ret);
781     } else {
782         s32Ret = OSD_UpdateTextBitmap(RgnHdl, (HI_OSD_CONTENT_S*)&pstAttr->stContent);
783         SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "UpdateTextBitmap fail, ret=%x\n", s32Ret);
784     }
785 
786     for (s32DispIdx = 0; s32DispIdx < pstAttr->u32DispNum; ++s32DispIdx) {
787         if (pstAttr->astDispAttr[s32DispIdx].bShow) {
788             OSD_RGNAttach(RgnHdl, &pstAttr->astDispAttr[s32DispIdx]);
789         }
790     }
791 
792     return HI_SUCCESS;
793 }
794 
OSD_Update_Relate_Info(HI_S32 s32OsdIdx)795 HI_VOID OSD_Update_Relate_Info(HI_S32 s32OsdIdx)
796 {
797     HI_S32 s32Ret = 0;
798 
799     for (s32OsdIdx = 0; s32OsdIdx < HI_OSD_MAX_CNT; ++s32OsdIdx) {
800         pthread_mutex_lock(&s_stOSDParam[s32OsdIdx].mutexLock);
801         if (s_stOSDParam[s32OsdIdx].stAttr.stContent.enType ==
802             HI_OSD_TYPE_TIME && s_stOSDParam[s32OsdIdx].bOn) {
803             /*
804              * 更新OSD时间字符串
805              * Update OSD Time String
806              */
807             OSD_GetTimeStr(&stTime,
808                 s_stOSDParam[s32OsdIdx].stAttr.stContent.szStr, HI_OSD_MAX_STR_LEN);
809             /*
810              * 更新OSD文本位图
811              * Update OSD Text Bitmap
812              */
813             s32Ret = OSD_UpdateTextBitmap(s32OsdIdx, &s_stOSDParam[s32OsdIdx].stAttr.stContent);
814             if (HI_SUCCESS != s32Ret) {
815                 pthread_mutex_unlock(&s_stOSDParam[s32OsdIdx].mutexLock);
816                 SAMPLE_PRT("Update Text Bitmap failed\n");
817                 continue;
818             }
819             /*
820              * 更新OSD属性
821              * Update OSD Attribute
822              */
823             s32Ret = OSD_Update(s32OsdIdx, &s_stOSDParam[s32OsdIdx].stAttr);
824             if (HI_SUCCESS != s32Ret) {
825                 SAMPLE_PRT("Update Attribute failed\n");
826             }
827         }
828         pthread_mutex_unlock(&s_stOSDParam[s32OsdIdx].mutexLock);
829     }
830 
831     return;
832 }
833 
834 /*
835  * @brief 时间 osd 更新任务
836  * @param[in]pvParam : 不使用
837  * @return 0 成功,非零错误码
838  *
839  * @brief   time osd update task
840  * @param[in]pvParam : nonuse
841  * @return 0 success, non-zero error code.
842  */
OSD_TimeUpdate(HI_VOID * pvParam)843 static HI_VOID* OSD_TimeUpdate(HI_VOID* pvParam)
844 {
845     HI_S32 s32Ret = 0;
846     HI_S32 s32OsdIdx = 0;
847     time_t nowTime = 0;
848     time_t lastTime = 0;
849     prctl(PR_SET_NAME, __FUNCTION__, 0, 0, 0);
850 
851     while (s_bOSDTimeRun) {
852         nowTime = time(NULL); // also means time(&nowTime)
853         if (nowTime == lastTime) {
854             usleep(10000); // 10000:usleep time
855             continue;
856         } else {
857             localtime_r(&nowTime, &stTime);
858             OSD_Update_Relate_Info(s32OsdIdx);
859             lastTime = nowTime; /* update time */
860         }
861         usleep(500000); // 500000: usleep time
862     }
863 
864     return NULL;
865 }
866 
867 /*
868  * @brief osd模块初始化,例如:创建时间OSD更新任务
869  * @param[in] pstFonts:osd 字体库
870  * @return 0 成功,非零表示错误码
871  *
872  * @brief    osd module initialization, eg. create time osd update task.
873  * @param[in] pstFonts:osd fonts lib
874  * @return 0 success, non-zero error code.
875  */
HI_OSD_Init(const HI_OSD_FONTS_S * pstFonts)876 HI_S32 HI_OSD_Init(const HI_OSD_FONTS_S* pstFonts)
877 {
878     if (!(HI_TRUE != s_bOSDInitFlg)) {
879         return HI_EINITIALIZED;
880     }
881     if (pstFonts != NULL) {
882         if (!pstFonts->pfnGetFontMod) {
883             return HI_EINVAL;
884         }
885         if (pstFonts->u32FontWidth % BYTE_BITS) {
886             SAMPLE_PRT("FontWidth must be a multiple of %d.", BYTE_BITS);
887             return HI_EINVAL;
888         }
889         memcpy_s(&s_stOSDFonts, sizeof(HI_OSD_FONTS_S), pstFonts, sizeof(HI_OSD_FONTS_S));
890     } else {
891         memset_s(&s_stOSDFonts, sizeof(HI_OSD_FONTS_S), 0, sizeof(HI_OSD_FONTS_S));
892     }
893     HI_S32 s32Idx = 0;
894     HI_S32 s32Ret = HI_SUCCESS;
895 
896     /*
897      * 初始化OSD参数
898      * Init OSD Param
899      */
900     for (s32Idx = 0; s32Idx < HI_OSD_MAX_CNT; ++s32Idx) {
901         pthread_mutex_init(&s_stOSDParam[s32Idx].mutexLock, NULL);
902         pthread_mutex_lock(&s_stOSDParam[s32Idx].mutexLock);
903         memset_s(&s_stOSDParam[s32Idx], sizeof(OSD_PARAM_S), 0, sizeof(OSD_PARAM_S));
904         pthread_mutex_unlock(&s_stOSDParam[s32Idx].mutexLock);
905     }
906 
907     if (pstFonts != NULL) {
908         /*
909          * 创建时间OSD更新线程
910          * Create Time OSD Update Thread
911          */
912         s_bOSDTimeRun = HI_TRUE;
913         s32Ret = pthread_create(&s_OSDTimeTskId, NULL, OSD_TimeUpdate, NULL);
914         if (HI_SUCCESS != s32Ret) {
915             SAMPLE_PRT("create OSD_TimeUpdate failed:%s\n", strerror(errno));
916             return HI_ENORES;
917         }
918     }
919 
920     s_bOSDInitFlg = HI_TRUE;
921     return HI_SUCCESS;
922 }
923 
924 /*
925  * 初始化OSD字体
926  * Initialize OSD font
927  */
OsdInitFont(HI_CHAR * character,HI_U8 ** fontMod,HI_S32 * fontModLen)928 static int OsdInitFont(HI_CHAR *character, HI_U8 **fontMod, HI_S32 *fontModLen)
929 {
930     static const HI_CHAR baseChar = 0x20;
931 
932     /*
933      * 获取ASCII字体库中的字体模组
934      * Get Font Mod in ASCII Fontlib
935      */
936     if (!character || !fontMod || !fontModLen) {
937         return HI_FAILURE;
938     }
939     /*
940      * 如果参数是ASCII字符则返回true,否则返回NULL(0)
941      * Return true if the parameter is an ASCII character, otherwise NULL (0)
942      */
943     if (!IsAscii(character[0])) {
944         return HI_FAILURE;
945     }
946     HI_U32 offset = (character[0] - baseChar) * (OSD_FONT_MOD_H * OSD_FONT_MOD_W / HI_BYTE_BITS);
947     *fontMod = (HI_U8 *)G_FONT_LIB + offset;
948     *fontModLen = OSD_FONT_MOD_H * OSD_FONT_MOD_W / HI_BYTE_BITS;
949     return HI_SUCCESS;
950 }
951 
952 /*
953  * 初始化OsdSet库
954  * Initialize OsdSet lib
955  */
OsdLibInit(void)956 int OsdLibInit(void)
957 {
958     RecurMutexInit(&g_osdMutex);
959 
960 #   if defined(OSD_FONT_HZK) || defined(OSD_FONT_ASC)
961     SAMPLE_PRT("==================success=================\n");
962     HI_OSD_FONTS_S stOsdFonts;
963     stOsdFonts.u32FontWidth = OSD_FONT_MOD_W;
964     stOsdFonts.u32FontHeight = OSD_FONT_MOD_H;
965     stOsdFonts.pfnGetFontMod = OsdInitFont;
966     return HI_OSD_Init(&stOsdFonts);
967 #   else
968     SAMPLE_PRT("##################success##################\n");
969     return HI_OSD_Init(NULL);
970 #   endif
971 }
972 
Osd_Param_Config(const HI_OSD_ATTR_S * pstAttr,OSD_PARAM_S * pstOsdParam)973 HI_VOID Osd_Param_Config(const HI_OSD_ATTR_S* pstAttr, OSD_PARAM_S* pstOsdParam)
974 {
975     /*
976      * 更新属性
977      * Update Attribute
978      */
979     pstOsdParam->stAttr.stContent.u32Color = pstAttr->stContent.u32Color;
980     pstOsdParam->stAttr.stContent.u32BgColor = pstAttr->stContent.u32BgColor;
981 
982     if (HI_OSD_TYPE_BITMAP != pstAttr->stContent.enType) {
983         if (HI_OSD_TYPE_TIME == pstAttr->stContent.enType) {
984             /*
985              * 时间类型:更新时间字符串
986              * Time Type: Update time string
987              */
988             pstOsdParam->stAttr.stContent.enTimeFmt = pstAttr->stContent.enTimeFmt;
989             OSD_GetTimeStr(NULL, ((HI_OSD_ATTR_S*)pstAttr)->stContent.szStr, HI_OSD_MAX_STR_LEN);
990         }
991 
992         /*
993          * 更新字符串
994          * Update string
995          */
996         if (snprintf_s(pstOsdParam->stAttr.stContent.szStr, HI_OSD_MAX_STR_LEN,
997             HI_OSD_MAX_STR_LEN - 1, "%s", pstAttr->stContent.szStr) < 0) {
998             HI_ASSERT(0);
999         }
1000 
1001         pstOsdParam->stAttr.stContent.stBitmap.enPixelFormat = PIXEL_FORMAT_ARGB_1555;
1002         ((HI_OSD_ATTR_S*)pstAttr)->stContent.stBitmap.u32Width =
1003             pstAttr->stContent.stFontSize.u32Width * strnlen(pstOsdParam->stAttr.stContent.szStr, HI_OSD_MAX_STR_LEN);
1004         ((HI_OSD_ATTR_S*)pstAttr)->stContent.stBitmap.u32Height= pstAttr->stContent.stFontSize.u32Height;
1005         pstOsdParam->stAttr.stContent.stFontSize = pstAttr->stContent.stFontSize;
1006     } else {
1007         pstOsdParam->stAttr.stContent.stBitmap.enPixelFormat = pstAttr->stContent.stBitmap.enPixelFormat;
1008         pstOsdParam->stAttr.stContent.stBitmap.u64PhyAddr = pstAttr->stContent.stBitmap.u64PhyAddr;
1009         pstOsdParam->stAttr.stContent.stBitmap.pvData = pstAttr->stContent.stBitmap.pvData;
1010     }
1011     pstOsdParam->stAttr.stContent.stBitmap.u32Width = pstAttr->stContent.stBitmap.u32Width;
1012     pstOsdParam->stAttr.stContent.stBitmap.u32Height = pstAttr->stContent.stBitmap.u32Height;
1013     pstOsdParam->stAttr.stContent.enType = pstAttr->stContent.enType;
1014 
1015     return;
1016 }
1017 
OSD_Update_RGN_Content(const HI_OSD_ATTR_S * pstAttr,OSD_PARAM_S * pstOsdParam,HI_S32 s32OsdIdx)1018 static HI_S32 OSD_Update_RGN_Content(const HI_OSD_ATTR_S* pstAttr, OSD_PARAM_S* pstOsdParam, HI_S32 s32OsdIdx)
1019 {
1020     HI_S32 s32Ret = HI_SUCCESS;
1021     /*
1022      * 更新RGN内容
1023      * Update RGN Content
1024      */
1025     if (pstAttr->stContent.enType == HI_OSD_TYPE_BITMAP) {
1026         BITMAP_S stBitmap;
1027         stBitmap.enPixelFormat = PIXEL_FORMAT_ARGB_1555;
1028         stBitmap.u32Width = pstAttr->stContent.stBitmap.u32Width;
1029         stBitmap.u32Height = pstAttr->stContent.stBitmap.u32Height;
1030         stBitmap.pData = pstAttr->stContent.stBitmap.pvData;
1031         /*
1032          * 设置区域位图,即对区域进行位图填充
1033          * Set the area bitmap, that is, fill the area with a bitmap
1034          */
1035         s32Ret = HI_MPI_RGN_SetBitMap(s32OsdIdx, &stBitmap);
1036         SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, FAIL, "HI_MPI_RGN_SetBitMap. s32Ret: 0x%x\n", s32Ret);
1037     } else {
1038         /*
1039          * 时间/字符串类型:更新文本位图
1040          * Time/String Type: Update text bitmap
1041          */
1042         s32Ret = OSD_UpdateTextBitmap(s32OsdIdx, (HI_OSD_CONTENT_S*)&pstOsdParam->stAttr.stContent);
1043         SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, FAIL, "OSD_UpdateTextBitmap fail, err(%#x)\n", s32Ret);
1044     }
1045 
1046     HI_S32 s32DispIdx = 0;
1047     for (s32DispIdx = 0; s32DispIdx < pstAttr->u32DispNum ; ++s32DispIdx) {
1048         if (HI_TRUE == pstAttr->astDispAttr[s32DispIdx].bShow && HI_FALSE ==
1049             pstOsdParam->stAttr.astDispAttr[s32DispIdx].bShow) {
1050             OSD_RGNAttach(s32OsdIdx, &pstAttr->astDispAttr[s32DispIdx]);
1051         } else if (HI_FALSE == pstAttr->astDispAttr[s32DispIdx].bShow && HI_TRUE ==
1052             pstOsdParam->stAttr.astDispAttr[s32DispIdx].bShow) {
1053             OSD_RGNDetach(s32OsdIdx, &pstOsdParam->stAttr.astDispAttr[s32DispIdx]);
1054         }
1055     }
1056     s32Ret = OSD_Update(s32OsdIdx, pstAttr);
1057     SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, FAIL, "OSD_Update fail, err(%#x)\n", s32Ret);
1058 
1059     return s32Ret;
1060 
1061 FAIL:
1062     pthread_mutex_unlock(&pstOsdParam->mutexLock);
1063     return s32Ret;
1064 }
1065 
1066 /*
1067  * @brief 设置osd属性
1068  * @param[in] s32OsdIdx:osd索引,范围[0,HI_OSD_MAX_CNT)
1069  * @param[in] pstAttr:osd配置属性
1070  * @return 0 成功,非零错误码
1071  *
1072  * @brief    set osd attribute.
1073  * @param[in] s32OsdIdx:osd index, range[0,HI_OSD_MAX_CNT)
1074  * @param[in] pstAttr:osd configure attribute
1075  * @return 0 success,non-zero error code.
1076  */
HI_OSD_SetAttr(HI_S32 s32OsdIdx,const HI_OSD_ATTR_S * pstAttr)1077 HI_S32 HI_OSD_SetAttr(HI_S32 s32OsdIdx, const HI_OSD_ATTR_S* pstAttr)
1078 {
1079     /*
1080      * 检查模块是否初始化成功
1081      * Check Module Init or not
1082      */
1083     HI_ASSERT(HI_TRUE == s_bOSDInitFlg);
1084     /*
1085      * 检查输入的参数
1086      * Check Input Param
1087      */
1088     HI_ASSERT(s32OsdIdx >= 0);
1089     HI_ASSERT(HI_OSD_MAX_CNT > s32OsdIdx);
1090     HI_ASSERT(pstAttr);
1091     HI_ASSERT(HI_OSD_MAX_DISP_CNT >= pstAttr->u32DispNum);
1092 
1093     if (HI_OSD_TYPE_BITMAP == pstAttr->stContent.enType) {
1094         if (!pstAttr->stContent.stBitmap.pvData) {
1095             return HI_FAILURE;
1096         }
1097     } else {
1098         if (s_stOSDFonts.pfnGetFontMod == NULL) {
1099             SAMPLE_PRT("The font library is not registered,only support bitmaps OSD\n");
1100             return HI_FAILURE;
1101         }
1102     }
1103 
1104     HI_S32 s32Ret = HI_SUCCESS;
1105     OSD_PARAM_S* pstOsdParam = &s_stOSDParam[s32OsdIdx];
1106     pthread_mutex_lock(&pstOsdParam->mutexLock);
1107     HI_BOOL bOn = pstOsdParam->bOn;
1108 
1109     /*
1110      * 更新属性
1111      * Update Attribute
1112      */
1113     Osd_Param_Config(pstAttr, pstOsdParam);
1114     if (bOn) {
1115         if (pstOsdParam->stMaxSize.u32Width < pstOsdParam->stAttr.stContent.stBitmap.u32Width
1116             || pstOsdParam->stMaxSize.u32Height < pstOsdParam->stAttr.stContent.stBitmap.u32Height) {
1117             SAMPLE_PRT("RGN(%d) size increase[%d,%d->%d,%d], rebuild\n", s32OsdIdx,
1118                 pstOsdParam->stMaxSize.u32Width, pstOsdParam->stMaxSize.u32Height,
1119                 pstAttr->stContent.stBitmap.u32Width, pstAttr->stContent.stBitmap.u32Height);
1120             /*
1121              * 销毁区域
1122              * Destory region
1123              */
1124             s32Ret = OSD_DestroyRGN(s32OsdIdx, &pstOsdParam->stAttr);
1125             if (s32Ret != HI_SUCCESS) {
1126                 pthread_mutex_unlock(&pstOsdParam->mutexLock);
1127                 return s32Ret;
1128             }
1129 
1130             s32Ret = OSD_CreateRGN(s32OsdIdx, pstAttr);
1131             if (s32Ret != HI_SUCCESS) {
1132                 pthread_mutex_unlock(&pstOsdParam->mutexLock);
1133                 return s32Ret;
1134             }
1135         } else {
1136             OSD_Update_RGN_Content(pstAttr, pstOsdParam, s32OsdIdx);
1137         }
1138     }
1139 
1140     memcpy_s(pstOsdParam->stAttr.astDispAttr, sizeof(HI_OSD_DISP_ATTR_S) * HI_OSD_MAX_DISP_CNT,
1141         pstAttr->astDispAttr, sizeof(HI_OSD_DISP_ATTR_S) * HI_OSD_MAX_DISP_CNT);
1142     pstOsdParam->stAttr.u32DispNum = pstAttr->u32DispNum;
1143     pstOsdParam->stMaxSize.u32Width =
1144         max(pstOsdParam->stMaxSize.u32Width, pstOsdParam->stAttr.stContent.stBitmap.u32Width);
1145     pstOsdParam->stMaxSize.u32Height=
1146         max(pstOsdParam->stMaxSize.u32Height, pstOsdParam->stAttr.stContent.stBitmap.u32Height);
1147     pstOsdParam->bInit = HI_TRUE;
1148     pthread_mutex_unlock(&pstOsdParam->mutexLock);
1149 
1150     return HI_SUCCESS;
1151 }
1152 
OSD_Start(HI_S32 s32OsdIdx)1153 static HI_S32 OSD_Start(HI_S32 s32OsdIdx)
1154 {
1155     HI_S32 s32Ret = HI_SUCCESS;
1156     OSD_PARAM_S* pstOsdParam = &s_stOSDParam[s32OsdIdx];
1157 
1158     /*
1159      * 时间OSD:更新时间字符串和位图
1160      * Time OSD: Update time string and bitmap
1161      */
1162     if (HI_OSD_TYPE_TIME == pstOsdParam->stAttr.stContent.enType) {
1163         OSD_GetTimeStr(NULL, pstOsdParam->stAttr.stContent.szStr, HI_OSD_MAX_STR_LEN);
1164     }
1165 
1166     s32Ret = OSD_CreateRGN(s32OsdIdx, &pstOsdParam->stAttr);
1167     if (HI_SUCCESS != s32Ret) {
1168         SAMPLE_PRT("OSD_CreateRGN s32OsdIdx[%d] failed:[0x%08X]\n", s32OsdIdx, s32Ret);
1169         return s32Ret;
1170     }
1171     pstOsdParam->bOn = HI_TRUE;
1172     return HI_SUCCESS;
1173 }
1174 
1175 /*
1176  * @brief 按索引启动 osd
1177  * @param[in] s32OsdIdx:osd 索引,范围[0,HI_OSD_MAX_CNT)
1178  * @return 0 成功,非零错误码
1179  *
1180  * @brief    start osd by index.
1181  * @param[in] s32OsdIdx:osd index, range[0,HI_OSD_MAX_CNT)
1182  * @return 0 success,non-zero error code.
1183  */
HI_OSD_Start(HI_S32 s32OsdIdx)1184 HI_S32 HI_OSD_Start(HI_S32 s32OsdIdx)
1185 {
1186     /*
1187      * 检查模块是否初始化成功
1188      * Check Module Init or not
1189      */
1190     HI_ASSERT(HI_TRUE == s_bOSDInitFlg);
1191     /*
1192      * 检查输入的参数
1193      * Check Input Param
1194      */
1195     HI_ASSERT(s32OsdIdx >= 0);
1196     HI_ASSERT(HI_OSD_MAX_CNT > s32OsdIdx);
1197 
1198     HI_S32 s32Ret = HI_SUCCESS;
1199     OSD_PARAM_S* pstOsdParam = &s_stOSDParam[s32OsdIdx];
1200 
1201     pthread_mutex_lock(&pstOsdParam->mutexLock);
1202 
1203     /*
1204      * 检查OSD属性是否初始化
1205      * Check OSD Attrbute init or not
1206      */
1207     if (!pstOsdParam->bInit) {
1208         pthread_mutex_unlock(&pstOsdParam->mutexLock);
1209         SAMPLE_PRT("OSD[%d] not init yet!\n", s32OsdIdx);
1210         return HI_EINVAL;
1211     }
1212 
1213     /*
1214      * 检查OSD是否停止
1215      * Check OSD stop or not
1216      */
1217     if (pstOsdParam->bOn) {
1218         pthread_mutex_unlock(&pstOsdParam->mutexLock);
1219         SAMPLE_PRT("OSD[%d] has already started!\n", s32OsdIdx);
1220         return HI_SUCCESS;
1221     }
1222 
1223     s32Ret = OSD_Start(s32OsdIdx);
1224     pthread_mutex_unlock(&pstOsdParam->mutexLock);
1225     return s32Ret;
1226 }
1227 
1228 /*
1229  * 在OsdSet中设置指定区域的属性
1230  * Set attributes for the specified region in OsdSet
1231  */
OsdsSetRgn(OsdSet * self,int rgnHnd,const HI_OSD_ATTR_S * rgnAttr)1232 int OsdsSetRgn(OsdSet* self, int rgnHnd, const HI_OSD_ATTR_S* rgnAttr)
1233 {
1234     HI_ASSERT(self);
1235     HI_ASSERT(rgnHnd >= 0 && rgnHnd < HI_OSD_MAX_CNT);
1236     HI_ASSERT(g_osdHndPool[rgnHnd] && g_osdHndPool[rgnHnd] == (void*)self); // not need lock
1237     HI_OSD_ATTR_S attr;
1238     int ret;
1239 
1240     if (!rgnAttr) { // hidden the region
1241         if (memset_s(&attr, sizeof(attr), 0, sizeof(attr)) != EOK) {
1242             HI_ASSERT(0);
1243         }
1244         attr.u32DispNum = 1;
1245         attr.astDispAttr[0].bShow = HI_FALSE;
1246     } else {
1247         attr = *rgnAttr;
1248     }
1249 
1250     attr.astDispAttr[0].enBindedMod = self->bindMod;
1251     attr.astDispAttr[0].ModHdl = self->modHnd;
1252     attr.astDispAttr[0].ChnHdl = self->chnHnd;
1253 
1254     ret = HI_OSD_SetAttr(rgnHnd, &attr);
1255     SAMPLE_CHECK_EXPR_RET(ret, "HI_OSD_SetAttr FAIL, ret=%d\n", ret);
1256 
1257     ret = HI_OSD_Start(rgnHnd);
1258     SAMPLE_CHECK_EXPR_RET(ret, "HI_OSD_Start FAIL, ret=%d\n", ret);
1259     return 0;
1260 }
1261 
1262 #ifdef __cplusplus
1263 #if __cplusplus
1264 }
1265 #endif
1266 #endif /* End of #ifdef __cplusplus */