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