[MPlayer-dev-eng] [PATCH] current pl_surround in mplayer CVS breaks playlist
Kis Gergely
kisg at lme.linux.hu
Sat Apr 6 22:55:19 CEST 2002
2002-04-06, szo keltezéssel Felix Buenemann ezt írta:
> On Saturday 06 April 2002 15:41, Kis Gergely wrote:
> > Actually it tries to free() an already freed buffer in
> > pl_surround.control(). The attached patch solves the problem.
> thx, commited.
>
> Btw. is the extrasurround stuff now stable and ready to be commited? What is
> the last patch for it?
Well, I currently fight with ao_plugin.c
I attach three patches.
The first patch fixes a bug in ao_plugin.c. ao_plugin_local_data.len was
not set to 0 on init and on uninit. This caused problems when using
playlists.
The second patch is the newest extrasurround patch (pl_surround.c).
Changes:
->updated to current pl_surround.c
->subwoofer cutoff freq is set to 300 Hz. (After consulting with a more
competent friend of mine.)
If you compile mplayer, and try it out, it won't work. I tried to
compile both in debug and normal mode, with gcc 2.95.4 (Debian
prerelease) and gcc 3.0.4
The problem is the previously described "real databuf len" - 1 bug.
There is a workaround for that (look for Anders' mail).
BUT:
If you now apply the third patch, which only adds some fprintfs for
debug purposes and recompile, it works!!!
Now that's an X-file for me. I must be lame, or just found a compiler
bug in both 2.95.4 and 3.0.4... I think the first version is more
likely...:-(
Could somebody please enlighten me?
Or at least reproduce?
Thanks,
kisg
-------------- next part --------------
--- ao_plugin.c.orig Fri Apr 5 10:16:13 2002
+++ ao_plugin.c Sat Apr 6 21:21:31 2002
@@ -172,6 +172,7 @@
if(ao_plugin_local_data.buf)
free(ao_plugin_local_data.buf);
ao_plugin_local_data.buf=malloc(MAX_OUTBURST);
+ ao_plugin_local_data.len=0;
if(!ao_plugin_local_data.buf) return 0;
@@ -190,6 +191,7 @@
if(ao_plugin_local_data.buf)
free(ao_plugin_local_data.buf);
ao_plugin_local_data.buf=NULL;
+ ao_plugin_local_data.len=0;
}
// stop playing and empty buffers (for seeking/pause)
-------------- next part --------------
--- pl_surround.c.orig Sat Apr 6 19:10:52 2002
+++ pl_surround.c Sat Apr 6 22:53:17 2002
@@ -64,6 +64,7 @@
int passthrough; // Just be a "NO-OP"
int msecs; // Rear channel delay in milliseconds
int16_t* databuf; // Output audio buffer
+ int databuf_len; // Output audio buffer length in samples
int16_t* Ls_delaybuf; // circular buffer to be used for delaying Ls audio
int16_t* Rs_delaybuf; // circular buffer to be used for delaying Rs audio
int delaybuf_len; // delaybuf buffer length in samples
@@ -72,10 +73,16 @@
int rate; // input data rate
int format; // input format
int input_channels; // input channels
+ int output_channels; // output channels
+ float lowp_cutoff; // cutoff freq for the lowpass filter
+ double lowp_A, lowp_B; // parameters for lowpass filter
+ double lowp_outm1; // output for lowpass filter (??)
} pl_surround_t;
-static pl_surround_t pl_surround={0,20,NULL,NULL,NULL,0,0,NULL,0,0,0};
+static pl_surround_t pl_surround={0,20,NULL,0,NULL,NULL,0,0,NULL,0,0,0,0,0,0,0,0};
+
+extern int audio_output_channels;
// to set/get/query special features/parameters
static int control(int cmd,int arg){
@@ -89,9 +96,20 @@
free(pl_surround.databuf); pl_surround.databuf = NULL;
}
// Allocate output buffer
- pl_surround.databuf = calloc(ao_plugin_data.len, 1);
+
+ fprintf(stderr, "pl_surround: We can produce: audio_plugin_data.len = %d\n",ao_plugin_data.len);
+
+ pl_surround.databuf_len = ao_plugin_data.len / sizeof(int16_t) / pl_surround.output_channels;
+
+ fprintf(stderr, "pl_surround: This means pl_surround.databuf_len = %d\n",pl_surround.databuf_len);
+
+ pl_surround.databuf = calloc(pl_surround.databuf_len*pl_surround.output_channels, sizeof(int16_t));
// Return back smaller len so we don't get overflowed...
- ao_plugin_data.len /= 2;
+ // ao_plugin_data.len /= 2;
+ ao_plugin_data.len = pl_surround.databuf_len * sizeof(int16_t) * pl_surround.input_channels;
+
+ fprintf(stderr, "pl_surround: We can receive: audio_plugin_data.len = %d\n",ao_plugin_data.len);
+
return CONTROL_OK;
}
return -1;
@@ -113,6 +131,12 @@
return 1;
}
+ if (audio_output_channels != 4 && audio_output_channels != 6) {
+ fprintf(stderr, "pl_surround: I'm dumb and can only output 4 or 6 channel sound, using passtrough mode\n");
+ pl_surround.passthrough = 1;
+ return 1;
+ }
+
pl_surround.passthrough = 0;
/* Store info on input format to expect */
@@ -120,9 +144,16 @@
pl_surround.format=ao_plugin_data.format;
pl_surround.input_channels=ao_plugin_data.channels;
+ /* Store info on output channel number */
+ pl_surround.output_channels = audio_output_channels;
+
+
// Input 2 channels, output will be 4 - tell ao_plugin
- ao_plugin_data.channels = 4;
- ao_plugin_data.sz_mult /= 2;
+// ao_plugin_data.channels = 4;
+// ao_plugin_data.sz_mult /= 2;
+
+ ao_plugin_data.channels = pl_surround.output_channels;
+ ao_plugin_data.sz_mult /= pl_surround.output_channels / pl_surround.input_channels;
// Figure out buffer space (in int16_ts) needed for the 15msec delay
// Extra 31 samples allow for lowpass filter delay (taps-1)
@@ -137,6 +168,16 @@
pl_surround.filter_coefs_surround = calc_coefficients_7kHz_lowpass(pl_surround.rate);
//dump_filter_coefficients(pl_surround.filter_coefs_surround);
//testfilter(pl_surround.filter_coefs_surround, 32, pl_surround.rate);
+
+ pl_surround.lowp_cutoff = 300;
+ if (pl_surround.lowp_cutoff > pl_surround.rate / 2) {
+ // Cutoff rate must be < sample rate / 2 (Nyquist rate)
+ pl_surround.lowp_cutoff = pl_surround.rate / 2 - 1;
+ }
+ pl_surround.lowp_B = exp ((-2.0 * M_PI * (pl_surround.lowp_cutoff / pl_surround.rate)));
+ pl_surround.lowp_A = 1 - pl_surround.lowp_B;
+ pl_surround.lowp_outm1 = 0.0;
+
return 1;
}
@@ -163,6 +204,7 @@
pl_surround.delaybuf_pos = 0;
memset(pl_surround.Ls_delaybuf, 0, sizeof(int16_t)*pl_surround.delaybuf_len);
memset(pl_surround.Rs_delaybuf, 0, sizeof(int16_t)*pl_surround.delaybuf_len);
+ pl_surround.lowp_outm1 = 0;
}
// The beginnings of an active matrix...
@@ -183,11 +225,11 @@
if (pl_surround.passthrough) return 1;
- // fprintf(stderr, "pl_surround: play %d bytes, %d samples\n", ao_plugin_data.len, samples);
samples = ao_plugin_data.len / sizeof(int16_t) / pl_surround.input_channels;
out = pl_surround.databuf; in = (int16_t *)ao_plugin_data.data;
+ fprintf(stderr, "pl_surround: play %d bytes, %d samples\n", ao_plugin_data.len, samples);
// Testing - place a 1kHz tone on Lt and Rt in anti-phase: should decode in S
//sinewave(in, samples, pl_surround.input_channels, 1000, 0.0, pl_surround.rate);
//sinewave(&in[1], samples, pl_surround.input_channels, 1000, PI, pl_surround.rate);
@@ -224,6 +266,26 @@
#else
out[3] = -out[2];
#endif
+ if (pl_surround.output_channels == 6) {
+
+ int32_t avg;
+ double d;
+ avg = (out[0] + out[1]) / 2;
+
+ d = pl_surround.lowp_A * avg + pl_surround.lowp_B * pl_surround.lowp_outm1;
+
+ if (d > 32767L) {
+ d = 32767L;
+ }
+ if (d < -32768L) {
+ d = -32768L;
+ }
+ pl_surround.lowp_outm1 = d;
+ out[5] = d;
+ // Only 4.1 output, center speaker remains silent
+ out[4] = 0;
+ }
+
// calculate and save surround for 20msecs time
#ifdef SPLITREAR
pl_surround.Ls_delaybuf[pl_surround.delaybuf_pos] =
@@ -237,7 +299,7 @@
pl_surround.delaybuf_pos %= pl_surround.delaybuf_len;
// next samples...
- in = &in[pl_surround.input_channels]; out = &out[4];
+ in = &in[pl_surround.input_channels]; out = &out[pl_surround.output_channels];
}
// Show some state
@@ -245,6 +307,6 @@
// Set output block/len
ao_plugin_data.data=pl_surround.databuf;
- ao_plugin_data.len=samples*sizeof(int16_t)*4;
+ ao_plugin_data.len=samples*sizeof(int16_t)*pl_surround.output_channels;
return 1;
}
-------------- next part --------------
--- ao_plugin.c.bugfix1 Sat Apr 6 21:21:31 2002
+++ ao_plugin.c Sat Apr 6 22:24:17 2002
@@ -216,10 +216,17 @@
// return: how many bytes can be played without blocking
static int get_space(){
double sz=(double)(driver()->get_space());
- if(sz+(double)ao_plugin_local_data.len > (double)MAX_OUTBURST)
+ fprintf(stderr,"ao_plugin: get_space(): Output driver says %f free space\n",sz);
+ fprintf(stderr,"ao_plugin: get_space(): ao_plugin_local_data.len says %f\n",(double)ao_plugin_local_data.len);
+ if(sz+(double)ao_plugin_local_data.len > (double)MAX_OUTBURST) {
+ fprintf(stderr,"ao_plugin: get_space(): sz+localbuffer length is > MAX_OUTBURST\n");
sz=(double)MAX_OUTBURST-(double)ao_plugin_local_data.len;
+ fprintf(stderr,"ao_plugin: get_space(): sz=MAX_OUTBURST - localdata.len = %f\n",sz);
+ }
sz*=ao_plugin_data.sz_mult;
+ fprintf(stderr,"ao_plugin: get_space(): sz*sz_mult = %f\n",sz);
sz+=ao_plugin_data.sz_fix;
+ fprintf(stderr,"ao_plugin: get_space(): sz+sz_fix = %f\n",sz);
return (int)(sz);
}
@@ -230,6 +237,7 @@
// Limit length to avoid over flow in plugins
int tmp = get_space();
int ret_len =(tmp<len)?tmp:len;
+ fprintf(stderr,"ao_plugin: play(): len = %d\n",len);
if(ret_len){
// Filter data
ao_plugin_data.len=ret_len;
More information about the MPlayer-dev-eng
mailing list