FFmpeg源码:avio_r8、avio_rl16、avio_rl24、avio_rl32、avio_rl64函数分析
一、引言
AVIOContext是FFmpeg(本文演示用的FFmpeg源码版本为5.0.3)中的字节流上下文结构体,用来管理输入输出数据。打开一个媒体文件的时候,需要先把数据从硬盘读到缓冲区,然后会用到AVIOContext中的如下成员:
typedef struct AVIOContext {
//.../** The following shows the relationship between buffer, buf_ptr,* buf_ptr_max, buf_end, buf_size, and pos, when reading and when writing* (since AVIOContext is used for both):************************************************************************************ READING************************************************************************************ | buffer_size |* |---------------------------------------|* | |** buffer buf_ptr buf_end* +---------------+-----------------------+* |/ / / / / / / /|/ / / / / / /| |* read buffer: |/ / consumed / | to be read /| |* |/ / / / / / / /|/ / / / / / /| |* +---------------+-----------------------+** pos* +-------------------------------------------+-----------------+* input file: | | |* +-------------------------------------------+-----------------+************************************************************************************* WRITING************************************************************************************ | buffer_size |* |--------------------------------------|* | |** buf_ptr_max* buffer (buf_ptr) buf_end* +-----------------------+--------------+* |/ / / / / / / / / / / /| |* write buffer: | / / to be flushed / / | |* |/ / / / / / / / / / / /| |* +-----------------------+--------------+* buf_ptr can be in this* due to a backward seek** pos* +-------------+----------------------------------------------+* output file: | | |* +-------------+----------------------------------------------+**/unsigned char *buffer; /**< Start of the buffer. */int buffer_size; /**< Maximum buffer size */unsigned char *buf_ptr; /**< Current position in the buffer */unsigned char *buf_end; /**< End of the data, may be less thanbuffer+buffer_size if the read function returnedless data than requested, e.g. for streams whereno more data has been received yet. */
//...int64_t pos; /**< position in the file of the current buffer */
//...
} AVIOContext;
从输入缓冲区读取数据的时候,
成员变量buffer:恒指向输入缓冲区的开头。
成员变量buffer_size:成员buffer指向的缓冲区的大小,单位为字节。
成员变量buf_ptr:指向输入缓冲区中当前读取到的位置。
成员变量buf_end:恒指向输入缓冲区的末尾。
简单来讲:
* READING************************************************************************************ | buffer_size |* |---------------------------------------|* | |** buffer buf_ptr buf_end* +---------------+-----------------------+* |/ / / / / / / /|/ / / / / / /| |* read buffer: |/ / consumed / | to be read /| |* |/ / / / / / / /|/ / / / / / /| |* +---------------+-----------------------+
FFmpeg源码中通过下面函数读取AVIOContext结构体中成员变量buffer指向的输入缓冲区的数据。这些函数都声明在FFmpeg源码的头文件libavformat/avio.h中:
/*** @name Functions for reading from AVIOContext* @{** @note return 0 if EOF, so you cannot use it if EOF handling is* necessary*/
int avio_r8 (AVIOContext *s);
unsigned int avio_rl16(AVIOContext *s);
unsigned int avio_rl24(AVIOContext *s);
unsigned int avio_rl32(AVIOContext *s);
uint64_t avio_rl64(AVIOContext *s);
unsigned int avio_rb16(AVIOContext *s);
unsigned int avio_rb24(AVIOContext *s);
unsigned int avio_rb32(AVIOContext *s);
uint64_t avio_rb64(AVIOContext *s);
二、avio_r8函数的定义
avio_r8函数定义在FFmpeg源码的源文件libavformat/aviobuf.c中:
/* XXX: put an inline version */
int avio_r8(AVIOContext *s)
{if (s->buf_ptr >= s->buf_end)fill_buffer(s);if (s->buf_ptr < s->buf_end)return *s->buf_ptr++;return 0;
}
该函数作用是:如果还没有读取到输入缓冲区的结尾,返回读取到的该输入缓冲区中的一个字节数据,也就是返回s->buf_ptr指向的一个字节数据,然后让s->buf_ptr指向下一个字节数据。如果已经读取到输入缓冲区的末尾,返回0。注意:读取到缓冲区的结尾时,该函数返回0,所以不能同时用它来读取ASCII值为0的字节并且判断是否读到了结尾,否则会冲突。也就是说avio_r8函数要么只能读取字符串但可以判断是否到了结尾,要么能读取二进制数据但不能判断是否到了结尾。一般来讲选择后者的用法,即用它读取二进制数据(包含ASCII值为0的数据)但不判断是否到了结尾。
三、avio_rl16函数的定义
avio_rl16函数定义在FFmpeg源码的源文件libavformat/aviobuf.c中:
unsigned int avio_rl16(AVIOContext *s)
{unsigned int val;val = avio_r8(s);val |= avio_r8(s) << 8;return val;
}
该函数作用是:如果还没有读取到输入缓冲区的结尾,返回按照小端模式读取到的该输入缓冲区中的二个字节数据,然后让s->buf_ptr指向下下个字节的数据。如果已经读取到输入缓冲区的末尾,返回0。注意:该函数跟avio_r8函数一样,一般用它来读取二进制数据(包含ASCII值为0的数据)但不判断是否到了结尾。
四、其它相关函数
同理:
avio_rl24函数:如果还没有读取到输入缓冲区的结尾,返回按照小端模式读取到的该输入缓冲区中的三个字节数据,然后让s->buf_ptr的值+3。如果已经读取到输入缓冲区的末尾,返回0。
avio_rl32函数:如果还没有读取到输入缓冲区的结尾,返回按照小端模式读取到的该输入缓冲区中的四个字节数据,然后让s->buf_ptr的值+4。如果已经读取到输入缓冲区的末尾,返回0。
avio_rl64函数:如果还没有读取到输入缓冲区的结尾,返回按照小端模式读取到的该输入缓冲区中的八个字节数据,然后让s->buf_ptr的值+8。如果已经读取到输入缓冲区的末尾,返回0。
avio_rb16函数:如果还没有读取到输入缓冲区的结尾,返回按照大端模式读取到的该输入缓冲区中的二个字节数据,然后让s->buf_ptr的值+2。如果已经读取到输入缓冲区的末尾,返回0。
avio_rb24函数:如果还没有读取到输入缓冲区的结尾,返回按照大端模式读取到的该输入缓冲区中的三个字节数据,然后让s->buf_ptr的值+3。如果已经读取到输入缓冲区的末尾,返回0。
avio_rb32函数:如果还没有读取到输入缓冲区的结尾,返回按照大端模式读取到的该输入缓冲区中的四个字节数据,然后让s->buf_ptr的值+4。如果已经读取到输入缓冲区的末尾,返回0。
avio_rb64函数:如果还没有读取到输入缓冲区的结尾,返回按照大端模式读取到的该输入缓冲区中的八个字节数据,然后让s->buf_ptr的值+8。如果已经读取到输入缓冲区的末尾,返回0。
所有函数跟avio_r8函数一样,一般用它们来读取二进制数据(包含ASCII值为0的数据)但不判断是否到了结尾。
相关文章:
FFmpeg源码:avio_r8、avio_rl16、avio_rl24、avio_rl32、avio_rl64函数分析
一、引言 AVIOContext是FFmpeg(本文演示用的FFmpeg源码版本为5.0.3)中的字节流上下文结构体,用来管理输入输出数据。打开一个媒体文件的时候,需要先把数据从硬盘读到缓冲区,然后会用到AVIOContext中的如下成员&#x…...
如何使用 API 查看极狐GitLab 镜像仓库中的镜像?
GitLab 是一个全球知名的一体化 DevOps 平台,很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab :https://gitlab.cn/install?channelcontent&utm_sourcecsdn 是 GitLab 在中国的发行版,专门为中国程序员服务。可以一键式部署…...

