FFmpeg源码:ffio_read_indirect函数分析

=================================================================

AVIOContext结构体和其相关的函数分析:

FFmpeg源码:avio_r8、avio_rl16、avio_rl24、avio_rl32、avio_rl64函数分析

FFmpeg源码:read_packet_wrapper、fill_buffer函数分析

FFmpeg源码:avio_read函数分析

FFmpeg源码:avio_seek函数分析

FFmpeg源码:avio_skip函数分析

FFmpeg源码:avio_tell函数分析

FFmpeg源码:ffurl_seek2、ffurl_seek、avio_size函数分析

FFmpeg源码:avio_feof函数分析

FFmpeg源码:avio_read_partial函数分析

FFmpeg源码:ffio_read_indirect函数分析

=================================================================

一、ffio_read_indirect函数的声明

ffio_read_indirect函数声明在FFmpeg源码(本文演示用的FFmpeg源码版本为7.0.1)的头文件libavformat/avio_internal.h.h中:

cpp 复制代码
/**
 * Read size bytes from AVIOContext, returning a pointer.
 * Note that the data pointed at by the returned pointer is only
 * valid until the next call that references the same IO context.
 * @param s IO context
 * @param buf pointer to buffer into which to assemble the requested
 *    data if it is not available in contiguous addresses in the
 *    underlying buffer
 * @param size number of bytes requested
 * @param data address at which to store pointer: this will be a
 *    a direct pointer into the underlying buffer if the requested
 *    number of bytes are available at contiguous addresses, otherwise
 *    will be a copy of buf
 * @return number of bytes read or AVERROR
 */
int ffio_read_indirect(AVIOContext *s, unsigned char *buf, int size, const unsigned char **data);

该函数的作用是:

情况一:如果AVIOContext输入缓冲区中还未被读取的数据量(s->buf_end - s->buf_ptr)不小于计划要读取的字节数(size),并且该媒体文件被打开是不是为了写入的(!s->write_flag为真),让"*data"指向"输入缓冲区中当前读取到的位置(s->buf_ptr)",然后让s->buf_ptr指向原来的位置之后的size个字节的位置。也就是说,如果AVIOContext输入缓冲区中的数据足够,直接从输入缓冲区中读取数据。

情况二:如果不满足"情况一"的条件(AVIOContext输入缓冲区中的数据不足),首先尝试从输入缓冲区中读取size个字节数据,如果输入缓冲区中没有数据或者数据已被读完或者读完后还不够size个字节,通过文件描述符去读取本地媒体文件中的数据或者通过socket接收网络流中的数据,直到读取到总共size个字节为止(除非出错)。将读取到的数据保存到形参buf指向的缓冲区中,让"*data"指向buf。

形参s:既是输入型参数也是输出型参数。指向一个AVIOContext(字节流上下文结构体)变量。执行ffio_read_indirect函数后,s->buf_ptr等成员会发生相应变化。

形参buf:输出型参数。仅当符合上述"情况二"的条件时有意义,保存读上来的数据的缓冲区。

形参size:输入型参数。要读取的字节数。

形参data:输出型参数。"情况一"和"情况二"时皆有意义,"*data"指向保存读上来的数据的缓冲区。

返回值:返回一个非负数表示成功,此时返回实际读取到的字节数;返回一个负数表示出错。

二、ffio_read_indirect函数的定义

ffio_read_indirect函数定义在源文件libavformat/aviobuf.c中:

cpp 复制代码
int ffio_read_indirect(AVIOContext *s, unsigned char *buf, int size, const unsigned char **data)
{
    if (s->buf_end - s->buf_ptr >= size && !s->write_flag) {
        *data = s->buf_ptr;
        s->buf_ptr += size;
        return size;
    } else {
        *data = buf;
        return avio_read(s, buf, size);
    }
}

可以看到该函数内部调用了avio_read函数,可以看作是对avio_read函数的封装。

相关推荐
给大佬递杯卡布奇诺4 小时前
FFmpeg 基本API avio_read函数内部调用流程分析
c++·ffmpeg·音视频
华仔啊18 小时前
别再用在线工具转GIF了!FFmpeg实现高清无损转换,这才是真优雅
ffmpeg
落淼喵_G19 小时前
ffmpeg转化mp3至wav格式
ffmpeg
jndingxin2 天前
瑞芯微算法环境搭建(1)------编译ffmpeg
ffmpeg
彷徨而立3 天前
【FFmpeg】销毁解码器时,必须清理剩余帧吗?
ffmpeg
骄傲的心别枯萎3 天前
项目1:FFMPEG推流器讲解(五):FFMPEG时间戳、时间基、时间转换的讲解
ffmpeg·音视频·视频编解码·时间戳·rv1126
彷徨而立3 天前
【FFmpeg】HW 解码器销毁时,资源回收顺序
ffmpeg
彷徨而立3 天前
【FFmpeg】如何判断 HW解码器输出的是 硬件帧?
ffmpeg
派阿喵搞电子3 天前
基于ffmpeg库,在AGX上编译jetsonFFmpeg库带有硬件加速的h264_nvmpi视频编解码器
ffmpeg·视频编解码
彷徨而立3 天前
【FFmpeg】HW解码器输出 硬件帧 or 软件帧
ffmpeg