2个YUV视频 拼接技术

/*************************************************
* 主要功能:两路 YUV4:2:0拼接一路左右半宽格式YUV视频
参考资料:http://www.pudn.com/downloads271/sourcecode/multimedia/vfw/detail1237363.html
U_size=V_size=Y_size/2
*************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define PREWEIGHT 1920
#define PREHEIGHT 1080
#define RESWEIGHT 3840
#define RESHEIGHT 1080
#define PREYSIZE ((PREWEIGHT)*(PREHEIGHT))
#define PREUSIZE ((PREWEIGHT/2)*(PREHEIGHT/2))
#define PREVSIZE ((PREWEIGHT/2)*(PREHEIGHT/2))
#define RESYSIZE ((RESWEIGHT)*(RESHEIGHT))
#define RESUSIZE ((RESWEIGHT/2)*(RESHEIGHT/2))
#define RESVSIZE ((RESWEIGHT/2)*(RESHEIGHT/2))
#define PRESIZE ((PREYSIZE)+(PREUSIZE)+(PREVSIZE))
#define RESSIZE ((RESYSIZE)+(RESUSIZE)+(RESVSIZE))

int GetFrameNum(const char *File)
{
	FILE *fp;
	int size=0;
	if (!(fp=fopen(File,"rb")))
	{
		printf("Open %s error !",File);
		exit(1);
	} 
	else
	{
		fseek(fp,0,SEEK_END);/*将文件指针移到YUV文件的末尾*/  
		size=ftell(fp);/*计算文件的总大小*/
	}
	return (size/PRESIZE);
}
void ReadYUV(char *ResBuf,char *PreBuf,int resstart,int prestart,int resoffset,int preoffset,int size,int height)
{
	int k;
	for (k=0;k<height;k++)
	{
		memmove(ResBuf+resstart+k*(resoffset),PreBuf+prestart+k*(preoffset),size);//注意这里用memmov不用strncpy
	}
}
int main(int argc,char *argv[])
{
	const char *FileName[]={"e:\BMX_L_1920x1080_240frms.yuv","e:\BMX_R_1920x1080_240frms.yuv"};/*两路YUV文件名*/
	FILE *FileResult;/*输出文件名*/
	FILE** fp_combine=(FILE**)malloc(sizeof(FILE *)*3);/*申请文件指针*/
	int *FileFrameNum=(int *)malloc(sizeof(int)*3);/*每个YUV的帧数*/
	char *PreBuf=(char *)malloc(sizeof(char)*(PRESIZE+1));/*处理前每一帧图像的大小*/
	char *ResBuf=(char*)malloc(sizeof(char)*(RESSIZE+1));/*处理后每一帧图像的大小*/
	int Y_start_section=0;/*预处理图片Y分量存入目标区域的起始区域*/
	int U_start_section = 0;/*预处理图片U分量存入目标区域的起始区域*/
	int V_start_section = 0;/*预处理图片V分量存入目标区域的起始区域*/
	int File_offset = 0;/*预处理文件偏移值*/    
	int i_combine=0,j_combine=0,k_combine=0;/*控制循环*/
	/*判断申请内存是否成功*/
	if (!((fp_combine)&&(FileFrameNum)&&(PreBuf)&&(ResBuf)))
	{
		printf("Allocate memeroy Faile !");
		exit(1);
	} 
	/*初始化申请空间*/
	memset(fp_combine,0,sizeof(FILE *)*2);
	memset(FileFrameNum,0,sizeof(int)*2);
	memset(PreBuf,0,sizeof(char)*PRESIZE);
	memset(ResBuf,0,sizeof(char)*RESSIZE);
	if (!(FileResult=fopen("hua_result.YUV","wb")))/*创建输出文件*/
	{
		printf("Creat File faile !");
		exit(1);
	} 
	for (i_combine=0;i_combine<2;i_combine++)
	{
		if(!(fp_combine[i_combine]=fopen(FileName[i_combine],"rb")))/*打开输入文件*/
		{
			printf("Open File %s Faile !",FileName[i_combine]);
			exit(1);
		}
		else
		{
			FileFrameNum[i_combine]=GetFrameNum(FileName[i_combine]);/*存储每一个视频的帧数*/
		}
	}
	i_combine=0;
	k_combine=FileFrameNum[i_combine];
	while (i_combine<k_combine)
	{
		File_offset = i_combine*PRESIZE;
		j_combine=0;
		while (j_combine<2)
		{
			fseek(fp_combine[j_combine],File_offset,SEEK_SET);/*移动文件指针至需要处理的数据的位置*/
			fread(PreBuf,1,PRESIZE,fp_combine[j_combine]);/*读取一幅图像*/
			if (j_combine==0)
			{
				/*把读取预处理图片Y/U/V分量的起始位置放置目标对应位置*/
				Y_start_section=0;
				U_start_section=RESYSIZE;
				V_start_section=RESYSIZE+RESUSIZE;
			} 
			else
			{
				/*把读取预处理图片Y/U/V分量的起始位置放置目标对应位置*/
				Y_start_section=PREWEIGHT;
				U_start_section=RESYSIZE+PREWEIGHT/2;
				V_start_section=RESYSIZE+RESUSIZE+PREWEIGHT/2;
			}
			/*分别读Y、U、V*/
			ReadYUV(ResBuf,PreBuf,Y_start_section,0,                 RESWEIGHT,PREWEIGHT,PREWEIGHT,PREHEIGHT);
			ReadYUV(ResBuf,PreBuf,U_start_section,PREYSIZE,          RESWEIGHT/2,PREWEIGHT/2,PREWEIGHT/2,PREHEIGHT/2);
			ReadYUV(ResBuf,PreBuf,V_start_section,PREYSIZE+PREUSIZE, RESWEIGHT/2,PREWEIGHT/2,PREWEIGHT/2,PREHEIGHT/2);
			j_combine++;
		}
		fwrite(ResBuf,1,RESSIZE,FileResult);
		fflush(FileResult);
		i_combine++;
	}
	fclose(fp_combine[0]);
	fclose(fp_combine[1]);
	fclose(FileResult);
	return 0;
}



 


 

你可能感兴趣的:(2个YUV视频 拼接技术)