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即可。