FFmpeg源码解析系列(三)结构体之AVFormatContext

首先从ffmpeg最顶端的一个结构体说起
AVFormatContext
AVFormatContext是API中直接接触到的结构体,位于avformat.h中,结构体描述了一个多媒体文件或流的构成和基本信息。,是FFmpeg中最为基本的一个结构体。贯穿了ffmpeg使用的整个流程。

头文件

https://github.com/FFmpeg/FFmpeg/blob/release/6.1/libavformat/avformat.h

关键字段

  1. iformat:输入封装格式。仅用于demu,由avformat_open_input()

  2. oformat:输出封装格式。仅用于复用,必须在avformat_write_header()由调用者设置

  3. priv_data:格式私有数据。这是一个启用了AV选项的结构。仅当iformat/oformat.priv_class不为NULL时设置。

  • 复用:由avformat_write_header()设置
  • 解复用:由avformat_open_input()设置
  1. AVIOContext:I/O上下文。后续会详细讲解这个结构
  • 解复用:可以由用户在avformat_open_input()之前设置(然后
    用户必须手动关闭它),或者由avformat_open_input()设置。
  • 复用:在avformat_write_header()之前由用户设置。调用者必须
    负责关闭/释放I/O上下文。
    如果iformat/oformat.flags中设置了AVFMT_NOFILE标志,则不要设置这个字段。在这种情况下,(解)复用器将以其他方式处理(libdevice中的muxers和demuxers都是AVFMT_NOFILE类型的,因为他的输入和输出一般都是特定的设备确定的,所以在这种情况下,请将该字段置为空)
  1. ctx_flags:标志,表示流属性。AVFMTCTX_*的组合。一般在read_header中设置

    • AVFMTCTX_NOHEADER 表示不存在header(流是动态添加的)

    • AVFMTCTX_UNSEEKABLE 表示流绝对不可定位,尝试调用seek函数将失败。

  2. nb_streams:流数量。AVFormatContext.streams中元素的数量,由avformat_new_stream()设置

  3. streams:文件中所有流的列表。新流通过avformat_new_stream()创建,如果是复用,则复用,则流在avformat_write_header()之前由用户创建。

  4. url:输入或输出URL。与旧的filename字段不同,该字段没有长度限制

    • 解复用:由avformat_open_input()设置,如果avformat_open_input()的url参数为NULL,则初始化为一个空字符串。

    • 复用:可以在调用avformat_write_header()之前由调用者设置为可由av_free()释放的字符串。如果在avformat_init_output()中首先调用它,则设置为空字符串。

  5. start_timedurationbit_rate,流相关信息,以AV_TIME_BASE分数秒为单位。不要直接设置这个值,它是从AVStream的值中推导出来的。

  6. flag,修改(解)复用器行为的标志。AVFMT_FLAG_*的组合。在avformat_open_input()/avformat_write_header()之前由用户设置。
    下面列举一些常用的flag

#define AVFMT_FLAG_GENPTS       0x0001 ///< 生成丢失的pts,即使需要解析未来的帧。
#define AVFMT_FLAG_NOBUFFER     0x0040 ///< 在可能的情况下不缓冲帧,可以减少延迟

#define AVFMT_FLAG_DISCARD_CORRUPT  0x0100 ///< 丢弃标记为损坏的帧
#define AVFMT_FLAG_FLUSH_PACKETS    0x0200 ///< 每个包后刷新

