APPRO IPNC RDK更换监控画面上TI Logo标志

Application/src/ipnc_rdk/av_capture/application/ipnc/av_server/src/fonts目录下

ascii_TI_Logo_160_64.c
ascii_TI_Logo_80_32.c

两文件中分别有两个数组用于存放TI LOGO图片的Y 和 UV分量,通过下面的代码,可将其中的数据保存为24位的bmp图像

int save_logo_ti_160_64_bmp24()
{
	AVFormatContext *fmtCtx = NULL;
	FILE *fp = NULL;
	struct SwsContext *pSwsCtx=NULL;
	int width=160,height=64;


	pSwsCtx = sws_getContext(
		width,
		height,
		PIX_FMT_YUV420P,
		width,
		height,
		PIX_FMT_BGR24,
		SWS_BILINEAR,
		NULL,
		NULL,
		NULL);
	fp = fopen("out.bmp", "wb");

	if(pSwsCtx)
	{
		int pitch = width/2;
		uint8_t * U=malloc(sizeof(TILogo_UV_160_64)/2),*V=malloc(sizeof(TILogo_UV_160_64)/2);
		uint8_t *data[4]={TILogo_Y_160_64,U,V,NULL};
		int linesize[4]={width,pitch,pitch,0};
		int i=0,ii=0,iii=0;
		uint8_t * buffer = NULL;
		AVFrame * rgb_frame = avcodec_alloc_frame();
		//memset(U,0x80,sizeof(TILogo_UV_160_64)/2);
		//memset(V,0x80,sizeof(TILogo_UV_160_64)/2);
		//TILogo_UV_160_64数组交替存储UV,序列为UVUVUVUVUVUV
		for(i=0;i<sizeof(TILogo_UV_160_64);i++)
		{
			if(i%2)
			{
				V[ii++]=TILogo_UV_160_64[i];
			}
			else
			{
				U[iii++]=TILogo_UV_160_64[i];
			}
		}
		buffer = (unsigned char *)av_malloc(avpicture_get_size(PIX_FMT_BGR24,width,height));
		avpicture_fill((AVPicture*)rgb_frame,(uint8_t *)buffer,PIX_FMT_BGR24,width,height);
		sws_scale(
			pSwsCtx,
			data,
			linesize,
			0,
			height,
			rgb_frame ->data,
			rgb_frame ->linesize);
		save_bmp(rgb_frame ->data[0],rgb_frame ->linesize[0]*height,width,height,fp);
		av_free(rgb_frame);
		av_free(buffer);
		free(U);
		free(V);
	}
	fclose(fp);
	return 0;
}
其中save_bmp函数的定义可参阅我的blog《 ffmpeg Windows下采集摄像头一帧数据,并保存为bmp图片》。

根据该原理,分别设计2个160x64和80x32的24位的bmp图像(注意,设计好图片后将其进行垂直翻转,否则,通过下面的函数转换出来的图片是反的),

使用下面的函数将bmp图片的bgr24数据转化为yuv420p数据.

