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 */