#include #include #include #include #include #include #include #include "fh_common.h" #include "fh_system_mpi.h" #include "fh_system_mpi.h" #include "fh_vb_mpi.h" #include "fh_defines.h" #include "vmm_api.h" #include "fh_vpu_mpi.h" #include "fh_vpu_mpi.h" #include "fh_vgs2_mpi.h" #include "fh_vgs_mpi.h" #include "types/bufCtrl.h" #include "common.h" #include "xconfig.h" #include "font.h" #define STB_TRUETYPE_IMPLEMENTATION #include "stb_truetype.h" /* global variables */ static stbtt_fontinfo gst_infoFont; extern bool g_bRunning; /* functions */ static int __maybe_unused __gosd_font_init(void) { /* 初始化字体 */ if (!stbtt_InitFont(&gst_infoFont, g_fontBuffer, 0)) { printf("stb init font failed\n"); return -1; } return 0; } static void __maybe_unused __gosd_font_cleanup(void) { } static int __maybe_unused __vpu_set_user_pic(int group, int chn, int width, int height, int type, char* fname) { int ret = 0; FILE *fp = NULL; if (NULL == fname) { return -1; } else { fp = fopen(fname, "rb"); if (NULL == fp) { printf("ERR: file: %s open failed!\n", fname); return -1; } } { FH_UINT32 u32Size = width * height * 2; VB_BLK VbBlk; FH_UINT32 u32PhyAddr; FH_UINT8 *pVirAddr; FH_VPU_USER_PIC userPic; int file_size = 0; int fpos = 0; memset(&userPic, 0, sizeof(userPic)); if (type == VPU_VOMODE_SCAN) { u32Size = width * height * 3 / 2; } else if (type == VPU_VOMODE_10BIT_NV12) { u32Size = width * height * 3 / 2; u32Size = u32Size * 10 >> 3; } fseek(fp, 0, SEEK_END); file_size = ftell(fp); fseek(fp, 0, SEEK_SET); fpos = 0; while (fpos < file_size) { /* get video buffer block form common pool */ VbBlk = FH_VB_GetBlock(VB_INVALID_POOLID, u32Size, NULL); if (VB_INVALID_HANDLE == VbBlk) { printf("ERR: SetUserPic FH_VB_GetBlock failed!\n"); ret = -__LINE__; goto exit_set_pic; } /* get physical address*/ u32PhyAddr = FH_VB_Handle2PhysAddr(VbBlk); if (0 == u32PhyAddr) { printf("ERR: SetUserPic FH_VB_Handle2PhysAddr failed!\n"); ret = -__LINE__; goto exit_set_pic; } pVirAddr = FH_SYS_Mmap(u32PhyAddr, u32Size); if (NULL == pVirAddr) { printf("ERR: SetUserPic FH_SYS_MmapCache failed!\n"); FH_VB_ReleaseBlock(VbBlk); ret = -__LINE__; goto exit_set_pic; } //read the yuv data from the file fseek(fp, fpos, SEEK_SET); fread(pVirAddr, 1, u32Size, fp); FH_SYS_Munmap(pVirAddr, u32Size); userPic.pic_size.u32Width = width; userPic.pic_size.u32Height = height; userPic.yluma = u32PhyAddr; userPic.chroma = u32PhyAddr + width * height; if (type == VPU_VOMODE_10BIT_NV12) { userPic.chroma = u32PhyAddr + (width * height * 10 >> 3); } if ((type == VPU_VOMODE_SCAN) || (VPU_VOMODE_NV16 == type)) { userPic.ystride = width; userPic.cstride = width; } else if (type == VPU_VOMODE_10BIT_NV12) { userPic.ystride = width * 10 >> 3; userPic.cstride = userPic.ystride; } else { userPic.ystride = width * 2; userPic.cstride = width * 2; } userPic.time_stamp = 0; userPic.data_format = type; userPic.work_mode = VPU_MODE_MEM; if (type == VPU_VOMODE_10BIT_NV12) { userPic.work_mode = VPU_MODE_OFFLINE_2DLUT; } userPic.pool_id = FH_VB_Handle2PoolId(VbBlk); FH_SYS_GetCurPts(&userPic.time_stamp ); if (0 == fpos) { printf("userpic: yluma = 0x%x, chroma = 0x%x\n", userPic.yluma , userPic.chroma); ret = FH_VPSS_SendUserPic(group, &userPic); //FY_MPI_VB_SubUserCnt(VbBlk); break; } } } exit_set_pic: if (fp) { fclose(fp); } return ret; } static int __maybe_unused __load_user_pic(int width, int height, int type, char* fname, FH_VPU_USER_PIC* pUsrPic) { int ret = 0; FILE *fp = NULL; if (NULL == fname) { return -1; } else { fp = fopen(fname, "rb"); if (NULL == fp) { printf("ERR: file: %s open failed!\n", fname); return -1; } } { FH_UINT32 u32Size = width * height * 2; VB_BLK VbBlk; FH_UINT32 u32PhyAddr; FH_UINT8 *pVirAddr; FH_VPU_USER_PIC userPic; int file_size = 0; int fpos = 0; memset(&userPic, 0, sizeof(userPic)); if (type == VPU_VOMODE_SCAN) { u32Size = width * height * 3 / 2; } else if (type == VPU_VOMODE_10BIT_NV12) { u32Size = width * height * 3 / 2; u32Size = u32Size * 2; } fseek(fp, 0, SEEK_END); file_size = ftell(fp); fseek(fp, 0, SEEK_SET); fpos = 0; while (fpos < file_size) { /* get video buffer block form common pool */ VbBlk = FH_VB_GetBlock(VB_INVALID_POOLID, u32Size, NULL); if (VB_INVALID_HANDLE == VbBlk) { printf("ERR: SetUserPic FH_VB_GetBlock failed!\n"); ret = -__LINE__; goto exit_set_pic; } /* get physical address*/ u32PhyAddr = FH_VB_Handle2PhysAddr(VbBlk); if (0 == u32PhyAddr) { printf("ERR: SetUserPic FH_VB_Handle2PhysAddr failed!\n"); ret = -__LINE__; goto exit_set_pic; } pVirAddr = FH_SYS_Mmap(u32PhyAddr, u32Size); if (NULL == pVirAddr) { printf("ERR: SetUserPic FH_SYS_MmapCache failed!\n"); FH_VB_ReleaseBlock(VbBlk); ret = -__LINE__; goto exit_set_pic; } //read the yuv data from the file fseek(fp, fpos, SEEK_SET); fread(pVirAddr, 1, u32Size, fp); FH_SYS_Munmap(pVirAddr, u32Size); userPic.pic_size.u32Width = width; userPic.pic_size.u32Height = height; userPic.yluma = u32PhyAddr; userPic.chroma = u32PhyAddr + width * height; if (type == VPU_VOMODE_10BIT_NV12) { userPic.chroma = u32PhyAddr + (width * height * 2); } if ((type == VPU_VOMODE_SCAN) || (VPU_VOMODE_NV16 == type)) { userPic.ystride = width; userPic.cstride = width; } else if (type == VPU_VOMODE_10BIT_NV12) { userPic.ystride = width * 2; userPic.cstride = userPic.ystride; } else { userPic.ystride = width * 2; userPic.cstride = width * 2; } userPic.time_stamp = 0; userPic.data_format = type; userPic.work_mode = VPU_MODE_MEM; if (type == VPU_VOMODE_10BIT_NV12) { userPic.work_mode = VPU_MODE_OFFLINE_2DLUT; } userPic.pool_id = FH_VB_Handle2PoolId(VbBlk); FH_SYS_GetCurPts(&userPic.time_stamp ); if (0 == fpos) { printf("userpic: yluma = 0x%x, chroma = 0x%x\n", userPic.yluma , userPic.chroma); memcpy(pUsrPic, &userPic, sizeof(userPic)); break; } } } exit_set_pic: if (fp) { fclose(fp); } return ret; } static int __generate_user_pic(int width, int height, int type, FH_VPU_USER_PIC* pUsrPic) { int ret = 0; FH_UINT32 u32Size = width * height * 2; FH_UINT32 vgstype = 0; //for user pic VB_BLK VbBlk; FH_UINT32 u32YUVPhyAddr = 0; if (type == VPU_VOMODE_SCAN) { u32Size = width * height * 3 / 2; vgstype = PIXEL_FMT_YUV_SEMIPLANAR_420; } else if (type == VPU_VOMODE_NV16) { u32Size = width * height * 2; vgstype = PIXEL_FMT_YUV_SEMIPLANAR_422; } else { printf("only support NV12/NV16! type = %d\n", type); return -1; } //generate a color bar graph with VGS /* get video buffer block form common pool */ VbBlk = FH_VB_GetBlock(VB_INVALID_POOLID, u32Size, NULL); if (VB_INVALID_HANDLE == VbBlk) { printf("ERR: SetUserPic FH_VB_GetBlock failed!\n"); ret = -__LINE__; goto exit0; } /* get physical address*/ u32YUVPhyAddr = FH_VB_Handle2PhysAddr(VbBlk); if (0 == u32YUVPhyAddr) { printf("ERR: SetUserPic FH_VB_Handle2PhysAddr failed!\n"); ret = -__LINE__; goto exit0; } VIDEO_FRAME_INFO_S frmYUV; memset(&frmYUV, 0, sizeof(frmYUV)); frmYUV.stVFrame.u32PhyAddr[0] = u32YUVPhyAddr; frmYUV.stVFrame.u32PhyAddr[1] = u32YUVPhyAddr + width * height; frmYUV.stVFrame.u32Width = width; frmYUV.stVFrame.u32Height = height; frmYUV.stVFrame.u32Stride[0] = width; frmYUV.stVFrame.u32Stride[1] = width; frmYUV.stVFrame.enPixelFormat = vgstype; frmYUV.stVFrame.u32Field = VIDEO_FIELD_FRAME; frmYUV.stVFrame.enVideoFormat = VIDEO_FORMAT_LINEAR; frmYUV.u32PoolId = VB_INVALID_POOLID; FH_UINT32 rgbs[] = {0xFFFF0000, 0xFFED9121, 0xFFFFFF00, 0xFF00C957, 0xFF00FFFF, 0xFF1E90FF, 0xFF8A2BE2, 0xff000000}; int cnt = sizeof(rgbs) / sizeof(FH_UINT32); for (int i = 0; i < cnt; i++) { RECT_S rect; rect.s32X = i * width / cnt; rect.s32Y = 0; rect.u32Width = width / cnt; rect.u32Height = height * 7 / 8; FH_VGS_DoFillColor(&frmYUV, &rect, rgbs[i]); } cnt = 0x10; for (int i = 0; i < cnt; i++) { RECT_S rect; rect.s32X = i * width / cnt; rect.s32Y = height * 7 / 8; rect.u32Width = width / cnt; rect.u32Height = height / 8; FH_UINT32 rgb = 0xff | i | i << 4 | i << 8 | i << 12 | i << 16 | i << 20 ; FH_VGS_DoFillColor(&frmYUV, &rect, rgb); } //convert to user frame memset(pUsrPic, 0, sizeof(FH_VPU_USER_PIC)); pUsrPic->pic_size.u32Width = width; pUsrPic->pic_size.u32Height = height; pUsrPic->yluma = u32YUVPhyAddr; pUsrPic->chroma = u32YUVPhyAddr + width * height; pUsrPic->ystride = width; pUsrPic->cstride = width; pUsrPic->data_format = type; pUsrPic->work_mode = VPU_MODE_MEM; pUsrPic->pool_id = FH_VB_Handle2PoolId(VbBlk); FH_SYS_GetCurPts(&pUsrPic->time_stamp ); exit0: return ret; } static int __vpu_gosd_draw_text(unsigned char *bitmap, int width, int height, char *word) { int ascent = 0; int descent = 0; int lineGap = 0; /* 计算字体缩放 */ float pixels = 32.0; float scale = stbtt_ScaleForPixelHeight(&gst_infoFont, pixels); /* scale = pixels / (ascent - descent) */ /** * 获取垂直方向上的度量 * ascent:字体从基线到顶部的高度; * descent:基线到底部的高度,通常为负值; * lineGap:两个字体之间的间距; * 行间距为:ascent - descent + lineGap。 */ stbtt_GetFontVMetrics(&gst_infoFont, &ascent, &descent, &lineGap); /* 根据缩放调整字高 */ ascent = roundf(ascent * scale); descent = roundf(descent * scale); int x = 0; /*位图的x*/ /* 循环加载word中每个字符 */ for (int i = 0; i < strlen(word); ++i) { /** * 获取水平方向上的度量 * advanceWidth:字宽; * leftSideBearing:左侧位置; */ int advanceWidth = 0; int leftSideBearing = 0; stbtt_GetCodepointHMetrics(&gst_infoFont, word[i], &advanceWidth, &leftSideBearing); /* 获取字符的边框(边界) */ int c_x1, c_y1, c_x2, c_y2; stbtt_GetCodepointBitmapBox(&gst_infoFont, word[i], scale, scale, &c_x1, &c_y1, &c_x2, &c_y2); /* 计算位图的y (不同字符的高度不同) */ int y = ascent + c_y1 + 8; //+8 add y offset /* 渲染字符 */ int byteOffset = x + roundf(leftSideBearing * scale) + (y * width); stbtt_MakeCodepointBitmap(&gst_infoFont, bitmap + byteOffset, c_x2 - c_x1, c_y2 - c_y1, width, scale, scale, word[i]); /* 调整x */ x += roundf(advanceWidth * scale); /* 调整字距 */ int kern; kern = stbtt_GetCodepointKernAdvance(&gst_infoFont, word[i], word[i + 1]); x += roundf(kern * scale); } return 0; } static int __vpu_gosd_draw_chn_info(int grpid, int chn, int width, int height, int type, VB_BLK *pVbBlk) { int ret = 0; char chntilte[64]; char chntype[16]; switch (type) { case VPU_VOMODE_SCAN: strcpy(chntype, "NV12"); break; case VPU_VOMODE_NV16: strcpy(chntype, "NV16"); break; case VPU_VOMODE_YUYV: strcpy(chntype, "YUYV"); break; case VPU_VOMODE_BLK : strcpy(chntype, "BLK"); break; case VPU_VOMODE_RGB888: strcpy(chntype, "RGB888"); break; case VPU_VOMODE_TILE192: strcpy(chntype, "TILE192"); break; case VPU_VOMODE_TILE224: strcpy(chntype, "TILE224"); break; case VPU_VOMODE_TILE256: strcpy(chntype, "TILE256"); break; case VPU_VOMODE_RRGGBB: strcpy(chntype, "RRGGBB"); break; default: sprintf(chntype, "T%d", type); } sprintf(chntilte, "CH%d: %dx%d %s", chn, width, height, chntype); //allocate the memory, generate the bitmap int bitmap_w = ALIGNTO(width / 2 , 16); /* 位图的宽 */ int bitmap_h = 48; /* 位图的高 */ VB_BLK VbBlk; FH_UINT32 u32PhyAddr; FH_UINT8 *pVirAddr; int size = bitmap_w * bitmap_h; /* get video buffer block form common pool */ VbBlk = FH_VB_GetBlock(VB_INVALID_POOLID, size, NULL); if (VB_INVALID_HANDLE == VbBlk) { printf("ERR: SetUserPic FY_MPI_VB_GetBlock failed!\n"); ret = -__LINE__; goto exit; } /* get physical address*/ u32PhyAddr = FH_VB_Handle2PhysAddr(VbBlk); if (0 == u32PhyAddr) { printf("ERR: SetUserPic FY_MPI_VB_Handle2PhysAddr failed!\n"); ret = -__LINE__; goto exit; } pVirAddr = FH_SYS_Mmap(u32PhyAddr, size); if (NULL == pVirAddr) { printf("ERR: SetUserPic FY_MPI_SYS_MmapCache failed!\n"); FH_VB_ReleaseBlock(VbBlk); ret = -__LINE__; goto exit; } memset(pVirAddr, 0, size); __vpu_gosd_draw_text(pVirAddr, bitmap_w, bitmap_h, chntilte); for (int i = 0; i < size; i++) { pVirAddr[i] = pVirAddr[i] >> 4; } FH_SYS_Munmap(pVirAddr, size); //set the gosd FH_VPU_LOGOV2 logo; memset(&logo, 0, sizeof(logo)); logo.logo_enable = 1; logo.logo_idx = 0; logo.logo_pixdepth = 8; logo.logo_startpos.u32X = 32; logo.logo_startpos.u32Y = 32; logo.stride_value = bitmap_w; logo.logo_addr = u32PhyAddr; logo.logo_cfg.global_alpha_en = 1; logo.logo_cfg.global_alpha = 80; logo.logo_cfg.rgb16_type = 1; logo.logo_cfg.logo_size.u32Width = bitmap_w; logo.logo_cfg.logo_size.u32Height = bitmap_h; for (int i = 0; i < 16; i++) { FH_UINT32 v = ((i == 0) ? 0 : i * 16 + 1); logo.color[i] = ((0xff << 24) | (v << 16) | (v << 8) | v ); } ret = FH_VPSS_SetChnGraphV2(grpid, chn, &logo); if (ret) { printf("FH_VPSS_SetChnGraphV2 fsailed! ret = 0x%x\n", ret); } if(pVbBlk) { *pVbBlk = VbBlk; } exit: //FH_VB_ReleaseBlock(VbBlk); return ret; } static int __gosd_load_logo(char* fname, VB_BLK* pVB) { int ret = 0; FILE *fp = NULL; *pVB = VB_INVALID_HANDLE; if (NULL == fname) { return -1; } else { fp = fopen(fname, "rb"); if (NULL == fp) { printf("ERR: file: %s open failed!\n", fname); return -1; } } { VB_BLK VbBlk; FH_UINT32 u32PhyAddr; FH_UINT8 *pVirAddr; FH_VPU_USER_PIC userPic; int file_size = 0; int fpos = 0; memset(&userPic, 0, sizeof(userPic)); fseek(fp, 0, SEEK_END); file_size = ftell(fp); fseek(fp, 0, SEEK_SET); fpos = 0; while (fpos < file_size) { /* get video buffer block form common pool */ VbBlk = FH_VB_GetBlock(VB_INVALID_POOLID, file_size, NULL); if (VB_INVALID_HANDLE == VbBlk) { printf("ERR: SetUserPic FH_VB_GetBlock failed!\n"); ret = -__LINE__; goto exit_set_pic; } /* get physical address*/ u32PhyAddr = FH_VB_Handle2PhysAddr(VbBlk); if (0 == u32PhyAddr) { printf("ERR: SetUserPic FH_VB_Handle2PhysAddr failed!\n"); ret = -__LINE__; goto exit_set_pic; } pVirAddr = FH_SYS_Mmap(u32PhyAddr, file_size); if (NULL == pVirAddr) { printf("ERR: SetUserPic FH_SYS_MmapCache failed!\n"); FH_VB_ReleaseBlock(VbBlk); ret = -__LINE__; goto exit_set_pic; } //read the yuv data from the file fread(pVirAddr, 1, file_size, fp); FH_SYS_Munmap(pVirAddr, file_size); *pVB = VbBlk; break; } } exit_set_pic: if (fp) { fclose(fp); } return ret; } static int __vpu_gosd_group(int grpid) { int ret = 0; FH_VPU_LOGOV2 logo; VB_BLK vb = VB_INVALID_HANDLE; ret = __gosd_load_logo("res/logo_565.rgb", &vb); if (!ret) { memset(&logo, 0, sizeof(logo)); logo.logo_enable = 1; logo.logo_idx = 1; logo.logo_pixdepth = 16; //16bit logo.logo_startpos.u32X = 32; logo.logo_startpos.u32Y = 512; logo.stride_value = 720 * 2; logo.logo_addr = FH_VB_Handle2PhysAddr(vb); logo.logo_cfg.global_alpha_en = 1; logo.logo_cfg.global_alpha = 128; logo.logo_cfg.rgb16_type = 1; logo.logo_cfg.logo_size.u32Width = 720; logo.logo_cfg.logo_size.u32Height = 42; ret = FH_VPSS_SetGlbGraphV2(grpid, &logo); if (ret) { printf("FH_VPSS_SetGlbGraphV2 fsailed! ret = 0x%x\n", ret); } } return ret; } static int __vpu_gosd_draw_title(int grpid, int chn, int x, int y, int index, char* chntilte, VB_BLK *pVbBlk) { int ret = 0; FH_VPU_CHN_CONFIG stChnAttr; ret = FH_VPSS_GetChnAttr(grpid, chn, &stChnAttr); //allocate the memory, generate the bitmap int bitmap_w = ALIGNTO(stChnAttr.vpu_chn_size.u32Width / 2 , 16); /* 位图的宽 */ int bitmap_h = 48; /* 位图的高 */ VB_BLK VbBlk; FH_UINT32 u32PhyAddr; FH_UINT8 *pVirAddr; int size = bitmap_w * bitmap_h; /* get video buffer block form common pool */ VbBlk = FH_VB_GetBlock(VB_INVALID_POOLID, size, NULL); if (VB_INVALID_HANDLE == VbBlk) { printf("ERR: SetUserPic FY_MPI_VB_GetBlock failed!\n"); ret = -__LINE__; goto exit; } /* get physical address*/ u32PhyAddr = FH_VB_Handle2PhysAddr(VbBlk); if (0 == u32PhyAddr) { printf("ERR: SetUserPic FY_MPI_VB_Handle2PhysAddr failed!\n"); ret = -__LINE__; goto exit; } pVirAddr = FH_SYS_Mmap(u32PhyAddr, size); if (NULL == pVirAddr) { printf("ERR: SetUserPic FY_MPI_SYS_MmapCache failed!\n"); FH_VB_ReleaseBlock(VbBlk); ret = -__LINE__; goto exit; } memset(pVirAddr, 0, size); __vpu_gosd_draw_text(pVirAddr, bitmap_w, bitmap_h, chntilte); for (int i = 0; i < size; i++) { pVirAddr[i] = pVirAddr[i] >> 4; } FH_SYS_Munmap(pVirAddr, size); //set the gosd FH_VPU_LOGOV2 logo; memset(&logo, 0, sizeof(logo)); logo.logo_enable = 1; logo.logo_idx = index; logo.logo_pixdepth = 8; logo.logo_startpos.u32X = x; logo.logo_startpos.u32Y = y; logo.stride_value = bitmap_w; logo.logo_addr = u32PhyAddr; logo.logo_cfg.global_alpha_en = 1; logo.logo_cfg.global_alpha = 80; logo.logo_cfg.rgb16_type = 1; logo.logo_cfg.logo_size.u32Width = bitmap_w; logo.logo_cfg.logo_size.u32Height = bitmap_h; for (int i = 0; i < 16; i++) { FH_UINT32 v = ((i == 0) ? 0 : i * 16 + 1); logo.color[i] = ((0xff << 24) | (v << 16) | (v << 8) | v ); } ret = FH_VPSS_SetChnGraphV2(grpid, chn, &logo); if (ret) { printf("FH_VPSS_SetChnGraphV2 fsailed! ret = 0x%x\n", ret); } if(pVbBlk) { *pVbBlk = VbBlk; } exit: //FH_VB_ReleaseBlock(VbBlk); return ret; } static int __vpu_gosd_update_title(int grpid, int chn, int index, char* chntilte) { int ret = 0; //get the current osd FH_VPU_LOGOV2 logo; memset(&logo, 0, sizeof(logo)); logo.logo_idx = index; ret = FH_VPSS_GetChnGraphV2(grpid, chn, &logo); IPO_LOG_CHECK_GOTO(ret, exit, "FH_VPSS_GetChnGraphV2 failed! ret = 0x%x", ret); //allocate the memory, generate the bitmap int bitmap_w = logo.logo_cfg.logo_size.u32Width; /* 位图的宽 */ int bitmap_h = logo.logo_cfg.logo_size.u32Height; /* 位图的高 */ FH_UINT32 u32PhyAddr; FH_UINT8 *pVirAddr; int size = bitmap_w * bitmap_h; /* get video buffer block form common pool */ u32PhyAddr = logo.logo_addr; pVirAddr = FH_SYS_Mmap(u32PhyAddr, size); if (NULL == pVirAddr) { printf("ERR: SetUserPic FY_MPI_SYS_MmapCache failed!\n"); ret = -__LINE__; goto exit; } memset(pVirAddr, 0, size); __vpu_gosd_draw_text(pVirAddr, bitmap_w, bitmap_h, chntilte); for (int i = 0; i < size; i++) { pVirAddr[i] = pVirAddr[i] >> 4; } FH_SYS_Munmap(pVirAddr, size); exit: return ret; } static int __vpu_set_mask(int grpid, int src_width, int src_height, const char* prefix) { int i; FH_VPU_MASK mask; memset(&mask, 0, sizeof(mask)); mask.masaic.masaic_enable = config_get_int(prefix, "mask.masaic.enable", 0); mask.masaic.masaic_size = config_get_int(prefix, "mask.masaic.size", 0); mask.color = config_get_int(prefix, "mask.color", 0);; for (i = 0; i < MAX_MASK_AREA; i++) { mask.mask_enable[i] = 1; mask.area_value[i].u32X = rand() % src_width; mask.area_value[i].u32Y = rand() % src_height; mask.area_value[i].u32Width = rand() % (src_width - mask.area_value[i].u32X); mask.area_value[i].u32Height = rand() % (src_height - mask.area_value[i].u32Y); } FH_VPSS_SetMask(grpid, &mask); return 0; } int vpu_group_init_by_config(const char* node) { FH_SINT32 ret = 0; FH_VPU_SET_GRP_INFO grp_info; FH_UINT32 grpid = 0; FH_UINT32 chan_vpu = 0; FH_VPU_SIZE vi_pic; //fill the group info memset(&grp_info, 0, sizeof(grp_info)); grp_info.vi_max_size.u32Width = config_get_int(node, "group.vi_max_size.u32Width", -1); grp_info.vi_max_size.u32Height = config_get_int(node, "group.vi_max_size.u32Height", -1); grp_info.ycmean_en = config_get_int(node, "group.ycmean_en", 0); grp_info.ycmean_ds = config_get_int(node, "group.ycmean_ds", 0); ret = FH_VPSS_CreateGrp(grpid, &grp_info); if (ret) { printf("Error(%d - %x): FH_VPSS_CreateGrp (grp):(%d)!\n", ret, ret, grpid); return ret; } //set vi attr vi_pic.vi_size.u32Width = config_get_int(node, "group.vi_max_size.u32Width", -1); vi_pic.vi_size.u32Height = config_get_int(node, "group.vi_max_size.u32Height", -1); vi_pic.crop_area.crop_en = 0; vi_pic.crop_area.vpu_crop_area.u32X = 0; vi_pic.crop_area.vpu_crop_area.u32Y = 0; vi_pic.crop_area.vpu_crop_area.u32Width = 0; vi_pic.crop_area.vpu_crop_area.u32Height = 0; ret = FH_VPSS_SetViAttr(grpid, &vi_pic); if (ret != 0) { printf("Error(%d - %x): FH_VPSS_SetViAttr (grp):(%d)!\n", ret, ret, grpid); return ret; } int vimode = config_get_int(node, "group.vimode", VPU_MODE_MEM); FH_VPSS_Enable(grpid, vimode); //set group osd __vpu_gosd_group(grpid); //get channel info for (int i = 0; i < 5; i++) { char chnode[32]; if (0 == config_has_index(node, "channels", i)) { continue; } sprintf(chnode, "%s.channels[%d]", node, i); FH_VPU_CHN_INFO chn_info; FH_VPU_CHN_CONFIG chn_attr; int chn_width, chn_height, chn_type; chan_vpu = i; memset(&chn_info, 0, sizeof(chn_info)); chn_info.bgm_enable = config_get_int(chnode, "info.bgm_enable", 0); chn_info.cpy_enable = config_get_int(chnode, "info.cpy_enable", 0); chn_info.sad_enable = config_get_int(chnode, "info.sad_enable", 0); chn_info.bgm_ds = config_get_int(chnode, "info.bgm_ds", 0); chn_info.chn_max_size.u32Width = config_get_int(chnode, "info.chn_max_size.u32Width", -1); chn_info.chn_max_size.u32Height = config_get_int(chnode, "info.chn_max_size.u32Height", -1); chn_info.out_mode = config_get_int(chnode, "info.out_mode", -1); chn_info.support_mode = config_get_int(chnode, "info.support_mode", -1); chn_info.bufnum = config_get_int(chnode, "info.bufnum", 0); chn_info.max_stride = config_get_int(chnode, "info.max_stride", 0); ret = FH_VPSS_CreateChn(grpid, chan_vpu, &chn_info); if (ret != 0) { printf("Error(%d - %x): FH_VPSS_CreateChn (grp-chn):(%d-%d)!\n", ret, ret, grpid, chan_vpu); return ret; } if(config_has_key(chnode, "info", "visel")) { int visel = config_get_int(chnode, "info.visel", 1); if(0 == visel) { ret = FH_VPSS_SetChnViSel(grpid, chan_vpu, visel); IPO_LOG_PRT("Set visel to %d for CHN %d, ret = 0x%x\n", visel, chan_vpu, ret); } } if (0 == config_has_key(chnode, NULL, "config")) { continue; } memset(&chn_attr, 0, sizeof(chn_attr)); chn_width = config_get_int(chnode, "config.vpu_chn_size.u32Width", -1); chn_height = config_get_int(chnode, "config.vpu_chn_size.u32Height", -1); chn_attr.vpu_chn_size.u32Width = chn_width; chn_attr.vpu_chn_size.u32Height = chn_height; chn_attr.stride = config_get_int(chnode, "config.stride", 0); chn_attr.offset = config_get_int(chnode, "config.offset", 0); chn_attr.depth = config_get_int(chnode, "config.depth", -1); ret = FH_VPSS_SetChnAttr(grpid, chan_vpu, &chn_attr); if (ret != 0) { printf("Error(%d - %x): FH_VPSS_SetChnAttr (grp-chn):(%d-%d)!\n", ret, ret, grpid, chan_vpu); return ret; } chn_type = config_get_int(chnode, "vomode", -1); ret = FH_VPSS_SetVOMode(grpid, chan_vpu, chn_type); if (ret != 0) { printf("Error(%d - %x): FH_VPSS_SetVOMode (grp-chn):(%d-%d)!\n", ret, ret, grpid, chan_vpu); return ret; } ret = FH_VPSS_SetVORotate(grpid, chan_vpu, 0); if (ret != 0) { printf("Error(%d - %x): FH_VPSS_SetVORotate (grp-chn):(%d-%d)!\n", ret, ret, grpid, chan_vpu); return ret; } ret = FH_VPSS_OpenChn(grpid, chan_vpu); if (ret != 0) { printf("Error(%d - %x): FH_VPSS_OpenChn (grp-chn):(%d-%d)!\n", ret, ret, grpid, chan_vpu); return ret; } //draw osd for channel if (chan_vpu < 3) { __vpu_gosd_draw_chn_info(grpid, chan_vpu, chn_width, chn_height, chn_type, NULL); FH_UINT64 tick = 0; FH_SYS_GetCurPts(&tick); char osdtime[64]; sprintf(osdtime, "Tick: %lld\n", tick); __vpu_gosd_draw_title(grpid, chan_vpu, 32, 100, 1, osdtime, NULL); } } //set the mask if(config_has_key(node, NULL, "mask")) { __vpu_set_mask(grpid, vi_pic.vi_size.u32Width, vi_pic.vi_size.u32Height, node); } return ret; } int vpu_update_gosd(int grpid, int chn, int index) { FH_UINT64 tick = 0; FH_SYS_GetCurPts(&tick); char osdtime[64]; sprintf(osdtime, "Tick: %lld\n", tick); __vpu_gosd_update_title(grpid, chn, 1, osdtime); return 0; } void vpu_send_offline_pic(void* param) { int ret = 0; int vi_mode = 0; FH_UINT32 grpid = 0; FH_UINT32 cnt = 0; char *node = (char*)param; IPO_LOG_PRT("node = %s!\n", node); vi_mode = config_get_int(node, "group.vimode", VPU_MODE_MEM); IPO_LOG_PRT("vi_mode = %d\n", vi_mode); if ((VPU_MODE_MEM == vi_mode) || (VPU_MODE_OFFLINE_2DLUT == vi_mode)) { int src_width = config_get_int(node, "src.width", 0); int src_height = config_get_int(node, "src.height", 0); int mode = config_get_int(node, "src.mode", VPU_VOMODE_SCAN); FH_VPU_USER_PIC userpic; const char *fname = config_get_string(node, "src.filename", NULL); if (NULL == fname) { IPO_LOG_PRT("no src file must be given!generate it!!\n"); __generate_user_pic(src_width, src_height, mode, &userpic); } else { IPO_LOG_PRT("yuv file = %s\n", fname); __load_user_pic(src_width, src_height, mode, (char*)fname, &userpic); } while (g_bRunning) { ret = FH_VPSS_SendUserPic(grpid, &userpic); if (0 == ret) { ++cnt; } { usleep(500 * 1000); } } } } int vpu_test_case(int tcase) { FH_SINT32 ret; //FH_UINT32 grpid = 0; FH_UINT64 duration = 0; FH_UINT32 intval = 0; char node[64]; char cases[64]; sprintf(cases, "test_cases[%d]", tcase); sprintf(node, "test_cases[%d].vpu", tcase); //get test param duration = config_get_int(cases, "param.duration", 2000); intval = config_get_int(cases, "param.interval", 0); printf("case[%d: duration = %lld, intval = %d\n", tcase, duration, intval); duration = duration * 1000; ret = vpu_group_init_by_config(node); if (0 != ret) { printf("vpu_group_chn_init failed!\n"); return ret; } return ret; } void vpu_test_channels(void *param) { FH_SIZE sizes[] = { {352, 288}, {640, 480}, {720, 576}, {1280, 720}, {1920, 1088}, {2560, 1440}, {3840, 2160}, {4096, 2160}, }; int vomodes[] = {VPU_VOMODE_BLK, VPU_VOMODE_SCAN, VPU_VOMODE_TILE192, VPU_VOMODE_TILE224, VPU_VOMODE_TILE256}; int ret = 0; int szz[] = {8, 5, 4}; int mods[] = {5, 5, 2}; int grpid = 0; int channels = 3; int chan_vpu; VB_BLK blk = VB_INVALID_HANDLE, blk2 = VB_INVALID_HANDLE; for (chan_vpu = 0; chan_vpu < channels; chan_vpu++) { int szs = szz[chan_vpu]; int z = 0; for (z = 0; z < szs; z++) { if(!g_bRunning) { goto exit; } int fmts = mods[chan_vpu]; int f = 0; for (f = 0; f < fmts; f++) { FH_VPU_CHN_CONFIG chn_attr; memset(&chn_attr, 0, sizeof(chn_attr)); chn_attr.vpu_chn_size.u32Width = sizes[z].u32Width; chn_attr.vpu_chn_size.u32Height = sizes[z].u32Height; chn_attr.stride = sizes[z].u32Width; chn_attr.offset = 0; chn_attr.depth = 1; ret = FH_VPSS_SetChnAttr(grpid, chan_vpu, &chn_attr); if (ret != 0) { printf("Error(%d - %x): FH_VPSS_SetChnAttr (grp-chn):(%d-%d)!\n", ret, ret, grpid, chan_vpu); goto exit; } ret = FH_VPSS_SetVOMode(grpid, chan_vpu, vomodes[f]); if (ret != 0) { printf("Error(%d - %x): FH_VPSS_SetVOMode (grp-chn):(%d-%d)!\n", ret, ret, grpid, chan_vpu); goto exit; } ret = FH_VPSS_SetVORotate(grpid, chan_vpu, 0); if (ret != 0) { printf("Error(%d - %x): FH_VPSS_SetVORotate (grp-chn):(%d-%d)!\n", ret, ret, grpid, chan_vpu); goto exit; } ret = FH_VPSS_OpenChn(grpid, chan_vpu); if (ret != 0) { printf("Error(%d - %x): FH_VPSS_OpenChn (grp-chn):(%d-%d)!\n", ret, ret, grpid, chan_vpu); goto exit; } //draw osd for channel if (chan_vpu < 3) { __vpu_gosd_draw_chn_info(grpid, chan_vpu, sizes[z].u32Width, sizes[z].u32Height, vomodes[f], &blk); /* FH_UINT64 tick = 0; FH_SYS_GetCurPts(&tick); char osdtime[64]; sprintf(osdtime, "Tick: %lld\n", tick); __vpu_gosd_draw_title(grpid, chan_vpu, 32, 100, 1, osdtime, &blk2); */ } sleep(3); ret = FH_VPSS_CloseChn(grpid, chan_vpu); if (ret != 0) { printf("Error(%d - %x): FH_VPSS_CloseChn (grp-chn):(%d-%d)!\n", ret, ret, grpid, chan_vpu); goto exit; } if(VB_INVALID_HANDLE != blk) { FH_VB_ReleaseBlock(blk); } if(VB_INVALID_HANDLE != blk2) { FH_VB_ReleaseBlock(blk2); } } } } exit: g_bRunning = 0; } int vpu_test_case_format() { FH_SINT32 ret; int tcase = 1; char node[64]; char cases[64]; sprintf(cases, "test_cases[%d]", tcase); sprintf(node, "test_cases[%d].vpu", tcase); ret = vpu_group_init_by_config(node); if (0 != ret) { printf("vpu_group_chn_init failed!\n"); return ret; } return 0; } FH_SINT32 fh_vpu_init(FH_VOID); FH_SINT32 fh_vpu_close(FH_VOID); int vpu_test_init() { int ret = 0; ret = __gosd_font_init(); ret = fh_vpu_init(); return ret; } int vpu_test_exit() { int ret = 0; __gosd_font_cleanup(); ret = fh_vpu_close(); return ret; }