前言
本文主要介绍了一些在ffmpeg中经常用到的方法以及一些常用结构体,本文将会在系列过程中不断完善,如果你发现本文依然很简陋,不要着急,慢慢会丰富起来的。
内存分配方法
内存管理永远是c的精髓,即便受无数人诟病,戕害了一代代程序员,但是本身却依旧如此具有魅力。
av_malloc / av_mallocz
这是在ffmpeg中经常出现的一个方法,用于分配内存空间。定义在mem.c文件中
void *av_malloc(size_t size)
{
void *ptr = NULL;
/* let's disallow possibly ambiguous cases */
if (size > (max_alloc_size - 32))
return NULL;
#if HAVE_POSIX_MEMALIGN
if (size) //OS X on SDK 10.6 has a broken posix_memalign implementation
if (posix_memalign(&ptr, ALIGN, size))
ptr = NULL;
#elif HAVE_ALIGNED_MALLOC
ptr = _aligned_malloc(size, ALIGN);
#elif HAVE_MEMALIGN
#ifndef __DJGPP__
ptr = memalign(ALIGN, size);
#else
ptr = memalign(size, ALIGN);
#endif
/* Why 64?
* Indeed, we should align it:
* on 4 for 386
* on 16 for 486
* on 32 for 586, PPro - K6-III
* on 64 for K7 (maybe for P3 too).
* Because L1 and L2 caches are aligned on those values.
* But I don't want to code such logic here!
*/
/* Why 32?
* For AVX ASM. SSE / NEON needs only 16.
* Why not larger? Because I did not see a difference in benchmarks ...
*/
/* benchmarks with P3
* memalign(64) + 1 3071, 3051, 3032
* memalign(64) + 2 3051, 3032, 3041
* memalign(64) + 4 2911, 2896, 2915
* memalign(64) + 8 2545, 2554, 2550
* memalign(64) + 16 2543, 2572, 2563
* memalign(64) + 32 2546, 2545, 2571
* memalign(64) + 64 2570, 2533, 2558
*
* BTW, malloc seems to do 8-byte alignment by default here.
*/
#else
ptr = malloc(size);
#endif
if(!ptr && !size) {
size = 1;
ptr= av_malloc(1);
}
#if CONFIG_MEMORY_POISONING
if (ptr)
memset(ptr, FF_MEMORY_POISON, size);
#endif
return ptr;
}
void *av_mallocz(size_t size)
{
void *ptr = av_malloc(size);
if (ptr)
memset(ptr, 0, size);
return ptr;
}
方法看上去很复杂,但是实际上多是多平台处理的代码,实际作用大概就是调用memalign(malloc或realloc返回的内存块地址都是8的倍数(如果是64位系统,则为16的倍数)。如果你需要更大的粒度,请使用memalign或valloc。)来分配指定大小的内存空间。
av_mallocz 方法是在av_malloc基础上再将分配所得的内存全部空间都置为0.
av_realloc / av_realloc_f / av_reallocp
void *av_realloc(void *ptr, size_t size)
{
/* let's disallow possibly ambiguous cases */
if (size > (max_alloc_size - 32))
return NULL;
#if HAVE_ALIGNED_MALLOC
return _aligned_realloc(ptr, size + !size, ALIGN);
#else
return realloc(ptr, size + !size);
#endif
}
void *av_realloc_f(void *ptr, size_t nelem, size_t elsize)
{
size_t size;
void *r;
if (av_size_mult(elsize, nelem, &size)) {
av_free(ptr);
return NULL;
}
r = av_realloc(ptr, size);
if (!r)
av_free(ptr);
return r;
}
int av_reallocp(void *ptr, size_t size)
{
void *val;
if (!size) {
av_freep(ptr);
return 0;
}
memcpy(&val, ptr, sizeof(val));
val = av_realloc(val, size);
if (!val) {
av_freep(ptr);
return AVERROR(ENOMEM);
}
memcpy(ptr, &val, sizeof(val));
return 0;
}
用于重新分配内存大小,相当于realloc不同的是在分配的时候会对size进行一些操作。假设我的size是110101,那么!size就是 1010,相加之后就是 111111,变成了一个2的指数倍数。相当于对其了。
av_realloc_f作用类似,他会把两个size_t表示的小相乘,再调用av_realloc进行重新分配。
av_reallocp 是现将原来内存中的内容拷贝出来,再使用av_realoc进行分配内存,分配完成之后再将原来的内存拷回去。
av_free / av_freep
void av_free(void *ptr)
{
#if HAVE_ALIGNED_MALLOC
_aligned_free(ptr);
#else
free(ptr);
#endif
}
void av_freep(void *arg)
{
void *val;
memcpy(&val, arg, sizeof(val));
memcpy(arg, &(void *){ NULL }, sizeof(val));
av_free(val);
}
av_free表示其实就是free,释放内存。
av_freep的作用是释放内存,并且将指针置NULL。
常用结构体
AVCodec
表示一个解*码*器或者编码器组件。
AVOutputFormat
描述一个 muxer组件。
AVInputFormat
描述一个demuxer组件。
URLProtocol
描述一个协议,比如文件协议,比如rtsp协议等。