本文简单记录一下FFmpeg中内存操作的函数。

内存操作的常见函数位于libavutil\mem.c中。本文记录FFmpeg开发中最常使用的几个函数:av_malloc(),av_realloc(),av_mallocz(),av_calloc(),av_free(),av_freep()。

av_malloc()

av_malloc()是FFmpeg中最常见的内存分配函数。它的定义如下。

[cpp] view plain copy

  1. #define FF_MEMORY_POISON 0x2a
  2. #define ALIGN (HAVE_AVX ? 32 : 16)
  3. static size_t max_alloc_size= INT_MAX;
  4. void *av_malloc(size_t size)
  5. {
  6. void *ptr = NULL;
  7. #if CONFIG_MEMALIGN_HACK
  8. long diff;
  9. #endif
  10. /* let's disallow possibly ambiguous cases */
  11. if (size > (max_alloc_size - 32))
  12. return NULL;
  13. #if CONFIG_MEMALIGN_HACK
  14. ptr = malloc(size + ALIGN);
  15. if (!ptr)
  16. return ptr;
  17. diff              = ((~(long)ptr)&(ALIGN - 1)) + 1;
  18. ptr               = (char *)ptr + diff;
  19. ((char *)ptr)[-1] = diff;
  20. #elif HAVE_POSIX_MEMALIGN
  21. if (size) //OS X on SDK 10.6 has a broken posix_memalign implementation
  22. if (posix_memalign(&ptr, ALIGN, size))
  23. ptr = NULL;
  24. #elif HAVE_ALIGNED_MALLOC
  25. ptr = _aligned_malloc(size, ALIGN);
  26. #elif HAVE_MEMALIGN
  27. #ifndef __DJGPP__
  28. ptr = memalign(ALIGN, size);
  29. #else
  30. ptr = memalign(size, ALIGN);
  31. #endif
  32. /* Why 64?
  33. * Indeed, we should align it:
  34. *   on  4 for 386
  35. *   on 16 for 486
  36. *   on 32 for 586, PPro - K6-III
  37. *   on 64 for K7 (maybe for P3 too).
  38. * Because L1 and L2 caches are aligned on those values.
  39. * But I don't want to code such logic here!
  40. */
  41. /* Why 32?
  42. * For AVX ASM. SSE / NEON needs only 16.
  43. * Why not larger? Because I did not see a difference in benchmarks ...
  44. */
  45. /* benchmarks with P3
  46. * memalign(64) + 1          3071, 3051, 3032
  47. * memalign(64) + 2          3051, 3032, 3041
  48. * memalign(64) + 4          2911, 2896, 2915
  49. * memalign(64) + 8          2545, 2554, 2550
  50. * memalign(64) + 16         2543, 2572, 2563
  51. * memalign(64) + 32         2546, 2545, 2571
  52. * memalign(64) + 64         2570, 2533, 2558
  53. *
  54. * BTW, malloc seems to do 8-byte alignment by default here.
  55. */
  56. #else
  57. ptr = malloc(size);
  58. #endif
  59. if(!ptr && !size) {
  60. size = 1;
  61. ptr= av_malloc(1);
  62. }
  63. #if CONFIG_MEMORY_POISONING
  64. if (ptr)
  65. memset(ptr, FF_MEMORY_POISON, size);
  66. #endif
  67. return ptr;
  68. }

如果不考虑上述代码中的一大堆宏定义(即类似CONFIG_MEMALIGN_HACK这类的宏都采用默认值0),av_malloc()的代码可以简化成如下形式。

[cpp] view plain copy

  1. void *av_malloc(size_t size)
  2. {
  3. void *ptr = NULL;
  4. /* let's disallow possibly ambiguous cases */
  5. if (size > (max_alloc_size - 32))
  6. return NULL;
  7. ptr = malloc(size);
  8. if(!ptr && !size) {
  9. size = 1;
  10. ptr= av_malloc(1);
  11. }
  12. return ptr;
  13. }

可以看出,此时的av_malloc()就是简单的封装了系统函数malloc(),并做了一些错误检查工作。

关于size_t

size _t 这个类型在FFmpeg中多次出现,简单解释一下其作用。size _t是为了增强程序的可移植性而定义的。不同系统上,定义size_t可能不一样。它实际上就是unsigned int。

为什么要内存对齐?

FFmpeg内存分配方面多次涉及到“内存对齐”(memory alignment)的概念。
这方面内容在IBM的网站上有一篇文章,讲的挺通俗易懂的,在此简单转述一下。

程序员通常认为内存就是一个字节数组,每次可以一个一个字节存取内存。例如在C语言中使用char *指代“一块内存”,Java中使用byte[]指代一块内存。如下所示。

但那实际上计算机处理器却不是这样认为的。处理器相对比较“懒惰”,它会以2字节,4字节,8字节,16字节甚至32字节来存取内存。例如下图显示了以4字节为单位读写内存的处理器“看待”上述内存的方式。

