summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libaf/af.c3
-rw-r--r--libaf/af.h5
-rw-r--r--libaf/af_equalizer.c2
-rw-r--r--libaf/af_lavcresample.c2
-rw-r--r--libaf/af_resample.c2
-rw-r--r--libaf/af_scaletempo.c5
-rw-r--r--mplayer.c9
7 files changed, 21 insertions, 7 deletions
diff --git a/libaf/af.c b/libaf/af.c
index 32c59dbbcd..c229f9eee6 100644
--- a/libaf/af.c
+++ b/libaf/af.c
@@ -542,7 +542,7 @@ double af_calc_filter_multiplier(af_stream_t* s)
return mul;
}
-/* Calculate the total delay [ms] caused by the filters */
+/* Calculate the total delay [bytes output] caused by the filters */
double af_calc_delay(af_stream_t* s)
{
af_instance_t* af=s->first;
@@ -550,6 +550,7 @@ double af_calc_delay(af_stream_t* s)
// Iterate through all filters
while(af){
delay += af->delay;
+ delay *= af->mul;
af=af->next;
}
return delay;
diff --git a/libaf/af.h b/libaf/af.h
index 4c983cb6e4..a4dc6f9535 100644
--- a/libaf/af.h
+++ b/libaf/af.h
@@ -54,7 +54,8 @@ typedef struct af_instance_s
af_data_t* data; // configuration for outgoing data stream
struct af_instance_s* next;
struct af_instance_s* prev;
- double delay; // Delay caused by the filter [ms]
+ double delay; /* Delay caused by the filter, in units of bytes read without
+ * corresponding output */
double mul; /* length multiplier: how much does this instance change
the length of the buffer. */
}af_instance_t;
@@ -196,7 +197,7 @@ double af_calc_filter_multiplier(af_stream_t* s);
/**
* \brief Calculate the total delay caused by the filters
- * \return delay in seconds
+ * \return delay in bytes of "missing" output
*/
double af_calc_delay(af_stream_t* s);
diff --git a/libaf/af_equalizer.c b/libaf/af_equalizer.c
index 9eb09a8188..5a92090d32 100644
--- a/libaf/af_equalizer.c
+++ b/libaf/af_equalizer.c
@@ -106,7 +106,7 @@ static int control(struct af_instance_s* af, int cmd, void* arg)
bp2(s->a[k],s->b[k],F[k]/((float)af->data->rate),Q);
// Calculate how much this plugin adds to the overall time delay
- af->delay += 2000.0/((float)af->data->rate);
+ af->delay = 2 * af->data->nch * af->data->bps;
// Calculate gain factor to prevent clipping at output
for(k=0;k<AF_NCH;k++)
diff --git a/libaf/af_lavcresample.c b/libaf/af_lavcresample.c
index f44f26cabf..026646499d 100644
--- a/libaf/af_lavcresample.c
+++ b/libaf/af_lavcresample.c
@@ -48,7 +48,7 @@ static int control(struct af_instance_s* af, int cmd, void* arg)
af->data->format = AF_FORMAT_S16_NE;
af->data->bps = 2;
af->mul = (double)af->data->rate / data->rate;
- af->delay = 500*s->filter_length/(double)min(af->data->rate, data->rate);
+ af->delay = af->data->nch * s->filter_length / min(af->mul, 1); // *bps*.5
if(s->avrctx) av_resample_close(s->avrctx);
s->avrctx= av_resample_init(af->data->rate, /*in_rate*/data->rate, s->filter_length, s->phase_shift, s->linear, s->cutoff);
diff --git a/libaf/af_resample.c b/libaf/af_resample.c
index e1bed4976b..57e2d39321 100644
--- a/libaf/af_resample.c
+++ b/libaf/af_resample.c
@@ -254,7 +254,7 @@ static int control(struct af_instance_s* af, int cmd, void* arg)
}
// Set multiplier and delay
- af->delay = (double)(1000*L/2)/((double)n->rate);
+ af->delay = 0; // not set correctly, but shouldn't be too large anyway
af->mul = (double)s->up / s->dn;
return rv;
}
diff --git a/libaf/af_scaletempo.c b/libaf/af_scaletempo.c
index 4cdde2d5c0..3ed14aec68 100644
--- a/libaf/af_scaletempo.c
+++ b/libaf/af_scaletempo.c
@@ -261,6 +261,11 @@ static af_data_t* play(struct af_instance_s* af, af_data_t* data)
offset_in += fill_queue(af, data, offset_in);
}
+ // This filter can have a negative delay when scale > 1:
+ // output corresponding to some length of input can be decided and written
+ // after receiving only a part of that input.
+ af->delay = s->bytes_queued - s->bytes_to_slide;
+
data->audio = af->data->audio;
data->len = pout - (int8_t *)af->data->audio;
return data;
diff --git a/mplayer.c b/mplayer.c
index a50e7f7694..6b7515e64b 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -1589,9 +1589,16 @@ static double written_audio_pts(sh_audio_t *sh_audio, demux_stream_t *d_audio)
// Decoded but not filtered
a_pts -= sh_audio->a_buffer_len / (double)sh_audio->o_bps;
+ // Data buffered in audio filters, measured in bytes of "missing" output
+ double buffered_output = af_calc_delay(sh_audio->afilter);
+
// Data that was ready for ao but was buffered because ao didn't fully
// accept everything to internal buffers yet
- a_pts -= sh_audio->a_out_buffer_len * playback_speed / (double)ao_data.bps;
+ buffered_output += sh_audio->a_out_buffer_len;
+
+ // Filters divide audio length by playback_speed, so multiply by it
+ // to get the length in original units without speedup or slowdown
+ a_pts -= buffered_output * playback_speed / ao_data.bps;
return a_pts;
}