最新版FFMPEG解码流程Word下载.docx
《最新版FFMPEG解码流程Word下载.docx》由会员分享,可在线阅读,更多相关《最新版FFMPEG解码流程Word下载.docx(40页珍藏版)》请在冰豆网上搜索。
/**
*一些编解码器需要/可以像使用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;
/*视频*/
*图片宽度/高度。
*请注意:
兼容性,它是可能的,而不是设置此
*coded_width/高解码之前。
intwidth,height;
......
/*仅音频*/
intsample_rate;
///<
每秒采样
intchannels;
音频通道数
*音频采样格式
由用户设置。
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。
inthas_b_frames;
*每包的字节数,如果常量和已知或0
*用于一些WAV的音频编解码器。
intblock_align;
*从分路器位每个样品/像素(huffyuv需要)。
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;
*时基应该是1/framerate的时间戳的增量应为1。
*解码流量的第一帧,在流量时-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。
流的时间基准,是一个实数,该流中媒体数据的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;
chartitle[512];
charauthor[512];
charcopyright[512];
charcomment[512];
charalbum[512];
intyear;
ID3year,0ifnone*/
inttrack;
tracknumber,0ifnone*/
chargenre[32];
ID3genre*/
intctx_flags;
格式特定的标志,看到AVFMTCTX_xx*/
/*分处理的私人数据(不直接修改)。
/**此缓冲区只需要当数据包已经被缓冲,但
不解码,例如,在MPEG编解码器的参数
流。
structAVPacketList*packet_buffer;
/**解码元件的第一帧的位置,在
AV_TIME_BASE分数秒。
从来没有设置这个值直接:
推导的AVStream值。
/**解码流的时间,在AV_TIME_BASE分数
秒。
只设置这个值,如果你知道没有个人流
工期,也不要设置任何他们。
这是从推导
AVStream值如果没有设置。
/**解码:
总的文件大小,如果未知0*/
int64_tfile_size;
在比特/秒的总流率,如果不
可用。
从来没有直接设置它如果得到file_size和
时间是已知的如FFmpeg的自动计算。
intbit_rate;
AVStream*cur_st;
constuint8_t*cur_ptr_deprecated;
intcur_len_deprecated;
AVPacketcur_pkt_deprecated;
/*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。
enumCodecIDaudio_codec_id;
*强制的:
字幕codec_id。
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;
基time_base单位时间的减压时间戳记;
*包解压。
int64_tdts;
uint8_t*data;
intsize;
intstream_index;
*这个包的时间AVStream->
基time_base单位,如果未知。
*等于next_pts-在呈现顺序this_pts。
intduration;
void(*destruct)(structAVPacket*);
void*priv;
int64_tpos;
如果未知字节的位置,在流,-1
*AVStream->
基time_base单位的时差,这点
*包从解码器输出的已融合在哪个点
*独立的前一帧的情况下。
也就是说,
*框架几乎是一致的,没有问题,如果解码开始从
*第一帧或从这个关键帧。
*AV_NOPTS_VALUE如果不明