FFMPEG中的结构体的重要属性

[本文不是自己阅读源码, 摘自雷神的博客]

关键结构体

  • AVFormatContext
  • AVOutputFormat
  • AVInputFormat
  • AVCodecContext
  • AVCodec
  • AVFrame
  • AVPacket
  • AVPicture
  • AVStream

关键函数

  1. 初始化函数:

    • av_register_all()
    • avcodec_open()
    • avcodec_close()
    • av_open_input_file()
    • av_find_input_format()
    • av_find_stream_info()
    • av_close_input_file()
  2. 音视频编解码函数:

    • avcodec_find_decoder()
    • avcodec_alloc_frame()
    • avpicture_get_size()
    • avpicture_fill()
    • img_convert()
    • avcodec_alloc_context()
    • avcodec_decode_video()
    • av_free_packet()
    • av_free()
  3. 文件操作:

    • avnew_steam()
    • av_read_frame()
    • av_write_frame()
    • dump_format()
  4. 其他函数:

    • avpicture_deinterlace()
    • ImgReSampleContext()

分集介绍

AVFormatContext

是一个贯穿始终的数据结构,很多函数都要用到它 作为参数;这个结构体包含了一个视频流的格式内容, 包括 AVInputFormat, AVStream, AVPacket等;

  1. AVInputFormat *iformat 输入数据的封装格式 执行 avformat_open_input()后, iformat 会被赋值
  2. AVIOContext *pb 输入数据的缓存
  3. AVStream **streams 所有流的数组
  4. unsigned int nb_streams 流的个数(音频流 1 个, 视频流 1 个等其他流)
  5. char filename[1024] 文件名
  6. int64_t duration 文件的时长(单位:微秒us,转换为秒需要除以1000000)
  7. int bit_rate 比特率(单位bps,转换为kbps需要除以1000)
  8. AVDictionary *metadata 元数据

AVInputFormat

视频的封装格式的一些数据

  1. const char *name 封装格式名称
  2. const char *long_name 封装格式的长名称
  3. const char *extensions 封装格式的扩展名

AVIOContext

输入输出对应的结构体,用于输入输出(读写文件,RTMP协议等)

  1. unsigned char *buffer 缓存开始位置(buffer用于存储ffmpeg读入的数据。例如打开一个视频文件的时候,先把数据从硬盘读入buffer,然后在送给解码器用于解码。)
  2. int buffer_size 缓存大小(默认32768)
  3. unsigned char *buf_ptr 当前指针读取到的位置
  4. unsigned char *buf_end 缓存结束的位置
  5. void *opaque URLContext结构体

AVStream

视音频流对应的结构体,用于视音频编解码

  1. int index 标识该视频/音频流
  2. AVCodecContext *codec 指向该视频/音频流的AVCodecContext(它们是一一对应的关系)
  3. AVRational time_base 时基。通过该值可以把PTS,DTS转化为真正的时间。FFMPEG其他结构体中也有这个字段,但是根据我的经验,只有AVStream中的time_base是可用的。PTS*time_base=真正的时间
  4. int64_t duration 该视频/音频流时长
  5. AVDictionary *metadata 元数据信息
  6. AVRational avg_frame_rate 帧率(注:对视频来说,这个挺重要的)
  7. AVPacket attached_pic 附带的图片。比如说一些MP3,AAC音频文件附带的专辑封面。

AVCodecContext

存储压缩数据(视频对应H.264等码流数据,音频对应AAC/MP3等码流数据)

  1. num AVMediaType codec_type 编解码器的类型(视频,音频…)
  2. struct AVCodec *codec 采用的解码器AVCodec(H.264,MPEG2…)
  3. int bit_rate 平均比特率
  4. uint8_t *extradata; int extradata_size 针对特定编码器包含的附加信息(例如对于H.264解码器来说,存储SPS,PPS等)
  5. AVRational time_base 根据该参数,可以把PTS转化为实际的时间(单位为秒s)
  6. int width, height 如果是视频的话,代表宽和高
  7. int refs 运动估计参考帧的个数(H.264的话会有多帧,MPEG2这类的一般就没有了)
  8. int sample_rate 采样率(音频)
  9. int channels 声道数(音频)
  10. enum AVSampleFormat sample_fmt 采样格式
  11. int profile 型(H.264里面就有,其他编码标准应该也有)
  12. int level 级(和profile差不太多)

AVCodec

