我测试的rgb素材是BGR24的,如果你的 rgb数据是AV_PIX_FMT_RGB24格式,请自行替换
#include <stdio.h>
#include <stdint.h>
#include <cstring>
#include <malloc.h>
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "libavutil/imgutils.h"
};
int main(int argc, char **argv){
av_register_all();
const int width = 400, height = 400;
enum AVPixelFormat src_pix_fmt = AV_PIX_FMT_BGR24, dst_pix_fmt = AV_PIX_FMT_YUV420P;
FILE* fp = NULL;
fopen_s(&fp, "sucai_rgb.rgb", "rb");
uint8_t* rgbbuf = (uint8_t*)malloc(width * height * 3);
fread(rgbbuf, width * height * 3, 1, fp);
fclose(fp);
AVFrame *pFrameYUV = av_frame_alloc();
uint8_t *out_buffer = new uint8_t[avpicture_get_size(dst_pix_fmt, width, height)];
//avpicture_fill是给pFrameYUV初始化一些字段,并且给填充data和linesize
avpicture_fill((AVPicture *)pFrameYUV, out_buffer, dst_pix_fmt, width, height);
AVFrame *rgbFrame = av_frame_alloc();
avpicture_fill((AVPicture *)rgbFrame, rgbbuf, src_pix_fmt, width, height);
SwsContext *sws_ctx = sws_getContext(
width, height, src_pix_fmt,
width, height, dst_pix_fmt,
SWS_BILINEAR, NULL, NULL, NULL);
/*
int sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[],
const int srcStride[], int srcSliceY, int srcSliceH,
uint8_t *const dst[], const int dstStride[]);
srcSlice[],dst[]是输入输出图像数据各颜色通道的buffer指针数组
srcStride[],dstStride[] 为输入输出图像数据各颜色通道每行存储的字节数数组
srcSliceY 为从输入图像数据的第多少列开始逐行扫描,通常设为0
srcSliceH 为需要扫描多少行,通常为输入图像数据的高度
*/
// *(rgbFrame->linesize)--->3*width
// *(pFrameYUV->linesize)-->width
sws_scale(sws_ctx, rgbFrame->data, rgbFrame->linesize, 0, height, pFrameYUV->data, pFrameYUV->linesize);
sws_freeContext(sws_ctx);
FILE* fpout = NULL;
fopen_s(&fpout, "yuv_out.yuv", "wb");
fwrite(pFrameYUV->data[0], width * height, 1, fpout);
fwrite(pFrameYUV->data[1], width * height / 4, 1, fpout);
fwrite(pFrameYUV->data[2], width * height / 4, 1, fpout);
fclose(fpout);
return 0;
}