FFMPEG学习【libavutil】:数据结构(一)

FFMPEG中libavutil的软件架构是怎么样的?如何使用? libavutil` 是 FFmpeg 项目中的一个支持库,它提供了一系列公共的实用函数和数据结构,这些函数和数据结构在 FFmpeg 的其他组件中广泛使用。`libavutil` 的目的是为编解码器、格式处理和过滤器提供通用的功能,以避免代码重复。 阅读详情

一、AvBuffer

AVBuffer是用于引用计数数据缓冲区的API。

这个API有两个核心对象 - AVBuffer和AVBufferRef。 AVBuffer表示数据缓冲区本身; 它是不透明的,并不意味着直接由调用者访问,而只能通过AVBufferRef。 然而,呼叫者可以例如 比较两个AVBuffer指针,以检查两个不同的引用是否描述相同的数据缓冲区。 AVBufferRef表示对AVBuffer的单一引用,它是可以由调用者直接操纵的对象。

提供了两个功能,用于创建一个具有单个引用的新AVBuffer - av_buffer_alloc()来分配新的缓冲区,并使用av_buffer_create()将现有的数组包装在AVBuffer中。 从现有参考中,可以使用av_buffer_ref()创建其他引用。 使用av_buffer_unref()来释放引用(一旦所有引用被释放,这将自动释放数据)。

整个API中的惯例和FFmpeg的其余部分使得如果只存在一个引用(并且没有被标记为只读),缓冲区被认为是可写的。 提供了av_buffer_is_writable()函数来检查是否为true,并且必要时,av_buffer_make_writable()将自动创建一个新的可写缓冲区。 当然没有什么可以阻止调用代码违反这个约定,但是只有当所有现有的引用都在其控制之下时才是安全的。

注意:引用和引用缓冲区是线程安全的,因此可以同时从多个线程完成,而不需要额外的锁定。
对相同缓冲区的两个不同引用可以指向缓冲区的不同部分(即它们的AVBufferRef.data将不相等)。


一)、数据结构

对数据缓冲区的引用。

此结构体的大小不是公共ABI的一部分,并不意味着直接分配。

struct   AVBufferRef{
AVBuffer * buffer;
uint8_t * data; //数据缓冲区。当且仅当这是缓冲区的引用时才被认为是可写的,在这种情况下,av_buffer_is_writable()返回1。
int size; //数据大小(以字节计)
}


二)、宏

#define AV_BUFFER_FLAG_READONLY(1 << 0)

始终将缓冲区视为只读,即使只有一个引用。



三)、函数

AVBufferRef *  av_buffer_alloc (int size)
使用av_malloc()分配给定大小的AVBuffer。

返回:一个给定大小的AVBufferRef或当内存不足时为空


AVBufferRef *  av_buffer_allocz (int size)
与av_buffer_alloc()相同,但返回的缓冲区将被初始化为零。


AVBufferRef *  av_buffer_create (uint8_t *data, int size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
从现有阵列创建AVBuffer。

如果此函数成功,则数据由AVBuffer拥有。 调用者只能通过返回的AVBufferRef和从其派生的引用来访问数据。 如果此功能失败,数据将保持不变。

参数:data:数据数组

   size:数据大小(以字节为单位)

   free:一个释放缓冲区数据的回调

   opaque:要加工或传递给自由的参数

   flags:组合AV_BUFFER_FLAG_ *

返回:AVBufferRef参考成功的数据,失败时为NULL。


void  av_buffer_default_free (void *opaque, uint8_t *data)
默认的释放回调函数,它调用缓冲区数据上的av_free()。

这个函数是传递给av_buffer_create(),不直接调用。


AVBufferRef *  av_buffer_ref (AVBufferRef *buf)
创建对AVBuffer的新引用。

返回:一个新的AVBufferRef引用与buf相同的AVBuffer或失败时为NULL。


void  av_buffer_unref (AVBufferRef **buf)
释放给定的引用,如果没有更多的引用,则自动释放缓冲区。

参数:buf:引用被释放。 指针在返回时设置为NULL。


int  av_buffer_is_writable (const AVBufferRef *buf)
返回:1如果调用者可以写入buf引用的数据(当且仅当buf是对基础AVBuffer的唯一引用时才是真实的)。 否则返回0。 一个肯定的回答是有效的,直到在buf上调用av_buffer_ref()。


void *  av_buffer_get_opaque (const AVBufferRef *buf)
返回:由av_buffer_create设置的opaque参数。


int  av_buffer_get_ref_count (const AVBufferRef *buf)

int  av_buffer_make_writable (AVBufferRef **buf)
从给定的缓冲区引用创建可写参考,避免数据复制。

参数:buf:缓冲区引用使可写。 在成功时,buf或者保持不变,或者是未引用的,并且一个新的可写AVBufferRef写在它的位置。 失败时,buf保持不变。

返回:0成功,否定AVERROR失败。


int  av_buffer_realloc (AVBufferRef **buf, int size)
重新分配给定的缓冲区。

参数:buf:一个缓冲区引用重新分配。 在成功的情况下,buf将被未引用,并且具有所需大小的新参考将被写入其中。 失败buf将保持不变。 * buf可能为NULL,则分配一个新的缓冲区。

   size:需要新的缓冲区大小。

返回:0成功,否定AVERROR失败。

注意:如果最初通过av_buffer_realloc(NULL)分配缓冲区,并且只有一个引用(即传递给此函数的引用),则av_realloc()才会实际使用av_realloc()重新分配缓冲区。 在所有其他情况下,会分配一个新的缓冲区并复制数据。



二、AVBufferPool

AVBufferPool是AVBuffers无锁线程安全池的API。

经常分配和释放大型缓冲区可能很慢。 如果调用者需要一组相同大小的缓冲区(最明显的用例是原始视频或音频帧的缓冲区),则AVBufferPool旨在解决此问题。

开始时,用户必须调用av_buffer_pool_init()来创建缓冲池。 然后每当需要缓冲区时,调用av_buffer_pool_get()来获取对新缓冲区的引用,类似于av_buffer_alloc()。 这个新引用与所有方面的工作方式与由av_buffer_alloc()创建的引用相同。 但是,当对此缓冲区的最后一次引用未被引用时,它将返回到池而不是被释放,并将被重新用于后续的av_buffer_pool_get()调用。

当调用者完成池并且不再需要分配任何新的缓冲区时,必须调用av_buffer_pool_uninit()来将池标记为可以使用。 一旦释放所有缓冲区,它将自动释放。

只要使用默认的alloc回调,或用户提供的线程安全,就可以使用该API分配和释放缓冲区是线程安全的。


一)、函数

AVBufferPool *  av_buffer_pool_init (int size, AVBufferRef *(*alloc)(int size))
分配并初始化缓冲池。

参数:size:该池中每个缓冲区的大小

   alloc:当池为空时,将用于分配新缓冲区的函数。 可能为NULL,那么默认的分配器将被使用(av_buffer_alloc())。

返回:新创建的缓冲池成功,NULL出错。


AVBufferPool *  av_buffer_pool_init2 (int size, void *opaque, AVBufferRef *(*alloc)(void *opaque, int size), void(*pool_free)(void *opaque))
使用更复杂的分配器分配和初始化缓冲池。

参数:size:该池中每个缓冲区的大小

   opaque:分配器使用的任意用户数据

   alloc: 当池为空时,将用于分配新缓冲区的函数。

      pool_free:一个在池释放之前立即被调用的函数。即 之后,av_buffer_pool_uninit()由调用者调用,所有的帧都返回到池中并被释放。 用于取消初始化用户不透明数据。

返回:新创建的缓冲池成功,NULL出错。


void  av_buffer_pool_uninit (AVBufferPool **pool)
将缓冲池标记为可用于释放。

只有释放与池相关联的所有分配的缓冲区,才能释放它。 因此,一些分配的缓冲区仍在使用中,可以安全地调用此函数。

参数:pool:指向要释放的池的指针。 它将被设置为NULL。


AVBufferRef *  av_buffer_pool_get (AVBufferPool *pool)
分配一个新的AVBuffer,在可用时从池中重新使用一个旧的缓冲区。

该函数可以从多个线程同时调用。

返回:引用新的缓冲区成功,NULL出错。

ffmpeg源码简析(十一)libavformat,libavcodec,libavutil libavformatavformat.h 文件 定义识别文件格式和媒体类型库使用的宏、数据结构和函数,通常这些宏、数据结构和函数在此模块内相 对全局有效allformat.c 文件 简单的注册/初始化函数,把相应的协议,文件格式,解码器等用相应的链表串起来便于查找。cutils.c 文件 文件格式分析模块使用的两个工具类函数,都是对字符串的操作。file.c 把 file 当做类似 阅读详情

相关推荐

多媒体编解码学习: ffmpeg(更新ffmpeg库使用方法)

文中内容部分参考大牛博客进行边操作边总结 一、ubuntu安装ffmpeg 1. 从ffmpeg官网:https://www.ffmpeg.org/download.html下载源代码,ffmpeg-3.1.2.tar.bz2 2. 解压文件   3. 安装步骤 进入解压目录:   配置makefile:   其中--enable-share生产动态链接库,编程

jayson_jang的专栏 5136

FFmpeg 源码之 AVBuffer 函数族

AVBuffer 表示数据缓冲区本身;它是不透明的,不能被调用者直接访问,只能通过 AVBufferRef 访问。 AVBuffer 函数族定义在 libavutil/buffer.h 头文件中。 一、av_buffer_alloc 使用 av_malloc() 分配给定大小的 AVBuffer。返回给定大小的 AVBufferRef,在内存不足时为 NULL。 使用 av_malloc 分配 buffer,av_malloc 详细分析参见《FFmpeg 源码之内存管理函数族》; 调用 av_buffer

洪伟的专栏 1458

FFmpeg入门详解之58:Libavutil详解:理论与实战

libavutil是一个实用库,用于辅助多媒体编程。此库包含安全的可移植字符串函数、随机数生成器、数据结构、附加数学函数、加密和多媒体相关功能(如像素和样本格式的枚举)。libavcodec和libavformat并不依赖此库。从FFmpeg官网的文档-libavutil来看,avutil主要有一下几种功能:数学函数字符串操作内存管理相关数据结构相关错误码及错误处理日志输出其他辅助信息,比如密钥、哈希值、宏、库版本、常量等AVLogParseUtil。

福优学苑@音视频+流媒体 1145

ffmpeg-AVBuffer、AVBufferRef、引用计数机制

ffmpeg-AVBuffer、AVBufferRef、引用计数机制

weixin_37515325的博客 1578

FFmpeg libavutil 深度剖析:万物之基

libavutil 是 FFmpeg 的零依赖基础设施层,所有上层库均依赖于它。本文深度剖析其内存管理、引用计数、媒体数据模型、选项系统、数学工具等核心子系统,所有代码引用均附文件路径与行号。

Chars 223

用Logisim搞定华科计组实验:单总线CPU设计从微程序到硬布线的保姆级通关攻略

本文详细介绍了如何使用Logisim完成华中科技大学计算机组成原理实验中的单总线CPU设计,涵盖从微程序控制器到硬布线控制器的完整实现过程。通过MIPS指令译码器设计、微程序控制原理、状态机实现等关键步骤的保姆级教程,帮助学生掌握CPU设计的核心技能,并提供Educoder平台提交与调试的实用技巧。

weixin_30897233的博客 476

FFmpeg总结(四)AV系列结构体之AVBuffer、AVBufferRef、AVBufferPool

位置:libavutil/buffer.h AVBuffer采用引用计数的数据Buffer的API。有两个核心对象这个API——AVBuffer和AVBufferRef。AVBuffer代表数据缓冲区本身,它是私有的,不能直接被调用者调用。我们可以通过AVBufferRef,调用者须要检查两个AVBuffer指针是否指向两个不同的引用在同一数据buffer中。AVBufferRef 代

欢迎关注公众号:【码农突围】,公号后台回复9999,可以获取一份500页的LeetCode刷题笔记。 7727

【OpenClaw 实战】Ubuntu 双机 Gateway + Node 部署全流程 + 所有常见坑(2026版)

如果你只是需要浏览器自动化、截屏、简单系统查询 →Node 模式够用,别折腾 exec。如果你需要 GOLD 运行任意 shell 命令、git、npm、自定义脚本 →必须升级成 Gateway。bind lan + pairing approve + token 统一。后续想玩多 Agent 团队,优先考虑双/多 Gateway + 聊天通道互发(社区已有不少成功案例)。欢迎评论区留言你的环境和报错,一起交流!

hampeter的博客 1547

ffmpeg的AVBuffer和AVBufferRef

可以看到在AVBufferRef结构体中有一个AVBuffer,这个就是它管理的buf了,它在外部还有data和size,这两个变量跟buffer内部的data和size是一样的,是用来在AVBufferRef中修改buffer的内容。看完代码,发现很简单,也没什么可以讲的,就是malloc和free,最关键的是recount原子变量的增加和减少,从而达到控制释放data的能力。首先看av_buffer_create()里面有一个回调函数free,用来释放data用的。

weixin_43360707的博客 1109

例题讲解拉格朗日乘子法、线性可分支持向量机(SVM)的推导

支持向量机(Support Vector Machine, SVM)的简单推导及例题

zzzssszzzzsz的博客 5683

避开SAM3安装大坑:手把手教你用国内镜像和Modelscope权重快速跑通Demo

本文详细介绍了如何在国内环境下快速部署SAM3视觉大模型,包括使用国内镜像加速Python包安装、通过Modelscope获取权重文件以及解决CUDA 11.8等低版本适配问题。手把手教你避开常见安装陷阱,实现高效Demo运行。

weixin_30642561的博客 1407

FFmpeg中libavutil库简介及测试代码

libavutil是一个实用库,用于辅助多媒体编程。此库包含安全的可移植字符串函数、随机数生成器、数据结构、附加数学函数、加密和多媒体相关功能(如像素和样本格式的枚举)。libavcodec和libavformat并不依赖此库。 以下是测试代码,包括base64, aes, des, hash, log, md5, sha, sha512, tea, twofish, xteaa。 funse...

网络资源是无限的 4475

Android手机本地语音转文字实战:用FunASR+ONNX Runtime打造离线ASR应用(附模型下载)

本文详细介绍了如何在Android应用中集成FunASR和ONNX Runtime,构建高性能的离线语音识别系统。通过模型选择、工程化集成和性能调优等实战技巧,开发者可以实现本地语音转文字功能,有效保护用户隐私并提升响应速度。

weixin_29046611的博客 266

FFmpeg学习(三)-- libavutil 代码组成

FFmpeg libavutil

云梦居 3714

SpringBoot从入门到精通(全)

前言 ==本博文结合软件idea进行主要讲解== **springboot的特性主要有** - 简化 Spring 应用程序的创建和开发过程 - 抛弃了繁琐的 xml 配置过程,采用大量的默认配置简化以及注解反射 - 直接使用 java main 方法启动内嵌的 Tomcat 服务器运行 Spring Boot 程序,不需要部署 war 包文件 **四大核心**分别为自动配置、起步依赖、Actuator和命令行界面

码农研究僧的博客 7万+

PCB铺铜技巧如何铺铜经验总结

铺铜是指在PCB电气层添加整块的铜皮;铺铜包括电源层铺铜,地层铺铜和信号走线层空闲区域铺铜;铺铜是PCB设计的一个重要的环节。

fydar的博客 1万+

Libavutil详解:理论与实战

libavutil 是一个实用库,用于辅助多媒体编程,本文记录 libavutil 库学习及 demo 例程展示。libavutil 是一个实用库,用于辅助多媒体编程。此库包含安全的可移植字符串函数、随机数生成器、数据结构、附加数学函数、加密和多媒体相关功能(如像素和样本格式的枚举)。libavcodec 和 libavformat 并不依赖此库。数学函数字符串操作内存管理相关数据结构相关错误码及错误处理日志输出其他辅助信息,比如密钥、哈希值、宏、库版本、常量等AVLog。

明天你好的博客 2173

15、运行语音识别应用:从Mac到微控制器的部署指南

本文详细介绍了如何在Mac上运行语音识别应用,并将其部署到Arduino Nano 33 BLE Sense和SparkFun Edge等微控制器设备上的完整流程。内容涵盖应用构建、设备特定的音频与输出实现、部署步骤、常见问题解决方案及进一步优化建议。通过本指南,开发者可快速实现基于TensorFlow Lite的嵌入式语音识别系统,并根据需求进行自定义修改与功能扩展。

l3m4n的博客 57

FFmpeg 头文件完美翻译之 libavutil 模块

众所周知,FFmpeg 的代码开发上手难度较高,源于官方提供的文档很少有包含代码教程相关的。要想熟练掌握 FFmpeg 的代码库开发,需要借助它的头文件,FFmpeg 把很多代码库教程都写在头文件里面。因此,熟读头文件的内容很重要,为此,我对 FFmpeg 6.x 版本的头文件进行了翻译,方便大家阅读理解。相信我,通读一遍头文件的注释后,你的 FFmpeg 的代码库开发技能将更上一层。本文适用于有 FFmpeg 代码库开发基础,但想深入熟练使用的同学。同时也可以参考我的Github 仓库。

Leon_Chenl的博客 965

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

FFmpeg 学习(一):FFmpeg 简介

它提供了录制、转换以及流化音视频的完整解决方案。如果您之前没有阅读FFmpeg代码的经验,建议优先阅读libavformat、libavcodec以及libavutil下面的代码,它们提供了音视频开发的最基本功能,应用范围也是最广的。链接:https://zhuanlan.zhihu.com/p/568800000。链接:https://zhuanlan.zhihu.com/p/568800000。商业转载请联系作者获得授权,非商业转载请注明出处。商业转载请联系作者获得授权,非商业转载请注明出处。

yinshipin007的博客 3764

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

FFmpeg libavutil主要功能概述

0 引言 FFmpeg使用很久了,一直没有认真看过FFmpeg内部源码所提供的各种机制和功能。本文的主要目标是能够初步总结FFmpeg的avutil中所提供的功能。从FFmpeg官网的文档-libavutil来看,avutil主要有一下几种功能(顺序做了重排): 数学函数 字符串操作 内存管理相关 数据结构相关 错误码及错误处理 日志输出 其他辅助信息,比如密钥、哈希值、宏、库版本、常量等 ...

SurpassLi的专栏 78

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

ffmpeg常用函数和数据结构

记录下ffmpeg常用的一些函数和数据结构环境:ffmpeg-6.1。

langzi113的专栏 1652

ffmpeg获取时间方法(libavutil/time.c)

FFmpeg libavutil/time.c int64_t av_gettime_relative(void) { #if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC) /* 如果有clock_gettime函数 和定义了CLOCK_MONOTONIC(从系统重启到现在所经过的时间) 就通过clock_gettime该函数...

mwsubt的博客 2969

ffmpeg数据结构简介

每个库的功能作用在 FFmpeg 的编译中可以编译出了6个so动态库:libavcodec.so libavfilter.so libavformat.so libavutil.so l...

音视频开发进阶 844

FFMPEG 最全版本介绍及下载(一)

版本:ffmpeg-1.2;版本:ffmpeg-1.1;版本:ffmpeg-1.0 ;版本 ffmpeg-0.11;版本:ffmpeg-0.10;版本:ffmpeg-0.9;版本:ffmpeg-0.8;版本:ffmpeg-0.7; 版本:ffmpeg-0.6; 版本:ffmpeg-0.5;

seniorwizard的专栏 1万+

解决 symbol lookup error av_opt_child_class_iterate, version LIBAVUTIL_56

经查,是因为我安装了gimp, 它会在 /lib/x86_64-linux-gnu 安装了libavformat, libavcodec, LIBAVUTIL 等库,干扰了ffmpeg 的运行。这个错误是说,LIBAVUTIL_56 这个库中没有av_opt_child_class_iterate 函数声明,因为我的库都在/opt/ffmpeg_build/lib 目录下,用ldd ffmpeg 观察,保证其为正确链接就可以正常运行了!算是解决问题的经验,留存!

hjjdebug的专栏 2365
上一篇: FFMPEG学习【libavutil】:Memory Management(二)
下一篇: FFMPEG学习【libavutil】:数据结构(二)
一世豁然
博客等级 码龄15年 1276粉丝 146原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值