#define AVFMT_FLAG_FAST_SEEK   0x80000 ///< 启用快速但不准确的寻址
#define AVFMT_FLAG_SHORTEST   0x100000 ///< 当最短流停止时停止复用。
#define AVFMT_FLAG_AUTO_BSF   0x200000 ///< 根据复用器请求添加比特流过滤器
  1. probesize,用于探测码流时数据读取的最大大小限制。仅用于解复用,由用户在avformat_open_input()之前设置。合理的设置可以降低出流时间。

  2. max_analyze_duration,在avformat_find_stream_info()中,从输入中读取的数据的最大持续时间,以AV_TIME_BASE为单位。仅用于解复用,由用户在avformat_find_stream_info()之前设置。可以设置为0以使用启发式算法。合理的设置可以降低查找流信息所花费的时间。

  3. video_codec_id audio_codec_id subtitle_codec_iddata_codec_id音频、视频、字幕、数据解码器的强制配置

  4. video_codec audio_codec subtitle_codecdata_codec音频、视频、字幕、数据解码器的强制配置,假设一个codec_id 对应多个codec,也使用这里指定的codec

  5. max_index_size:用于每个流索引的最大内存量,以字节为单位。如果索引超过这个大小,根据需要丢弃条目以保持较小的大小。这可能导致较慢或不太准确的寻址(取决于解复用器)。

  6. max_picture_buffer :用于缓冲从实时捕获设备获取的帧的最大内存量,以字节为单位。

  • 请注意,并非所有格式都支持此选项,如果不支持,使用它可能会导致不可预测的结果。
  1. nb_chapterschapters :AVChapter数量以及AVChapter数组。当复用时,AVChapter通常写入文件头,因此nb_chapters通常在调用write_header时初始化。某些复用器(例如mov和mkv)也可以在尾部写入章节。要在尾部写入章节,必须在调用write_header时将nb_chapters设置为零,并在write_trailer时设置为非零。

  2. metadata,适用于整个文件的元数据。解复用:由libavformat在avformat_open_input()中设置
    , 复用:可以在avformat_write_header()之前由用户设置,由libavformat在avformat_free_context()中释放。

  3. start_time_realtime,实时世界时间中流的起始时间,以自1970年1月1日Unix时代以来的微秒为单位。也就是流中的pts=0是在这个实际世界时间捕获的。

  • 复用:由用户在avformat_write_header()之前设置。如果设置为0或AV_NOPTS_VALUE,将使用当前的墙上时间。
  • 解复用:由libavformat设置。如果未知,则为AV_NOPTS_VALUE。请注意,该值可能在接收到一定数量的帧之后变得已知。
  1. fps_probe_size,用于avformat_find_stream_info()中确定帧率的帧数。仅用于解复用,由用户在avformat_find_stream_info()之前设置。合理的设置可以降低fps_probe_size 的时间

  2. error_recognition,错误识别;较高的值将检测到更多错误,但可能会误检测。仅用于解复用,由用户在avformat_open_input()之前设置。

  3. interrupt_callback,I/O层的自定义中断回调。

  • 解复用:由用户在avformat_open_input()之前设置
  • 复用:由用户在avformat_write_header()之前设置(主要用于AVFMT_NOFILE格式)。如果它用于打开文件,也应该传递给avio_open2()。
  1. debug, 用于启用调试的标志。 FF_FDEBUG_TS: 0x0001 复用:未使用,解复用:由用户设置。

  2. max_interleave_delta用于交错的最大缓冲持续时间。为了确保所有的流正确地交错,av_interleaved_write_frame()将等到至少为每个流排队了一个包后才实际写入任何包到输出文件。比如收到的流是包含音视频的,那ffmpeg会等音视频都到了才开始写,当一些流“稀疏”(即连续包之间存在大的间隔)时,这可能导致过多的缓冲。这个字段指定了排队的包中的第一个包和最后一个包的时间戳之间的最大差异,超过这个差异,libavformat将输出一个包,无论它是否已为所有流排队了包。仅用于封装,由用户在avformat_write_header()之前设置。

  3. event_flags,用于用户检测文件上发生的事件的标志。比如包数据读取过程元数据更新了, 标志必须由用户在事件处理后清除。

#define AVSTREAM_EVENT_FLAG_METADATA_UPDATED 0x0001 ///< The call resulted in updated metadata.
  1. max_ts_probe,在等待第一个时间戳时最多要读取的数据包数。仅用于解码

  2. avoid_negative_ts,避免在封装时出现负时间戳,仅在av_interleaved_write_frame中有效

#define AVFMT_AVOID_NEG_TS_AUTO -1 ///< Enabled when required by target format
#define AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE 1 ///< Shift timestamps so they are non negative
#define AVFMT_AVOID_NEG_TS_MAKE_ZERO 2 ///< Shift timestamps so that they start at 0
  1. use_wallclock_as_timestamps 强制使用壁钟时间戳作为数据包的pts/dts。这在存在B帧时会导致未定义的结果。只能自解码时使用。

  2. duration_estimation_method,可以通过多种方式估算持续时间字段,而这个字段可以用于知道持续时间是如何估算的。定义如下

enum AVDurationEstimationMethod {
  AVFMT_DURATION_FROM_PTS,    ///< Duration accurately estimated from PTSes
  AVFMT_DURATION_FROM_STREAM, ///< Duration estimated from a stream with a known duration
  AVFMT_DURATION_FROM_BITRATE ///< Duration estimated from bitrate (less accurate)
};
  1. skip_initial_bytes ,在打开流时跳过的初始字节。

  2. correct_ts_overflow ,修正单个时间戳溢出。

  3. seek2any,seek任意帧,也可以seek到非关键帧

  4. flush_packets,在每个数据包后刷新I/O上下文。在编码时由用户设置。

  5. format_probesize,用于识别格式的最大读取字节数。在解码时由用户设置。

  6. codec_whitelist,逗号分隔的允许解码器列表。如果为NULL,则允许所有解码器。解码时由用户设置

  7. internal,用于libavformat内部使用的不透明字段。不得由调用者以任何方式访问。

  8. io_repositioned,IO重新定位标志。 这由avformat设置,当底层IO上下文读指针被重新定位时,例如在进行基于字节的寻址时。解封装器可以使用该标志来检测此类更改。

  9. metadata_header_padding,写入元数据头部时要写入的填充字节数。封装:通过av_format_set_metadata_header_padding由用户设置。

  10. opaque,用户数据。 这是用户的一些私有数据的位置。

  11. control_message_cb,用于设备与应用程序通信的回调。

  12. output_ts_offset,输出时间戳偏移,以微秒为单位。封装时由用户设置。

  13. io_open 每当封装器或解封装器需要打开一个IO流(通常是从avformat_open_input()用于解封装器,但对于某些格式也可能发生在其他时间),它会调用此回调以获取IO上下文。另外某些封装器和解封装器嵌套,即它们会打开一个或多个额外的内部格式上下文。因此,传递给此回调的AVFormatContext指针可能与面向调用者的指针不同。但是,它将具有相同的“opaque”字段。

  14. io_close 用于关闭由AVFormatContext.io_open()打开的流的回调。

  15. max_streams 最大流数量

系列文章目录

FFmpeg目录和编译
主要结构体
更新中…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值