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

Zhao Zhili quinkblack at foxmail.com
Thu Aug 31 15:32:42 CEST 2017



On 2017年08月31日 18:44, Rémi Denis-Courmont wrote:
> Le 31 août 2017 12:24:03 GMT+02:00, Zhao Zhili <quinkblack at foxmail.com> a écrit :
>> On 2017年08月31日 17:58, Francois Cartegnie wrote:
>>> Le 31/08/2017 à 08:48, Zhao Zhili a écrit :
>>>> ---
>>>>    modules/demux/avformat/demux.c | 41
>>>> +++++++++++++++++++++++++++++------------
>>>>    1 file changed, 29 insertions(+), 12 deletions(-)
>>>>
>>> If the timestamps are negative from the start, I don't see
>>> why the issue should be on the API user side.
>>>
>>> But, this seems the same as last February discussion around
>>> "mux/avformat: normalize pts and dts in AVPacket"
>>> which had regressions.
>>>
>>> https://trac.videolan.org/vlc/ticket/17988
>>>
>> I'm trying to fix a case like this:
>>
>> original_start_time = 1000 * 1000 us;
>> original_pts = 1000 * 1000 us;
>> original_dts = 960 * 1000 us;
>>
>> new_pts = original_pts - original_start_time + VLC_TS_0 = 1 us;
>> new_dts = original_dts - original_start_time + VLC_TS_0 = -39999 us;
>>
>> So it's the difference between PTS and DTS lead to the issue.
>> _______________________________________________
>> vlc-devel mailing list
>> To unsubscribe or modify your subscription options:
>> https://mailman.videolan.org/listinfo/vlc-devel
> Negative timestamps can occur in some legal corner cases. There are no systematic ways to avoid them. You really shouldn't even try.
>
> Just make sure than 0 is not a special value. There is VLC_TS_INVALID for that.

How about this:
1. If the original PTS and DTS output from libavformat is negative, do 
nothing.

2. Otherwise, which most likely means the negative PTS and DTS is produced
by shift, then shift start_time to produced positive timestamps.

3. PTS/DTS wrap can lead to negative timestamps too, which is harder to 
handle.
Don't distinguish this case from case 2.

A new patch is attached.

---
  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..3bb7813 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 && pkt.dts >= 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 && pkt.pts >= 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: 0001-demux-avformat-workaround-negative-PTS-DTS-which-was.patch
Type: text/x-patch
Size: 4261 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20170831/83f7c5e8/attachment.bin>


More information about the vlc-devel mailing list