[vlc-commits] transcode: keep in track of input pts drift for video
Ilkka Ollakka
git at videolan.org
Fri May 23 14:08:05 CEST 2014
vlc | branch: master | Ilkka Ollakka <ileoo at videolan.org> | Fri May 23 15:04:55 2014 +0300| [991d2ebf6edf186f22280c268f720047f0d6564c] | committer: Ilkka Ollakka
transcode: keep in track of input pts drift for video
Also name it to be next_input_pts instead of interpolated_pts
If input drift is more than 100ms that we estimate, we have most
likely dropped some packet and we should reset timers. Otherwise
it can cause lipsync issues if we for example just transcode video
track and audio track keeps original (jumped) pts.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=991d2ebf6edf186f22280c268f720047f0d6564c
---
modules/stream_out/transcode/audio.c | 18 +++++++++---------
modules/stream_out/transcode/transcode.h | 4 ++--
modules/stream_out/transcode/video.c | 26 +++++++++++++++++++++++++-
3 files changed, 36 insertions(+), 12 deletions(-)
diff --git a/modules/stream_out/transcode/audio.c b/modules/stream_out/transcode/audio.c
index ab9dfec..6012420 100644
--- a/modules/stream_out/transcode/audio.c
+++ b/modules/stream_out/transcode/audio.c
@@ -250,8 +250,8 @@ int transcode_audio_process( sout_stream_t *p_stream,
if( unlikely( transcode_audio_initialize_filters( p_stream, id, p_sys,
&id->p_decoder->fmt_out.audio ) != VLC_SUCCESS ) )
return VLC_EGENERIC;
- date_Init( &id->interpolated_pts, id->p_decoder->fmt_out.audio.i_rate, 1 );
- date_Set( &id->interpolated_pts, p_audio_buf->i_pts );
+ date_Init( &id->next_input_pts, id->p_decoder->fmt_out.audio.i_rate, 1 );
+ date_Set( &id->next_input_pts, p_audio_buf->i_pts );
}
/* Check if audio format has changed, and filters need reinit */
@@ -270,14 +270,14 @@ int transcode_audio_process( sout_stream_t *p_stream,
&id->p_decoder->fmt_out.audio ) != VLC_SUCCESS )
return VLC_EGENERIC;
- /* Set interpolated_pts to run with new samplerate */
- date_Init( &id->interpolated_pts, p_sys->fmt_audio.i_rate, 1 );
- date_Set( &id->interpolated_pts, p_audio_buf->i_pts );
+ /* Set next_input_pts to run with new samplerate */
+ date_Init( &id->next_input_pts, id->fmt_audio.i_rate, 1 );
+ date_Set( &id->next_input_pts, p_audio_buf->i_pts );
}
if( p_sys->b_master_sync )
{
- mtime_t i_pts = date_Get( &id->interpolated_pts );
+ mtime_t i_pts = date_Get( &id->next_input_pts );
mtime_t i_drift = 0;
if( likely( p_audio_buf->i_pts != VLC_TS_INVALID ) )
@@ -289,13 +289,13 @@ int transcode_audio_process( sout_stream_t *p_stream,
msg_Dbg( p_stream,
"audio drift is too high (%"PRId64"), resetting master sync",
i_drift );
- date_Set( &id->interpolated_pts, p_audio_buf->i_pts );
- i_pts = date_Get( &id->interpolated_pts );
+ date_Set( &id->next_input_pts, p_audio_buf->i_pts );
+ i_pts = date_Get( &id->next_input_pts );
if( likely(p_audio_buf->i_pts != VLC_TS_INVALID ) )
i_drift = p_audio_buf->i_pts - i_pts;
}
p_sys->i_master_drift = i_drift;
- date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples );
+ date_Increment( &id->next_input_pts, p_audio_buf->i_nb_samples );
}
p_audio_buf->i_dts = p_audio_buf->i_pts;
diff --git a/modules/stream_out/transcode/transcode.h b/modules/stream_out/transcode/transcode.h
index 50c3d75..66daca0 100644
--- a/modules/stream_out/transcode/transcode.h
+++ b/modules/stream_out/transcode/transcode.h
@@ -105,10 +105,10 @@ struct sout_stream_id_sys_t
encoder_t *p_encoder;
/* Sync */
- date_t interpolated_pts; /**< Incoming calculated PTS */
+ date_t next_input_pts; /**< Incoming calculated PTS */
date_t next_output_pts; /**< output calculated PTS */
- int i_output_frame_interval;
int i_input_frame_interval;
+ int i_output_frame_interval;
};
/* OSD */
diff --git a/modules/stream_out/transcode/video.c b/modules/stream_out/transcode/video.c
index 6f775dd..60b66bb 100644
--- a/modules/stream_out/transcode/video.c
+++ b/modules/stream_out/transcode/video.c
@@ -548,10 +548,18 @@ static void transcode_video_encoder_init( sout_stream_t *p_stream,
id->p_encoder->fmt_in.video.i_frame_rate,
id->p_encoder->fmt_in.video.i_frame_rate_base );
- id->i_output_frame_interval = id->p_encoder->fmt_out.video.i_frame_rate_base * CLOCK_FREQ / id->p_encoder->fmt_out.video.i_frame_rate;
+ id->i_input_frame_interval = id->p_decoder->fmt_out.video.i_frame_rate_base * CLOCK_FREQ / id->p_decoder->fmt_out.video.i_frame_rate;
+ msg_Info( p_stream, "input interval %d (base %d)",
+ id->i_input_frame_interval, id->p_decoder->fmt_out.video.i_frame_rate_base );
+
+ id->i_output_frame_interval = id->p_encoder->fmt_in.video.i_frame_rate_base * CLOCK_FREQ / id->p_encoder->fmt_in.video.i_frame_rate;
msg_Info( p_stream, "output interval %d (base %d)",
id->i_output_frame_interval, id->p_encoder->fmt_in.video.i_frame_rate_base );
+ date_Init( &id->next_input_pts,
+ id->p_decoder->fmt_out.video.i_frame_rate,
+ 1 );
+
date_Init( &id->next_output_pts,
id->p_encoder->fmt_in.video.i_frame_rate,
1 );
@@ -885,6 +893,7 @@ int transcode_video_process( sout_stream_t *p_stream, sout_stream_id_sys_t *id,
return VLC_EGENERIC;
}
date_Set( &id->next_output_pts, p_pic->date );
+ date_Set( &id->next_input_pts, p_pic->date );
}
/*Input lipsync and drop check */
@@ -912,6 +921,21 @@ int transcode_video_process( sout_stream_t *p_stream, sout_stream_id_sys_t *id,
#endif
}
+ /* Check input drift regardless, if it's more than 100ms from our approximation, we most likely have lost pictures
+ * and are in danger to become out of sync, so better reset timestamps then */
+ if( likely( p_pic->date != VLC_TS_INVALID ) )
+ {
+ mtime_t input_drift = p_pic->date - date_Get( &id->next_input_pts );
+ if( unlikely( (input_drift > (CLOCK_FREQ/10)) ||
+ (input_drift < -(CLOCK_FREQ/10))
+ ) )
+ {
+ msg_Warn( p_stream, "Reseting video sync" );
+ date_Set( &id->next_output_pts, p_pic->date );
+ date_Set( &id->next_input_pts, p_pic->date );
+ }
+ }
+ date_Increment( &id->next_input_pts, id->p_decoder->fmt_out.video.i_frame_rate_base );
/* Run the filter and output chains; first with the picture,
* and then with NULL as many times as we need until they
More information about the vlc-commits
mailing list