a52dec工程ao数据结构和ffmpeg工程codec数据结构比较(2007.9.14)

 a52dec工程ao数据结构和ffmpeg工程codec数据结构比较

 

关键词:

数据结构,算法,分立数据结构,集合数据结构,引用数据结构. 数组集合.

引用注册函数,集合数据结构的注册函数, 分立数据结构的注册函数,

 

1 a52 工程音频输出数据结构建立过程

1.1 数据结构的建立

typedef struct ao_instance_s ao_instance_t;

//分立数据结构

struct ao_instance_s {

    int (* setup) (ao_instance_t * instance, int sample_rate, int * flags,

                 sample_t * level, sample_t * bias);

    int (* play) (ao_instance_t * instance, int flags, sample_t * samples);

    void (* close) (ao_instance_t * instance);

};

 

typedef ao_instance_t * ao_open_t (void);

//引用数据结构

typedef struct ao_driver_s {

    char * name;

    ao_open_t * open;

} ao_driver_t;

 

  1. 定义了基本数据结构ao_instance_s和ao_driver_s. ao_instance_s内部算法包括setup, play和close. ao_driver_s中name表示该输出driver的名字. ao_open_t就是前面定义的ao_instance_s.定义了这个driver的算法的函数指针.以后使用时只要做2部注册就可以了.

1.2 数据结构的例化

extern ao_open_t ao_oss_open;

extern ao_open_t ao_ossdolby_open;

……

extern ao_open_t ao_win_open;

extern ao_open_t ao_windolby_open;

extern ao_open_t ao_wav_open;

extern ao_open_t ao_wavdolby_open;

extern ao_open_t ao_aif_open;

extern ao_open_t ao_aifdolby_open;

……

extern ao_open_t ao_float_open;

 

//集合数据结构

 

static ao_driver_t audio_out_drivers[] = {

#ifdef LIBAO_OSS

    {"oss", ao_oss_open},

……(略)

    {"oss6", ao_oss6_open},

#endif

……(略)

#ifdef LIBAO_AL

……(略)

#endif

#ifdef LIBAO_WIN

    {"win", ao_win_open},

    {"windolby", ao_windolby_open},

#endif

    {"wav", ao_wav_open},

    {"wavdolby", ao_wavdolby_open},

    {"aif", ao_aif_open},

    {"aifdolby", ao_aifdolby_open},

……(略)

    {"float", ao_float_open},

    {NULL, NULL}

};

 

1.extern ao_open_t ao_xxx_open实现了对不同driver的注册例化.这些数据结构来自libao文件夹下的C代码.在libao文件夹下定义了audio output的driver实体.

2.static ao_driver_t audio_out_drivers[]实现了使用数组把所有的driver连接到一起.并同时初始化.数组的最后一个数据是{NULL, NULL}表示dirver结束.

 

1.3 音频输出数据结构的引用.

//集合数据结构的注册函数

ao_driver_t * ao_drivers (void)

{

    return audio_out_drivers;

}

算法ao_driver_t * ao_drivers (void)实现数据结构的注册返回.表明可以使用数据结构audio_out_drivers了.

 

 

1.4   数据结构的实体

在libao文件下有各个driver的实体文件,以”wav”这个driver举例.在libao文件夹下有audio_out_wav.c整个文件负责定义ao_open_t ao_wav_open数据结构和相应的step,play,close算法.

例如:

//公共算法实体

static int wav_setup (ao_instance_t * _instance, int sample_rate, int * flags,

                    sample_t * level, sample_t * bias)

{

    wav_instance_t * instance = (wav_instance_t *) _instance;

    static int init=0;

(略)

    return 0;

}

 

static int wav_play (ao_instance_t * _instance, int flags, sample_t * _samples)

{

    wav_instance_t * instance = (wav_instance_t *) _instance;

    int16_t int16_samples[256*2];

 (略)

    return 0;

}

 

static void wav_close (ao_instance_t * _instance)

{

    wav_instance_t * instance = (wav_instance_t *) _instance;

    (略)

fclose(outfd);

}

 

使用wav_open函数注册以上三个算法到相应的数据结构wav_instance_t.

//分立数据结构的注册函数

static ao_instance_t * wav_open (int flags)

{

    wav_instance_t * instance;

    instance = malloc (sizeof (wav_instance_t));

    if (instance == NULL)

       return NULL;

 

    instance->ao.setup = wav_setup;

    instance->ao.play = wav_play;

    instance->ao.close = wav_close;

 

    instance->sample_rate = 0;

    instance->set_params = 1;

    instance->flags = flags;

    instance->size = 0;

 

    return (ao_instance_t *) instance;

}

使用ao_wav_open函数实现对注册函数的引用.

#define A52_STEREO 2

ao_instance_t * ao_wav_open (void)

{

    return wav_open (A52_STEREO);

}

 

1.5   总结

  a52dec工程ao模块的特点:使用数组建立driver集.

  数据结构特点:

  Driver 的分立数据结构ao_instance_s:定义不同driver的公共算法

  Driver 的引用数据结构ao_driver_s定义了一个名字用于引用和遍历

  Driver 的集合数据结构audio_out_drivers定义了一个数组,把所有的driver连接到一起.

 

  数据结构注册特点:

集合数据结构的注册函数: ao_driver_t * ao_drivers (void),实现audio_out_drivers的引用

分立数据结构的注册函数: ao_instance_t * wav_open (int flags)对分立driver的公共算法注册到相应的ao_instance_s结构体中.

 

公共算法的实体:

在相应的子目录下建立相应的算法实体.便于管理和修改.外部引用通过注册和extern.

 

 

 

2          ffmpeg工程codec数据结构

 

主要区别:链表建立集合数据结构

 

 

//分立数据结构,引用数据结构

//二者合一了

/**

 * AVCodec.

 */

typedef struct AVCodec {

    const char *name;

    enum CodecType type;

    enum CodecID id;

    int priv_data_size;

    int (*init)(AVCodecContext *);

    int (*encode)(AVCodecContext *, uint8_t *buf, int buf_size, void *data);

    int (*close)(AVCodecContext *);

    int (*decode)(AVCodecContext *, void *outdata, int *outdata_size,

                  uint8_t *buf, int buf_size);

    int capabilities;

#if LIBAVCODEC_VERSION_INT < ((50<<16)+(0<<8)+0)

    void *dummy; // FIXME remove next time we break binary compatibility

#endif

    struct AVCodec *next;

    void (*flush)(AVCodecContext *);

    const AVRational *supported_framerates; ///array of supported framerates, or NULL if any, array is terminated by {0,0}

    const enum PixelFormat *pix_fmts;       ///array of supported pixel formats, or NULL if unknown, array is terminanted by -1

} AVCodec;

 

  1. ffmpeg还很好的处理了不同cpu平台的问题.通过宏和dsputil_static_init();函数实现.

 

ffmpeg工程的对指针注册的方式完美应用非常值得学习.

posted @ 2012-03-10 21:18  杭州桓泽  阅读(544)  评论(0编辑  收藏  举报