海思编码通道添加显示时间

说明

这里的需求是要往生成的录像文件中添加显示时间,实际上也就是海思的VENC与OSD的绑定。

在上一篇博客海思平台freetype、SDL、SDL_TTL的编译编译出三个库之后,又提供了例程生成一个bmp图片,但是实际上我们每次往海思通道贴图,不可能说都像例程一样保存成bmp图片再贴图,这样会造成资源的浪费。

所以这里进行了进一步的修改,让我们能够直接拿到bmp图片的位图数据,而不需要生成bmp图片。

一、bmp位图数据的获取

/*
getVencOsd  获取生成的位图数据
bitmap 海思 BITMAP_S 位图数据结构体指针
*/
static SV_S32 getVencOsd(BITMAP_S *bitmap) {

	if( bitmap == NULL || bitmap->pData == NULL ) {
		LOG(ERROR)<<"bitmap or pData is NULL";
		return SV_FAILURE;
	}
	
	//初始化字库
	if ( TTF_Init() < 0 ) {
		SDL_Quit();
		return SV_FAILURE;
	}

	//打开字库
	font = TTF_OpenFont("/root/res/wqy-microhei.ttc", 48);
	if ( font == NULL ) {
		fprintf(stderr, "Couldn't load %d pt font from %s: %s\n", 18, "ptsize", SDL_GetError());
		SDL_Quit();
		return SV_FAILURE;
	}

	//生成显示时间
	std::string time("2019-10-10 10:10:10");
	SDL_Color forecol = { 0xff, 0xff, 0xff, 0xff };
	SDL_Surface *text = TTF_RenderUTF8_Solid(font, time.c_str(), forecol);
	if ( text == NULL ) {
		LOG(ERROR)<<"temp is NULL";
		return SV_FAILURE;
	}

	SDL_PixelFormat fmt;
	memset(&fmt, 0, sizeof(SDL_PixelFormat));
	fmt.BitsPerPixel = 16;
	fmt.BytesPerPixel = 2;
	fmt.colorkey = 0xffffffff;
	fmt.alpha = 0xff;
	fmt.Rmask = 0xff000000;//0x00FF0000
	fmt.Gmask = 0x0000ff00;//0x0000FF00
	fmt.Bmask = 0x000000ff;//0x000000FF
	fmt.Amask = 0;

	SDL_Surface *temp = SDL_ConvertSurface(text, &fmt, 0);
	if ( temp == NULL ) {
		LOG(ERROR)<<"temp is NULL";
		SDL_FreeSurface(text);
		return SV_FAILURE;
	}

	memset(bitmap->pData, 0, DATA_BUFF);
	memcpy(bitmap->pData, temp->pixels, (2*(temp->w)*(temp->h)));

	bitmap->u32Width = temp->w;
	bitmap->u32Height = temp->h;
	bitmap->enPixelFormat = PIXEL_FORMAT_RGB_1555 ;

	SDL_FreeSurface(text);
	SDL_FreeSurface(temp);
	return SV_SUCCEED;
}

二、创建RGN区域

/*
s32CreateRgnAndAttachVencChn  创建贴图区域并绑定到编码通道
OsdRGBAs 海思 SV_OSD_RGBA_S 结构体对象
s32VencChn 编码通道号
s32RgnHandle 通道句柄

注意:海思的编码通道位图只支持PIXEL_FORMAT_RGB_1555或PIXEL_FORMAT_RGB_4444这里用的是1555
*/
static SV_S32 s32CreateRgnAndAttachVencChn(const SV_OSD_RGBA_S OsdRGBAs, const SV_S32 s32VencChn, const SV_S32 s32RgnHandle) {

	MPP_CHN_S stChn;
	//RGN 区域绑定到对应VENC
	stChn.enModId  = HI_ID_VENC;
	stChn.s32DevId = 0;
	stChn.s32ChnId = s32VencChn;

	//创建RGN区域
	RGN_ATTR_S stRgnAttrSet;
	stRgnAttrSet.enType = OVERLAY_RGN;
	stRgnAttrSet.unAttr.stOverlay.enPixelFmt       = PIXEL_FORMAT_RGB_1555;
	stRgnAttrSet.unAttr.stOverlay.stSize.u32Width  = std::max(2, ALIGN_BACK(OsdRGBAs.stPixRect.stRectSize.s32Width, 2));
	stRgnAttrSet.unAttr.stOverlay.stSize.u32Height = std::max(2, ALIGN_BACK(OsdRGBAs.stPixRect.stRectSize.s32Height, 2));
	stRgnAttrSet.unAttr.stOverlay.u32BgColor       = 0;

	HI_MPI_RGN_DetachFromChn(s32RgnHandle, &stChn);
	HI_MPI_RGN_Destroy(s32RgnHandle);
	SV_S32 s32Ret = HI_MPI_RGN_Create(s32RgnHandle, &stRgnAttrSet);
	if(s32Ret != SV_SUCCEED) {
		LOG(ERROR)<<"HI_MPI_RGN_Create failed with 0x"<

三、加载bmp位图

/*
s32LoadBmp 加载显示bmp
pData 用来存放位图的buffer
*/
SV_S32 s32LoadBmp(SV_VOID *pData) {

	BITMAP_S bitmap;
	bitmap.pData = pData;
	
	SV_S32 s32VencChn = 0;
	SV_S32 s32Ret = getVencOsd(s32VencChn, &bitmap);
	if( s32Ret == SV_FAILURE ) {
		LOG(ERROR)<<"getVencOsd is failed!";
		return SV_FAILURE;
	}

	SV_OSD_RGBA_S pOsd;
	pOsd.stPixRect.stStartPoint.s32X = 0;
	pOsd.stPixRect.stStartPoint.s32Y = 0;
	pOsd.stPixRect.stRectSize.s32Width = bitmap.u32Width;
	pOsd.stPixRect.stRectSize.s32Height = bitmap.u32Height;
	
	SV_S32 s32RgnHandle = 0;
	s32Ret = this->s32CreateRgnAndAttachVencChn(pOsd, s32VencChn, s32RgnHandle);
	if( s32Ret == SV_FAILURE ) {
		LOG(ERROR)<<"s32CreateRgnAndAttachVencChn failed with "<

四、主函数

int main (void) {

	char *pData = (char *)malloc(1024 * 512);
	s32LoadBmp( pData );
	
	return 0;
}

你可能感兴趣的:(海思开发)