1.avio介绍
avio是FFmpeg中的一个模块,用于实现多种输入输出方式的封装。
avio提供了一系列API,可以将数据从内存读取到缓冲区中,也可以将缓冲区中的数据写入到内存中。其实现依赖于IOContext结构体,该结构体定义了当前输入/输出事件的状态、数据、回调函数等信息,并支持通过自定义回调函数实现不同的输入/输出方式。
内存输入(Memory Input)是指将数据从内存中读取到缓冲区中,常见的应用场景包括:从内存中读取音视频数据进行解码或处理。在使用avio实现内存输入时,需要首先创建一个AVIOContext结构体,并将内存数据缓冲区作为参数传递给avio_open函数进行初始化。之后,可以使用avio_read函数从缓冲区中读取数据,直至读取完成。
内存输出(Memory Output)是指将数据从缓冲区中写入到内存中,常见的应用场景包括:将音视频数据编码并保存到内存中。在使用avio实现内存输出时,需要首先创建一个AVIOContext结构体,并将内存数据缓冲区和缓冲区大小作为参数传递给avio_open函数进行初始化。之后,可以使用avio_write函数将数据写入缓冲区中,并在完成输出后调用avio_close函数关闭AVIOContext结构体。
总的来说,内存输入和输出是指在使用FFmpeg进行音视频处理时,将数据从内存中读取或写入到内存中的一种方式。使用avio模块可以方便地实现这种输入输出方式,并支持自定义回调函数以满足不同的应用需求。
2.为什么要用avio?
使用FFmpeg的avio模块实现内存输入和输出有以下几个优点:
2.1.灵活性高
传统的音视频处理方式往往需要将音视频数据保存到文件中,然后再进行读取和处理。而使用avio模块可以将数据直接读取或写入到内存中,从而提高了音视频处理的灵活性。这种方式可以避免繁琐的文件IO操作,节省磁盘空间。
2.2.扩展性强
内存输入和输出功能可以方便地扩展为其他更高级的应用程序,例如:流媒体服务器、实时音视频采集与处理等。这是因为内存输出能够较为轻松地将音视频数据编码并存储到内存缓冲区中,进而交由网络传输;内存输入则可直接从内存缓冲区获取音视频数据,快速响应用户请求。
2.3.可定制性好
FFmpeg的avio模块提供了一系列API,可以通过设置回调函数实现各种自定义功能。例如:自定义网络协议传输方式、增加错误重试机制、实现多路复用等。这使得处理器可以根据自己的需求对avio模块进行灵活配置,以最大限度地满足不同场景下的业务需求。
因此,使用FFmpeg的avio模块实现内存输入和输出可以提高音视频处理的效率,增加程序的灵活性和扩展性,同时还具有良好的可定制性。
3.内存区作为输入
3.1.回调函数何时被回调呢?
所有需要从输入源中读取数据的时刻,都将调用回调函数。和输入源是普通文件相比,只不过输入源变成了内存区,其他各种外在表现并无不同。
如下各函数在不同的阶段从输入源读数据,都会调用回调函数:
函数一:打开媒体文件并获取媒体文件信息的函数
第二个参数是要打开的音影文件,或者媒体文件的URL。
如果第一个参数 AVFormatContext 中 pb(类型是AVIOContext) 是有值的话,第二个参数可以传递NULL
int avformat_open_input(AVFormatContext **ps, const char *url,
const AVInputFormat *fmt, AVDictionary **options);
AVFormatContext里面有一个参数 AVIOContext *pb;
函数二,为了获取 每个音视频流。
avformat_find_stream_info()函数是用于获取媒体文件中每个音视频流的详细信息的函数