ffmpeg常用结构体
概括
FFMpeg中主要数据结构存在包含关系,AVFormatContext ->AVStream-> AVCodecContext -> AVCodec, 其中后者是前者的数据成员。
AVFormatContext 是一个贯穿始终的数据结构, 很多函数都用到它作为参数, 是输入输出相关信息的一个容器。
主要成员如下:
-
AVInputFormat 和 AVOutputFormat,
同一时间只能存在一个。 当播放视频时 AVInputFormat生效, 录制视频时则 AVOutputFormat 生效。 -
AVStream
AVStream是继 AVFormatContext 之后第二个贯穿始终的数据结构, 它保存于数据流相关的编解码器、 数据段等信息, 还包含“流” 这个概念中的一些信息。
AVCodecContext 保存 AVCodec 指针和与 codec 相关的数据。 -
AVCodecContext
在 AVStream 初始化后, AVCodecContext 的初始化是 Codec 使用中最重要的一环。
AVCodecContext 中的 codec_type, codec_id 二个变量对于 encoder/decoder 的匹配来说,最为重要。
AVCodecContext 中有两个成员: AVCodec, AVFrame。 -
AVCodec
AVCodec 记录了所要使用的 Codec 的信息并有 5 个函数: init,encoder,close,decode,flush来完成编解码工作。 -
AVFrame
AVFrame 中主要包含了编码后的帧信息。
分类
ffmpeg中的结构体可以分为这几类:解协议、解封装、解码、存数据。
解协议相关 (http,rtsp,rtmp, mms)
AVIOContext,URLProtocol,URLContext主要存储视音频使用的协议的类型以及状态。
URLProtocol存储输入视音频使用的封装格式。每种协议都对应一个URLProtocol结构。
(注意:FFMPEG中文件也被当做一种协议“file”)
解封装相关(flv,avi,rmvb,mp4)
AVFormatContext主要存储视音频封装格式中包含的信息,位于avformat.h中;
AVInputFormat存储输入视音频使用的封装格式。每种视音频封装格式都对应一个AVInputFormat 结构。
AVFormatContext
常见成员
dutation //视频时长,duration是以AV_TIME_BASE为单位的,AV_TIME_BASE意思是把
1秒钟分为了AV_TIME_BASE份。计算视频有多少秒:duration / (AV_TIME_BASE);
计算视频有多少毫秒:duration / (AV_TIME_BASE / 1000)
解码相关(h264,mpeg2,aac,mp3)
每个AVStream存储一个视频/音频流的相关数据;
每个AVStream对应一个AVCodecContext,存储该视频/音频流使用解码方式的相关数据;
每个AVCodecContext中对应一个AVCodec,包含该视频/音频对应的解码器。每种解码器都对应一个AVCodec结构。
AVCodec可根据不同的编码器类型生成,如下
AVCodecContext根据AVCodec生成,如下:
#### AVStream
常见成员:
nt index:标识该视频/音频流AVCodecContext *codec:指向该视频/音频流的AVCodecContext(它们是一一对应的关系)
AVRational time_base:时基。里面存的是分子、分母。通过该值可以把PTS,DTS转化为真正的时间。
FFMPEG其他结构体中也有这个字段,但是根据我的经验,只有AVStream中的
time_base是可用的。PTS*time_base=真正的时间。
duration的1对应多少分之一的秒。比如duration为1,time_base=1/1000,那么
duration的实际时长为1*1/1000秒,即一毫秒。
int64_t duration:该视频/音频流长度。
将duration转化为秒:duration*((double)time_base.num/(double)time_base.den)
AVDictionary *metadata:元数据信息
AVRational avg_frame_rate:帧率
AVPacket attached_pic:附带的图片。比如说一些MP3,AAC音频文件附带的专辑封面。
AVCodecParameters *codecpar 编码器参数
存数据相关
视频的话,每个结构一般是存一帧;音频可能有好几帧
解码前数据:AVPacket,经过编码的数据,如经过264编码的数据
解码后数据:AVFrame, 即视频的原始数据,YUV等
AVPacket
常见成员
AVBufferRef *buf : 引用计数,当引用计数为0,AVPacket空间将被清除
uint8_t *data:压缩编码的数据。 例如对于H.264来说。1个AVPacket的data通常对应一个NAL。
注意:在这里只是对应,而不是一模一样。他们之间有微小的差别:使用FFMPEG类库分离出
多媒体文件中的H.264码流。因此在使用FFMPEG进行视音频处理的时候,常常可以将
得到的AVPacket的data数据直接写成文件,从而得到视音频的码流文件。
int size:data的大小
int64_t pts:显示时间戳,ffmpeg会按照pts来显示
int64_t dts:解码时间戳,ffmpeg会按照dts来解码,
int stream_index:标识该AVPacket所属的视频/音频流
注:我们一般说AVPacket有两块内存,一块是它本身的;另一块是它里面数据的,也就是data指向的内存。
释放时需要分别释放,AVPacket本身的内存调用av_packet_free()来释放,而内部的data通过引用计数来
释放,当引用计算减到0的时候,其内存就释放了。
常用函数
AVPacket *av_packet_alloc(void) 创建并初始化
AVPacket *av_packet_clone(const AVPacket *src);创建并增加引用计数
int av_packet_ref(AVPacket *dst, const AVPacket *src); 增加引用
av_packet_unref(AVPacket *pkt);减少引用
void av_packet_free(AVPacket **pkt); 清空对象并减引用计数
这些函数中通过ffmpeg进行空间管理的,也有自己进行空间管理的。看情况使用。
AVPacket,初始化相关函数:
https://blog.csdn.net/u010380485/article/details/54668696?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2defaultCTRLISTRate-1.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2defaultCTRLISTRate-1.pc_relevant_default&utm_relevant_index=1
AVPacket讲解参考:https://blog.csdn.net/leixiaohua1020/article/details/14215755
AVFrame
该结构体位于avcodec.h中。
AVFrame结构体一般用于存储原始数据(即非压缩数据,例如对视频来说是YUV,RGB,对音频来
说是PCM),此外还包含了一些相关的信息。比如说,解码的时候存储了宏块类型表,QP表,运动
矢量表等数据。编码的时候也存储了相关的数据。因此在使用FFMPEG进行码流分析的时候,AVFrame
是一个很重要的结构体。
常用成员
uint8_t *data[AV_NUM_DATA_POINTERS]:解码后原始数据(对视频来说是YUV,RGB,对音频来说是PCM)int linesize[AV_NUM_DATA_POINTERS]:data中“一行”数据的大小。注意:未必等于图像的宽,一般大于图像的宽。
int width, height:视频帧宽和高(1920x1080,1280x720...)
int nb_samples:音频的一个AVFrame中可能包含多个音频帧,在此标记包含了几个
int format:解码后原始数据类型(YUV420,YUV422,RGB24...)
int key_frame:是否是关键帧
enum AVPictureType pict_type:帧类型(I,B,P...)
AVRational sample_aspect_ratio:宽高比(16:9,4:3...)
int64_t pts:显示时间戳
int coded_picture_number:编码帧序号
int display_picture_number:显示帧序号
int8_t *qscale_table:QP表
uint8_t *mbskip_table:跳过宏块表
int16_t (*motion_val[2])[2]:运动矢量表
uint32_t *mb_type:宏块类型表
short *dct_coeff:DCT系数,这个没有提取过
int8_t *ref_index[2]:运动估计参考帧列表(貌似H.264这种比较新的标准才会涉及到多参考帧)
int interlaced_frame:是否是隔行扫描
uint8_t motion_subsample_log2:一个宏块中的运动矢量采样个数,取log的
常用API
文章内容从网上搜集、整理而来,如有侵权请联系作者删除。