ffmpeg源码简析(十二)FFMPEG中的主要结构体总结
FFMPEG中结构体很多。最关键的结构体可以分成以下几类:
a) 解协议(http,rtsp,rtmp,mms)
AVIOContext,URLProtocol,URLContext主要存储视音频使用的协议的类型以及状态。URLProtocol存储输入视音频使用的封装格式。每种协议都对应一个URLProtocol结构。(注意:FFMPEG中文件也被当做一种协议“file”)
b) 解封装(flv,avi,rmvb,mp4)
AVFormatContext主要存储视音频封装格式中包含的信息;AVInputFormat存储输入视音频使用的封装格式。每种视音频封装格式都对应一个AVInputFormat 结构。
c) 解码(h264,mpeg2,aac,mp3)
每个AVStream存储一个视频/音频流的相关数据;每个AVStream对应一个AVCodecContext,存储该视频/音频流使用解码方式的相关数据;每个AVCodecContext中对应一个AVCodec,包含该视频/音频对应的解码器。每种解码器都对应一个AVCodec结构。
d) 存数据
视频的话,每个结构一般是存一帧;音频可能有好几帧
解码前数据:AVPacket
解码后数据:AVFrame
AVIOContext(avio.h)
AVIOContext是FFMPEG管理输入输出数据的结构体
AVIOContext中有以下几个变量比较重要:
unsigned char *buffer:缓存开始位置int buffer_size:缓存大小(默认32768)unsigned char *buf_ptr:当前指针读取到的位置unsigned char *buf_end:缓存结束的位置void *opaque:URLContext结构体
在解码的情况下,buffer用于存储ffmpeg读入的数据。例如打开一个视频文件的时候,先把数据从硬盘读入buffer,然后在送给解码器用于解码。
AVFormatContext(avformat.h)
在使用FFMPEG进行开发的时候,AVFormatContext是一个贯穿始终的数据结构,很多函数都要用到它作为参数。它是FFMPEG解封装(flv,mp4,rmvb,avi)功能的结构体。下面看几个主要变量的作用(在这里考虑解码的情况):
AVIOContext *pb:输入数据的缓存unsigned int nb_streams:视音频流的个数AVStream **streams:视音频流char filename[1024]:文件名int64_t duration:时长(单位:微秒us,转换为秒需要除以1000000)int bit_rate:比特率(单位bps,转换为kbps需要除以1000)AVDictionary *metadata:元数据
视频的时长可以转换成HH:MM:SS的形式,示例代码如下:
AVFormatContext *pFormatCtx;
CString timelong;
...
//duration是以微秒为单位
//转换成hh:mm:ss形式
int tns, thh, tmm, tss;
tns = (pFormatCtx->duration)/1000000;
thh = tns / 3600;
tmm = (tns % 3600) / 60;
tss = (tns % 60);
timelong.Format("%02d:%02d:%02d",thh,tmm,tss);
AVStream(avformat.h)
AVStream是存储每一个视频/音频流信息的结构体
AVStream重要的变量如下所示:
int index:标识该视频/音频流AVCodecContext *codec:指向该视频/音频流的AVCodecContext(它们是一一对应的关系)AVRational time_base:时基。通过该值可以把PTS,DTS转化为真正的时间。FFMPEG其他结构体中也有这个字段,但是根据我的经验,只有AVStream中的time_base是可用的。PTS*time_base=真正的时间int64_t duration:该视频/音频流长度AVDictionary *metadata:元数据信息AVRational avg_frame_rate:帧率(注:对视频来说,这个挺重要的)AVPacket attached_pic:附带的图片。比如说一些MP3,AAC音频文件附带的专辑封面。
AVCodecContext(avcodec.h)
每个AVStream对应一个AVCodecContext,存储该视频/音频流使用解码方式的相关数据;每个AVCodecContext中对应一个AVCodec,包含该视频/音频对应的解码器。每种解码器都对应一个AVCodec结构。
AVCodecContext中很多的参数是编码的时候使用的,而不是解码的时候使用的。
下面挑一些关键的变量来看看(这里只考虑解码)。
enum AVMediaType codec_type:编解码器的类型(视频,音频...)struct AVCodec *codec:采用的解码器AVCodec(H.264,MPEG2...)int bit_rate:平均比特率uint8_t *extradata; int extradata_size:针对特定编码器包含的附加信息(例如对于H.264解码器来说,存储SPS,PPS等)AVRational time_base:根据该参数,可以把PTS转化为实际的时间(单位为秒s)int width, height:如果是视频的话,代表宽和高int refs:运动估计参考帧的个数(H.264的话会有多帧,MPEG2这类的一般就没有了)int sample_rate:采样率(音频)int channels:声道数(音频)enum AVSampleFormat sample_fmt:采样格式int profile:型(H.264里面就有,其他编码标准应该也有)int level:级(和profile差不太多)
AVCodec(avcodec.h)
AVCodec是存储编解码器信息的结构体
下面说一下最主要的几个变量:
const char *name:编解码器的名字,比较短const char *long_name:编解码器的名字,全称,比较长enum AVMediaType type:指明了类型,是视频,音频,还是字幕enum AVCodecID id:ID,不重复const AVRational *supported_framerates:支持的帧率(仅视频)const enum AVPixelFormat *pix_fmts:支持的像素格式(仅视频)const int *supported_samplerates:支持的采样率(仅音频)const enum AVSampleFormat *sample_fmts:支持的采样格式(仅音频)const uint64_t *channel_layouts:支持的声道数(仅音频)int priv_data_size:私有数据的大小
1.注册所有编解码器:av_register_all();
2.声明一个AVCodec类型的指针,比如说AVCodec* first_c;
3.调用av_codec_next()函数,即可获得指向链表下一个解码器的指针,循环往复可以获得所有解码器的信息。注意,如果想要获得指向第一个解码器的指针,则需要将该函数的参数设置为NULL。
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的
data[]
对于packed格式的数据(例如RGB24),会存到data[0]里面。
对于planar格式的数据(例如YUV420P),则会分开成data[0],data[1],data[2]…(YUV420P中data[0]存Y,data[1]存U,data[2]存V)
AVPacket(avcodec.h)
AVPacket是存储压缩编码数据相关信息的结构体
在AVPacket结构体中,重要的变量有以下几个:
uint8_t *data:压缩编码的数据。例如对于H.264来说。1个AVPacket的data通常对应一个NAL。注意:在这里只是对应,而不是一模一样。他们之间有微小的差别:使用FFMPEG类库分离出多媒体文件中的H.264码流因此在使用FFMPEG进行视音频处理的时候,常常可以将得到的AVPacket的data数据直接写成文件,从而得到视音频的码流文件。int size:data的大小int64_t pts:显示时间戳int64_t dts:解码时间戳int stream_index:标识该AVPacket所属的视频/音频流。
这个结构体虽然比较简单,但是非常的常用。
ffmpeg源码简析(十二)FFMPEG中的主要结构体总结相关推荐
- ffmpeg源码简析(十)libswscale中的SwsContext,sws_scale()
libswscale是一个主要用于处理图片像素数据的类库.可以完成图片像素格式的转换,图片的拉伸等工作. libswscale常用的函数数量很少,一般情况下就3个: sws_getContext() ...
- ffmpeg源码简析(九)av_log(),AVClass,AVOption
1.av_log() av_log()是FFmpeg中输出日志的函数.随便打开一个FFmpeg的源代码文件,就会发现其中遍布着av_log()函数.一般情况下FFmpeg类库的源代码中是不允许使用pr ...
- ffmpeg源码简析(六)编码-av_write_frame(),av_write_trailer()
1.av_write_frame() av_write_frame()用于输出一帧视音频数据,它的声明位于libavformat\avformat.h,如下所示. int av_write_frame ...
- (Ajax)axios源码简析(三)——请求与取消请求
传送门: axios源码简析(一)--axios入口文件 axios源码简析(二)--Axios类与拦截器 axios源码简析(三)--请求与取消请求 请求过程 在Axios.prototype.re ...
- ffmpeg实战教程(十三)iJKPlayer源码简析
要使用封装优化ijk就必须先了解ffmpeg,然后看ijk对ffmpeg的C层封装! 这是我看ijk源码时候的笔记,比较散乱.不喜勿喷~ ijk源码简析: 1.ijkplayer_jni.c 封装的播 ...
- 【Golang源码分析】Go Web常用程序包gorilla/mux的使用与源码简析
目录[阅读时间:约10分钟] 一.概述 二.对比: gorilla/mux与net/http DefaultServeMux 三.简单使用 四.源码简析 1.NewRouter函数 2.HandleF ...
- java ArrayList 概述 与源码简析
ArrayList 概述 与源码简析 1 ArrayList 创建 ArrayList<String> list = new ArrayList<>(); //构造一个初始容量 ...
- Alamofire源码解读系列(十二)之请求(Request)
本篇是Alamofire中的请求抽象层的讲解 前言 在Alamofire中,围绕着Request,设计了很多额外的特性,这也恰恰表明,Request是所有请求的基础部分和发起点.这无疑给我们一个Req ...
- django源码简析——后台程序入口
django源码简析--后台程序入口 这一年一直在用云笔记,平时记录一些tips或者问题很方便,所以也就不再用博客进行记录,还是想把最近学习到的一些东西和大家作以分享,也能够对自己做一个总结.工作中主 ...
最新文章
- 机器人动力学简化模型(Euler-Lagrange equation)
- MySQL的内置函数
- Js中RegExp对象
- 多语言ASR?没有什么听不懂,15种语言我全都要
- 浅谈Python-IO多路复用(select、poll、epoll模式)
- db2 随机数函数_sql中的随机函数怎么用?
- loadrunner下载地址
- 计算机里的及格率和有优秀率怎么算,Excel中怎么用函数计算成绩的及格率和优秀率?_excle优秀率及格率...
- 再谈:数据治理的长效运营机制!
- 破解苹果电脑开机密码
- oracle ora 604,ORA-01092:ORACLE实例终止,强制断开连接 ORA 00704 00604 00942
- 中兴ZXQ10排队机出现问题了...
- Python框架Flask系列教程(1)——基础-黄勇-专题视频课程
- 贝叶斯公式的理解及简单推导
- 详谈气象站的功能区别
- HTML常用标签(a标签/img标签/table标签)
- 2020年中国地理信息产业产值或达万亿元
- 电子设计竞赛前的点点滴滴
- 矩阵乘法精解!(一图胜千言)
- 欧美市场独立站选品技巧