APPRO IPNC RDK는 모니터 화면의 TI 로고를 대체합니다.

5505 단어
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 함수의 정의는 내 블로그 "
ffmpeg는 Windows에서 카메라 데이터 프레임을 캡처하여 bmp 이미지로 저장합니다.

이 원칙에 따라 각각 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
"); 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***************************/
unsigned char logo_Y[]={"); fwrite(buf,1,strlen(buf),fp); for(i=0;i<yuv_frame ->linesize[0]*height;i++) { if(!(i%16)) { sprintf(buf,"
\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,"
};
//%d bytes
/**************end of Y***************************/

",yuv_frame ->linesize[0]*h); fwrite(buf,strlen(buf),1,fp); sprintf(buf,"/********************UV***************************/
unsigned 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,"
\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,"
};
//%d bytes
/*************end of UV***************************/

",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를 재컴파일합니다.

좋은 웹페이지 즐겨찾기