[vlc-devel] [PATCH 2/3] demux: avformat: fix negative PTS/DTS

Zhao Zhili quinkblack at foxmail.com
Thu Aug 31 08:48:19 CEST 2017


---
  modules/demux/avformat/demux.c | 41 
+++++++++++++++++++++++++++++------------
  1 file changed, 29 insertions(+), 12 deletions(-)

diff --git a/modules/demux/avformat/demux.c b/modules/demux/avformat/demux.c
index 3c4c112..edda0a9 100644
--- a/modules/demux/avformat/demux.c
+++ b/modules/demux/avformat/demux.c
@@ -72,6 +72,7 @@ struct demux_sys_t

      /* Only one title with seekpoints possible atm. */
      input_title_t *p_title;
+    int64_t i_start_time;
  };

  #define AVFORMAT_IOBUFFER_SIZE 32768  /* FIXME */
@@ -274,6 +275,7 @@ int OpenDemux( vlc_object_t *p_this )
      p_sys->i_ssa_order = 0;
      TAB_INIT( p_sys->i_attachments, p_sys->attachments);
      p_sys->p_title = NULL;
+    p_sys->i_start_time = 0;

      /* Create I/O wrapper */
      unsigned char * p_io_buffer = av_malloc( AVFORMAT_IOBUFFER_SIZE );
@@ -623,8 +625,11 @@ int OpenDemux( vlc_object_t *p_this )
      }
      p_sys->tk_pcr = xcalloc( p_sys->i_tk, sizeof(*p_sys->tk_pcr) );

-    if( p_sys->ic->start_time != (int64_t)AV_NOPTS_VALUE )
-        i_start_time = p_sys->ic->start_time * 1000000 / AV_TIME_BASE;
+    if( p_sys->ic->start_time != (int64_t)AV_NOPTS_VALUE ) {
+        lldiv_t q = lldiv( p_sys->ic->start_time, AV_TIME_BASE);
+        i_start_time = q.quot * CLOCK_FREQ + q.rem * CLOCK_FREQ / 
AV_TIME_BASE;
+        p_sys->i_start_time = i_start_time;
+    }

      msg_Dbg( p_demux, "AVFormat(%s %s) supported stream", 
AVPROVIDER(LIBAVFORMAT), LIBAVFORMAT_IDENT );
      msg_Dbg( p_demux, "    - format = %s (%s)",
@@ -701,7 +706,6 @@ static int Demux( demux_t *p_demux )
      demux_sys_t *p_sys = p_demux->p_sys;
      AVPacket    pkt;
      block_t     *p_frame;
-    int64_t     i_start_time;

      /* Read a frame */
      int i_av_ret = av_read_frame( p_sys->ic, &pkt );
@@ -749,13 +753,6 @@ static int Demux( demux_t *p_demux )

      /* Used to avoid timestamps overlow */
      lldiv_t q;
-    if( p_sys->ic->start_time != (int64_t)AV_NOPTS_VALUE )
-    {
-        q = lldiv( p_sys->ic->start_time, AV_TIME_BASE);
-        i_start_time = q.quot * CLOCK_FREQ + q.rem * CLOCK_FREQ / 
AV_TIME_BASE;
-    }
-    else
-        i_start_time = 0;

      if( pkt.dts == (int64_t)AV_NOPTS_VALUE )
          p_frame->i_dts = VLC_TS_INVALID;
@@ -765,7 +762,16 @@ static int Demux( demux_t *p_demux )
          p_frame->i_dts = q.quot * CLOCK_FREQ *
              p_stream->time_base.num + q.rem * CLOCK_FREQ *
              p_stream->time_base.num /
-            p_stream->time_base.den - i_start_time + VLC_TS_0;
+            p_stream->time_base.den - p_sys->i_start_time + VLC_TS_0;
+        if( p_frame->i_dts < VLC_TS_0 && p_sys->i_start_time != 0 )
+        {
+            int64_t i_start_time = p_sys->i_start_time;
+            p_sys->i_start_time -= VLC_TS_0 - p_frame->i_dts;
+            msg_Dbg( p_demux, "adjust start time from %" PRId64 " to %" 
PRId64
+                    " since DTS < 0", i_start_time, p_sys->i_start_time );
+
+            p_frame->i_dts = VLC_TS_0;
+        }
      }

      if( pkt.pts == (int64_t)AV_NOPTS_VALUE )
@@ -776,7 +782,18 @@ static int Demux( demux_t *p_demux )
          p_frame->i_pts = q.quot * CLOCK_FREQ *
              p_stream->time_base.num + q.rem * CLOCK_FREQ *
              p_stream->time_base.num /
-            p_stream->time_base.den - i_start_time + VLC_TS_0;
+            p_stream->time_base.den - p_sys->i_start_time + VLC_TS_0;
+        if( p_frame->i_pts < VLC_TS_0 && p_sys->i_start_time != 0 )
+        {
+            int64_t i_start_time = p_sys->i_start_time;
+            p_sys->i_start_time -= VLC_TS_0 - p_frame->i_pts;
+            msg_Dbg( p_demux, "adjust start time from %" PRId64 " to %" 
PRId64
+                    " since PTS < 0", i_start_time, p_sys->i_start_time );
+
+            p_frame->i_pts = VLC_TS_0;
+            if( p_frame->i_dts != VLC_TS_INVALID )
+                p_frame->i_dts += VLC_TS_0 - p_frame->i_pts;
+        }
      }
      if( pkt.duration > 0 && p_frame->i_length <= 0 )
          p_frame->i_length = pkt.duration * CLOCK_FREQ *
-- 
2.7.4

-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-demux-avformat-fix-negative-PTS-DTS.patch
Type: text/x-patch
Size: 4240 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20170831/0d21b625/attachment.bin>


More information about the vlc-devel mailing list