foreword
This article mainly introduces some methods that are often used in ffmpeg and some commonly used structures. This article will be continuously improved in the series process. If you find that this article is still very simple, don't worry, it will be enriched gradually.
memory allocation method
Memory management is always the essence of c. Even though it has been criticized by countless people and has killed generations of programmers, it is still so attractive.
av_malloc / av_mallocz
This is a method that often appears in ffmpeg to allocate memory space. Defined in the mem.c file
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;
}
The method looks complicated, but in fact it is mostly multi-platform processing code, and the actual effect is probably to call memalign (the memory block address returned by malloc or realloc is a multiple of 8 (if it is a 64-bit system, it is a multiple of 16) .If you need larger granularity, please use memalign or valloc.) to allocate memory space of specified size.
The av_mallocz method is to set all the allocated memory space to 0 on the basis of av_malloc.
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;
}
It is used to reallocate the memory size, which is equivalent to realloc. The difference is that some operations are performed on the size when allocating. Suppose my size is 110101, then! size is 1010, and after adding it, it is 111111, which becomes an exponential multiple of 2. Equivalent to it.
av_realloc_f has a similar function. It will multiply the two small values represented by size_t, and then call av_realloc to reallocate.
av_reallocp is to copy the contents of the original memory, and then use av_realoc to allocate memory. After the allocation is complete, copy the original memory back.
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 means that it is actually free, freeing memory.
The role of av_freep is to free the memory and set the pointer to NULL.
common structure
AVCodec
Represents a decoder or encoder component.
AVOutputFormat
Describes a muxer component.
AVInputFormat
Describes a demuxer component.
URLProtocol
Describe a protocol, such as file protocol, such as rtsp protocol, etc.