【FFMPEG】AVFrame中buffer分配的两种方式
AVFrame在使用ffmpeg进行编解码过程中,是最基本的数据结构。
在某些场景下,需要对AVFrame的数据区域进行提前分配,有两种方法,需要根据自己的需求来使用。
(1)
* This function will fill AVFrame.data and AVFrame.buf arrays and, if
* necessary, allocate and fill AVFrame.extended_data and AVFrame.extended_buf.
* For planar formats, one buffer will be allocated for each plane.
int av_frame_get_buffer(AVFrame *frame, int align);
使用该接口分配到的数据空间,是可复用的,即内部有引用计数(reference),本次对frame data使用完成,可以解除引用,av_frame_unref(AVFrame *frame),调用后,引用计数减1,如果引用计数变为0,则释放data空间。
当然,也可以添加引用,接口:av_frame_ref(AVFrame *dst, const AVFrame *src)。
(2)
* Allocate an image with size w and h and pixel format pix_fmt, and
* fill pointers and linesizes accordingly.
* The allocated image buffer has to be freed by using
* av_freep(&pointers[0]).
int av_image_alloc(uint8_t *pointers[4], int linesizes[4], int w, int h, enum AVPixelFormat pix_fmt, int align);
如上接口,和(1)不同在于,(1)只要输入frame指针即可,而本接口看不到frame的数据结构,相比(1),分配的级别更低,看注释中“The allocated image buffer has to be freed by using av_freep(&pointers[0])”,即,这种分配方式,不能用(2)中的解除引用来进行隐形释放了,需要自行调用释放才行。
注意使用过程中的坑:使用(1)进行分配后,调用ffmpeg某底层接口,结果,该接口对输入的frame做了一次解除引用,而外部调用并不知晓本次操作,从而导致可能的内存误释放,进而引起程序崩溃。
两个接口使用的代码示例:
AVFrame *AllocFrame(enum AVPixelFormat format, int width, int height)
{AVFrame *frame = av_frame_alloc();if (!frame) return NULL;frame->format = format;frame->width = width;frame->height = height;frame->pts = 0;int ret = av_image_alloc(frame->data, frame->linesize, frame->width, frame->height, (enum AVPixelFormat)frame->format, 1);if (ret < 0){av_frame_free(&frame);return NULL;}return frame;
}
AVFrame *AllocFrame(enum AVPixelFormat pix_fmt, int width, int height) {AVFrame *frame;int ret;frame = av_frame_alloc();if (!frame) return NULL;frame->format = pix_fmt;frame->width = width;frame->height = height;ret = av_frame_get_buffer(frame, 32);if (ret < 0) { av_frame_free(&frame); return NULL;}return frame;
}
【FFMPEG】AVFrame中buffer分配的两种方式相关推荐
- 实验四:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
贺邦+原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验目的: 使用库函数 ...
- Java中HashMap遍历的两种方式
第一种: Map map = new HashMap(); Iterator iter = map.entrySet().iterator(); while (iter.hasNext()) { Ma ...
- 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
实验4:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用 姓名:李冬辉 学号:20133201 注: 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http ...
- sh执行文件 参数传递_详解shell中脚本参数传递的两种方式
方式一:$0,$1,$2.. 采用$0,$1,$2..等方式获取脚本命令行传入的参数,值得注意的是,$0获取到的是脚本路径以及脚本名,后面按顺序获取参数,当参数超过10个时(包括10个),需要使用${ ...
- Java中实现多线程的两种方式之间的区别
Java提供了线程类Thread来创建多线程的程序.其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象.每个Thread对象描述了一个单独的线程.要产生一个线 ...
- java多线程区别_Java中实现多线程的两种方式之间的区别
Java提供了线程类Thread来创建多线程的程序.其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象.每个Thread对象描述了一个单独的线程.要产生一个线 ...
- Java中Http连接的两种方式
在java中连接http,介绍两种方法,一种是java的HttpUrlConnection,另一种是apacha公司的httpClient,后者是第三方的类库需要从外部,导入,同时这也是第一次使用外部 ...
- 二级指针在子函数中申请内存的两种方式
二级指针:在主函数中申明变量,在子函数中分配内存,有两种方式返回二级指针.在这个过程只有深刻理解了C的函数调用模型,以及指针的内存模型,才能够掌握好. #pragma once #include &l ...
- WCF中的ServiceHost初始化两种方式
在宿主程序中初始化ServiceHost有直接写代码和使用配置文件两种方式.使用ServiceHost首先要引用System.ServiceModel 命名空间. 1 代码方式 using(Servi ...
最新文章
- asp.net httpmodule 访问页面控件 备忘
- 由优劣语言之争引起的思考
- Across the universe
- python语言术语_python的一些术语
- 微服务框架Demo.MicroServer运行手册
- TensorflowSharp 简单使用与KNN识别MNIST流程
- 西北工业大学计算机毕业论文,光纤通信发射机本科毕业论文 西北工业大学.docx...
- 删除和创建用户的脚本
- 获得邮件列表失败_邮件经常失败回弹很糟心?一定要知道这几个小知识
- mysql sql 限制条数据类型_数据库的数据类型和约束条件
- 转 TCP中的序号和确认号
- startallback怎么用_startallback使用教程
- win10系统如何安装Oracle 10G
- Microsoft sqlserver2000如何导入.mdf格式的数据库文件
- win7系统下文件夹重命名提示找不到该项目:的解决!
- Linux操作学习笔记(CentOS7)
- 合作式智能运输系统车路协同云控系统V2X设备接入技术规范
- C语言malloc与calloc区别
- 材料阻尼测试原理、方法、装置和内耗分析的应用
- 应用nslookup命令查看A记录、MX记录、CNAME记录和NS记录
热门文章
- mencoder 和ffmpeg常用命令
- 极客日报:小米计划3年内成为全球第一;谷歌计划在韩国开放第三方支付;Firefox 94发布
- 电子电路期末考试复习预测题一(内附详细解析)
- css3圣诞节喜庆文字祝福代码
- fuse的安装与使用
- 2021年年度总结(记录一下自己大学期间吧)
- 基于InforFlow的业务流程管理系统解决方案(转载)
- document.getElementById(“id”)与$(#id)的区别
- opencv2计算机视觉编程手册(中文)pdf
- 《职工带薪年休假条例》2008年元旦起施行(全文)