上述的存取单位的大小称之为内存存取粒度。
下面看一个实例,分别从地址0,和地址1读取4个字节到寄存器。

从程序员的角度来看,读取方式如下图所示。

而2字节存取粒度的处理器的读取方式如下图所示。

可以看出2字节存取粒度的处理器从地址0读取4个字节一共读取2次;从地址1读取4个字节一共读取了3次。由于每次读取的开销是固定的,因此从地址1读取4字节的效率有所下降。

4字节存取粒度的处理器的读取方式如下图所示。

可以看出4字节存取粒度的处理器从地址0读取4个字节一共读取1次;从地址1读取4个字节一共读取了2次。从地址1读取的开销比从地址0读取多了一倍。由此可见内存不对齐对CPU的性能是有影响的。

av_realloc()

av_realloc()用于对申请的内存的大小进行调整。它的定义如下。

[cpp] view plain copy

  1. void *av_realloc(void *ptr, size_t size)
  2. {
  3. #if CONFIG_MEMALIGN_HACK
  4. int diff;
  5. #endif
  6. /* let's disallow possibly ambiguous cases */
  7. if (size > (max_alloc_size - 32))
  8. return NULL;
  9. #if CONFIG_MEMALIGN_HACK
  10. //FIXME this isn't aligned correctly, though it probably isn't needed
  11. if (!ptr)
  12. return av_malloc(size);
  13. diff = ((char *)ptr)[-1];
  14. av_assert0(diff>0 && diff<=ALIGN);
  15. ptr = realloc((char *)ptr - diff, size + diff);
  16. if (ptr)
  17. ptr = (char *)ptr + diff;
  18. return ptr;
  19. #elif HAVE_ALIGNED_MALLOC
  20. return _aligned_realloc(ptr, size + !size, ALIGN);
  21. #else
  22. return realloc(ptr, size + !size);
  23. #endif
  24. }

默认情况下(CONFIG_MEMALIGN_HACK这些宏使用默认值0)的代码:

[cpp] view plain copy

  1. void *av_realloc(void *ptr, size_t size)
  2. {
  3. /* let's disallow possibly ambiguous cases */
  4. if (size > (max_alloc_size - 32))
  5. return NULL;
  6. return realloc(ptr, size + !size);
  7. }

可以看出av_realloc()简单封装了系统的realloc()函数。

av_mallocz()

av_mallocz()可以理解为av_malloc()+zeromemory。代码如下。

[cpp] view plain copy

  1. void *av_mallocz(size_t size)
  2. {
  3. void *ptr = av_malloc(size);
  4. if (ptr)
  5. memset(ptr, 0, size);
  6. return ptr;
  7. }

从源代码可以看出av_mallocz()中调用了av_malloc()之后,又调用memset()将分配的内存设置为0。

av_calloc()

av_calloc()则是简单封装了av_mallocz(),定义如下所示。

[cpp] view plain copy

  1. void *av_calloc(size_t nmemb, size_t size)
  2. {
  3. if (size <= 0 || nmemb >= INT_MAX / size)
  4. return NULL;
  5. return av_mallocz(nmemb * size);
  6. }

从代码中可以看出,它调用av_mallocz()分配了nmemb*size个字节的内存。

av_free()

av_free()用于释放申请的内存。它的定义如下。

[cpp] view plain copy

  1. void av_free(void *ptr)
  2. {
  3. #if CONFIG_MEMALIGN_HACK
  4. if (ptr) {
  5. int v= ((char *)ptr)[-1];
  6. av_assert0(v>0 && v<=ALIGN);
  7. free((char *)ptr - v);
  8. }
  9. #elif HAVE_ALIGNED_MALLOC
  10. _aligned_free(ptr);
  11. #else
  12. free(ptr);
  13. #endif
  14. }

默认情况下(CONFIG_MEMALIGN_HACK这些宏使用默认值0)的代码:

[cpp] view plain copy

  1. void av_free(void *ptr)
  2. {
  3. free(ptr);
  4. }

可以看出av_free()简单的封装了free()。

av_freep()

av_freep()简单封装了av_free()。并且在释放内存之后将目标指针设置为NULL。

[cpp] view plain copy

  1. void av_freep(void *arg)
  2. {
  3. void **ptr = (void **)arg;
  4. av_free(*ptr);
  5. *ptr = NULL;
  6. }

--------------------- 本文来自 嵌入式挖掘机 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/handsomehong/article/details/73732393?utm_source=copy

