C++使用FFmpeg实现YUV数据编码转视频文件.docx

C++使用FFmpeg实现YUV数据编码转视频文件.docx

C++使用FFmpeg实现YUV数据编码转视频文件

目录使用ffmpeg编码流程源码补充本文中实现的一个小功能是把一个YUV原始视频数据(时间序列图像)经过h264编码为视频码流,然后在使用mp4封装格式封装。

编码封装的流程图如下:

使用ffmpeg编码流程

1、首先使用av_register_all()函数注册所有的编码器和复用器(理解为格式封装器)。该步骤必须放在所有ffmpeg代码前第一个执行

2、avformat_alloc_output_context2():初始化包含有输出码流(AVStream)和解复用器(AVInputFormat)的AVFormatContext

3、avio_open()打开输出文件

4、av_new_stream()创建视频码流该函数生成一个空AVstream该结构存放编码后的视频码流。视频码流被拆分为AVPacket新式保存在AVStream中。

5、设置编码器信息,该步骤主要是为AVCodecContext(从AVStream-codec获取指针)结构体设置一些参数,包括codec_id、codec_type、width、height、pix_fmt.....根据编码器的不同,还要额外设置一些参数(如h264要设置qmax、qmin、qcompress参数才能正常使用h264编码)

6、查找并打开编码器,根据前一步设置的编码器参数信息,来查找初始化一个编码其,并将其打开。用到函数为av_fine_encoder()和av_open2()。

7、写头文件avformat_write_header()。这一步主要是将封装格式的信息写入文件头部位置。

8、编码帧。用到的函数avcodec_encode_video2()将AVFrame编码为AVPacket

9、在写入文件之前还需要做一件事情就是设置AVPacket一些信息。这些信息关乎最后封装格式能否被正确读取。后面回详细讲述该部分内容

10、编码帧写入文件av_write_frame()

11、flush_encoder():输入的像素数据读取完成后调用此函数。用于输出编码器中剩余的AVPacket。

12、av_write_trailer():写文件尾(对于某些没有文件头的封装格式,不需要此函数。比如说MPEG2TS)。

源码

#includestdio.h

#includepch.h

#includeiostream

externC{

#includelibavcodec/avcodec.h

#includelibavformat/avformat.h

#includelibavcodec/avcodec.h

#includelibswscale/swscale.h

#includelibavformat/avformat.h

usingnamespacestd;

intflush_encoder(AVFormatContext*fmt_ctx,unsignedintstream_index);

intYUV2H264()

AVFormatContext*pFormatCtx=nullptr;

AVOutputFormat*fmt=nullptr;

AVStream*video_st=nullptr;

AVCodecContext*pCodecCtx=nullptr;

AVCodec*pCodec=nullptr;

uint8_t*picture_buf=nullptr;

AVFrame*picture=nullptr;

intsize;

//打开视频文件

FILE*in_file=fopen(111.yuv,rb);

if(!in_file){

coutcannotopenfile!endl;

return-1;

//352x288

intin_w=352,in_h=288;

intframenum=50;

constchar*out_file=111.H264;

//[1]--注册所有ffmpeg组件

avcodec_register_all();

av_register_all();

//[2]--初始化AVFormatContext结构体,根据文件名获取到合适的封装格式

avformat

文档评论(0)

1亿VIP精品文档

相关文档