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

一、宏对齐

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


一)、宏

#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 be
uint16_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 values
int    nb    = 0;    //< a variable to keep track of the length of the array
type 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 values
int   nb    = 0;    //< a variable to keep track of the length of the array
type 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:要设置为新的最大大小的值

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

你可能感兴趣的:(ffmpeg,ffmpeg)