FFmpeg内存的分配和释放---av_malloc()、av_free()等相关推荐

  1. FFmpeg源代码简单分析:内存的分配和释放(av_malloc()、av_free()等)

    ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...

  2. FFmpeg源代码简单分析-通用- 内存的分配和释放(av_malloc()、av_free()等)

    参考链接 FFmpeg源代码简单分析:内存的分配和释放(av_malloc().av_free()等)_雷霄骅的博客-CSDN博客_av_malloc 内容介绍 内存操作的常见函数位于libavuti ...

  3. java怎么释放分配的内存,linux 内存的分配和释放,linux分配释放

    linux 内存的分配和释放,linux分配释放 了解内存分配机制(共享映射与请求分页) 通过 pmap 命令,可以获取用户进程逻辑地址空间中映射的内存信息: pmap -x $pid 其中 -x 表 ...

  4. 结构体的使用和动态内存的分配及释放

    结构体 什么是结构体?结构体是用户根据实际需要自己定义的复合数据类型.结构体的出现是为了表示一些复杂的数据,而普通的数据类型无法满足要求. 结构体的定义: struct Student //struc ...

  5. ffmpeg源代码处理流程分析_FFmpeg源代码简单分析:内存的分配和释放

    内存操作的常见函数位于libavutil\mem.c中.本文记录FFmpeg开发中最常使用的几个函数:av_malloc(),av_realloc(),av_mallocz(),av_calloc() ...

  6. 如何简化临时内存的分配与释放

    描述:在编制 C++ 程序时,最常遇到的一个令人恼火的问题便是临时资源的分配与释放问题, 由于程序的逻辑关系通常很复杂,引发异常的可能性也很多,为了妥善处理运行时异常, 我们不得不在可能引发异常的任何 ...

  7. 动态内存的分配与释放

    1.new与delete运算 c++提供了两个中重要的运算符:new和delete.由于他们是运算符不是函数,因此执行效率更高. 运算符 功能 目 结合性 用法 new[] 动态分配 单目 自右向左 ...

  8. 比大小,人类智慧天花板,任意类型,任意个数。内容包含函数模板的创建,类的创建,动态内存的分配与释放,函数调用指针的用法。牵扯多个知识点。

    比大小,看这一篇就足够,大家好,我是姜姜一名热爱C++编程的大学生,接下来我将通过代码演示如何利用C++实现任意类型,任意个数的比大小,并且找出最大的数. 由于本人比较懒,所有没写注释还请各位读者多多 ...

  9. 利用二叉树的思想来实现分配和释放内存方法

    虽然大部分系统都有提供内存动态分配和释放函数(即C语言中的malloc和free函数),但是在嵌入式开发中由于系统的限制往往需要自己来实现内存管理,如在有些平台上可动态申请的最大空间不能满足程序设计的 ...

最新文章

  1. 2022-2028年中国氟硅橡胶产业发展动态及投资前景分析报告
  2. 人生哲理 |南怀瑾最经典的50句话
  3. SpringBoot整合kafka(实现producer和consumer)
  4. android studio简易记账本,Android记账本
  5. ueditor如何设置上传图片的高度宽度_上百张图片上传并对齐,你加班2小时没搞定,同事简单三步就完成...
  6. 2019年全球最受欢迎数据库新鲜出炉,你猜中了吗?
  7. 什么是.Net的异步机制(异步Stream读/写) - step 4
  8. 数据结构例程——哈希表及其运算的实现
  9. 通俗易懂!视觉slam第十一部分——线性系统和卡尔曼滤波
  10. 此计算机上的windows防火墙阻止了远程调试_除了防火墙,用PowerShell命令也可以屏蔽网站,这个方法更简单...
  11. python一个函数调用另一个函数_python下如何在目录下让Python文件去调用另一个文件内的函数或类...
  12. 修改Docker镜像源地址为网易镜像源地址
  13. 搜索引擎开发需要用到什么技术?
  14. python dataframe修改_pandas DataFrame的修改方法
  15. PC电脑版微信聊天记录迁移方法
  16. why python?
  17. npm安装依赖报错——npm ERR gyp verb cli的解决方法 Node Sass version 7.0.1 is incompatible with ^4.0.0. 因为在此系统上禁止运
  18. 使用TL-WDN5200H无线网卡
  19. 常见格式浏览器在线预览
  20. 【权威榜单发布】CB Insights AI 100 - Jina AI 上榜啦!

热门文章

  1. 关于58同城自媒体号注册的链接问题!
  2. 缘起|蚂蚁应用级服务发现的实践之路
  3. Redis 非关系型数据库 安装以及相关命令
  4. SEM百分比分析,你会吗?
  5. android手机短信息中心设置
  6. 无监督学习与有监督学习的本质差异是什么_机器学习入门:有监督、无监督和强化学习都是什么,有什么差别?...
  7. Cocos2d-x 3.2 大富翁游戏项目开发-第十三部分 购买空地
  8. ANN-CA学习记录
  9. 餐饮连锁收银系统总结会议——对合作做事情的思考
  10. MySQL like查询后置%索引失效分析