软件-vscode-plantUML-IDEA
文章目录 vscode基础命令 实操1. vscode实现springboot项目搭建 (包括spring data jpa和sqlLite连接) PlantUMLIDEA下载及安装Eval Reset插件配置修改IDEA创建项目的默认目录IDEA配置gitIDEA翻译插件translationIDEA断点调试IDEA全局搜索快捷键不能使用代…...

ES6语法详解,面试必会,通俗易懂版
目录 Set的基本使用WeakSet 使用Set 和 WeakSet 区别内存泄漏示例:使用普通 Set 保存 DOM 节点如何避免这个内存泄漏MapWeakMap 的使用 Set的基本使用 在ES6之前,我们存储数据的结构主要有两种:数组、对象。 在ES6中新增了另外两种数据结构&a…...

CTFshow--Web--代码审计
目录 web301 web302 web303 web304 web305 web306 web307 web308 web309 web310 web301 开始一个登录框, 下意识sql尝试一下 发现 1 的时候会到一个 checklogin.php 的路径下, 但啥也没有 好吧, 这是要审计代码的 ,下载好源码, 开始审计 看了一下源码 , 应该就是sql…...

Java语言程序设计——篇十(1)
🌿🌿🌿跟随博主脚步,从这里开始→博主主页🌿🌿🌿 接口介绍 接口概述接口定义接口的实现实战演练 👅接口的继承实战演练实战演练 接口的类型常量实战演练 静态方法默认方法解决默认方…...
Qt对比MFC优势
从Qt小白到现在使用了有四年的时间,之前也搞过MFC,WinForm,基本上都是桌面的框架, 从难易程度看MFC>QT>WinForm; 运行的效率上来看MFC>QT>WinForm; 开发效率上WinForm>QT>MFC; 跨平台Qt首选; 界面的美观难易程度Qt>…...

