最新版FFMPEG解码流程欢迎愿意分享资料群友下载载.docx
- 文档编号:13673051
- 上传时间:2023-06-16
- 格式:DOCX
- 页数:48
- 大小:157.76KB
最新版FFMPEG解码流程欢迎愿意分享资料群友下载载.docx
《最新版FFMPEG解码流程欢迎愿意分享资料群友下载载.docx》由会员分享,可在线阅读,更多相关《最新版FFMPEG解码流程欢迎愿意分享资料群友下载载.docx(48页珍藏版)》请在冰点文库上搜索。
最新版FFMPEG解码流程欢迎愿意分享资料群友下载载
LIBAV
FFMPEG解码流程:
1.注册所有容器格式和CODEC:
av_register_all()
2.打开文件:
av_open_input_file()
3.从文件中提取流信息:
av_find_stream_info()
4.穷举所有的流,查找其中种类为CODEC_TYPE_VIDEO
5.查找对应的解码器:
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:
编解码器的信息。
AVStream
该结构体描述一个媒体流,定义如下:
typedefstructAVStream{
intindex;/**<在AVFormatContext流的索引*/
intid;/**<特定格式的流ID*/
AVCodecContext*codec;/** /** *流的实时帧率基地。 *这是所有时间戳可以最低帧率 *准确代表(它是所有的最小公倍数 *流的帧率)。 请注意,这个值只是一个猜测! *例如,如果时间基数为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<(53<<16) 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<(53<<16) chartitle[512]; charauthor[512]; charcopyright[512]; charcomment[512]; charalbum[512]; intyear;/** inttrack;/** chargenre[32];/** #endif intctx_flags;/**<格式特定的标志,看到AVFMTCTX_xx*/ /*分处理的私人数据(不直接修改)。 */ /**此缓冲区只需要当数据包已经被缓冲,但 不解码,例如,在MPEG编解码器的参数 流。 */ structAVPacketList*packet_buffer; /**解码元件的第一帧的位置,在 AV_TIME_BASE分数秒。 从来没有设置这个值直接: 推导的AVStream值。 */ int64_tstart_time; /**解码流的时间,在AV_TIME_BASE分数 秒。 只设置这个值,如果你知道没有个人流 工期,也不要设置任何他们。 这是从推导 AVStream值如果没有设置。 int64_tduration; /**解码: 总的文件大小,如果未知0*/ int64_tfile_size; /**解码: 在比特/秒的总流率,如果不 可用。 从来没有直接设置它如果得到file_size和 时间是已知的如FFmpeg的自动计算。 */ intbit_rate; /*av_read_frame()支持*/ AVStream*cur_st; #ifLIBAVFORMAT_VERSION_INT<(53<<16) constuint8_t*cur_ptr_deprecated; intcur_len_deprecated; AVPacketcur_pkt_deprecated; #endif /*av_seek_frame()支持*/ int64_tdata_offset;/**第一包抵消*/ intindex_built; intmux_rate; unsignedintpacket_size; intpreload; intmax_delay; #defineAVFMT_NOOUTPUTLOOP-1 #defineAVFMT_INFINITEOUTPUTLOOP0 /**次循环输出的格式支持它的数量*/ intloop_output; intflags; #defineAVFMT_FLAG_GENPTS0x0001///<生成失踪分,即使它需要解析未来框架。 #defineAVFMT_FLAG_IGNIDX0x0002///<忽略指数。 #defineAVFMT_FLAG_NONBLOCK0x0004///<从输入中读取数据包时,不要阻止。 #defineAVFMT_FLAG_IGNDTS0x0008///<忽略帧的DTS包含DTS与PTS #defineAVFMT_FLAG_NOFILLIN0x0010///<不要从任何其他值推断值,只是返回存储在容器中 #defineAVFMT_FLAG_NOPARSE0x0020///<不要使用AVParsers,你还必须设置为FILLIN帧代码的工作,没有解析AVFMT_FLAG_NOFILLIN->无帧。 也在寻求框架不能工作,如果找到帧边界的解析已被禁用 #defineAVFMT_FLAG_RTP_HINT0x0040///<暗示到输出文件添加的RTP intloop_input; /**解码: 对探测数据的大小;编码: 未使用。 */ unsignedintprobesize; /** 在此期间,输入*最大时间(在AV_TIME_BASE单位)应 *进行分析在avformat_find_stream_info()。 */ intmax_analyze_duration; constuint8_t*key; intkeylen; unsignedintnb_programs; AVProgram**programs; /** *强迫影片codec_id。 *Demuxing: 由用户设置。 */ enumCodecIDvideo_codec_id; /** *强迫音频codec_id。 *Demuxing: 由用户设置。 */ enumCodecIDaudio_codec_id; /** *强制的: 字幕codec_id。 *Demuxing: 由用户设置。 */ enumCodecIDsubtitle_codec_id; /** *以字节为单位的最高限额为每个数据流的索引使用的内存。 *如果该指数超过此大小,条目将被丢弃 *需要保持一个较小的规模。 这可能会导致较慢或更少 *准确的寻求(分路器)。 *分路器内存中的一个完整的指数是强制性的将忽略 *此。 *混流: 未使用 *demuxing: 由用户设置*/ unsignedintmax_index_size; /** *以字节为单位的最高限额使用帧缓冲内存 *从实时捕获设备获得。 */ unsignedintmax_picture_buffer; unsignedintnb_chapters; AVChapter**chapters; /** *标志启用调试。 */ intdebug; #defineFF_FDEBUG_TS0x0001 /** *原始数据包从分路器之前,解析和解码。 *此缓冲区用于缓冲数据包,直到编解码器可以 *确定,因为不知道不能做解析 *编解码器。 */ structAVPacketList*raw_packet_buffer; structAVPacketList*raw_packet_buffer_end; structAVPacketList*packet_buffer_end; AVMetadata*metadata; /** *剩余的大小可为raw_packet_buffer,以字节为单位。 *不属于公共API*/ #defineRAW_PACKET_BUFFER_SIZE2500000 intraw_packet_buffer_remaining_size; /** *在现实世界中的时间流的开始时间,以微秒 *自Unix纪元(1970年1月1日起00: 00)。 也就是说,pts=0 在这个现实世界的时间*流被抓获。 *-编码: 由用户设置。 *-解码: 未使用。 */ int64_tstart_time_realtime; }AVFormatContext; 这是FFMpeg中最为基本的一个结构,是其他所有结构的根,是一个多媒体文件或流的根本抽象。 其中: nb_streams和streams所表示的AVStream结构指针数组包含了所有内嵌媒体流的描述; iformat和oformat指向对应的demuxer和muxer指针; pb则指向一个控制底层数据读写的ByteIOContext结构。 start_time和duration是从streams数组的各个AVStream中推断出的多媒体文件的起始时间和长度,以微妙为单位。 通常,这个结构由avformat_open_input在内部创建并以缺省值初始化部分成员。 但是,如果调用者希望自己创建该结构,则需要显式为该结构的一些成员置缺省值——如果没有缺省值的话,会导致之后的动作产生异常。 以下成员需要被关注: probesize mux_rate packet_size flags max_analyze_duration key max_index_size max_picture_buffer max_delay AVPacket AVPacket定义在avcodec.h中,如下: typedefstructAVPacket{ /** AVStream->基time_base单位介绍时间戳的时间 *解压缩包将被提交给用户。 *可AV_NOPTS_VALUE如果没有存储在文件中。 *分必须大于或等于DTS作为演示不能发生之前 *减压,除非要查看十六进制转储。 有些格式滥用 *DTS和PTS/CTS的条款意味着不同的东西。 如时间戳 *必须转换为真正的PTS/DTS之前,他们在AVPacket存储。 */ int64_tpts; /** AVStream->基time_base单位时间的减压时间戳记; *包解压。 *可AV_NOPTS_VALUE如果没有存储在文件中。 */ int64_tdts; uint8_t*data; intsize; intstream_index; intflags; /** *这个包的时间AVStream->基time_base单位,如果未知。 *等于next_pts-在呈现顺序this_pts。 */ intduration; void(*destruct)(structAVPacket*); void*priv; int64_tpos;///<如果未知字节的位置,在流,-1 /** *AVStream->基time_base单位的时差,这点 *包从解码器输出的已融合在哪个点 *独立的前一帧的情况下。 也就是说, *框架几乎是一致的,没有问题,如果解码开始从 *第一帧或从这个关键帧。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 最新版 FFMPEG 解码 流程 欢迎 愿意 分享 资料 下载