#include <iostream>

extern "C"
{
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}

#pragma comment(lib,"avformat.lib")
#pragma comment(lib,"avcodec.lib")
#pragma comment(lib,"avutil.lib")
#pragma comment(lib,"swscale.lib")

using namespace std;

int main()
{
	char infile[] = "dove_RGB24.rgb";
	char outfile[] = "out.yuv";

	// 源图像参数(这里参数要设置正确,否则会转换异常)
	int width = 640;
	int height = 360;

	//1 打开RGB和YUV文件
	FILE *fpin = fopen(infile, "rb");
	if (!fpin)
	{
		cout << infile << "open infile failed!" << endl;
		getchar();
		return -1;
	}

	FILE* fpout = fopen(outfile, "wb");
	if (!fpout)
	{
		cout << infile << "open outfile failed!" << endl;
		getchar();
		return -1;
	}
	// 创建RGB缓冲区同时分配内存
	unsigned char *rgbBuf = new unsigned char[width * height * 3];

	// 注册所有和编解码器有关的组件
	av_register_all();

	//2 创建视频重采样上下文:指定源和目标图像分辨率、格式
	SwsContext *swsCtx = NULL;
	swsCtx = sws_getCachedContext(swsCtx,
		width, height, AV_PIX_FMT_RGB24,
		width, height, AV_PIX_FMT_YUV420P,
		SWS_BICUBIC,
		NULL, NULL, NULL
		);

	//3 创建YUV视频帧并配置
	AVFrame *yuvFrame = av_frame_alloc();
	yuvFrame->format = AV_PIX_FMT_YUV420P;
	yuvFrame->width = width;
	yuvFrame->height = height;
	av_frame_get_buffer(yuvFrame, 3 * 8);

	// 循环写视频文件
	for (;;)
	{
		//4 每次读取一帧RGB数据到rgbBuf,读取完毕则退出
		int len = fread(rgbBuf, width*height * 3, 1, fpin);
		if (len <= 0)
		{
			break;
		}
        
		//5 创建RGB视频帧并绑定RGB缓冲区(avpicture_fill是给rgbFrame初始化一些字段,并且会自动填充data和linesize)
		AVFrame *rgbFrame = av_frame_alloc();
		avpicture_fill((AVPicture *)rgbFrame, rgbBuf, AV_PIX_FMT_BGR24, width, height);

		//6 像素格式转换,转换后的YUV数据存放在yuvFrame
		int outSliceH = sws_scale(swsCtx, rgbFrame->data, rgbFrame->linesize, 0, height,
			yuvFrame->data, yuvFrame->linesize);
		if (outSliceH <= 0)
			break;

		//7 将YUV各分量数据写入文件
		fwrite(yuvFrame->data[0], width * height, 1, fpout);
		fwrite(yuvFrame->data[1], width * height / 4, 1, fpout);
		fwrite(yuvFrame->data[2], width * height / 4, 1, fpout);

		cout << ".";
	}

	cout << "\n======================end=========================" << endl;

	// 关闭RGB和YUV文件
	fclose(fpin);
	fclose(fpout);
    
	// 释放RGB缓冲区
	delete rgbBuf;    

	//清理视频重采样上下文
	sws_freeContext(swsCtx);

	getchar();

	return 0;
}

https://www.cnblogs.com/linuxAndMcu/p/12127975.html https://blog.csdn.net/leixiaohua1020/article/details/50466201 https://blog.csdn.net/leixiaohua1020/article/details/14215391

除额外注明的地方外,本维基上的内容按下列许可协议发布: CC Attribution-Share Alike 4.0 International