当前位置: 首页 > news >正文

FFmpeg 基本数据结构 URLProtocol分析

1、URLProtocol 结构体定义

URLProtocol 是 FFmpeg 中用于自定义 I/O 协议的核心结构体,允许开发者实现非标准协议(如私有网络传输、加密流、内存流等)的读写支持。它通过定义一组回调函数抽象底层 I/O 操作,是 FFmpeg I/O 层的基础组件。
基本结构定义分析如下:

typedef struct URLProtocol {const char *name; // 协议名称int     (*url_open)( URLContext *h, const char *url, int flags); // 打开URLint     (*url_open2)(URLContext *h, const char *url, int flags, AVDictionary **options); // 打开URL(带有选项)int     (*url_accept)(URLContext *s, URLContext **c); // 接受URL连接int     (*url_handshake)(URLContext *c); // 执行URL握手int     (*url_read)( URLContext *h, unsigned char *buf, int size); // 读取数据int     (*url_write)(URLContext *h, const unsigned char *buf, int size); // 写入数据int64_t (*url_seek)( URLContext *h, int64_t pos, int whence); // 定位文件指针int     (*url_close)(URLContext *h); // 关闭URLint (*url_read_pause)(void *urlcontext, int pause); // 暂停/恢复读取int64_t (*url_read_seek)(void *urlcontext, int stream_index, int64_t timestamp, int flags); // 查找指定时间戳的帧int (*url_get_file_handle)(URLContext *h); // 获取文件句柄int (*url_get_multi_file_handle)(URLContext *h, int **handles, int *numhandles); // 获取多个文件句柄int (*url_get_short_seek)(URLContext *h); // 检查是否支持短 seekint (*url_shutdown)(URLContext *h, int flags); // 关闭URL(异步)const AVClass *priv_data_class; // 私有数据类int priv_data_size; // 私有数据大小int flags; // 协议标志int (*url_check)(URLContext *h, int mask); // 检查URL是否支持特定操作int (*url_open_dir)(URLContext *h); // 打开目录int (*url_read_dir)(URLContext *h, AVIODirEntry **next); // 读取目录内容int (*url_close_dir)(URLContext *h); // 关闭目录int (*url_delete)(URLContext *h); // 删除文件int (*url_move)(URLContext *h_src, URLContext *h_dst); // 移动文件const char *default_whitelist; // 默认协议白名单
} URLProtocol;

各个成员的含义如下:

  • name: 一个字符指针,用于表示URLProtocol的名称。
  • url_open: 一个函数指针,用于表示打开URL的函数。
  • url_open2: 一个函数指针,用于表示打开URL(带有选项)的函数。
  • url_accept: 一个函数指针,用于表示接受URL连接的函数。
  • url_handshake: 一个函数指针,用于表示执行URL握手的函数。
  • url_read: 一个函数指针,用于表示读取数据的函数。
  • url_write: 一个函数指针,用于表示写入数据的函数。
  • url_seek: 一个函数指针,用于表示定位文件指针的函数。
  • url_close: 一个函数指针,用于表示关闭URL的函数。
  • url_read_pause: 一个函数指针,用于表示暂停/恢复读取的函数。
  • url_read_seek: 一个函数指针,用于表示查找指定时间戳的帧的函数。
  • url_get_file_handle: 一个函数指针,用于表示获取文件句柄的函数。
  • url_get_multi_file_handle: 一个函数指针,用于表示获取多个文件句柄的函数。
  • url_get_short_seek: 一个函数指针,用于表示检查是否支持短 seek 的函数。
  • url_shutdown: 一个函数指针,用于表示关闭URL(异步)的函数。
  • priv_data_class: 一个指向AVClass结构的指针,用于表示URLProtocol的私有数据类。
  • priv_data_size: 一个整数,用于表示URLProtocol的私有数据大小。
  • flags: 一个整数,用于表示URLProtocol的属性标志。
  • url_check: 一个函数指针,用于表示检查URL是否支持特定操作

