[vlc-devel] [PATCH 1/2] scaletempo: fix pts/length
Thomas Guillem
thomas at gllm.fr
Thu Feb 28 15:45:52 CET 2019
The output block PTS/length was wrongly set to the PTS/length of the last input
block. This could cause a PTS delay when the filter needed more than one input
block to return an output one. Example: with a rate of 4, the filter
(approximately) returned 3 time a NULL buffer, and used the PTS/length of the
4th one. This caused a PTS delay of 4 * block->i_length.
The returned PTS/length correspond now exactly to what the filer module wrote.
---
modules/audio_filter/scaletempo.c | 28 +++++++++++++++++++++++++---
1 file changed, 25 insertions(+), 3 deletions(-)
diff --git a/modules/audio_filter/scaletempo.c b/modules/audio_filter/scaletempo.c
index 3f47a76ae7..c7fc621796 100644
--- a/modules/audio_filter/scaletempo.c
+++ b/modules/audio_filter/scaletempo.c
@@ -43,6 +43,7 @@
static int Open( vlc_object_t * );
static void Close( vlc_object_t * );
static block_t *DoWork( filter_t *, block_t * );
+static void Flush( filter_t * );
#ifdef PITCH_SHIFTER
static int OpenPitch( vlc_object_t * );
@@ -129,6 +130,8 @@ typedef struct
void *buf_pre_corr;
void *table_window;
unsigned(*best_overlap_offset)( filter_t *p_filter );
+
+ date_t pts;
#ifdef PITCH_SHIFTER
/* pitch */
filter_t * resampler;
@@ -434,6 +437,7 @@ static int Open( vlc_object_t *p_this )
p_sys->bytes_queued = 0;
p_sys->bytes_to_slide = 0;
p_sys->frames_stride_error = 0;
+ date_Init( &p_sys->pts, p_sys->sample_rate, 1 );
if( reinit_buffers( p_filter ) != VLC_SUCCESS )
{
@@ -445,6 +449,7 @@ static int Open( vlc_object_t *p_this )
aout_FormatPrepare(&p_filter->fmt_in.audio);
p_filter->fmt_out.audio = p_filter->fmt_in.audio;
p_filter->pf_audio_filter = DoWork;
+ p_filter->pf_flush = Flush;
return VLC_SUCCESS;
}
@@ -552,7 +557,11 @@ static block_t *DoWork( filter_t * p_filter, block_t * p_in_buf )
filter_sys_t *p = p_filter->p_sys;
if( p_filter->fmt_in.audio.i_rate == p->sample_rate )
+ {
+ if( date_Get( &p->pts) != VLC_TICK_INVALID )
+ date_Set( &p->pts, VLC_TICK_INVALID );
return p_in_buf;
+ }
double scale = p_filter->fmt_in.audio.i_rate / (double)p->sample_rate;
if( scale != p->scale ) {
@@ -565,6 +574,9 @@ static block_t *DoWork( filter_t * p_filter, block_t * p_in_buf )
(int)( p->bytes_stride / p->bytes_per_frame ), p->sample_rate );
}
+ if( date_Get( &p->pts) == VLC_TICK_INVALID )
+ date_Set( &p->pts, p_in_buf->i_pts );
+
block_t *p_out_buf = NULL;
size_t i_outsize = calculate_output_buffer_size ( p_filter, p_in_buf->i_buffer );
@@ -587,11 +599,14 @@ static block_t *DoWork( filter_t * p_filter, block_t * p_in_buf )
offset_in += fill_queue( p_filter, p_in_buf->p_buffer,
p_in_buf->i_buffer, offset_in );
}
+
p_out_buf->i_buffer = bytes_out;
p_out_buf->i_nb_samples = bytes_out / p->bytes_per_frame;
- p_out_buf->i_dts = p_in_buf->i_dts;
- p_out_buf->i_pts = p_in_buf->i_pts;
- p_out_buf->i_length = p_in_buf->i_length;
+ p_out_buf->i_length =
+ vlc_tick_from_samples(p_out_buf->i_nb_samples, p->sample_rate);
+ p_out_buf->i_dts = p_out_buf->i_pts = date_Get( &p->pts );
+ date_Increment( &p->pts, p_out_buf->i_nb_samples );
+ assert( p_out_buf->i_pts + p_out_buf->i_length == date_Get( &p->pts ) );
}
block_Release( p_in_buf );
@@ -616,3 +631,10 @@ static block_t *DoPitchWork( filter_t * p_filter, block_t * p_in_buf )
return DoWork( p_filter, p_in_buf );
}
#endif
+
+static void Flush( filter_t * p_filter )
+{
+ filter_sys_t *p = p_filter->p_sys;
+
+ date_Set( &p->pts, VLC_TICK_INVALID );
+}
--
2.20.1
More information about the vlc-devel
mailing list