int conv_bgr24_to_yuv420p(const char * src_bmp24_file,const char * dst_yuv420p_data_file)
{
	AVFormatContext *fmtCtx = NULL;
	FILE *fp = NULL;
	struct SwsContext *pSwsCtx=NULL;
	uint8_t * bmp_data = NULL;
	int data_size = 0;
	int w=0,h=0;

	fp = fopen(src_bmp24_file, "rb");//打开图片文件
	if(fp)
	{
		//位图文件头
		BITMAPFILEHEADER bmpheader={0}; 
		BITMAPINFO bmpinfo={0}; 

		fread(&bmpheader,sizeof(BITMAPFILEHEADER),1,fp);
		fread(&bmpinfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp);
		w = bmpinfo.bmiHeader.biWidth;
		h = bmpinfo.bmiHeader.biHeight;
		data_size = bmpheader.bfSize - bmpheader.bfOffBits;
		if(data_size != w * h * 3)
		{
			printf("not 24 bit bmp\n");
			fclose(fp);
			return -1;
		}
		bmp_data = (uint8_t *)malloc(data_size);
		memset(bmp_data,0,data_size);
		if(bmp_data)
		{
			fread(bmp_data,data_size,1,fp);
		}
		fclose(fp);
		fp = NULL;
	}
	if(bmp_data)
	{
		pSwsCtx = sws_getContext(
			w,
			h,
			PIX_FMT_BGR24,
			w,
			h,
			PIX_FMT_YUV420P,
			SWS_POINT/*SWS_BILINEAR*/,
			NULL,
			NULL,
			NULL);
		if(pSwsCtx)
		{
			uint8_t *data[4]={bmp_data,NULL,NULL,NULL};
			int linesize[4]	={w*3,0,0,0};
			int height		= 0;
			uint8_t * buffer	= NULL;
			AVFrame * yuv_frame = avcodec_alloc_frame();
			buffer = (unsigned char *)av_malloc(avpicture_get_size(PIX_FMT_YUV420P,w,h));
			memset(buffer,0,avpicture_get_size(PIX_FMT_YUV420P,w,h));
			avpicture_fill((AVPicture*)yuv_frame,(uint8_t *)buffer,PIX_FMT_YUV420P,w,h);
			height = sws_scale(
				pSwsCtx,
				data,
				linesize,
				0,
				h,
				yuv_frame ->data,
				yuv_frame ->linesize);
			fp = fopen(dst_yuv420p_data_file,"w");
			if(fp)
			{
				char buf[1024]={0};
				int i=0;
				sprintf(buf,"/*********************Y***************************/\nunsigned char logo_Y[]={");
				fwrite(buf,1,strlen(buf),fp);
				for(i=0;i<yuv_frame ->linesize[0]*height;i++)
				{
					if(!(i%16))
					{
						sprintf(buf,"\n\t");
						fwrite(buf,strlen(buf),1,fp);
					}
					if(i)
					{
						sprintf(buf,",0x%02X",*(yuv_frame ->data[0]+i));
					}
					else
					{
						sprintf(buf," 0x%02X",*(yuv_frame ->data[0]+i));
					}
					fwrite(buf,strlen(buf),1,fp);
				}
				sprintf(buf,"\n};\n//%d bytes\n/**************end of Y***************************/\n\n",yuv_frame ->linesize[0]*h);
				fwrite(buf,strlen(buf),1,fp);
				sprintf(buf,"/********************UV***************************/\nunsigned char logo_UV[]={");
				fwrite(buf,1,strlen(buf),fp);
				for(i=0;i<yuv_frame ->linesize[1]*height/2;i++)
				{
					if(!(i%8))
					{
						sprintf(buf,"\n\t");
						fwrite(buf,strlen(buf),1,fp);
					}
					if(i)
					{
						sprintf(buf,",0x%02X,0x%02X",*(yuv_frame ->data[1]+i),*(yuv_frame ->data[2]+i));
					}
					else
					{
						sprintf(buf," 0x%02X,0x%02X",*(yuv_frame ->data[1]+i),*(yuv_frame ->data[2]+i));
					}
					fwrite(buf,strlen(buf),1,fp);
				}
				sprintf(buf,"\n};\n//%d bytes\n/*************end of UV***************************/\n\n",yuv_frame ->linesize[1]*h);
				fwrite(buf,strlen(buf),1,fp);
				fclose(fp);
				fp = NULL;
			}
			av_free(yuv_frame);
			av_free(buffer);

			sws_freeContext(pSwsCtx);
			pSwsCtx = NULL;
		}
		free(bmp_data);
		bmp_data = NULL;
	}
	return 0;
}

转换完成后,将dst_yuv420p_data_file文件中的logo_Y数组和logo_UV数组中的数据替换ascii_TI_Logo_160_64.c 和ascii_TI_Logo_80_32.c中Y和UV数组,重新编译av_server即可。


你可能感兴趣的:(APPRO IPNC RDK更换监控画面上TI Logo标志)