如何从一个帧数有限的yuv文件获得更多帧数的文件

//实现功能:把某一个1080p的yuv文件重复写入新的yuv文件
//N:表示重复写入的次数,生成一个更大的yuv文件,用来测试
//得注意一个问题:feof()

#include <stdio.h>
#include <memory.h>
#include <stdlib.h>

#define  VIDEO_SOURCE_FILE "D:\\cudaEncode\\data\\ED_1920_1080.yuv"//214帧
#define  VIDEO_OUTPUT_FILE "D:\\cudaEncode\\data\\ED_1920_1080_2.yuv"
#define  SIZE  1920*1080*3/2
#define  N 2

int main()
{
	FILE *fpIn,*fpOut;
	int count=1;
	if ((fpIn=fopen(VIDEO_SOURCE_FILE,"rb"))==NULL)
	{
		printf("fopen() error!\n");
	}
	if((fpOut=fopen(VIDEO_OUTPUT_FILE,"wb"))==NULL)
	{
		printf("fopen() error!\n");
	}
	char *buf;
	buf=(char *)malloc(SIZE);
	memset(buf,0,SIZE);
	
	for (int i=0;i<N;i++)
	{
		fread(buf,1,SIZE,fpIn);
		while (!feof(fpIn))
		{
			printf("第 %d 次写入第 %3d 帧\n",i,count);
			fwrite(buf,1,SIZE,fpOut);
			fread(buf,1,SIZE,fpIn);
			count++;
		}
		/*
		while (!feof(fpIn))
		{
			fread(buf,1,SIZE,fpIn);
			printf("第 %d 次写入第 %3d 帧\n",i,count);
			fwrite(buf,1,SIZE,fpOut);
			count++;
		}
		//这种写法会把最后一帧重复写一遍
		//为什么呢?因为feof判断最后一帧的时候,并不能确定是最后一帧,
		//只有再接着fread才能确定,此时才返回1值
		*/
		rewind(fpIn);//或fseek(fpIn,0L,SEEK_SET);
		count=1;
	}
	printf("完成!\n");
	free(buf);
	buf=NULL;
	fclose(fpIn);
	fclose(fpOut);
	return 0;
}

上面针对的是1080p的yuv文件,4:2:0,分辨率为1920x1080.

如果是其他格式的yuv分辨率,只需把SIZE修改下,4:2:0下,一帧的大小:分辨率乘积*3/2

为什么是先乘以3再除以2呢,这与采样格式有关。

对于4:4:4没有压缩的格式,8比特量化后,每个像素占用3个字节,那么4:4:4采样格式的文件每一帧大小为:分辨率乘积*3

对于4:2:2采样格式,每4个像素,需要字节数为4+2+2=8,则每个像素占用8/4=2个字节,则每一帧大小为:分辨率乘积*2

对于4:1:1采样格式,每4个像素,需要字节数为4+1+1=6,则每个像素占用6/4=1.5个字节,则每一帧大小为:分辨率乘积*3/2

对于4:2:0采样格式(最常用),同时对水平方向和垂直方向采样

两行8个像素,需要字节数为:第一行4+2,第二行4+2,总共需要字节数为12,则每个像素占用12/8=1.5个字节,则每一帧大小为:分辨率乘积*3/2

你可能感兴趣的:(video,File,测试,null,ini,output)