FFMPEG将YUV图片生成视频
1.基本步骤
-
查找编码器
AVCodec
,函数为av_codec_find_encoder()
或者av_codec_find_encoder_by_name()
-
根据编码器创建编码器上下文
AVCodecContext
,函数为avcodec_alloc_context3()
-
分配
AVPacket
内存空间(AVPacket
保存数据包),函数为av_packet_alloc()
-
设置
AVCodecContext
的参数bit_rate
(一般设置为400000
,原因目前还没弄懂,先记着吧,后面深究的时候在研究)width
和height
(编码后视频的大小)time_base
(相当于一帧的时间,含den
和num
两个参数,den
表示分母,num
表示分子)framerate
(表示帧率,和上面的time_base
刚好相反,互为倒数,也有den
和num
两个参数,值与上面time_base
的den
和num
相反)gop_size
max_b_frame
pix_fmt
(编码格式)
-
设置
AVOptions
参数,函数为av_opt_set
-
打开编码器,函数
avcodec_open2()
-
打开输出文件
-
分配帧空间
AVFrame
,函数为av_frame_alloc()
-
设置帧参数
-format
width
height
-
获取帧缓存,函数为
av_frame_get_buffer()
-
打开
yuv
图片文件 -
读取
yuv
数据 -
将帧数据设置为可写
-
设置帧数据
data[0][i]
表示Y
data[1][i]
表示U
data[2]
表示V
pts
(时间戳)
-
将帧数据发送给编码器,函数为
avcodec_send_frame()
-
接收包,函数为
avcodec_receive_packet()
,即将帧数据进行编码后放入包数据中 -
写入输出文件中
-
写完后刷新编码器
-
写入尾数据
-
释放资源
2.示例:
#include <string.h>
#include <iostream>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavutil/opt.h>
#include <libavutil/imgutils.h>
}
using namespace std;
#pragma comment(lib,"avformat.lib")
#pragma comment(lib,"avutil.lib")
#pragma comment(lib,"avcodec.lib")
static int encode(AVCodecContext *enc_ctx, AVFrame *frame, AVPacket *pkt,
FILE *outfile)
{
int ret;
/* send the frame to the encoder */
if (frame)
cout << "Send frame " << frame->pts << endl;
ret = avcodec_send_frame(enc_ctx, frame);
if (ret < 0) {
fprintf(stderr, "Error sending a frame for encoding\n");
return -1;
}
while (ret >= 0) {
ret = avcodec_receive_packet(enc_ctx, pkt);
if (ret