FFmpeg内存管理

FFmpeg 的社群来了,想加入微信社群的朋友请购买《FFmpeg原理》VIP版 电子书,里有更高级的内容与答疑服务。


FFmpeg 是一个 C程序的项目,C语言是需要手动管理内存的。内存管理有一个技巧,只要你分清楚这个变量是在栈上,还是在堆上的就可以了。在栈上的变量不需要手动释放,而在堆上的变量需要自己释放。

下面通过一个实例, 通过 反汇编 来讲解一下 栈变量 为什么不需要自己释放,代码如下:

int add_something(int a, int b, int c) {
    int d = 4;
    int e = 5;
    int f = 6;
    return a + b + c + d + e + f;
}

int sub_something(int a, int b, int c) {
    int g = 7;
    int h = 8;
    int j = 9;
    return a + b + c - g - h - j;
}

int main() {
    int a = 1;
    int b = 2;
    int c = 3;
    int total;
    total = add_something(a, b, c);
    total = sub_something(a, b, c);
    return total;
}

首先,一个线程在大多数系统上会默认有1M的栈内存,这个大小可以通过配置修改。也就是一个线程创建的时候,默认就会先申请1M的栈内存。

有些同学可能会觉得,1M 是不是有点小,如果定义了太多的局部变量,用完这 1M 怎么办?用完了就会报错,如果你的程序访问了 1M 地址之外的内存,就会报 segment fault 错误。

我们知道,函数调用会先 压栈,然后再弹栈,但是还有一个地方也会用到栈内存,就是局部变量,你每创建一个局部变量,栈就会变得更小一点。

首先,栈内存的访问通常是由两个寄存器控制的。如下:

1,esp ,栈寄存器,存储的是当前的栈地址,会随着代码运行不断地变化

2,ebp,栈顶寄存器,存储的是栈顶的地址,变化较少。

现在反汇编一下上面的代码,如下:

可以看到,进入 add_something 函数的时候,入口那里,有个 sub 指令,这个指令会直接切走一块栈内存,给 局部变量用。也不仅仅是给局部变量用,也有其他用途。

我们注意看,现在 EBP 寄存器的值是 0x00B5F630,也就是 d 变量的地址是 0x00B5F630 - 4 = 0x00B5F62C ,为什么我们不需要用 free 函数释放 0x00B5F62C 地址的内存呢?我们继续断点,进入 sub_something 函数,就清楚了,如下:

可以看到,g 变量的内存地址也是 0x00B5F630 - 4 = 0x00B5F62C,所以当 sub_something 执行的时候,之前 add_something 函数里面的 局部变量 d,e,f 指向的内存就会被覆盖。

所以栈内存,是一个可以不断重复使用的内存。所以局部变量不需要释放,只要离开了函数的作用域,之前的局部变量内存就会被重新覆盖使用。

扩展知识:函数调用,压栈,弹栈,会不断修改恢复 ebp 跟 esp所以栈内存能不断被重复使用main 也是一个函数,main 的外面其实还有一层函数调它。


下面开始介绍一下 FFmpeg 跟内存相关的函数,如下:

1,av_frame_alloc,创建一个 AVFrame 结构的堆内存。对应 av_frame_free

2,av_packet_alloc,创建一个 AVPacket 结构的堆内存。对应 av_packet_free

3,avformat_alloc_context,创建一个 AVFormatContext 结构的堆内存。对应 avformat_close_input 或者 avformat_free_context

4,avcodec_alloc_context3,创建一个 AVCodecContext 结构的堆内存。对应 avcodec_close 或者 avcodec_free_context

5,av_malloc,申请内存。对应 av_free 跟 av_freep ,其中 av_freep 函数接受的是二级指针,所以会把指针置为 NULL。这样做可以减少错误。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Loken2020

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值