[audio and video series 1] detailed explanation of video formats YUV444, YUV422 and YUV420

This article only introduces the frequently used formats such as YUV444, YUV422 and YUV420

Introduction:

YUV, divided into three components, "Y" indicates brightness (Luminance or Luma), that is, gray value; "U" and "V" represent chromaticity (Chroma or Chroma), which is used to describe the image color and saturation, and to specify the color of pixels.

history:

The invention of Y'UV is due to the transition period between color TV and black-and-white TV. Black and white video only has Y (Luma, Luminance) video, that is, gray scale value. When it comes to the formulation of color TV specifications, color TV images are processed in YUV/YIQ format, and UV is regarded as C (chromeance or Chroma) representing chromaticity. If the C signal is ignored, the remaining Y (Luma) signal is the same as the previous black-and-white TV frequency. In this way, the compatibility between color TV and black-and-white TV is solved. The biggest advantage of Y'UV is that it only takes up very little bandwidth.

YUV color spatial distribution:

If the width and height of an image have been determined, the byte occupation of each format for the converted YUV is as follows:

YUV444: it means that each Y corresponds to a UV component (as shown in the figure), so the number of YUV is the same, and the space occupied by YUV444: that is, the encoded byte space is = width * height * 3   (Y = U = V, width and height are equal)

    

YUV422: indicates that every two Y corresponds to a UV component, then the number of Y is the number of UVs * 2, and the space occupied by YUV422: that is, the encoded byte space is = (Y) width * height + (U) width * height * 1/2 + (V) width * height * 1 / 2   = Width * height * 2   (y width = 2*U width = 2*V width, height YUV is the same)

     

  YUV420: indicates that every four y corresponds to a UV component, then the number of Y is the number of UVs * 4, and YUV420 occupies space: that is, the encoded byte space is = (Y) width * height + (U) width * height * 1/4 * (V) width * height * 1 / 4 = width * height * 3 / 2   (both y width and height are twice the UV width and height)

    

 

analysis:

Write C code to read / write and analyze each format respectively. Each component of YUV needs to be saved as a Y component file. At this time, the software for YUV playback needs to use YUV player temporarily

1: First use ffmpeg to convert the file in 3 formats (this paper uses pictures to test: equivalent to one frame of video)

Get a picture from the network and generate YUV files in three formats using ffmpeg. The commands are as follows:

ffmpeg -i test.jpg -pix_fmt yuv444p test_444.yuv
ffmpeg -i test.jpg -pix_fmt yuv422p test_422.yuv
ffmpeg -i test.jpg -pix_fmt yuv420p test_420.yuv

  

  2: Read and separate the Y, U and V component files of each file with C code:

enum YUVTYPE
{
	YUV444,
	YUV422,
	YUV420
};
void read_split_yuvfile(const char* file, int width, int heiht, YUVTYPE yuvtype, int frames) {
	FILE* yuvFp = fopen(file, "rb+");
	FILE* yFp = fopen("E:\\test_y.y", "wb+");
	FILE* uFp = fopen("E:\\test_u.y", "wb+");
	FILE* vFp = fopen("E:\\test_v.y", "wb+");
	unsigned char* buf = NULL;
	int size = width * heiht;
	if (YUV444 == yuvtype)
		buf = (unsigned char*)malloc(size * 3);
	else if (YUV422 == yuvtype)
		buf = (unsigned char*)malloc(size << 1);
	else
		buf = (unsigned char*)malloc(size * 3 >> 1);
	for (int i = 0; i < frames; i++) {
		if (YUV444 == yuvtype) {
			fread(buf, 1, size * 3, yuvFp);
			fwrite(buf, 1, size, yFp);
			fwrite(buf + size, 1, size, uFp);
			fwrite(buf + (size << 1), 1, size, vFp);
		}
		else if (YUV422 == yuvtype) {
			fread(buf, 1, size << 1, yuvFp);
			fwrite(buf, 1, size, yFp);
			fwrite(buf + size, 1, size >> 1, uFp);
			fwrite(buf + (size * 3 >> 1), 1, size >> 1, vFp);
		}
		else {
			fread(buf, 1, size * 3 >> 1, yuvFp);
			fwrite(buf, 1, size, yFp);
			fwrite(buf + size, 1, size >> 2, uFp);
			fwrite(buf + (size * 5 >> 2), 1, size >> 2, vFp);
		}
		
	}
	free(buf);
	buf = NULL;
	fclose(yuvFp);
	fclose(yFp);
	fclose(uFp);
	fclose(vFp);
}

The size of the generated file is the same as the component ratio of YUV. YUV444 is 1:1:1, YUV422 is 2:1:1, and YUV420 is 4:1:1

Due to the high compression, YUV420 is used more. The YUV component is shown as follows:

 Y:

 

 U:

 

 V:

Posted on Tue, 02 Nov 2021 05:25:56 -0400 by Myss