2、URLProtocol 核心作用与定位

  1. 协议抽象层
    • URLProtocol 定义了协议操作的接口(如 url_open, url_read, url_write),FFmpeg 通过它访问各种协议(file://, http://, rtmp:// 等)。
    • 开发者可扩展此结构体,实现自定义协议(如 myproto://),集成到 FFmpeg 的 I/O 体系中。
  2. 与 AVIOContext 的关系
    • AVIOContext 是上层 I/O 抽象,依赖 URLProtocol 处理底层协议操作。
    • avio_open2() 内部会根据协议名查找对应的 URLProtocol 实现。

3、URLProtocol 核心回调函数

URLProtocol 其内部核心函数指针如下:

typedef struct URLProtocol {const char *name;  // 协议名称(如 "http")int (*url_open)(URLContext *h, const char *url, int flags);int (*url_read)(URLContext *h, unsigned char *buf, int size);int (*url_write)(URLContext *h, const unsigned char *buf, int size);int64_t (*url_seek)(URLContext *h, int64_t pos, int whence);int (*url_close)(URLContext *h);// ... 其他可选回调(如超时设置、分块传输等)
} URLProtocol;
  • url_open:初始化协议连接,解析 URL 参数,建立网络/文件句柄等。flags 指定模式(读/写/读写),如 AVIO_FLAG_READ67。
  • url_read/url_write:数据读写接口,返回实际传输字节数。需处理错误(返回 AVERROR(EIO))和 EOF(返回 AVERROR_EOF)。
  • url_seek: 支持随机访问时需实现。whence 参数同标准 lseek(SEEK_SET, SEEK_CUR 等)6。
  • url_close:释放资源(如关闭 socket、释放缓冲区

4、URLProtocol 定义示例

// 定义URLProtocol
URLProtocol ff_file_protocol = {.name                = "file",.url_open            = file_open,.url_read            = file_read,.url_write           = file_write,.url_seek            = file_seek,.url_close           = file_close,.priv_data_size      = sizeof(FileContext),
};

URLProtocol 是 FFmpeg I/O 子系统的基石,它通过统一的接口:

  • 抽象了各种数据源,使得上层代码无需关心数据来自文件、网络还是内存。
  • 提供了极大的灵活性,允许开发者通过自定义协议接入任何数据源。
  • 封装了协议的复杂性,将协议特定的逻辑(如 HTTP 握手、RTMP 信令)隐藏在各自的实现中。
http://www.dtcms.com/a/535943.html

相关文章:

  • Socket和Websocket编程的区别
  • 龙岗区住房和建设局官方网站巩义做网站优化
  • 网站建设的扁平化设计微信公众平台官网登录入口网页版
  • 《国家哲学社会科学文献中心:类似网站列表》
  • DC-DC降压芯片120V转12V5V3.3V4A大电流大功率H6253L 150V高耐压内置MOS管 电动车电源芯片
  • 学习和掌握RabbitMQ及其与springboot的整合实践(篇一)
  • 【数据集】【YOLO】目标检测游泳数据集 4481 张,溺水数据集,YOLO河道、海滩游泳识别算法实战训练教程。
  • 从“十五五”规划看中国视频基础设施的下一个五年:SmartMediaKit 的战略跃迁与时代机遇
  • ionic 列表:详解移动端UI设计中的列表组件
  • 做网站销售电话术语住房和城乡建设部网站评估
  • C#数据类型:List
  • 帝国网站地图模板酒类网站建设
  • [nanoGPT] 检查点 | `ckpt.pt`记忆 | 预训练模型加载`from_pretrained`
  • Spring事务管理:从原理到实战
  • 彩票类网站开发哪些网站可以做免费推广
  • AOI设置在光伏制造领域的核心应用
  • win7 VSCode 1.70设置R语言的版本,电脑上有两个版本
  • 大疆/地平线招聘要求参考:未来学习方向
  • MySQL忘记Root密码,详细找回密码步骤
  • Flutter UI组件跨端复用技术调研
  • MySQL安装避坑指南:从下载到启动的全平台避坑手册
  • wordpress 多站点错误自己做的网站本地调试
  • iOS描述文件功能解析
  • C++拓展:(一)计算器实现:从中缀表达式到逆波兰表达式
  • Linux小课堂: 网络配置详解之DHCP动态分配与静态IP地址设置
  • 政务AI大模型落地:聚焦四大场景,提升服务效率
  • 微美全息(NASDAQ:WIMI)双向跨链交互,搭建区块链互联互通“生态桥梁”
  • 郑州建网站价jquery 做网站
  • 【Rust实战】打造内存安全的网络代理:深入异步IO与并发编程
  • 公司网站建设是什么意思59一起做网站