编解码器信息的结构体

  1. const char *name 编解码器的名字,比较短
  2. const char *long_name 编解码器的名字,全称,比较长
  3. enum AVMediaType type 指明了类型,是视频,音频,还是字幕
  4. enum AVCodecID id ID,不重复
  5. const AVRational *supported_framerates 支持的帧率(仅视频)
  6. const enum AVPixelFormat *pix_fmts 支持的像素格式(仅视频)
  7. const int *supported_samplerates 支持的采样率(仅音频)
  8. const enum AVSampleFormat *sample_fmts 支持的采样格式(仅音频)
  9. const uint64_t *channel_layouts 支持的声道数(仅音频)
  10. int priv_data_size 私有数据的大小

AVPacket

存储压缩编码数据相关信息的结构体

  1. uint8_t *data:压缩编码的数据, 对于H.264来说。1个AVPacket的data通常对应一个NAL。(在这里只是对应,而不是一模一样。他们之间有微小的差别. 因此在使用FFMPEG进行视音频处理的时候,常常可以将得到的AVPacket的data数据直接写成文件,从而得到视音频的码流文件)
  2. int size:data的大小
  3. int64_t pts:显示时间戳
  4. int64_t dts:解码时间戳
  5. int stream_index:标识该AVPacket所属的视频/音频流。

AVFrame

存储每一个视频/音频流信息的结构体(视频对应RGB/YUV像素数据,音频对应PCM采样数据)

  1. uint8_t *data[AV_NUM_DATA_POINTERS] 解码后原始数据(对视频来说是YUV,RGB,对音频来说是PCM)对于packet格式,一幅YUV图像的Y、U、V交织存储在一个plane中,形如YUVYUV…,data[0]指向这个plane;
    一个双声道的音频帧其左声道L、右声道R交织存储在一个plane中,形如LRLRLR…,data[0]指向这个plane。
    对于planar格式,一幅YUV图像有Y、U、V三个plane,data[0]指向Y plane,data[1]指向U plane,data[2]指向V plane;
    一个双声道的音频帧有左声道L和右声道R两个plane,data[0]指向L plane,data[1]指向R plane。
  2. int linesize[AV_NUM_DATA_POINTERS] data中“一行”数据的大小。注意:未必等于图像的宽,一般大于图像的宽。
  3. int width, height 视频帧宽和高(1920x1080,1280x720…)
  4. int nb_samples 音频的一个AVFrame中可能包含多个音频帧,在此标记包含了几个
  5. int format 解码后原始数据类型(YUV420,YUV422,RGB24…)
  6. int key_frame 是否是关键帧
  7. enum AVPictureType pict_type 帧类型(I,B,P…)
  8. AVRational sample_aspect_ratio 宽高比(16:9,4:3…)
  9. int64_t pts 显示时间戳
  10. int coded_picture_number 编码帧序号
  11. int display_picture_number 显示帧序号
  12. int8_t *qscale_table QP表
  13. uint8_t *mbskip_table 跳过宏块表
  14. int16_t (*motion_val[2])[2] 运动矢量表
  15. uint32_t *mb_type 宏块类型表
  16. short *dct_coeff DCT系数,这个没有提取过
  17. int8_t *ref_index[2] 运动估计参考帧列表(貌似H.264这种比较新的标准才会涉及到多参考帧)
  18. int interlaced_frame 是否是隔行扫描
  19. uint8_t motion_subsample_log2 一个宏块中的运动矢量采样个数,取log的

函数

av_register_all()

注册所有的组件, 该函数在所有基于ffmpeg的应用程序中几乎都是第一个被调用的。只有调用了该函数,才能使用复用器,编码器等。

avformat_alloc_context(), avio_alloc_context(), avformat_new_stream(), avcodec_alloc_context3(), av_frame_alloc(), av_init_packet();

结构体的初始化

avcodec_find_decoder(), av_find_encoder()

寻找解码编码器

avcodec_open2()

最关键的一步就是调用AVCodec的init()方法初始化具体的编码器

avformat_open_input()

打开输入文件

avformat_find_stream_info()

从文件中提取流信息

av_find_best_stream()

查找传入的流对应的stream_index 就是 传入的流在streams中对应的索引.

av_read_frame()

解码数据

avcodec_decode_video2

读取码流中的音频若干帧或者视频一帧

avcodec_send_packet()

进行解码

avcodec_receive_frame()

获取解码后的数据

avformat_close_input()

关闭一个AVFormatContext,一般情况下是和avformat_open_input()成对使用的。

av_dump_format()

打印流的多媒体信息

编码结构图
解码结构图
结构体之间的关系

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值