[MPlayer-dev-eng] New audio filter layer finished
Arpi
arpi at thot.banki.hu
Thu Oct 3 00:25:17 CEST 2002
Hi,
> > > now, the problems.
> > > i've tried to play the matrix 1 trailer .vob (2.0ch 48khz ac3) wiht -srate
> > > 44100 and i got strange noise, clicks sometimes.
ok i've found this one as well... you won't believe.. or yes?
yes. it's the good old sample size problem...
i wonder why is this basic design issue still there in new libaf ?
ok i've added the workaround to my code, for now it works fine:
// round to whole samples:
declen/=sh_audio->samplesize*sh_audio->channels;
declen*=sh_audio->samplesize*sh_audio->channels;
actually this should be done at least in af_inputlen(), or better in deeper
part, maybe inside the plugins?
that af_inputlen() is buggy anyway, it gives me a number, but if i request
decoding of that number of bytes, i'll get few percent (hundreds bytes!)
bigger output than requested, causing data loss sometimes :(
ok here's teh enw patch, works fine for me, but still no mencoder.c mods:
Index: mplayer.c
===================================================================
RCS file: /cvsroot/mplayer/main/mplayer.c,v
retrieving revision 1.585
diff -u -r1.585 mplayer.c
--- mplayer.c 2 Oct 2002 13:16:03 -0000 1.585
+++ mplayer.c 2 Oct 2002 22:15:38 -0000
@@ -1237,6 +1237,7 @@
if(!(audio_out=init_best_audio_out(audio_driver_list,
(ao_plugin_cfg.plugin_list), // plugin flag
force_srate?force_srate:sh_audio->samplerate,
+ audio_output_channels?audio_output_channels:
sh_audio->channels,sh_audio->sample_format,0))){
// FAILED:
mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_CannotInitAO);
@@ -1253,6 +1254,14 @@
audio_out->info->name, audio_out->info->author);
if(strlen(audio_out->info->comment) > 0)
mp_msg(MSGT_CPLAYER,MSGL_V,MSGTR_AOComment, audio_out->info->comment);
+ // init audio filters:
+ if(!init_audio_filters(sh_audio,
+ ao_data.samplerate, ao_data.channels, ao_data.format,
+ audio_out_format_bits(ao_data.format)/8, /* ao_data.bps, */
+ ao_data.outburst*4, ao_data.buffersize)){
+ mp_msg(MSGT_CPLAYER,MSGL_ERR,"Couldn't find matching filter / ao format, -> nosound\n");
+ sh_audio=d_audio->sh=NULL; // -> nosound
+ }
}
}
@@ -1338,24 +1347,24 @@
// Fill buffer if needed:
current_module="decode_audio"; // Enter AUDIO decoder module
t=GetTimer();
- while(sh_audio->a_buffer_len<playsize && !d_audio->eof){
- int ret=decode_audio(sh_audio,&sh_audio->a_buffer[sh_audio->a_buffer_len],
- playsize-sh_audio->a_buffer_len,sh_audio->a_buffer_size-sh_audio->a_buffer_len);
+ while(sh_audio->a_out_buffer_len<playsize && !d_audio->eof){
+ int ret=decode_audio(sh_audio,&sh_audio->a_out_buffer[sh_audio->a_out_buffer_len],
+ playsize-sh_audio->a_out_buffer_len,sh_audio->a_out_buffer_size-sh_audio->a_out_buffer_len);
if(ret<=0) break; // EOF?
- sh_audio->a_buffer_len+=ret;
+ sh_audio->a_out_buffer_len+=ret;
}
t=GetTimer()-t;
tt = t*0.000001f; audio_time_usage+=tt;
- if(playsize>sh_audio->a_buffer_len) playsize=sh_audio->a_buffer_len;
+ if(playsize>sh_audio->a_out_buffer_len) playsize=sh_audio->a_out_buffer_len;
// play audio:
current_module="play_audio";
- playsize=audio_out->play(sh_audio->a_buffer,playsize,0);
+ playsize=audio_out->play(sh_audio->a_out_buffer,playsize,0);
if(playsize>0){
- sh_audio->a_buffer_len-=playsize;
- memmove(sh_audio->a_buffer,&sh_audio->a_buffer[playsize],sh_audio->a_buffer_len);
- sh_audio->timer+=playsize/(float)(sh_audio->o_bps);
+ sh_audio->a_out_buffer_len-=playsize;
+ memmove(sh_audio->a_out_buffer,&sh_audio->a_out_buffer[playsize],sh_audio->a_out_buffer_len);
+ sh_audio->timer+=playsize/(float)(ao_data.bps ? ao_data.bps : sh_audio->o_bps);
}
break;
Index: libmpcodecs/dec_audio.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpcodecs/dec_audio.c,v
retrieving revision 1.13
diff -u -r1.13 dec_audio.c
--- libmpcodecs/dec_audio.c 29 Sep 2002 21:52:10 -0000 1.13
+++ libmpcodecs/dec_audio.c 2 Oct 2002 22:15:39 -0000
@@ -18,6 +18,8 @@
#include "ad.h"
#include "../libao2/afmt.h"
+#include "../libaf/af.h"
+
#ifdef USE_FAKE_MONO
int fakemono=0;
#endif
@@ -221,12 +223,128 @@
sh_audio->a_in_buffer=NULL;
}
+ /* Init audio filters */
+int init_audio_filters(sh_audio_t *sh_audio,
+ 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 = sh_audio->samplerate;
+ afs->input.nch = sh_audio->channels;
+ afs->input.format = sh_audio->sample_format;
+ afs->input.bps = sh_audio->samplesize;
+
+ // 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);
+ }
+
+// if(minlen>=65536) minlen=32768;
+
+ declen=af_inputlen(sh_audio->afilter,minlen);
+
+ mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"\ndecaudio: minlen=%d maxlen=%d declen=%d (max=%d)\n",
+ minlen, maxlen, declen, sh_audio->a_buffer_size);
+
+ // limit declen to buffer size:
+ 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 :(
+
+ // 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 0; // 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)
Index: libmpcodecs/dec_audio.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpcodecs/dec_audio.h,v
retrieving revision 1.5
diff -u -r1.5 dec_audio.h
--- libmpcodecs/dec_audio.h 28 Sep 2002 02:23:20 -0000 1.5
+++ libmpcodecs/dec_audio.h 2 Oct 2002 22:15:39 -0000
@@ -9,3 +9,8 @@
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 out_samplerate, int out_channels, int out_format, int out_bps,
+ int out_minsize, int out_maxsize);
+
Index: libmpdemux/stheader.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/stheader.h,v
retrieving revision 1.33
diff -u -r1.33 stheader.h
--- libmpdemux/stheader.h 22 Sep 2002 00:43:14 -0000 1.33
+++ libmpdemux/stheader.h 2 Oct 2002 22:15:39 -0000
@@ -55,15 +55,21 @@
int o_bps; // == samplerate*samplesize*channels (uncompr. bytes/sec)
int i_bps; // == bitrate (compressed bytes/sec)
// in buffers:
- int audio_in_minsize;
+ int audio_in_minsize; // max. compressed packet size (== min. in buffer size)
char* a_in_buffer;
int a_in_buffer_len;
int a_in_buffer_size;
- // out buffers:
- int audio_out_minsize;
+ // decoder buffers:
+ int audio_out_minsize; // max. uncompressed packet size (==min. out buffsize)
char* a_buffer;
int a_buffer_len;
int a_buffer_size;
+ // output buffers:
+ char* a_out_buffer;
+ int a_out_buffer_len;
+ int a_out_buffer_size;
+// void* audio_out; // the audio_out handle, used for this audio stream
+ void* afilter; // the audio filter stream
// win32-compatible codec parameters:
AVIStreamHeader audio;
WAVEFORMATEX* wf;
A'rpi / Astral & ESP-team
--
Developer of MPlayer, the Movie Player for Linux - http://www.MPlayerHQ.hu
More information about the MPlayer-dev-eng
mailing list