ffmpeg源码分析 (二)

前言

    本文主要介绍了一些在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,释放内存。

扫描二维码关注公众号,回复: 110804 查看本文章

    av_freep的作用是释放内存,并且将指针置NULL。

常用结构体

AVCodec

    表示一个解*码*器或者编码器组件。

AVOutputFormat

    描述一个 muxer组件。

    

AVInputFormat

    描述一个demuxer组件。

URLProtocol

    描述一个协议,比如文件协议,比如rtsp协议等。    

猜你喜欢

转载自my.oschina.net/zzxzzg/blog/1806996