diff options
author | arpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2002-10-05 22:55:45 +0000 |
---|---|---|
committer | arpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2002-10-05 22:55:45 +0000 |
commit | 3053a8b7f248363d7f47c5718e1b292b7f974960 (patch) | |
tree | da0af1c1ba6b9dc2872aa7aa85f4d5ad88b10f6e /libmpcodecs | |
parent | 18e342e06c5e756bfa8e2de056ab716bd590a5a9 (diff) | |
download | mpv-3053a8b7f248363d7f47c5718e1b292b7f974960.tar.bz2 mpv-3053a8b7f248363d7f47c5718e1b292b7f974960.tar.xz |
aufio filter layer (libaf) integration to libmpcodecs, mplayer and mencoder
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@7605 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpcodecs')
-rw-r--r-- | libmpcodecs/dec_audio.c | 138 | ||||
-rw-r--r-- | libmpcodecs/dec_audio.h | 5 |
2 files changed, 140 insertions, 3 deletions
diff --git a/libmpcodecs/dec_audio.c b/libmpcodecs/dec_audio.c index 29ceefbf5b..51353ed0b2 100644 --- a/libmpcodecs/dec_audio.c +++ b/libmpcodecs/dec_audio.c @@ -18,6 +18,8 @@ extern int verbose; // defined in mplayer.c #include "ad.h" #include "../libao2/afmt.h" +#include "../libaf/af.h" + #ifdef USE_FAKE_MONO int fakemono=0; #endif @@ -118,6 +120,10 @@ int init_audio_codec(sh_audio_t *sh_audio) sh_audio->samplerate,sh_audio->channels, sh_audio->samplesize*8,sh_audio->sample_format, sh_audio->i_bps,sh_audio->o_bps,sh_audio->i_bps*8*0.001); + + sh_audio->a_out_buffer_size=sh_audio->a_buffer_size; + sh_audio->a_out_buffer=sh_audio->a_buffer; + sh_audio->a_out_buffer_len=sh_audio->a_buffer_len; return 1; } @@ -210,23 +216,149 @@ return 1; // success void uninit_audio(sh_audio_t *sh_audio) { + if(sh_audio->afilter){ + mp_msg(MSGT_DECAUDIO,MSGL_V,"Uninit audio filters...\n"); + af_uninit(sh_audio->afilter); + sh_audio->afilter=NULL; + } if(sh_audio->inited){ mp_msg(MSGT_DECAUDIO,MSGL_V,MSGTR_UninitAudioStr,sh_audio->codec->drv); mpadec->uninit(sh_audio); sh_audio->inited=0; } + if(sh_audio->a_out_buffer!=sh_audio->a_buffer) free(sh_audio->a_out_buffer); + sh_audio->a_out_buffer=NULL; if(sh_audio->a_buffer) free(sh_audio->a_buffer); sh_audio->a_buffer=NULL; if(sh_audio->a_in_buffer) free(sh_audio->a_in_buffer); sh_audio->a_in_buffer=NULL; } + /* Init audio filters */ +int init_audio_filters(sh_audio_t *sh_audio, + int in_samplerate, int in_channels, int in_format, int in_bps, + int out_samplerate, int out_channels, int out_format, int out_bps, + int out_minsize, int out_maxsize){ + af_stream_t* afs=malloc(sizeof(af_stream_t)); + memset(afs,0,sizeof(af_stream_t)); + + // input format: same as codec's output format: + afs->input.rate = in_samplerate; + afs->input.nch = in_channels; + afs->input.format = in_format; + afs->input.bps = in_bps; + + // output format: same as ao driver's input format (if missing, fallback to input) + afs->output.rate = out_samplerate ? out_samplerate : afs->input.rate; + afs->output.nch = out_channels ? out_channels : afs->input.nch; + afs->output.format = out_format ? out_format : afs->input.format; + afs->output.bps = out_bps ? out_bps : afs->input.bps; + + // filter config: + afs->cfg.force = 0; + afs->cfg.list = NULL; + + mp_msg(MSGT_DECAUDIO, MSGL_INFO, "Building audio filter chain for %dHz/%dch/%dbit -> %dHz/%dch/%dbit...\n", + afs->input.rate,afs->input.nch,afs->input.bps*8, + afs->output.rate,afs->output.nch,afs->output.bps*8); + + // let's autoprobe it! + if(0 != af_init(afs)){ + free(afs); + return 0; // failed :( + } + + // allocate the a_out_* buffers: + if(out_maxsize<out_minsize) out_maxsize=out_minsize; + if(out_maxsize<8192) out_maxsize=MAX_OUTBURST; // not sure this is ok + + sh_audio->a_out_buffer_size=out_maxsize; + sh_audio->a_out_buffer=malloc(sh_audio->a_out_buffer_size); + memset(sh_audio->a_out_buffer,0,sh_audio->a_out_buffer_size); + sh_audio->a_out_buffer_len=0; + + // ok! + sh_audio->afilter=(void*)afs; + return 1; +} + int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen) { - if(sh_audio->inited) - return mpadec->decode_audio(sh_audio,buf,minlen,maxlen); + int declen; + af_data_t afd; // filter input + af_data_t* pafd; // filter output + + if(!sh_audio->inited) return -1; // no codec + if(!sh_audio->afilter){ + // no filter, just decode: + // FIXME: don't drop initial decoded data in a_buffer! + return mpadec->decode_audio(sh_audio,buf,minlen,maxlen); + } + +// declen=af_inputlen(sh_audio->afilter,minlen); + declen=af_calc_insize_constrained(sh_audio->afilter,minlen,maxlen, + sh_audio->a_buffer_size-sh_audio->audio_out_minsize); + + mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"\ndecaudio: minlen=%d maxlen=%d declen=%d (max=%d)\n", + minlen, maxlen, declen, sh_audio->a_buffer_size); + + if(declen<=0) return -1; // error! + + // limit declen to buffer size: - DONE by af_calc_insize_constrained +// if(declen>sh_audio->a_buffer_size) declen=sh_audio->a_buffer_size; + + // decode if needed: + while(declen>sh_audio->a_buffer_len){ + int len=declen-sh_audio->a_buffer_len; + int maxlen=sh_audio->a_buffer_size-sh_audio->a_buffer_len; + + mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"decaudio: decoding %d bytes, max: %d (%d)\n", + len, maxlen, sh_audio->audio_out_minsize); + + if(maxlen<sh_audio->audio_out_minsize) break; // don't overflow buffer! + // not enough decoded data waiting, decode 'len' bytes more: + len=mpadec->decode_audio(sh_audio, + sh_audio->a_buffer+sh_audio->a_buffer_len, len, maxlen); + if(len<=0) break; // EOF? + sh_audio->a_buffer_len+=len; + } + if(declen>sh_audio->a_buffer_len) + declen=sh_audio->a_buffer_len; // still no enough data (EOF) :( + + // round to whole samples: +// declen/=sh_audio->samplesize*sh_audio->channels; +// declen*=sh_audio->samplesize*sh_audio->channels; + + // run the filters: + afd.audio=sh_audio->a_buffer; + afd.len=declen; + afd.rate=sh_audio->samplerate; + afd.nch=sh_audio->channels; + afd.format=sh_audio->sample_format; + afd.bps=sh_audio->samplesize; + //pafd=&afd; +// printf("\nAF: %d --> ",declen); + pafd=af_play(sh_audio->afilter,&afd); +// printf("%d \n",pafd->len); + + if(!pafd) return -1; // error + + mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"decaudio: declen=%d out=%d (max %d)\n", + declen, pafd->len, maxlen); + + // copy filter==>out: + if(maxlen < pafd->len) + mp_msg(MSGT_DECAUDIO,MSGL_WARN,"%i bytes of audio data lost due to buffer overflow, len = %i", pafd->len - maxlen,pafd->len); else - return -1; + maxlen=pafd->len; + memmove(buf, pafd->audio, maxlen); + + // remove processed data from decoder buffer: + sh_audio->a_buffer_len-=declen; + if(sh_audio->a_buffer_len>0) + memmove(sh_audio->a_buffer, sh_audio->a_buffer+declen, sh_audio->a_buffer_len); + + return maxlen; } void resync_audio_stream(sh_audio_t *sh_audio) diff --git a/libmpcodecs/dec_audio.h b/libmpcodecs/dec_audio.h index d4d5b67917..cc44607dab 100644 --- a/libmpcodecs/dec_audio.h +++ b/libmpcodecs/dec_audio.h @@ -9,3 +9,8 @@ extern int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int m extern void resync_audio_stream(sh_audio_t *sh_audio); extern void skip_audio_frame(sh_audio_t *sh_audio); extern void uninit_audio(sh_audio_t *sh_audio); + +extern int init_audio_filters(sh_audio_t *sh_audio, + int in_samplerate, int in_channels, int in_format, int in_bps, + int out_samplerate, int out_channels, int out_format, int out_bps, + int out_minsize, int out_maxsize);
\ No newline at end of file |