RuntimeError: No CUDA GPUs are available
RuntimeError: No CUDA GPUs are available 目录 RuntimeError: No CUDA GPUs are available 【常见模块错误】 【解决方案】 解决步骤如下: 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页,我是博主英杰,211科…...
URL参数中携带中文?分享 1 段优质 JS 代码片段!
本内容首发于工粽号:程序员大澈,每日分享一段优质代码片段,欢迎关注和投稿! 大家好,我是大澈! 本文约 800 字,整篇阅读约需 1 分钟。 今天分享一段优质 JS 代码片段,在发送 ajax 请…...
sass的使用
一、变量 //声明一个变量 $highlight-color: #F90; .selected {border: 1px solid $highlight-color; }//编译后 .selected {border: 1px solid #F90; }二、导入 import "xxx.scss"三、混合器简单定义 通过mixin定义,通过include调用 // mixin.scss /…...

【足球走地软件】走地数据分析预测【大模型篇】走地预测软件实战分享
了解什么是走地数据? 走地数据分析,在足球赛事的上下文中,是一种针对正在进行中的比赛进行实时数据分析的方法。这种方法主要用于预测比赛中的某些结果或趋势,如总进球数、比分变化、球队表现等。 在足球走地数据分析中…...

现在有什么赛道可以干到退休?
最近,一则“90后无论男女都得65岁以后退休”的消息在多个网络平台流传,也不知道是真是假,好巧不巧今天刷热点的时候又看到一条这样的热点:现在有什么赛道可以干到退休? 点进去看了几条热评,第一条热评说的…...

c程序杂谈系列(职责链模式与if_else)
从处理器的角度来说,条件分支会导致指令流水线的中断,所以控制语句需要严格保存状态,因为处理器是很难直接进行逻辑判断的,有可能它会执行一段时间,发现出错后再返回,也有可能通过延时等手段完成控制流的正…...
前端开发技术之CSS(层叠样式表)
盒模型(Box Model) CSS盒模型描述了如何计算一个元素的总宽度和高度。 它包括以下几个部分: 1. 内容(Content):元素的实际内容,比如文本或图片。 2. 内边距(Padding)&…...

go语言day20 使用gin框架获取参数 使用自定义的logger记录日志
Golang 操作 Logger、Zap Logger 日志_golang zap-CSDN博客 目录 一、 从控制器中获取参数的几种形式 1) 页面请求url直接拼接参数。 2) 页面请求提交form表单 3) 页面请求发送json数据,使用上下文对象c的BindJSON()方法接…...

DHCP笔记
DHCP---动态主机配置协议 作用:为终端动态提供IP地址,子网掩码,网关,DNS网址等信息 具体流程 报文抓包 在DHCP服务器分配iP地址之间会进行广播发送arp报文,接收IP地址的设备也会发送,防止其他设备已经使用…...

TCP为什么需要四次挥手?
tcp为什么需要四次挥手? 答案有两个: 1.将发送fin包的权限交给被动断开发的应用层去处理,也就是让程序员处理 2.接第一个答案,应用层有了发送fin的权限,可以在发送fin前继续向对端发送消息 为了搞清楚这个问题&…...

MySQL 索引相关基本概念
文章目录 前言一. B Tree 索引1. 概念2. 聚集索引/聚簇索引3. 辅助索引/二级索引4. 回表5. 联合索引/复合索引6. 覆盖索引 二. 哈希索引三. 全文索引 前言 InnoDB存储引擎支持以下几种常见索引:BTree索引,哈希索引,全文索引 一. B Tree 索引…...

Neutralinojs教程项目实战初体验(踩坑指南),干翻 electron
Neutralinojs 项目实战初体验(踩坑指南),干翻 electron Neutralinojs 官方文档 卧槽卧槽,!这个年轻人居然用浏览器把电脑关机了_哔哩哔哩_bilibili正是在下 本教程搭建的是纯原生项目,没有和其它前端框架…...

【轻松拿捏】Java-List、Set、Map 之间的区别是什么?
List、Set、Map 之间的区别是什么? 一、List 二、Set 三、Map 🎈边走、边悟🎈迟早会好 一、List 有序性:List 保持元素的插入顺序,即元素按添加的顺序存储和访问。允许重复:List 可以包含重复的元素。…...

【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...

LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...
uniapp 实现腾讯云IM群文件上传下载功能
UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中,群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS,在uniapp中实现: 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...