FFMPEG学习【libavutil】:Memory Management(一)

来源:互联网 发布:汽修教学软件 编辑:程序博客网 时间:2024/05/18 01:23

一、宏对齐

帮助宏用于声明对齐变量。


一)、宏

#define DECLARE_ALIGNED(n, t, v)   t __attribute__ ((aligned (n))) v声明在内存中对齐的变量。

DECLARE_ALIGNED(16, uint16_t, aligned_int) = 42;DECLARE_ALIGNED(32, uint8_t, aligned_array)[128];// The default-alignment equivalent would beuint16_t aligned_int = 42;uint8_t aligned_array[128];
参数:n:最小对齐字节

   t:变量(或数组元素)的类型

   v:变量的名称


#define DECLARE_ASM_CONST(n, t, v)   static const t av_used __attribute__ ((aligned (n))) v声明适用于内联汇编代码的静态常量对齐变量。

DECLARE_ASM_CONST(16, uint64_t, pw_08) = UINT64_C(0x0008000800080008);

参数:n:最小对齐字节

   t:变量(或数组元素)的类型

   v:变量的名称



二、功能属性

功能属性适用于内存处理功能。

这些功能属性可以帮助编译器发出更有用的警告,或者生成更好的代码。


一)、宏

#define av_malloc_attrib   __attribute__((__malloc__))功能属性表示类似malloc的功能。


#define av_alloc_size(...)   __attribute__((alloc_size(__VA_ARGS__)))在分配内存的函数中使用的函数属性,其大小由指定的参数给出。

void *av_malloc(size_t size) av_alloc_size(1);void *av_calloc(size_t nmemb, size_t size) av_alloc_size(1, 2);
参数:...:一个或两个参数索引,用逗号分隔


三、动态数组

使数组在需要时增长的实用程序。

有时,程序员希望有一个可以在需要时增长的数组。 libavutil动态数组实用程序填补了这一点。

libavutil支持将动态分配的数组附加元素的两个系统,第一个存储指向数组中值的指针,第二个直接存储该值。 在两个系统中,调用者负责维护包含数组长度的变量,以及使用后释放数组。

第一个系统存储指向动态分配内存块中的值的指针。 由于只存储指针,所以该函数不需要知道类型的大小。 av_dynarray_add()和av_dynarray_add_nofree()都实现了这个系统。

type **array = NULL; //< an array of pointers to valuesint    nb    = 0;    //< a variable to keep track of the length of the arraytype to_be_added  = ...;type to_be_added2 = ...;av_dynarray_add(&array, &nb, &to_be_added);if (nb == 0)    return AVERROR(ENOMEM);av_dynarray_add(&array, &nb, &to_be_added2);if (nb == 0)    return AVERROR(ENOMEM);// Now://  nb           == 2// &to_be_added  == array[0]// &to_be_added2 == array[1]av_freep(&array);

第二个系统将值直接存储在一个内存块中。 因此,函数必须知道类型的大小。 av_dynarray2_add()实现这个机制。

type *array = NULL; //< an array of valuesint   nb    = 0;    //< a variable to keep track of the length of the arraytype to_be_added  = ...;type to_be_added2 = ...;type *addr = av_dynarray2_add((void **)&array, &nb, sizeof(*array), NULL);if (!addr)    return AVERROR(ENOMEM);memcpy(addr, &to_be_added, sizeof(to_be_added));// Shortcut of the above.type *addr = av_dynarray2_add((void **)&array, &nb, sizeof(*array),                              (const void *)&to_be_added2);if (!addr)    return AVERROR(ENOMEM);// Now://  nb           == 2//  to_be_added  == array[0]//  to_be_added2 == array[1]av_freep(&array);



一)、函数

void av_dynarray_add (void *tab_ptr, int *nb_ptr, void *elem)将指向元素的指针添加到动态数组。

要增长的数组应该是一个指向结构的指针数组,要添加的元素必须是指向已分配结构的指针。

当数组的大小达到2的幂时,该数组被重新分配。因此,添加元素的摊销成本是恒定的。

在成功的情况下,更新指向数组的指针,以指向新增长的数组,并且增加nb_ptr指向的数字。 如果发生故障,数组将被释放,* tab_ptr设置为NULL,并将* nb_ptr设置为0。

参数:nb_ptr:指向数组的指针增长

   nb_ptr:指向数组中的元素数

   elem:要添加的元素


av_warn_unused_result int av_dynarray_add_nofree (void *tab_ptr, int *nb_ptr, void *elem)将一个元素添加到动态数组。

函数与av_dynarray_add()具有相同的功能,但它不会释放内存失败。 它返回错误代码,并保持当前缓冲区不变。

返回:> = 0成功,否则为否


void * av_dynarray2_add (void **tab_ptr, int *nb_ptr, size_t elem_size, const uint8_t *elem_data)将大小elem_size的元素添加到动态数组。

当元素的数量达到2时,该数组被重新分配。因此,添加元素的摊销成本是不变的。

在成功的情况下,更新指向数组的指针,以指向新增长的数组,并且增加nb_ptr指向的数字。 如果发生故障,数组将被释放,* tab_ptr设置为NULL,并将* nb_ptr设置为0。

参数:tab_ptr:指向数组的指针增长

   nb_ptr:指向数组中的元素数

   elem_size:数组中元素的字节大小

   elem_data:指向要添加的元素的数据。 如果为NULL,则新添加的元素的空间将被分配但未初始化。

返回:指向要在新分配的空间中复制的元素的数据的指针



四、杂项功能

与内存分配有关的其他功能。


一)、函数

static int av_size_mult (size_t a, size_t b, size_t *r)乘以两个size_t值来检查溢出。

参数:a,b:乘法操作数

   r:指向操作结果

返回:0成功,AVERROR(EINVAL)溢出


void av_max_alloc (size_t max)设置一个块中可能分配的最大大小。

使用此函数指定的值对于所有libavutil的堆管理功能都是有效的。

默认情况下,最大值定义为INT_MAX。

参数:max:要设置为新的最大大小的值

警告:使用此函数时请格外小心。 如果您不明白这样做的全部后果,请勿触碰。

原创粉丝点击