<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>