海思3559C实现OSD字符叠加的探索(一)详细介绍了编译的过程,本文适合快速上手,快速编译,如无特别说明,代码版本与上文保持一致。
经过上文的探索,发现可以不主动去编译FreeType这里就省略了。
交叉编译SDL
下载目前最新版本代码:
Release 2.26.5 · libsdl-org/SDL (github.com)
#解压代码
tar -zxvf SDL-release-2.26.5.tar.gz
#重命名 可以不操作该步骤
mv SDL-release-2.26.5/ libSDL
#进入目录 创建install目录
cd libSDL/
mkdir install
#配置交叉编译环境
./configure --prefix=$PWD/install CC=aarch64-himix100-linux-gcc --host=aarch64-linux --disable-alsa --disable-pulseaudio --enable-esd=no
#编译
make -j16
#安装
make install
--prefix=$PWD/install
指定编译器的安装路径为当前目录下的install文件夹。CC=aarch64-himix100-linux-gcc
指定编译器为aarch64-himix100-linux-gcc。--host=aarch64-linux
指定目标平台为aarch64-linux。--disable-alsa
禁用ALSA音频驱动库。--disable-pulseaudio
禁用PulseAudio音频驱动库。--enable-esd=no
禁用ESD音频驱动库。
交叉编译SDL_ttf
下载目前最新版本代码:
Index of /projects/SDL_ttf/release (libsdl.org)
下载SDL2_ttf-2.20.2.tar.gz
#进入代码根目录创建install目录
mkdir install
#配置
./configure --prefix=$PWD/install CC=aarch64-himix100-linux-gcc --host=aarch64-linux --with-sdl-prefix=$PWD/../libSDL/install
#编译
make -j 16
#安装
make install
--prefix=$PWD/install
指定安装路径为当前目录下的install文件夹。CC=aarch64-himix100-linux-gcc
指定使用交叉编译器aarch64-himix100-linux-gcc
进行编译。--host=aarch64-linux
指定目标机器的操作系统为aarch64-linux。--with-sdl-prefix=$PWD/../libSDL/install
指定SDL库的安装路径为上级目录下的libSDL/install文件夹。
测试程序和编译命令
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include "SDL.h"
#include "SDL_ttf.h"
#include "time.h"
#define FONT_PATH "./SourceHanSansCN-Regular.ttf"
int string_to_bmp(char *pu8Str);
int cnt = 0;
int main()
{
time_t now;
struct tm *ptm;
char timestr[100] = {0};
struct timeval start_time, end_time;
int elapsed_time;
while (1)
{
sleep(1);
time(&now);
ptm = localtime(&now);
snprintf(timestr, 100, "时间%d-%02d-%02d %02d:%02d:%02d", ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
gettimeofday(&start_time, NULL); // 记录程序开始时刻
string_to_bmp(timestr);
gettimeofday(&end_time, NULL); // 记录程序结束时刻
elapsed_time = (int)(1000.0 * (end_time.tv_sec - start_time.tv_sec) + 0.001 * (end_time.tv_usec - start_time.tv_usec));
printf("生成位图时间:%d 毫秒\n", elapsed_time);
memset(timestr, 0, 100);
if (cnt++ > 4)
{
break;
}
}
return 0;
}
int string_to_bmp(char *pu8Str)
{
SDL_PixelFormat *fmt;
TTF_Font *font;
SDL_Surface *text, *temp;
if (TTF_Init() < 0)
{
fprintf(stderr, "Couldn't initialize TTF: %s\n", SDL_GetError());
SDL_Quit();
}
font = TTF_OpenFont(FONT_PATH, 80);
if (font == NULL)
{
fprintf(stderr, "Couldn't load %d pt font from %s: %s\n", 18, "ptsize", SDL_GetError());
}
SDL_Color forecol = {0xff, 0xff, 0xff, 0xff};
text = TTF_RenderUTF8_Solid(font, pu8Str, forecol);
fmt = (SDL_PixelFormat *)malloc(sizeof(SDL_PixelFormat));
memset(fmt, 0, sizeof(SDL_PixelFormat));
fmt->BitsPerPixel = 16;
fmt->BytesPerPixel = 2;
// fmt->colorkey = 0xffffffff;
// fmt->alpha = 0xff;
temp = SDL_ConvertSurface(text, fmt, 0);
char savename[10] = {0};
snprintf(savename, 10, "%d.bmp", cnt);
printf("savename = %s\n", savename);
SDL_SaveBMP(temp, savename);
SDL_FreeSurface(text);
SDL_FreeSurface(temp);
TTF_CloseFont(font);
TTF_Quit();
free(fmt);
fmt = NULL;
return 0;
}
aarch64-himix100-linux-gcc test.c -o str2bmp -I../libSDL/install/include/SDL2 -I../libSDL2_ttf/install/include/SDL2 -L. -lSDL2 -lSDL2_ttf -lpthread
在Hi3559C上叠加时间戳
#ifdef __cplusplus
#if __cplusplus
extern "C"
{
#endif
#endif /* End of #ifdef __cplusplus */
#define LOG_TAG "VideoModuleMain"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include "sample_comm.h"
#include "elog.h"
#include "str2bmp.h"
#define FONT_PATH "/mnt/appfs/app/SourceHanSansSC-Normal.ttf"
#define FONT_SIZE 36
int StopStat = 0;
/******************************************************************************
* function : to process abnormal case
******************************************************************************/
void SAMPLE_VIO_HandleSig(HI_S32 signo)
{
if (SIGINT == signo || SIGTERM == signo)
{
StopStat = 1;
SAMPLE_COMM_All_ISP_Stop();
SAMPLE_COMM_SYS_Exit();
printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
}
exit(-1);
}
int dump_row(const char *pFileName, int size, char *buffer)
{
FILE *pFile = NULL;
int fileLen;
pFile = fopen(pFileName, "wb");
if (pFile == NULL)
{
printf("error opening file %s\n", pFileName);
return -1;
}
fileLen = fwrite(buffer, 1, size, pFile);
if (fileLen != size)
printf("write file %s\n", pFileName);
fclose(pFile);
return 0;
}
OSD_SDL_ATTR_S stOsdAttr = {0};
HI_S32 SampleVpssChnCreateRegion()
{
HI_S32 s32Ret;
MPP_CHN_S stChn;
RGN_ATTR_S stRgnAttr;
RGN_CHN_ATTR_S stChnAttr;
BITMAP_S stBitmap;
VPSS_CHN VpssChn = 0;
char osdStr[128] = {0};
/* load bitmap*/
memset(&stOsdAttr, 0, sizeof(OSD_SDL_ATTR_S));
snprintf(osdStr, sizeof(osdStr), "测试北京dHKhAi!@#$132ou9");
stOsdAttr.pcStr = osdStr;
stOsdAttr.u32FontSize = 88;
stOsdAttr.u32FgColor = 0xfff08f72;
stOsdAttr.u32BgColor = 0;
s32Ret = OSD_SDL_Str2Bmp32(&stOsdAttr);
if (s32Ret)
{
log_e("failed!");
}
else
{
log_i("osd bitmap success width:%d height:%d stOsdAttr.u32BgColor:%#x\n", stOsdAttr.u32Width, stOsdAttr.u32Height, stOsdAttr.u32BgColor);
}
stBitmap.enPixelFormat = PIXEL_FORMAT_ARGB_8888;
stBitmap.u32Height = stOsdAttr.u32Height;
stBitmap.u32Width = stOsdAttr.u32Width;
stBitmap.pData = stOsdAttr.pData;
/* creat region*/
stRgnAttr.enType = OVERLAYEX_RGN;
stRgnAttr.unAttr.stOverlayEx.enPixelFmt = PIXEL_FORMAT_ARGB_8888;
stRgnAttr.unAttr.stOverlayEx.stSize.u32Width = 2000;
stRgnAttr.unAttr.stOverlayEx.stSize.u32Height = 500;
stRgnAttr.unAttr.stOverlayEx.u32BgColor = 0xfc;
stRgnAttr.unAttr.stOverlayEx.u32CanvasNum = 2;
s32Ret = HI_MPI_RGN_Create(VpssChn, &stRgnAttr);
if (s32Ret != HI_SUCCESS)
{
printf("region of vpss chn %d create fail. value=0x%x.", VpssChn, s32Ret);
return s32Ret;
}
/*attach region to chn*/
stChn.enModId = HI_ID_VPSS;
stChn.s32DevId = 0;
stChn.s32ChnId = VpssChn;
stChnAttr.bShow = HI_TRUE;
stChnAttr.enType = OVERLAYEX_RGN;
stChnAttr.unChnAttr.stOverlayExChn.stPoint.s32X = 128;
stChnAttr.unChnAttr.stOverlayExChn.stPoint.s32Y = 128;
stChnAttr.unChnAttr.stOverlayExChn.u32BgAlpha = 128;
stChnAttr.unChnAttr.stOverlayExChn.u32FgAlpha = 128;
stChnAttr.unChnAttr.stOverlayExChn.u32Layer = 0;
s32Ret = HI_MPI_RGN_SetBitMap(VpssChn, &stBitmap);
if (s32Ret != HI_SUCCESS)
{
printf("region set bitmap to vpss chn %d fail. value=0x%x.", VpssChn, s32Ret);
free(stBitmap.pData);
return s32Ret;
}
s32Ret = HI_MPI_RGN_AttachToChn(VpssChn, &stChn, &stChnAttr);
if (s32Ret != HI_SUCCESS)
{
printf("region attach to vpss chn %d fail. value=0x%x.", VpssChn, s32Ret);
return s32Ret;
}
return HI_SUCCESS;
}
HI_S32 SampleVpssChnDestroyRegion()
{
HI_S32 s32Ret;
MPP_CHN_S stChn;
VPSS_CHN VpssChn = 0;
stChn.enModId = HI_ID_VPSS;
stChn.s32DevId = 0;
stChn.s32ChnId = VpssChn;
/* detach region from chn */
s32Ret = HI_MPI_RGN_DetachFromChn(VpssChn, &stChn);
if (s32Ret != HI_SUCCESS)
{
printf("region attach to vpss chn %d fail. value=0x%x.", VpssChn, s32Ret);
return s32Ret;
}
/* destroy region */
s32Ret = HI_MPI_RGN_Destroy(VpssChn);
if (s32Ret != HI_SUCCESS)
{
printf("destroy vpss chn %d region fail. value=0x%x.", VpssChn, s32Ret);
return s32Ret;
}
free(stOsdAttr.pData);
stOsdAttr.pData = NULL;
return HI_SUCCESS;
}
static int get_cur_time_ms(void)
{
struct timeval tv;
gettimeofday(&tv, NULL); // 使用gettimeofday获取当前系统时间
return (tv.tv_sec * 1000 + tv.tv_usec / 1000); // 利用struct timeval结构体将时间转换为ms
}
void *thread_function(void *arg)
{
HI_S32 s32Ret = HI_SUCCESS;
BITMAP_S stBitmap;
VPSS_CHN VpssChn = 0;
int t1;
sleep(2);
while (1)
{
t1 = get_cur_time_ms();
// 获取当前时间
time_t now = time(NULL);
struct tm *tm_now = localtime(&now);
// 格式化当前时间
char time_str[30];
sprintf(time_str, "%04d-%02d-%02d %02d:%02d:%02d",
tm_now->tm_year + 1900, tm_now->tm_mon + 1, tm_now->tm_mday,
tm_now->tm_hour, tm_now->tm_min, tm_now->tm_sec);
/* load bitmap*/
// t1 = get_cur_time_ms();
memset(&stOsdAttr, 0, sizeof(OSD_SDL_ATTR_S));
stOsdAttr.pcStr = time_str;
stOsdAttr.u32FontSize = 50;
stOsdAttr.u32FgColor = 0xff18dcff;
stOsdAttr.u32BgColor = 0;
s32Ret = OSD_SDL_Str2Bmp32(&stOsdAttr);
if (s32Ret)
log_e("failed!");
// log_d("Bitmap width:%d height:%d speed time %d \n", stOsdAttr.u32Width, stOsdAttr.u32Height, get_cur_time_ms() - t1);
stBitmap.enPixelFormat = PIXEL_FORMAT_ARGB_8888;
stBitmap.u32Height = stOsdAttr.u32Height;
stBitmap.u32Width = stOsdAttr.u32Width;
stBitmap.pData = stOsdAttr.pData;
s32Ret = HI_MPI_RGN_SetBitMap(0, &stBitmap);
if (s32Ret != HI_SUCCESS)
{
printf("region set bitmap to vpss chn %d fail. value=0x%x.", VpssChn, s32Ret);
free(stBitmap.pData);
}
printf("%d ", get_cur_time_ms() - t1);
// 等待1秒钟
usleep(900 * 1000);
}
}
HI_S32 SAMPLE_VIO_1080P60_PARALLEL(VO_INTF_TYPE_E enVoIntfType)
{
HI_S32 s32Ret = HI_SUCCESS;
VI_DEV ViDev0 = 0;
VI_PIPE ViPipe0 = 0;
VI_CHN ViChn = 0;
HI_S32 s32ViCnt = 1;
VPSS_GRP VpssGrp0 = 0;
VPSS_CHN VpssChn[4] = {VPSS_CHN0, VPSS_CHN1, VPSS_CHN2, VPSS_CHN3};
VPSS_GRP_ATTR_S stVpssGrpAttr = {0};
VPSS_CHN_ATTR_S stVpssChnAttr[VPSS_MAX_PHY_CHN_NUM];
HI_BOOL abChnEnable[VPSS_MAX_PHY_CHN_NUM] = {HI_TRUE};
VO_DEV VoDev = SAMPLE_VO_DEV_DHD0;
VO_CHN VoChn = 0;
VO_INTF_SYNC_E g_enIntfSync = VO_OUTPUT_1080P60; // VO_OUTPUT_3840x2160_30;
HI_U32 g_u32DisBufLen = 3;
PIC_SIZE_E enPicSize = PIC_3840x2160;
WDR_MODE_E enWDRMode = WDR_MODE_NONE;
DYNAMIC_RANGE_E enDynamicRange = DYNAMIC_RANGE_SDR8;
PIXEL_FORMAT_E enPixFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420;
VIDEO_FORMAT_E enVideoFormat = VIDEO_FORMAT_LINEAR;
COMPRESS_MODE_E enCompressMode = COMPRESS_MODE_NONE;
VI_VPSS_MODE_E enMastPipeMode = VI_PARALLEL_VPSS_PARALLEL;
SIZE_S stSize;
HI_U32 u32BlkSize;
VB_CONFIG_S stVbConf;
SAMPLE_VI_CONFIG_S stViConfig;
SAMPLE_VO_CONFIG_S stVoConfig;
/************************************************
step 1: Get all sensors information, need one vi
,and need one mipi --
*************************************************/
SAMPLE_COMM_VI_GetSensorInfo(&stViConfig);
stViConfig.s32WorkingViNum = s32ViCnt;
stViConfig.as32WorkingViId[0] = 0;
stViConfig.astViInfo[0].stSnsInfo.MipiDev = SAMPLE_COMM_VI_GetComboDevBySensor(stViConfig.astViInfo[0].stSnsInfo.enSnsType, 0);
stViConfig.astViInfo[0].stSnsInfo.s32BusId = 0;
stViConfig.astViInfo[0].stDevInfo.ViDev = ViDev0;
stViConfig.astViInfo[0].stDevInfo.enWDRMode = enWDRMode;
stViConfig.astViInfo[0].stPipeInfo.enMastPipeMode = enMastPipeMode;
stViConfig.astViInfo[0].stPipeInfo.aPipe[0] = ViPipe0;
stViConfig.astViInfo[0].stPipeInfo.aPipe[1] = -1;
stViConfig.astViInfo[0].stPipeInfo.aPipe[2] = -1;
stViConfig.astViInfo[0].stPipeInfo.aPipe[3] = -1;
stViConfig.astViInfo[0].stChnInfo.ViChn = ViChn;
stViConfig.astViInfo[0].stChnInfo.enPixFormat = enPixFormat;
stViConfig.astViInfo[0].stChnInfo.enDynamicRange = enDynamicRange;
stViConfig.astViInfo[0].stChnInfo.enVideoFormat = enVideoFormat;
stViConfig.astViInfo[0].stChnInfo.enCompressMode = enCompressMode;
/************************************************
step 2: Get input size
*************************************************/
s32Ret = SAMPLE_COMM_VI_GetSizeBySensor(stViConfig.astViInfo[0].stSnsInfo.enSnsType, &enPicSize);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("SAMPLE_COMM_VI_GetSizeBySensor failed with %d!\n", s32Ret);
return s32Ret;
}
s32Ret = SAMPLE_COMM_SYS_GetPicSize(enPicSize, &stSize);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("SAMPLE_COMM_SYS_GetPicSize failed with %d!\n", s32Ret);
return s32Ret;
}
/************************************************
step3: Init SYS and common VB
*************************************************/
memset_s(&stVbConf, sizeof(VB_CONFIG_S), 0, sizeof(VB_CONFIG_S));
stVbConf.u32MaxPoolCnt = 2;
u32BlkSize = COMMON_GetPicBufferSize(stSize.u32Width, stSize.u32Height, SAMPLE_PIXEL_FORMAT, DATA_BITWIDTH_10, COMPRESS_MODE_SEG, DEFAULT_ALIGN);
stVbConf.astCommPool[0].u64BlkSize = u32BlkSize;
stVbConf.astCommPool[0].u32BlkCnt = 10;
u32BlkSize = VI_GetRawBufferSize(stSize.u32Width, stSize.u32Height, PIXEL_FORMAT_RGB_BAYER_16BPP, COMPRESS_MODE_NONE, DEFAULT_ALIGN);
stVbConf.astCommPool[1].u64BlkSize = u32BlkSize;
stVbConf.astCommPool[1].u32BlkCnt = 4;
s32Ret = SAMPLE_COMM_SYS_Init(&stVbConf);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("system init failed with %d!\n", s32Ret);
goto EXIT;
}
s32Ret = SAMPLE_COMM_VI_SetParam(&stViConfig);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("SAMPLE_COMM_VI_SetParam failed with %d!\n", s32Ret);
goto EXIT;
}
/************************************************
step 4: start VI
*************************************************/
s32Ret = SAMPLE_COMM_VI_StartVi(&stViConfig);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("SAMPLE_COMM_VI_StartVi failed with %d!\n", s32Ret);
goto EXIT3;
}
/************************************************
step 5: start VPSS, need one grp
*************************************************/
stVpssGrpAttr.u32MaxW = stSize.u32Width;
stVpssGrpAttr.u32MaxH = stSize.u32Height;
stVpssGrpAttr.enPixelFormat = enPixFormat;
stVpssGrpAttr.enDynamicRange = enDynamicRange;
stVpssGrpAttr.stFrameRate.s32SrcFrameRate = -1;
stVpssGrpAttr.stFrameRate.s32DstFrameRate = -1;
abChnEnable[0] = HI_TRUE;
stVpssChnAttr[0].u32Width = stSize.u32Width;
stVpssChnAttr[0].u32Height = stSize.u32Height;
stVpssChnAttr[0].enChnMode = VPSS_CHN_MODE_USER;
stVpssChnAttr[0].enCompressMode = enCompressMode;
stVpssChnAttr[0].enDynamicRange = enDynamicRange;
stVpssChnAttr[0].enPixelFormat = enPixFormat;
stVpssChnAttr[0].enVideoFormat = enVideoFormat;
stVpssChnAttr[0].stFrameRate.s32SrcFrameRate = -1;
stVpssChnAttr[0].stFrameRate.s32DstFrameRate = -1;
stVpssChnAttr[0].u32Depth = 1;
stVpssChnAttr[0].bMirror = HI_FALSE;
stVpssChnAttr[0].bFlip = HI_FALSE;
stVpssChnAttr[0].stAspectRatio.enMode = ASPECT_RATIO_NONE;
s32Ret = SAMPLE_COMM_VPSS_Start(VpssGrp0, abChnEnable, &stVpssGrpAttr, stVpssChnAttr);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("SAMPLE_COMM_VPSS_Start Grp0 failed with %d!\n", s32Ret);
goto EXIT2;
}
/************************************************
step 6: VI bind VPSS, for total parallel, no need bind
*************************************************/
/************************************************
step 7: start V0
*************************************************/
SAMPLE_COMM_VO_GetDefConfig(&stVoConfig);
stVoConfig.VoDev = VoDev;
stVoConfig.enVoIntfType = enVoIntfType;
stVoConfig.enIntfSync = g_enIntfSync;
stVoConfig.enPicSize = enPicSize;
stVoConfig.u32DisBufLen = g_u32DisBufLen;
stVoConfig.enDstDynamicRange = enDynamicRange;
stVoConfig.enVoMode = VO_MODE_1MUX;
s32Ret = SAMPLE_COMM_VO_StartVO(&stVoConfig);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("SAMPLE_COMM_VO_StartVO failed with %d!\n", s32Ret);
goto EXIT1;
}
/************************************************
step 8: VI bind VPSS bind VO
*************************************************/
s32Ret = SAMPLE_COMM_VI_Bind_VPSS(ViPipe0, ViChn, VpssGrp0);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("SAMPLE_COMM_VI_Bind_VPSS failed with %d!\n", s32Ret);
goto EXIT1;
}
SAMPLE_COMM_VENC_Onvif_Start();
SAMPLE_COMM_VPSS_FrameProcStart();
/* s32Ret = SAMPLE_COMM_VPSS_Bind_VO(VpssGrp0, VpssChn[0], stVoConfig.VoDev, VoChn);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("SAMPLE_COMM_VPSS_Bind_VO Grp0 failed with %d!\n", s32Ret);
goto EXIT0;
} */
SampleVpssChnCreateRegion();
PAUSE();
StopStat = 1;
SampleVpssChnDestroyRegion();
SAMPLE_COMM_VPSS_UnBind_VO(VpssGrp0, VpssChn[0], stVoConfig.VoDev, VoChn);
SAMPLE_COMM_VI_UnBind_VPSS(ViPipe0, ViChn, VpssGrp0);
EXIT1:
SAMPLE_COMM_VO_StopVO(&stVoConfig);
EXIT2:
SAMPLE_COMM_VPSS_Stop(VpssGrp0, abChnEnable);
EXIT3:
SAMPLE_COMM_VI_StopVi(&stViConfig);
EXIT:
SAMPLE_COMM_SYS_Exit();
return s32Ret;
}
/******************************************************************************
* function : main()
* Description : main
******************************************************************************/
#ifdef __HuaweiLite__
int app_main(int argc, char *argv[])
#else
int main(int argc, char *argv[])
#endif
{
HI_S32 s32Ret = HI_FAILURE;
VO_INTF_TYPE_E enVoIntfType = VO_INTF_HDMI;
#ifdef __HuaweiLite__
#else
signal(SIGINT, SAMPLE_VIO_HandleSig);
signal(SIGTERM, SAMPLE_VIO_HandleSig);
#endif
/* close printf buffer */
setbuf(stdout, NULL);
/* initialize EasyLogger */
elog_init();
/* set EasyLogger log format */
elog_set_fmt(ELOG_LVL_ASSERT, ELOG_FMT_ALL);
elog_set_fmt(ELOG_LVL_ERROR, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
elog_set_fmt(ELOG_LVL_WARN, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
elog_set_fmt(ELOG_LVL_INFO, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
elog_set_fmt(ELOG_LVL_DEBUG, ELOG_FMT_ALL & ~ELOG_FMT_FUNC);
elog_set_fmt(ELOG_LVL_VERBOSE, ELOG_FMT_ALL & ~ELOG_FMT_FUNC);
#ifdef ELOG_COLOR_ENABLE
elog_set_text_color_enabled(true);
#endif
/* start EasyLogger */
elog_start();
s32Ret = OSD_SDL_Init(FONT_PATH, FONT_SIZE);
if (HI_SUCCESS != s32Ret)
log_e("fail");
// 创建线程
pthread_t tid;
s32Ret = pthread_create(&tid, NULL, thread_function, NULL);
if (s32Ret != 0)
{
printf("Create thread failed!\n");
return s32Ret;
}
#if 1
// imx477 hdmi vo sample
SAMPLE_VIO_1080P60_PARALLEL(enVoIntfType);
#endif
return s32Ret;
}
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
生成位图和叠加位图耗时(也就是thread_function中每个循环的耗时,生成位图宽度:451 高度:73 单位:毫秒):
6 6 9 7 5 6 5 5 5 6 6 5 6 10 5 5 5 5 5 10 5 5 9 6 5 6 7 6 11 5 5 7 5 5 5 5 5 5 10 5 5 6 4 5 5 7 5 5 10 5 5 5 5 5 9 5 6 5 8 5 6 5 7 5 5 9 5 5 5 5 5 5 5 5 5 5 5 5 5 11 5 5 7 5 5 10 7 5 5 5 6 5 6 5 5 9 6 5 5 7 5 5 5 6 5 5 7 4 5 4 6 5 6 5 7 4 6 11 5 5 7 4 6 9 5 5 5 7 5 5 5 6 4 5 9 5 5 6 12 5 5 5 5 5 5 5 5 4 10 5 4 6 5 5 10 5 5 5 5 5 5 5 5 5 6 4 5 5 6 5 4 5 5 5 5 5 5 5 5 7 5 5 5 5 5 5 10 5 5 6 5 7 9 5 4 4 5 4 5 4 5 5 5 5 5 5 5 5 5 5 5 5 5 4 5 5 5 4 5 5 5 5 5 4 5 10 5 5 8 6 5 7 5 5 5 5 4 5 5 5 5 4 5 5 5 4 5 5 4 7 4 5 5 5 5 5 4 5 5 4 5 4 5 5 6 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4 4 5 5 5 4 5 5 5 6 4 5 4 5 4 5 4 5 5 5 5 4 4 4 5 4 5 4 5 5 5 6 5 4 5 5 5 5 4 5 5 5 5 4 5 5 5 4 5 5 5 5 4 4
str2bmp.c
#include <pthread.h>
#include "SDL_ttf.h"
#include "SDL.h"
#include "str2bmp.h"
#ifndef OSD_SDL_CHECK_RET_W
#define OSD_SDL_CHECK_RET_W(express) \
do \
{ \
s32Ret = express; \
if (EI_SUCCESS != s32Ret) \
{ \
printf("Failed at %s: LINE: %d (ret:0x%#x!)\n", __FUNCTION__, __LINE__, s32Ret); \
} \
} while (0)
#endif
#ifndef OSD_SDL_CHECK_RET_E
#define OSD_SDL_CHECK_RET_E(express) \
do \
{ \
s32Ret = express; \
if (EI_SUCCESS != s32Ret) \
{ \
printf("Failed at %s: LINE: %d (ret:0x%#x!)\n", __FUNCTION__, __LINE__, s32Ret); \
goto exit; \
} \
} while (0)
#endif
#define OSD_SDL_CHECK_NULL_PTR(pstPtr) \
do \
{ \
if (NULL == (pstPtr)) \
{ \
printf("Null pointer! FUNCTION %s,LINE %d!\n", __FUNCTION__, __LINE__); \
s32Ret = -1; \
goto exit; \
} \
} while (0)
/* sdl_ttf and freetype is not mutil-threading safe */
typedef pthread_mutex_t OSD_SDL_Mutex;
#define OSD_SDL_CreateMutex(m) pthread_mutex_init(&m, NULL)
#define OSD_SDL_DestroyMutex(m) pthread_mutex_destroy(&m)
#define OSD_SDL_LockMutex(m) pthread_mutex_lock(&(m))
#define OSD_SDL_UnLockMutex(m) pthread_mutex_unlock(&(m))
static OSD_SDL_Mutex osd_mutex;
#define ALIGN_UP(x, align) (((int)(x) + (align - 1)) & ~(align - 1))
#define ALIGN_DOWN(x, align) (((int)(x) & ~(align - 1)))
static TTF_Font *font;
int OSD_SDL_Init(const char *file, int ptsize)
{
OSD_SDL_CreateMutex(osd_mutex);
if (TTF_Init() < 0)
{
printf("Couldn't initialize TTF: %s\n", SDL_GetError());
SDL_Quit();
return -1;
}
font = TTF_OpenFont(file, ptsize);
if (font == NULL)
{
printf("Couldn't load %d pt font from %s: %s\n",
ptsize, "ptsize", SDL_GetError());
return -1;
}
return 0;
}
int OSD_SDL_DeInit()
{
TTF_CloseFont(font);
TTF_Quit();
OSD_SDL_DestroyMutex(osd_mutex);
return 0;
}
int OSD_SDL_Str2Bmp32(OSD_SDL_ATTR_S *pstOsdAttr)
{
int s32Ret = 0;
OSD_SDL_LockMutex(osd_mutex);
SDL_PixelFormat fmt;
SDL_Surface *text = NULL;
SDL_Surface *temp = NULL;
SDL_Color fg = {0};
SDL_Color bg = {0};
OSD_SDL_CHECK_NULL_PTR(font);
if (pstOsdAttr->u32DataSzie)
OSD_SDL_CHECK_NULL_PTR(pstOsdAttr->pData);
memset(&fmt, 0, sizeof(SDL_PixelFormat));
fmt.BitsPerPixel = 32;
fmt.BytesPerPixel = 4;
fmt.Rmask = 0x00ff0000;
fmt.Gmask = 0x0000ff00;
fmt.Bmask = 0x000000ff;
fmt.Amask = 0xff000000;
fmt.palette = NULL;
fg.a = (pstOsdAttr->u32FgColor & fmt.Amask) >> 24;
fg.r = (pstOsdAttr->u32FgColor & fmt.Rmask) >> 16;
fg.g = (pstOsdAttr->u32FgColor & fmt.Gmask) >> 8;
fg.b = (pstOsdAttr->u32FgColor & fmt.Bmask);
bg.a = (pstOsdAttr->u32BgColor & fmt.Amask) >> 24;
bg.r = (pstOsdAttr->u32BgColor & fmt.Rmask) >> 16;
bg.g = (pstOsdAttr->u32BgColor & fmt.Gmask) >> 8;
bg.b = (pstOsdAttr->u32BgColor & fmt.Bmask);
TTF_SetFontSize(font, pstOsdAttr->u32FontSize);
if (bg.a == 0x00)
text = TTF_RenderUTF8_Solid(font, pstOsdAttr->pcStr, fg);
else
text = TTF_RenderUTF8(font, pstOsdAttr->pcStr, fg, bg);
OSD_SDL_CHECK_NULL_PTR(text);
temp = SDL_ConvertSurface(text, &fmt, 0);
OSD_SDL_CHECK_NULL_PTR(temp);
if (pstOsdAttr->u32DataSzie)
{
if ((temp->w) * (temp->h) * fmt.BytesPerPixel > pstOsdAttr->u32DataSzie)
{
printf("[%s %d] Bitmap is too large w:%d h:%d BytesPerPixel:%d u32DataSzie:%d",
__func__, __LINE__, temp->w, temp->h, fmt.BytesPerPixel, pstOsdAttr->u32DataSzie);
s32Ret = -1;
goto exit;
}
}
else
{
pstOsdAttr->pData = calloc(1, temp->w * temp->h * fmt.BytesPerPixel);
}
memcpy(pstOsdAttr->pData, temp->pixels, (temp->w) * (temp->h) * fmt.BytesPerPixel);
pstOsdAttr->u32Width = temp->w;
pstOsdAttr->u32Height = temp->h;
exit:
if (text)
SDL_FreeSurface(text);
if (temp)
SDL_FreeSurface(temp);
OSD_SDL_UnLockMutex(osd_mutex);
return s32Ret;
}
本网站尊重知识产权,如有侵权,请及时联系我们删除。
本站所有原创内容仅用于学习和交流目的,未经作者和本站授权不得进行商业使用或盈利行为。
暂无评论内容