原文地址:http://my.oschina.net/u/555701/blog/56748
先上一个图:
![ffmpeg常用数据结构_第1张图片](http://img.e-com-net.com/image/info5/34d191dc2f5e440d816993aee2b4fb96.png)
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
该结构体描述一个媒体流,定义如下:
- typedef struct AVStream {
- int index;
- int id;
- AVCodecContext *codec;
-
-
-
-
-
-
-
-
- AVRational r_frame_rate;
-
- ......
-
-
-
-
-
-
- AVRational time_base;
-
- ......
-
-
-
-
-
-
-
-
-
- int64_t start_time;
-
-
-
-
-
- int64_t duration;
-
- #if LIBAVFORMAT_VERSION_INT < (53<<16)
- char language[4];
- #endif
-
-
- enum AVStreamParseType need_parsing;
- struct AVCodecParserContext *parser;
-
- ......
-
-
- AVIndexEntry *index_entries;
-
- int nb_index_entries;
- unsigned int index_entries_allocated_size;
-
- int64_t nb_frames;
-
- ......
-
-
-
-
- AVRational avg_frame_rate;
- ......
- } AVStream;
主要域的释义如下,其中大部分域的值可以由avformat_open_input根据文件头的信息确定,缺少的信息需要通过调用avformat_find_stream_info读帧及软解码进一步获取:
1、index/id:index对应流的索引,这个数字是自动生成的,根据index可以从AVFormatContext::streams表中索引到该流;而id则是流的标识,依赖于具体的容器格式。比如对于MPEG TS格式,id就是pid。
2、time_base:流的时间基准,是一个实数,该流中媒体数据的pts和dts都将以这个时间基准为粒度。通常,使用av_rescale/av_rescale_q可以实现不同时间基准的转换。
3、start_time:流的起始时间,以流的时间基准为单位,通常是该流中第一个帧的pts。
4、duration:流的总时间,以流的时间基准为单位。
5、need_parsing:对该流parsing过程的控制域。
6、nb_frames:流内的帧数目。
7、r_frame_rate/framerate/avg_frame_rate:帧率相关。
8、codec:指向该流对应的AVCodecContext结构,调用avformat_open_input时生成。
9、parser:指向该流对应的AVCodecParserContext结构,调用avformat_find_stream_info时生成。
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中,如下:
- typedef struct AVPacket {
-
-
-
-
-
-
-
-
-
- int64_t pts;
-
-
-
-
-
- int64_t dts;
- uint8_t *data;
- int size;
- int stream_index;
- int flags;
-
-
-
-
- int duration;
- void (*destruct)(struct AVPacket *);
- void *priv;
- int64_t pos;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- int64_t convergence_duration;
- } AVPacket;
FFMPEG使用AVPacket来暂存解复用之后、解码之前的媒体数据(一个音/视频帧、一个字幕包等)及附加信息(解码时间戳、显示时间戳、时长等)。其中:
-
dts表示解码时间戳,pts表示显示时间戳,它们的单位是所属媒体流的时间基准。
-
stream_index给出所属媒体流的索引;
-
data为数据缓冲区指针,size为长度;
-
duration为数据的时长,也是以所属媒体流的时间基准为单位;
-
pos表示该数据在媒体流中的字节偏移量;
-
destruct为用于释放数据缓冲区的函数指针;
-
flags为标志域,其中,最低为置1表示该数据是一个关键帧。
AVPacket结构本身只是个容器,它使用data成员引用实际的数据缓冲区。这个缓冲区通常是由av_new_packet创建的,但也可能由 FFMPEG的API创建(如av_read_frame)。当某个AVPacket结构的数据缓冲区不再被使用时,要需要通过调用 av_free_packet释放。av_free_packet调用的是结构体本身的destruct函数,它的值有两种情 况:1)av_destruct_packet_nofree或0;2)av_destruct_packet,其中,情况1)仅仅是将data和 size的值清0而已,情况2)才会真正地释放缓冲区。
FFMPEG内部使用AVPacket结构建立缓冲区装载数据,同时提供destruct函数,如果FFMPEG打算自己维护缓冲区,则将 destruct设为av_destruct_packet_nofree,用户调用av_free_packet清理缓冲区时并不能够将其释放;如果 FFMPEG打算将该缓冲区彻底交给调用者,则将destruct设为av_destruct_packet,表示它能够被释放。安全起见,如果用户希望 自由地使用一个FFMPEG内部创建的AVPacket结构,最好调用av_dup_packet进行缓冲区的克隆,将其转化为缓冲区能够被释放的 AVPacket,以免对缓冲区的不当占用造成异常错误。av_dup_packet会为destruct指针为 av_destruct_packet_nofree的AVPacket新建一个缓冲区,然后将原缓冲区的数据拷贝至新缓冲区,置data的值为新缓冲区 的地址,同时设destruct指针为av_destruct_packet。
from:http://blog.csdn.net/zhenhuibox/article/details/7716128