ffmpeg3.3新版本AVStream的封装流参数由codec替换codecpar(解码)
ffmpeg新版本中(封装流)AVStream的codec参数要被codecpar参数所替代,这样替代我们要注意什么,为什么要替代,我们先来看下ffmpeg的代码。
代码分析和新参数优势
typedefstructAVStream{#ifFF_API_LAVF_AVCTX/***@deprecatedusethecodecparstructinstead*/attribute_deprecatedAVCodecContext*codec;#endif。。。。。。。。。。。。。。。。。。。。。。。。。。。。。/**Codecparametersassociatedwiththisstream.Allocatedandfreedby*libavformatinavformat_new_stream()andavformat_free_context()*respectively.**-demuxing:filledbylibavformatonstreamcreationorin*avformat_find_stream_info()*-muxing:filledbythecallerbeforeavformat_write_header()*/AVCodecParameters*codecpar;}
从代码中我们可以看出codec参数在58版本及之后就不会支持了,需要由codecpar参数所替代。这样做的目的我想主要是将编码和封装彻底分离,之前封装和编码使用的参数都是存放在codec中,这样的好处是代码简洁,不需要额外给封装传递参数,但坏处是把编码和封装的代码融合在一块耦合性较大,有很多需求,我们只需要编码并不需要做封装,比如我们做自己的推流协议,直接吧编码后h364数据通过自定义的协议发送。
再比如直播推流中我们编码和封装推流会在不同的线程中处理,如果共用一个上下文肯定还需要处理互斥问题,分开就不会存在这个问题。
既然必须要替换我们如何处理;
比如原来的视频播放处理方式是这样(错误处理省略):
//打开多媒体文件,我们假定视频流索引为0AVFormatContext*ic=NULL;avformat_open_input(&ic,"test.mp4",0,0);//找到视频×××,比如H264AVCodec*codec=avcodec_find_decoder(ic->streams[0]->codec->codecid);//打开视频×××,打开音频×××用的也是同一个函数avcodec_open2(enc,ic->streams[0]->codec,NULL);
看代码我们知道avformat_open_input之后音视频的配置信息已经被写在了codec中,解封装和解码用同一套参数。但是如果替换为codecpar ,那×××是独立创建的,那是否还要手动填写一遍解码参数,理论上是需要的,不过还好ffmpeg提供给我们一个函数做参数复制
int avcodec_parameters_to_context(AVCodecContext *codec, const AVCodecParameters *par);
那我们codec参数替换为codecpar 代码就可以这样写了(错误处理省略)
//打开多媒体文件,我们假定视频流索引为0AVFormatContext*ic=NULL;avformat_open_input(&ic,"test.mp4",0,0);//找到视频×××,比如H264AVCodec*codec=avcodec_find_decoder(ic->streams[0]->codecpar->codec_id);//独立的解码上下文AVCodecContext*vc=avcodec_alloc_context3(codec);avcodec_parameters_to_context(vc,ic->streams[0]->codecpar);avcodec_open2(vc,codec,NULL);
代码改变后解码上下文就是独立的,后面解码也不需要与解封装上下文关联,包括清理。
×××的ID号也变为从codecpar->codec_id成员获取。
更多的资料也可以关注我51cto上的视频课程
夏老师的课堂http://edu.51cto.com/lecturer/12016059.html
C++编程FFMpegSDK美颜直播推流实战-基于qt5,opencv视频课程http://edu.51cto.com/course/10840.html
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。