<div dir="ltr">Hi,<br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Feb 7, 2017 at 1:15 PM, Filip Roséen <span dir="ltr"><<a href="mailto:filip@atch.se" target="_blank">filip@atch.se</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">According to the ffmpeg documentation of AVPacket when used in muxing,<br>
pkt.{pts,dts} are absolute values for when a packet is to be<br>
interpreted, where the first packet shall start at zero.<br>
<br>
As the pts/dts in VLC are all relative to the PCR, those timestamps<br>
are not guaranteed to start at zero; which means that we would confuse<br>
avformat in scenarios where it heavily depends on zero-based pts/dts.<br>
<br>
These changes make sure that we start all timestamps at zero by<br>
normalizing each outgoing timestamp to the relative distance from the<br>
first entity received for each stream.<br>
<br>
fixes #17988<br>
<br>
--<br>
<br>
 Ticket:<br>
     - <a href="https://trac.videolan.org/vlc/ticket/17988" rel="noreferrer" target="_blank">https://trac.videolan.org/vlc/<wbr>ticket/17988</a><br>
<br>
 Relevant part of ffmpeg mkv mux (explains why the duration becomes wrong):<br>
     - <a href="https://www.ffmpeg.org/doxygen/3.2/matroskaenc_8c_source.html#l02148" rel="noreferrer" target="_blank">https://www.ffmpeg.org/doxygen<wbr>/3.2/matroskaenc_8c_source.htm<wbr>l#l02148</a><br>
<br>
 AVPacket documentation:<br>
     - <a href="https://www.ffmpeg.org/doxygen/3.2/structAVPacket.htmi" rel="noreferrer" target="_blank">https://www.ffmpeg.org/doxygen<wbr>/3.2/structAVPacket.htmi</a><br>
---<br>
 modules/demux/avformat/mux.c | 48 ++++++++++++++++++++++++++++++<wbr>++++----------<br>
 1 file changed, 37 insertions(+), 11 deletions(-)<br>
<br>
diff --git a/modules/demux/avformat/mux.c b/modules/demux/avformat/mux.c<br>
index 9072c2f8e1..b2b7bb467d 100644<br>
--- a/modules/demux/avformat/mux.c<br>
+++ b/modules/demux/avformat/mux.c<br>
@@ -66,6 +66,18 @@ struct sout_mux_sys_t<br>
 #endif<br>
 };<br>
<br>
+typedef struct<br>
+{<br>
+    int i_stream;<br>
+<br>
+    struct {<br>
+        mtime_t i_pts;<br>
+        mtime_t i_dts;<br>
+    } base_ts;<br>
+<br>
+} sout_input_sys_t;<br>
+<br>
+<br>
 /****************************<wbr>******************************<wbr>*******************<br>
  * Local prototypes<br>
  ******************************<wbr>******************************<wbr>*****************/<br>
@@ -221,11 +233,14 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )<br>
     }<br>
<br>
     /* */<br>
-    p_input->p_sys = malloc( sizeof( int ) );<br>
-    if( unlikely(p_input->p_sys == NULL) )<br>
+    sout_input_sys_t* p_input_sys = malloc( sizeof *p_input_sys );<br>
+    if( unlikely( p_input_sys == NULL ) )<br>
         return VLC_ENOMEM;<br>
<br>
-    *((int *)p_input->p_sys) = p_sys->oc->nb_streams;<br>
+    p_input->p_sys = p_input_sys;<br>
+    p_input_sys->i_stream = p_sys->oc->nb_streams;<br>
+    p_input_sys->base_ts.i_pts = VLC_TS_INVALID;<br>
+    p_input_sys->base_ts.i_dts = VLC_TS_INVALID;<br>
<br>
     /* */<br>
     stream = avformat_new_stream( p_sys->oc, NULL);<br>
@@ -322,11 +337,21 @@ static void DelStream( sout_mux_t *p_mux, sout_input_t *p_input )<br>
     free( p_input->p_sys );<br>
 }<br>
<br>
+static mtime_t NormalizeTS( mtime_t *base, AVStream* p_stream, mtime_t timestamp )<br>
+{<br>
+    if( *base == VLC_TS_INVALID )<br>
+        *base = timestamp;<br>
+<br>
+    return ( timestamp - *base ) * p_stream->time_base.den /<br>
+           CLOCK_FREQ / p_stream->time_base.num;<br></blockquote><div><br></div><div>If you can avoid integer overflow, you may want to do a multiplication instead of a second division here:<br>( timestamp - *base ) * p_stream->time_base.den / (CLOCK_FREQ * p_stream->time_base.num); <br><br></div><div>Disclaimer: have not tested or profiled this (hence the "may").</div><div><br></div><div>Best,</div><div>Tristan</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+}<br>
+<br>
 static int MuxBlock( sout_mux_t *p_mux, sout_input_t *p_input )<br>
 {<br>
     sout_mux_sys_t *p_sys = p_mux->p_sys;<br>
+    sout_input_sys_t *p_input_sys = p_input->p_sys;<br>
     block_t *p_data = block_FifoGet( p_input->p_fifo );<br>
-    int i_stream = *((int *)p_input->p_sys);<br>
+    int i_stream = p_input_sys->i_stream;<br>
     AVStream *p_stream = p_sys->oc->streams[i_stream];<br>
     AVPacket pkt;<br>
<br>
@@ -350,15 +375,16 @@ static int MuxBlock( sout_mux_t *p_mux, sout_input_t *p_input )<br>
     }<br>
<br>
     if( p_data->i_pts > 0 )<br>
-        pkt.pts = p_data->i_pts * p_stream->time_base.den /<br>
-            CLOCK_FREQ / p_stream->time_base.num;<br>
+        pkt.pts = NormalizeTS( &p_input_sys->base_ts.i_pts,<br>
+                                p_stream, p_data->i_pts );<br>
+<br>
     if( p_data->i_dts > 0 )<br>
-        pkt.dts = p_data->i_dts * p_stream->time_base.den /<br>
-            CLOCK_FREQ / p_stream->time_base.num;<br>
+        pkt.dts = NormalizeTS( &p_input_sys->base_ts.i_dts,<br>
+                                p_stream, p_data->i_dts );<br>
<br>
-    /* this is another hack to prevent libavformat from triggering the "non monotone timestamps" check in avformat/utils.c */<br>
-    p_stream->cur_dts = ( p_data->i_dts * p_stream->time_base.den /<br>
-            CLOCK_FREQ / p_stream->time_base.num ) - 1;<br>
+    /* This is another hack to prevent libavformat from triggering the<br>
+     * "non monotone timestamps" check in avformat/utils.c */<br>
+    p_stream->cur_dts = pkt.dts;<br>
<br>
     if( av_write_frame( p_sys->oc, &pkt ) < 0 )<br>
     {<br>
<span class="m_4913276035047425556m_4306661787567005663gmail-HOEnZb"><font color="#888888">--<br>
2.11.1<br>
<br>
______________________________<wbr>_________________<br>
vlc-devel mailing list<br>
To unsubscribe or modify your subscription options:<br>
<a href="https://mailman.videolan.org/listinfo/vlc-devel" rel="noreferrer" target="_blank">https://mailman.videolan.org/l<wbr>istinfo/vlc-devel</a></font></span></blockquote></div><br></div></div>