FFmpeg 基本API avio_read函数内部调用流程分析

1、avio_read函数介绍

avio_read 函数是 FFmpeg 中的一个 I/O 函数,它用于从流中读取数据。与 avio_write 类似,avio_read 也通过 AVIOContext 来抽象读操作。avio_read 用于从文件、网络连接或其他数据源中读取字节数据。

cpp 复制代码
int avio_read(AVIOContext *s, unsigned char *buf, int size);
  • 参数:
    • s: 一个指向 AVIOContext 的指针,表示输入流的上下文。
    • buf: 一个缓冲区,用来存放从流中读取的数据。
    • size: 要读取的字节数。
  • 返回值:
    • 如果成功,返回读取的字节数。
    • 如果到达文件末尾或出错,返回负值。
      • 如果返回值是 0,表示已到达文件末尾(EOF)。
      • 如果返回负值,表示发生了错误。

主要用途:

  • 读取音视频数据:avio_read 用于从输入流(如文件或网络流)中读取音视频数据,通常是从文件、流媒体协议(如 RTSP、HTTP)或者网络套接字读取数据。
  • 流媒体处理:当接收流媒体数据时,avio_read 会被用来从网络流中获取音视频数据包。

例如:

  • 对于文件读取,avio_read 会调用操作系统的文件 I/O 操作。
  • 对于网络流读取,avio_read 会使用套接字操作,通过网络协议接收数据。

2、avio_read内部调用流程分析

2.1 参数检查

  • 检查 size 是否有效(非负)。
  • 验证 AVIOContext 是否包含有效的读回调 (read_packet)。

2.2 缓冲区直接读取

cpp 复制代码
/*如果请求的数据量 小于等于缓冲区可用数据:*/
if (s->buf_end - s->buf_ptr >= size) {
    memcpy(buf, s->buf_ptr, size);  // 直接拷贝数据
    s->buf_ptr += size;             // 移动缓冲区指针
    return size;                    // 返回实际读取大小
}

2.3 大文件直接读取(Direct I/O)

cpp 复制代码
/*
当满足以下条件时,绕过内部缓冲区直接调用用户回调:
请求的 size 大于缓冲区大小。
AVIOContext 启用了 direct 标志。
*/
if (s->direct && size > s->buffer_size) {
    len = s->read_packet(s->opaque, buf, size);  // 直接调用用户回调
    s->pos += len;                               // 更新文件位置
    return len;
}

2.4 缓冲区填充与混合读取

cpp 复制代码
/*
若数据不足,分阶段处理:
步骤1:拷贝缓冲区剩余数据(若有)。
步骤2:循环填充缓冲区并拷贝数据,直到满足请求或遇到错误。
*/
while (size > 0) {// 填充缓冲区(内部调用 read_packet)fill_buffer(s);// 计算本次可拷贝的数据量
    len = FFMIN(s->buf_end - s->buf_ptr, size);
    memcpy(buf, s->buf_ptr, len);// 更新指针和计数器
    buf += len;
    size -= len;
    total_read += len;
 }

3、avio_read调用时序图

相关推荐
加油201919 小时前
音视频处理(一):什么决定了你的音色?声音的三要素
音视频·音色·声音三要素
Dream it possible!19 小时前
LeetCode 面试经典 150_栈_简化路径(53_71_C++_中等)(栈+stringstream)
c++·leetcode·面试·
爱和冰阔落19 小时前
【C++继承下】继承与友元 / static 菱形继承与虚继承 组合的详解分析
c++·面试·腾讯云ai代码助手
草莓熊Lotso20 小时前
《C++ Stack 与 Queue 完全使用指南:基础操作 + 经典场景 + 实战习题》
开发语言·c++·算法
敲上瘾20 小时前
单序列和双序列问题——动态规划
c++·算法·动态规划
ajassi200020 小时前
开源 C++ QT QML 开发(二十二)多媒体--ffmpeg编码和录像
c++·qt·开源
小糖学代码1 天前
Linux:11.线程概念与控制
linux·服务器·c语言·开发语言·c++
Larry_Yanan1 天前
QML学习笔记(四十)QML的ApplicationWindow和StackView
c++·笔记·qt·学习·ui
Kratzdisteln1 天前
【C语言】Dev-C++如何编译C语言程序?从安装到运行一步到位
c语言·c++
Dream it possible!1 天前
LeetCode 面试经典 150_栈_有效的括号(52_20_C++_简单)(栈+哈希表)
c++·leetcode·面试··哈希表