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

相关推荐
OH_TPC17 小时前
【鸿蒙优选三方库】@ohos/ffmpeg-kit:把 FFmpeg 的全部能量带进鸿蒙
华为·ffmpeg·harmonyos·鸿蒙
是jin奥17 小时前
最新 FFmpeg 安装脚本:Linux x86_64
linux·运维·ffmpeg
骑着蜗牛撵大象32718 小时前
用 Codex 批量做数字人商品口播视频:从分镜 JSON 到成片校验的流水线
java·ffmpeg·json·音视频·数字人·视频·codex
企业数字化笔记20 小时前
视频加放大特写后音画不同步怎么办?OpenCV转场与FFmpeg音轨续接实战
opencv·ffmpeg·音视频
开开心心就好3 天前
课堂随机点名工具,绿色版免安装双击即用
java·服务器·前端·ffmpeg·音视频·perl·symfony
小鹿软件办公3 天前
不依赖 FFmpeg 也能录屏?ShareX 22 新增录屏等十余款新工具
ffmpeg·sharex·免费录屏工具
lll23526917793 天前
Android APP短视频音频提取,主流工具怎么选
ffmpeg·音视频
成都旺小宝科技4 天前
首访决策人没来,AI一客一策两天成交!
大数据·人工智能·机器学习·ffmpeg·语音识别
余槐i4 天前
加了Cookie yt-dlp仍报HTTP 403:3个容易漏的请求头差异
python·http·ffmpeg·开发工具·yt-dlp
余槐i4 天前
yt-dlp 线程开到 16 反而更慢:1000 个视频的实测与限速原因
性能优化·ffmpeg·自动化·开发工具·yt-dlp