RV1126实现OSD时间戳叠加
说到安防监控摄像头,时间戳添加显示是刚需功能。OSD进行时间戳添加就是通过硬件RGN(Region)高性能处理模式来实现,有效降低CPU占用率且直接从物理内存操作数据,实现内存零拷贝。

拿到视频裸数据后,硬件RGN叠加时间戳具体流程如下:
一,时间戳字符串渲染。将时间戳进行字符串处理,使用TTF库进行获取相应字体格式与大小,最后调用TTF_RenderText_Solid将时间戳字符串进行RGB格式上色,此时时间戳就是一个贴图。
int ret;
TTF_Font *ttf_font;
char date_ptr[100];
SDL_Surface *text_surface;
SDL_Surface *convert_text_surface;
ret = TTF_Init();
if (ret < 0)
{
printf("TTF_Init Failed..........\n");
}
printf("TTF_Init Success...........\n");
ttf_font = TTF_OpenFont("./fzlth.ttf", 48);
if (ttf_font == NULL)
{
printf("TTF_OpenFont failed..........\n");
}
printf("TTF_OpenFont Success..........\n");
SDL_Color sdl_color;
sdl_color.r = 0;
sdl_color.g = 0;
sdl_color.b = 0;
time_t g_time; // Init g_time
tm *p; // Init *p
time(&g_time); // get time for g_time, and change time by now..........
p = gmtime(&g_time); // put g_time for *p
sprintf(date_ptr, "%4d-%02d-%02d %02d:%02d:%02d", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday, 8 + p->tm_hour, p->tm_min, p->tm_sec);
// char *pstr = date_ptr;
text_surface = TTF_RenderText_Solid(ttf_font, date_ptr, sdl_color);
二,图像格式转换。使用SDL库调用SDLConvertSurface将时间戳贴图转化成RGBA8888格式。
SDL_PixelFormat *pixel_format;
pixel_format = (SDL_PixelFormat *)malloc(sizeof(SDL_PixelFormat));
pixel_format->BitsPerPixel = 32;
pixel_format->BytesPerPixel = 4;
pixel_format->Amask = 0XFF000000;
pixel_format->Rmask = 0X00FF0000;
pixel_format->Gmask = 0X0000FF00;
pixel_format->Bmask = 0X000000FF;
convert_text_surface = SDL_ConvertSurface(text_surface, pixel_format, 0); // by mask to convert the test
if (convert_text_surface == NULL)
{
printf("convert text surface failed........\n");
}
三,Bitmap位图封装。将RGBA8888格式的时间戳贴图封装成Bitmap位图,其中需要注意位图宽高进行16字节对齐,不然容易导致位图出现渲染字符偏移。
BITMAP_S bitmap;
bitmap.u32Width = convert_text_surface->w;
bitmap.u32Height = convert_text_surface->h;
bitmap.enPixelFormat = PIXEL_FORMAT_ARGB_8888;
bitmap.pData = malloc((bitmap.u32Height) * (bitmap.u32Width) * (pixel_format->BytesPerPixel));
memcpy(bitmap.pData, (convert_text_surface->pixels), (convert_text_surface->w) * (convert_text_surface->h) * (pixel_format->BytesPerPixel));
四,配置rgn_info区域参数。就是OSD_REGION_INFO_S的设置,决定bitmap位图在视频上的显示属性(位置、尺寸、使能、层级)。
OSD_REGION_INFO_S rgn_info;
rgn_info.enRegionId = REGION_ID_0;
rgn_info.u32Width = get_align16_value(convert_text_surface->w, 16);
rgn_info.u32Height = get_align16_value(convert_text_surface->h, 16);
rgn_info.u32PosX = 144; // start POSE-x
rgn_info.u32PosY = 64; // start pose-Y
rgn_info.u8Enable = 1;
rgn_info.u8Inverse = 0;
最后,硬件叠加并绑定VENC编码通道。调用RK_MPI_RGN_SetBitMap根据rgn_info的配置将Bitmap位图设置到VENC编码通道中。这样通过RGN就可将Bitmap时间戳贴图叠加到每一帧图像数据中再进行VENC编码。
ret = RK_MPI_VENC_RGN_SetBitMap(0, &rgn_info, &bitmap);
if (!ret)
{
printf("VENC_RGN SetBitMap Success........\n");
}
使用OSD硬件进行时间戳添加,几乎不耗CPU,适合安防场景。若想实现占用CPU移植性强轻便,跨平台,不依赖硬件进行时间戳添加的方案,则可采用OpenCV开源库,可通过cv::Mat矩阵进行处理采集的裸数据,通过cv::putText将string时间戳字符串进行添加到cv::Mat矩阵中,完成软件层字符串叠加。
//将其中的argv[1]改成视频流中的每一帧数据就可以展示了
Mat testImage = imread(argv[1]);
if (testImage.empty())
{
printf("read testImg failed.........\n");
return 0;
}
string str = argv[2]; // str
Point bg; // point position
bg.x = 0;
bg.y = 400;
int fontFace = cv::FONT_HERSHEY_PLAIN; // font
double fontScale = 4.0;
int thickness = 4;
putText(testImage, str, bg, fontFace, fontScale, Scalar(0, 0, 255), thickness, LINE_8); // LINE_8 is the type of the thick
imwrite("putText.jpg", testImage);
更多推荐
所有评论(0)