[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