ffmpeg 如何转换 rgb 图片到 yuv420p?如何使用 C 语言实现 rgb24 如何转换 yuv420p ?

// convert to nv21 
ffmpeg -i test.png -s 800x480 -pix_fmt nv21 test.yuv
// convert to i420
ffmpeg -i test.png -s 800x480 -pix_fmt yuv420p yuv420p.yuv

如何使用 C 语言实现 rgb24 如何转换 yuv420p ?

void RGB24ToYUV420P(int width, int height, unsigned char rgb[], unsigned char yuv[]) {
	//rgb size w*h*(1 + 1 + 1) => r = 1 g = 1 b = 1
	//yuv size w*h*(1 + 1/4 + 1/4) => y = 1 u = 1/4 v = 1/4
	// w*h*3/2
	unsigned char *y_channel = &yuv[0];//1
	unsigned char *u_channel = &yuv[0 + width * height];//1/4
	unsigned char *v_channel = &yuv[0 + width * height + width * height * 1 / 4];//1/4

	//memset(yuv, 0, width * height * (1 + 1 / 4 + 1 / 4));
	unsigned char *rgb_channel = 0;
	unsigned char r, g, b;
	int y, u, v;
	for (int h = 0; h < height; ++h) {
		rgb_channel = &rgb[width * h * 3];
		for (int w = 0; w < width; ++w) {
			r = *(rgb_channel++);
			g = *(rgb_channel++);
			b = *(rgb_channel++);
			y = ((66 * r + 129 * g + 25 * b + 128) >> 8) + 16;
			u = ((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128;
			v = ((112 * r - 94 * g - 18 * b + 128) >> 8) + 128;

			*(y_channel++) = y > 255 ? 255 : (y < 0 ? 0 : y);
			if (h % 2 == 0 && w % 2 == 0) {
				*(u_channel++) = u > 255 ? 255 : (u < 0 ? 0 : u);
			} else {
				if (w % 2 == 0) {
					*(v_channel++) = v > 255 ? 255 : (v < 0 ? 0 : v);
				}
			}
		}
	}
}
	const int raw_width = 1920;
	const int raw_height = 1080;
	unsigned char raw_rgb24[raw_width*raw_height * 3];
	unsigned char raw_yuv420p[raw_width*raw_height * 3 / 2];
	RGB24ToYUV420P(raw_width, raw_height, raw_rgb24, raw_yuv420p);
posted @ 2021-03-01 15:10  學海無涯  阅读(249)  评论(0编辑  收藏  举报