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

相关推荐
邪恶的贝利亚13 小时前
《ffplay 读线程与解码线程分析:从初始化到 seek 操作,对比视频与音频解码的差异》
ffmpeg·php·音视频
路溪非溪1 天前
关于ffmpeg的简介和使用总结
ffmpeg
gushansanren1 天前
基于WSL用MSVC编译ffmpeg7.1
windows·ffmpeg
追随远方3 天前
Android平台FFmpeg音视频开发深度指南
android·ffmpeg·音视频
charlie1145141915 天前
编译日志:关于编译opencv带有ffmpeg视频解码支持的若干办法
opencv·ffmpeg·音视频·imx6ull·移植教程
追随远方5 天前
Android平台FFmpeg视频解码全流程指南
android·ffmpeg·音视频
urhero6 天前
Python+ffmpeg 实现给视频添加字幕
ffmpeg·音视频·python编程·视频编辑·实用视频工具·添加字幕
追随远方6 天前
Android NDK版本迭代与FFmpeg交叉编译完全指南
android·ffmpeg
带鱼工作室6 天前
ffmpeg多媒体(音视频)处理常用命令
ffmpeg·音视频
批量小王子7 天前
2025-05-07-FFmpeg视频裁剪(尺寸调整,画面比例不变)
ffmpeg·音视频