您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > 最新版FFMPEG解码流程
FFMPEG解码流程:1.注册所有容器格式和CODEC:av_register_all()2.打开文件:av_open_input_file()3.从文件中提取流信息:av_find_stream_info()4.穷举所有的流,查找其中种类为CODEC_TYPE_VIDEO5.查找对应的解码器:avcodec_find_decoder()6.打开编解码器:avcodec_open()7.为解码帧分配内存:avcodec_alloc_frame()8.不停地从码流中提取出帧数据:av_read_frame()9.判断帧的类型,对于视频帧调用:avcodec_decode_video()10.解码完后,释放解码器:avcodec_close()11.关闭输入文件:avformat_close_input_file()主要数据结构:基本概念:编解码器、数据帧、媒体流和容器是数字媒体处理系统的四个基本概念。首先需要统一术语:容器/文件(Conainer/File):即特定格式的多媒体文件。媒体流(Stream):指时间轴上的一段连续数据,如一段声音数据,一段视频数据或一段字幕数据,可以是压缩的,也可以是非压缩的,压缩的数据需要关联特定的编解码器。数据帧/数据包(Frame/Packet):通常,一个媒体流由大量的数据帧组成,对于压缩数据,帧对应着编解码器的最小处理单元。通常,分属于不同媒体流的数据帧交错复用于容器之中,参见交错。编解码器:编解码器以帧为单位实现压缩数据和原始数据之间的相互转换。在FFMPEG中,使用AVFormatContext、AVStream、AVCodecContext、AVCodec及AVPacket等结构来抽象这些基本要素,它们的关系如上图所示:AVCodecContext:这是一个描述编解码器上下文的数据结构,包含了众多编解码器需要的参数信息,如下列出了部分比较重要的域:typedefstructAVCodecContext{/***一些编解码器需要/可以像使用extradataHuffman表。*MJPEG:Huffman表*RV10其他标志*MPEG4:全球头(也可以是在比特流或这里)*分配的内存应该是FF_INPUT_BUFFER_PADDING_SIZE字节较大*,比extradata_size避免比特流器,如果它与读prolems。*extradata按字节的内容必须不依赖于架构或CPU的字节顺序。*-编码:设置/分配/释放由libavcodec的。*-解码:由用户设置/分配/释放。*/uint8_t*extradata;intextradata_size;/***这是时间的基本单位,在条件(以秒为单位)*帧时间戳派代表出席了会议。对于固定fps的内容,*基应该1/framerate和时间戳的增量应该*相同的1。*-编码:必须由用户设置。*-解码:libavcodec的设置。*/AVRationaltime_base;/*视频*//***图片宽度/高度。*-编码:必须由用户设置。*-解码:libavcodec的设置。*请注意:兼容性,它是可能的,而不是设置此*coded_width/高解码之前。*/intwidth,height;....../*仅音频*/intsample_rate;///每秒采样intchannels;///音频通道数/***音频采样格式*-编码:由用户设置。*-解码:libavcodec的设置。*/enumSampleFormatsample_fmt;///样本格式/*下面的数据不应该被初始化。*//***每包样品,初始化时调用“init”。*/intframe_size;intframe_number;///音频或视频帧数量charcodec_name[32];enumAVMediaTypecodec_type;/*看到AVMEDIA_TYPE_xxx*/enumCodecIDcodec_id;/*seeCODEC_ID_xxx*//***的fourcc(LSB在前,所以“的ABCD”-(“D”24)(“C”16)(“B”8)+“A”)。*这是用来解决一些编码错误。*分路器应设置什么是编解码器用于识别领域中。*如果有分路器等多个领域,在一个容器,然后选择一个*最大化使用的编解码器有关的信息。*如果在容器中的编解码器标记字段然后32位大分路器应该*重新映射到一个表或其他结构的32位编号。也可选择新*extra_codec_tag+大小可以添加,但必须证明这是一个明显的优势*第一。*-编码:由用户设置,如果没有则默认基础上codec_id将使用。*-解码:由用户设置,将被转换成在初始化libavcodec的大写。*/unsignedintcodec_tag;....../***在解码器的帧重排序缓冲区的大小。*对于MPEG-2,这是IPB1或0低延时IP。*-编码:libavcodec的设置。*-解码:libavcodec的设置。*/inthas_b_frames;/***每包的字节数,如果常量和已知或0*用于一些WAV的音频编解码器。*/intblock_align;/***从分路器位每个样品/像素(huffyuv需要)。*-编码:libavcodec的设置。*-解码:由用户设置。*/intbits_per_coded_sample;.....}AVCodecContext;如果是单纯使用libavcodec,这部分信息需要调用者进行初始化;如果是使用整个FFMPEG库,这部分信息在调用avformat_open_input和avformat_find_stream_info的过程中根据文件的头信息及媒体流内的头部信息完成初始化。其中几个主要域的释义如下:extradata/extradata_size:这个buffer中存放了解码器可能会用到的额外信息,在av_read_frame中填充。一般来说,首先,某种具体格式的demuxer在读取格式头信息的时候会填充extradata,其次,如果demuxer没有做这个事情,比如可能在头部压根儿就没有相关的编解码信息,则相应的parser会继续从已经解复用出来的媒体流中继续寻找。在没有找到任何额外信息的情况下,这个buffer指针为空。time_base:width/height:视频的宽和高。sample_rate/channels:音频的采样率和信道数目。sample_fmt:音频的原始采样格式。codec_name/codec_type/codec_id/codec_tag:编解码器的信息。AVStrea该结构体描述一个媒体流,定义如下:typedefstructAVStream{intindex;/**在AVFormatContext流的索引*/intid;/**特定格式的流ID*/AVCodecContext*codec;/**codeccontext*//***流的实时帧率基地。*这是所有时间戳可以最低帧率*准确代表(它是所有的最小公倍数*流的帧率)。请注意,这个值只是一个猜测!*例如,如果时间基数为1/90000和所有帧*约3600或1800计时器刻度,,然后r_frame_rate将是50/1。*/AVRationalr_frame_rate;/***这是时间的基本单位,在条件(以秒为单位)*帧时间戳派代表出席了会议。对于固定fps的内容,*时基应该是1/framerate的时间戳的增量应为1。*/AVRationaltime_base;....../***解码流量的第一帧,在流量时-base分。*如果你是绝对100%的把握,设定值*它真的是第一帧点。*这可能是未定义(AV_NOPTS_VALUE)的。*@注意的业余头不弱者受制与正确的START_TIME的业余*分路器必须不设定此。*/int64_tstart_time;/***解码:时间流流时基。*如果源文件中没有指定的时间,但不指定*比特率,这个值将被从码率和文件大小的估计。*/int64_tduration;#ifLIBAVFORMAT_VERSION_INT(5316)charlanguage[4];/**ISO639-2/B3-letterlanguagecode(emptystringifundefined)*/#endif/*av_read_frame()支持*/enumAVStreamParseTypeneed_parsing;structAVCodecParserContext*parser;...../*函数av_seek_frame()支持*/AVIndexEntry*index_entries;/**仅用于如果格式不notsupport寻求本身。*/intnb_index_entries;unsignedintindex_entries_allocated_size;int64_tnb_frames;///在此流的帧,如果已知或0......//*平均帧率AVRationalavg_frame_rate;......}AVStream;主要域的释义如下,其中大部分域的值可以由avformat_open_input根据文件头的信息确定,缺少的信息需要通过调用avformat_find_stream_info读帧及软解码进一步获取:index/id:index对应流的索引,这个数字是自动生成的,根据index可以从AVFormatContext::streams表中索引到该流;而id则是流的标识,依赖于具体的容器格式。比如对于MPEGTS格式,id就是pid。time_base:流的时间基准,是一个实数,该流中媒体数据的pts和dts都将以这个时间基准为粒度。通常,使用av_rescale/av_rescale_q可以实现不同时间基准的转换。start_time:流的起始时间,以流的时间基准为单位,通常是该流中第一个帧的pts。duration:流的总时间,以流的时间基准为单位。need_parsing:对该流parsing过程的控制域。nb_frames:流内的帧数目。r_frame_rate/framerate/avg_frame_rate:帧率相关。codec:指向该流对应的AVCodecContext结构,调用avformat_open_input时生成。parser:指向该流对应的AVCodecParserContext结构,调用avformat_find_stream_info时生成。。AVFormatContext这个结构体描述了一个媒体文件或媒体流的构成和基本信息,定义如下:typedefstructAVFormatContext{constAVClass*av_class;/**由avformat_alloc_context设置的。*//*只能是iFormat的,或在同一时间oformat,不是两个。*/structAVInputFormat*iformat;structAVOutputFormat*oformat;void*priv_data;ByteIOContext*pb;unsignedintnb_streams;AVStream*streams[MAX_STREAMS];charfilename[1024];/**输入或输出的文件名*//*流信息*/int64_ttimestamp;#ifLIBAVFORMAT_VERSION_INT(5316)chartitle[512];charauthor[512];charcopyright[512];charcomment[512];charalbum[512];intyear;/**ID3year,0ifnone*/inttrack;/**tracknumber,0ifnone*/chargenre[32];/**ID3genre*/#endifintctx_flags;/**格式特定的标志,看到A
本文标题:最新版FFMPEG解码流程
链接地址:https://www.777doc.com/doc-4269664 .html