U32 audioHandle = AudioDecOpen(int type) { if(type == aac) return aac_open(); else if(type == mpeg) return mpeg_open(); }
typedef int (*OpenFunc) (void *this); typedef int (*CloseFunc) (void *this); typedef int (*ControlFunc) (void *this, int command, void *param);
struct module { OpenFunc Open; CloseFunc Close; ControlFunc Control;}; struct AudioDecoder{ struct module m; int audioType; void* private; };
struct AudioPool{ int audioType; struct module* audioModule; }pool[] = { {aac , aac_module}, {mpeg , mpeg_module}, };
int AudioCreate(int type , Handle *handle) { AudioDecoder dec = alloc_audioDec(); foreach(pool , k) { if(k->audioType == type) { dec->m = k->audioModule; } } *handle = (Handle)dec; }這樣,當外界去Create一個Audio的對象時,就已經初始化好對應的函數入口了。Open就非常簡單了:
int AudioOpen(struct AudioDecoder *dec) { return dec->m->Open(dec); }其中AudioDecoder中的Private 則是在各自的Open中自己申請,自己釋放,Close,Control 類似。
struct AudioPool{ int audioType; struct module* audioModule; }pool[MAX_POOL];
int Pool_Register(int type , struct module* module); { for_each(pool , k) { if(k->type == INVALID_AUDIO_TYPE) { k->type = type; k->audioModule = module; } } if(k == NULL) { return REACH_POOL_END; } return NO_ERROR; }
. . . static int Close(void *this) { AudioSoftDecoder *ad = (AudioSoftDecoder*)this; if(!ad || !ad->privateData) { syslog(LOG_ERR , "%s(%d):Bad Parameter !!!\n" , __FUNCTION__ , __LINE__ ); return CT_ERROR_BAD_PARAMETER; } AacFaadPrivate *private = (AacFaadPrivate *)ad->privateData; private->exit = TRUE; if(private->decoderPid > 0) { pthread_join(private->decoderPid , NULL); } if(private->hDecoder) { NeAACDecClose(private->hDecoder); } free(private); ad->privateData = NULL; return CT_ERROR_NO_ERROR; } int AAC_Init() { return RegisterAudioSoftDec(AudioDecType_AAC ,&aacModule); }
. . . int Close(void *this) { AudioSoftDecoder *ad = (AudioSoftDecoder*)this; if(!ad || !ad->privateData) { syslog(LOG_ERR , "%s(%d):Bad Parameter !!!\n" , __FUNCTION__ , __LINE__ ); return CT_ERROR_BAD_PARAMETER; } mpegMadPrivate *private = (mpegMadPrivate *)ad->privateData; private->exit = TRUE; if(private->decoderPid > 0) { pthread_join(private->decoderPid , NULL); } mad_decoder_finish(&private->decoder); if(private->data.buffer) { free(private->data.buffer); } free(private); ad->privateData = NULL; return CT_ERROR_NO_ERROR; } int Control(void *this , U32 cmd ,void* param) { return CT_ERROR_NO_ERROR; } int MPEG_Init() { return RegisterAudioSoftDec(AudioDecType_MPEG ,&mpegModule); }