type
status
date
slug
summary
tags
category
icon
password
Property
Mar 22, 2023 09:19 AM
基础知识
AVIO 简介
AVIO 是 FFmpeg 提供的一组 I/O 库函数,用于处理多媒体数据的输入输出操作,支持各种输入输出方式,如文件、内存等。它包括了 AVIOContext 结构体和一组函数,可以实现读写操作、网络流传输、HTTP 传输等。
AVIOContext 结构体代表了一个 AVIO 流,其中包含了读写缓存、读写函数指针、读写偏移量等信息。AVIO 可以用于从文件、内存、网络、命名管道和其他数据源读取和写入数据。它还支持自定义协议,可以访问一些不支持标准 I/O 函数的数据源,例如通过 HTTP 或 FTP 下载的文件。
使用 AVIO 的好处之一是它可以提供高度定制化的 I/O 操作。例如,您可以实现自己的协议,或者通过实现自己的读写回调函数来处理数据。此外,AVIO 还提供了一些高级功能,例如缓冲和自动重试,以便更好地管理数据流。
- 处理自定义协议:
AVIO 提供了自定义协议的支持,可以通过自己实现回调函数来处理特定的数据源。这些回调函数包括打开 URL、关闭 URL、读取数据、写入数据、移动数据指针等,通过实现这些函数,可以实现对各种类型的数据源的读写操作。

AVIO 相关 API
av_malloc()
:用于分配内存空间
av_malloc()
函数的原型如下:其中,size_t 类型的 size 参数表示要分配的内存空间大小,函数返回一个 void 指针,指向新分配的内存空间的起始地址。
avio_alloc_context()
:用于分配并初始化AVIOContext
结构体,该结构体提供了输入/输出缓冲区的管理和读写操作。AVIOContext
结构体包含了许多字段,包括输入/输出缓冲区指针、缓冲区大小、当前缓冲区位置、读写操作的回调函数等。avio_alloc_context()
函数会根据传入的参数分配一段内存用于存储AVIOContext
结构体,并设置其各个字段的初值,返回指向该结构体的指针buffer
:指向输入/输出缓冲区的指针。如果为 NULL,则 avio_alloc_context() 函数会自动分配一段缓冲区内存- buffer ⽤作FFmpeg输⼊时,由用户负责向 buffer 中填充数据,FFmpeg取⾛数据
- buffer ⽤作FFmpeg输出时,由FFmpeg负责向 buffer 中填充数据,⽤户取⾛数据
buffer_size
:缓冲区大小。每次读取的 buffer_size 会比这里的 buffer_size 小write_flag
:是缓冲区读写标志,读写的主语是指FFmpeg- write_flag 为1时, buffer ⽤于写,即作为FFmpeg输出
- write_flag 为0时, buffer ⽤于读,即作为FFmpeg输⼊
opaque
:不透明指针,是 read_packet / write_packet 的第⼀个参数,用于传递给读写操作的回调函数,一般用于传递用户自定义数据read_packet
:读操作回调函数指针write_packet
:写操作回调函数指针seek
:定位操作回调函数指针,需要⽀持seek时使⽤,可以类比fseek的机制
avio_alloc_context()
函数的原型如下:参数说明:

AVIOContext结构体内部有一个环形缓存区。这个环形缓存区在实际读写数据时会被使用。
AVIOContext结构体中的环形缓存区可以通过成员变量buffer和buffer_size来访问。它的作用是在读写数据时,将数据暂时存储在缓冲区中,以提高读写效率。当缓冲区满了或者需要刷新缓冲区时,缓冲区中的数据会被写入到实际的存储设备中。因此,环形缓存区在数据读写过程中发挥了重要的作用。
注意:
AVIOContext
结构体是FFmpeg库中的一个重要数据结构,用于管理输入/输出缓冲区。在使用FFmpeg库进行音视频处理时,往往需要使用avio_alloc_context()
函数来分配并初始化AVIOContext
结构体,以便进行文件读写等操作avcodec_find_decoder()
:用于查找特定编解码器的解码器- 该函数的作用是根据编解码器的ID或名称,查找FFmpeg库中对应的解码器。它的参数通常是一个编解码器的ID或名称,函数会返回一个指向该解码器结构体的指针
av_read_frame()
:用于读取媒体文件中下一个数据包(packet)。通常,使用该函数读取的数据包需要被解码(demux)才能被播放器播放。因此,读取数据包后需要调用其他函数,例如avcodec_send_packet()
将数据包发送到解码器中进行解码。s
:输入参数,指向已打开的媒体文件的 AVFormatContext 上下文pkt
:输出参数,用于存储读取到的数据包- 成功返回 0
- 如果到达文件结尾或发生其他错误,返回一个负数
函数参数:
函数返回值:
利用 AVIO 对 AAC 码流解码
前置知识:FFmpeg 进行 AAC 码流解码
总体流程

代码实现
- 使用了uint8_t类型来定义io_buffer的指针变量:
- 是因为在FFmpeg多媒体框架中,经常需要处理二进制数据,例如音视频数据、图片数据等。这些数据通常是以字节为单位进行处理和传输的
- uint8_t是一个定义在stdint.h标准头文件中的无符号8位整数类型,它的取值范围是0-255。使用uint8_t类型定义io_buffer的指针变量,可以确保我们处理的数据是以字节为单位的,而且数据中每个字节的取值范围是0-255,非常适合处理二进制数据
- 在实际开发中,如果需要处理其他类型的数据,例如16位整数、32位整数、浮点数等,可以使用不同的类型定义指针变量,例如uint16_t、uint32_t、float等
- opaque 中的数据是如何传递到
read_packet()
中的: avio_alloc_context()
中会调用ffio_init_context()
ffio_init_context()
中会将函数参数的值都复制给AVIOContext
的成员变量- 在使用FFmpeg库进行解码或编码操作时,通常会通过
avformat_open_input()
或avformat_alloc_context()
等函数创建一个AVFormatContext
结构体,该结构体中包含了读取媒体数据所需的各种信息,如音视频流信息、文件格式信息等。在打开输入文件时,可以通过设置AVFormatContext
的pb
字段为一个AVIOContext
实例来指定数据读取的来源,而在创建AVIOContext
实例时,可以通过设置opaque
字段来传递不透明数据 - 调用
read_packet()
时,FFmpeg 将传递AVFormatContext
结构体中的opaque
字段作为回调函数的参数


- 作者:OctalZero
- 链接:https://octalzero.com/article/17802173-7d46-4be2-be66-46c5a1824724
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章