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函数的封装。

相关推荐
Memory_荒年1 天前
FFmpeg:音视频界的“万能瑞士军刀”
ffmpeg
QJtDK1R5a2 天前
V4L2 vs GStreamer vs FFmpeg:Linux多媒体处理的三个层级
linux·运维·ffmpeg
AI视觉网奇4 天前
webrtc 硬编码
ffmpeg·webrtc
九转成圣4 天前
避坑指南:彻底解决 FFmpeg drawtext 烧录多行文本出现“方块(□)”乱码的终极方案
ffmpeg
bbq烤鸡4 天前
ffmpeg精确极速剪辑方案
ffmpeg
小镇学者5 天前
【python】 macos 安装ffmpeg 命令行工具
python·macos·ffmpeg
QMCY_jason5 天前
RK3588平台编译 ffmpeg-rockchip 使用rkmpp rkrga 进行硬件转码
ffmpeg
悢七5 天前
单机部署 OceanBase 集群
数据库·ffmpeg·oceanbase
yy我不解释5 天前
关于FFmpeg的安装使用(m3u8转码MP4)
ffmpeg
Chars-D6 天前
FFmpeg源码深度剖析:架构、模块与转码流水线
架构·ffmpeg