FFmpeg:AVIOContext结构体分析

15 篇文章 16 订阅
12 篇文章 7 订阅

分享一个FFmpeg的文档地址,如果本文有什么没讲清楚的,建议直接去查找:传送门

AVIOContext

这个结构体,是FFmpeg中有关io操作的顶层结构体,是avio的核心。FFmpeg支持打开本地文件路径和流媒体协议的URL。

虽然AVIOContext时avio操作的核心,但AVIOContext中的所有函数指针都不应该直接调用,它们只应在实现自定义I / O时由客户端应用程序设置。 通常这些设置为avio_alloc_context()中指定的函数指针(下一节中的read_packet函数指针)。

AVIOContext的相关调用都是在AVFormatContext中间接触发的。

比较重要的字段有:

  • (*read_packet):读取音视频数据的函数。
  • (*write_packet):写入音视频数据的函数。
  • (*read_pause):暂停或恢复网络流媒体协议的播放 。

初始化与清理

典型的使用方式是:

size_t buffer_size, avio_ctx_buffer_size = 4096;
struct buffer_data bd = { 0 };
AVFormatContext *fmt_ctx = avformat_alloc_context();
unsigned char *avio_ctx_buffer = (unsigned char *) av_malloc(avio_ctx_buffer_size);
AVIOContext *avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size, 0, &bd, &read_packet, NULL, NULL);
fmt_ctx->pb = avio_ctx;
// 清理
av_freep(&avio_ctx->buffer);
av_freep(&avio_ctx);

先通过文件的buffer大小,申请一段内存。然后使用avio_alloc_contextAVIOContext分配内存,申请时,注册内存数据读取的回掉接口read_packet,最后将申请到的AVIOContext句柄挂载到AVFormatContextpb字段,然后就可以通过AVFormatContext对文件进行操作了。

结构定义及成员解读

typedef struct AVIOContext {
  	// 私有选项(options)的类指针。如果AVIOContext是通过avio_open2()创建,av_class已设置并将选项传递给协议。如果是手动allocated的,av_class可能是被调用者设置。这个字段一定不能为空
    const AVClass *av_class;
    /*
     * 下面的图,显示了在读和写缓冲区时buf_ptr,buf_end,buf_size和pos之间的关系。
     **********************************************************************************
     *                                   READING
     **********************************************************************************
     *
     *                            |              buffer_size              |
     *                            |---------------------------------------|
     *                            |                                       |
     *
     *                         buffer          buf_ptr       buf_end
     *                            +---------------+-----------------------+
     *                            |/ / / / / / / /|/ / / / / / /|         |
     *  read buffer:              |/ / consumed / | to be read /|         |
     *                            |/ / / / / / / /|/ / / / / / /|         |
     *                            +---------------+-----------------------+
     *
     *                                                         pos
     *              +-------------------------------------------+-----------------+
     *  input file: |                                           |                 |
     *              +-------------------------------------------+-----------------+
     *
     *
     **********************************************************************************
     *                                   WRITING
     **********************************************************************************
     *
     *                                          |          buffer_size          |
     *                                          |-------------------------------|
     *                                          |                               |
     *
     *                                       buffer              buf_ptr     buf_end
     *                                          +-------------------+-----------+
     *                                          |/ / / / / / / / / /|           |
     *  write buffer:                           | / to be flushed / |           |
     *                                          |/ / / / / / / / / /|           |
     *                                          +-------------------+-----------+
     *
     *                                         pos
     *               +--------------------------+-----------------------------------+
     *  output file: |                          |                                   |
     *               +--------------------------+-----------------------------------+
     *
     */
    unsigned char *buffer;  // buffer起始地址
    int buffer_size;        // 可以读取或者写入的最大的buffer size
    unsigned char *buf_ptr; // 当前正在读或写操作的buffer地址
    unsigned char *buf_end; // 数据结束的buffer地址,如果读取函数返回的数据小于请求数据,buf_end可能小于buffer + buffer_size
    void *opaque;  // 一个私有指针,传递给read / write / seek / 等函数
    int (*read_packet)(void *opaque, uint8_t *buf, int buf_size); // 读取音视频数据的函数。
    int (*write_packet)(void *opaque, uint8_t *buf, int buf_size); // 写入音视频数据的函数
    int64_t (*seek)(void *opaque, int64_t offset, int whence);
    int64_t pos; // 当前buffer在文件中的位置
    int must_flush; // 如果下一个seek应该刷新,则为true
    int eof_reached; // 如果到达eof(end of file 文件尾),则为true
    int write_flag; // 如果开放写,则为true
    int (*read_pause)(void *opaque, int pause); // 暂停或恢复网络流媒体协议的播放
    int64_t (*read_seek)(void *opaque, int stream_index,
                         int64_t timestamp, int flags); // 快进到指定timestamp
    int seekable; // 如果为0,表示不可seek操作。其它值查看AVIO_SEEKABLE_XXX
    int64_t maxsize; // max filesize,用于限制分配空间大小
    int direct; // avio_seek是否直接调用底层的seek功能。
    int64_t bytes_read; // 字节读取统计数据
    int seek_count; // seek计数
    int writeout_count; // 写入次数统计
    int orig_buffer_size; // 原始buffer大小
    const char *protocol_whitelist; // 允许协议白名单,以','分隔
    const char *protocol_blacklist; // 不允许的协议黑名单,以','分隔
		// 用于替换write_packet的回调函数。
    int (*write_data_type)(void *opaque, uint8_t *buf, int buf_size,
                           enum AVIODataMarkerType type, int64_t time);
} AVIOContext;
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值