[vlc-commits] demux: avformat: use native rescaling

Francois Cartegnie git at videolan.org
Wed Dec 9 12:06:45 UTC 2020


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Fri Nov 27 17:39:05 2020 +0100| [a95d024bbb82df95263224e398dabed9a55fd2ca] | committer: Francois Cartegnie

demux: avformat: use native rescaling

Comparison & arithmetic through different time bases
are bogus (start_offset timebase vs streams pts timebase) when
rescaled using our own helpers.
We need to use the same rescaling functions to avoid different
roundings, then errors.
refs #25117

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=a95d024bbb82df95263224e398dabed9a55fd2ca
---

 modules/codec/avcodec/avcommon.h | 10 ++++++++++
 modules/demux/avformat/demux.c   | 33 ++++++++++-----------------------
 modules/demux/avformat/mux.c     | 14 ++++++++------
 3 files changed, 28 insertions(+), 29 deletions(-)

diff --git a/modules/codec/avcodec/avcommon.h b/modules/codec/avcodec/avcommon.h
index acd4790651..99a1308eda 100644
--- a/modules/codec/avcodec/avcommon.h
+++ b/modules/codec/avcodec/avcommon.h
@@ -42,9 +42,19 @@
 # include <libavutil/cpu.h>
 # include <libavutil/log.h>
 
+#define VLC_TIME_BASE_Q     (AVRational){1, CLOCK_FREQ}
+
+#define FROM_AVSCALE(x, scale) \
+    av_rescale_q((x), (scale), VLC_TIME_BASE_Q)
+#define TO_AVSCALE(x, scale)\
+    av_rescale_q((x), VLC_TIME_BASE_Q, (scale))
+
 #if (CLOCK_FREQ == AV_TIME_BASE)
 #define FROM_AV_TS(x)  (x)
 #define TO_AV_TS(x)    (x)
+#elif defined(USE_AV_RESCALEQ) /* until we migrate all conversions */
+#define FROM_AV_TS(x)  FROM_AVSCALE(x, AV_TIME_BASE_Q)
+#define TO_AV_TS(x)    TO_AVSCALE(x, AV_TIME_BASE_Q)
 #elif (CLOCK_FREQ % AV_TIME_BASE) == 0
 #define FROM_AV_TS(x)  ((x) * (CLOCK_FREQ / AV_TIME_BASE))
 #define TO_AV_TS(x)    ((x) / (CLOCK_FREQ / AV_TIME_BASE))
diff --git a/modules/demux/avformat/demux.c b/modules/demux/avformat/demux.c
index 91c4e005f4..4696070980 100644
--- a/modules/demux/avformat/demux.c
+++ b/modules/demux/avformat/demux.c
@@ -37,6 +37,8 @@
 #include <vlc_charset.h>
 #include <vlc_avcodec.h>
 
+#define USE_AV_RESCALEQ
+
 #include "../../codec/avcodec/avcodec.h"
 #include "../../codec/avcodec/chroma.h"
 #include "../../codec/avcodec/avcommon_compat.h"
@@ -748,10 +750,9 @@ int avformat_OpenDemux( vlc_object_t *p_this )
             EnsureUTF8( s->psz_name );
             msg_Dbg( p_demux, "    - chapter %d: %s", i, s->psz_name );
         }
-        s->i_time_offset = vlc_tick_from_samples( p_sys->ic->chapters[i]->start *
-            p_sys->ic->chapters[i]->time_base.num,
-            p_sys->ic->chapters[i]->time_base.den ) -
-            (i_start_time != VLC_TICK_INVALID ? i_start_time : 0 );
+        s->i_time_offset = FROM_AVSCALE( p_sys->ic->chapters[i]->start,
+                                         p_sys->ic->chapters[i]->time_base )
+                 - (i_start_time != VLC_TICK_INVALID ? i_start_time : 0 );
         TAB_APPEND( p_sys->p_title->i_seekpoint, p_sys->p_title->seekpoint, s );
     }
 
@@ -859,7 +860,7 @@ static int Demux( demux_t *p_demux )
     /* Used to avoid timestamps overlow */
     if( p_sys->ic->start_time != (int64_t)AV_NOPTS_VALUE )
     {
-        i_start_time = vlc_tick_from_frac(p_sys->ic->start_time, AV_TIME_BASE);
+        i_start_time = FROM_AV_TS(p_sys->ic->start_time);
     }
     else
         i_start_time = 0;
@@ -868,7 +869,7 @@ static int Demux( demux_t *p_demux )
         p_frame->i_dts = VLC_TICK_INVALID;
     else
     {
-        p_frame->i_dts = vlc_tick_from_frac( pkt.dts * p_stream->time_base.num, p_stream->time_base.den )
+        p_frame->i_dts = FROM_AVSCALE( pkt.dts, p_stream->time_base )
                 - i_start_time + VLC_TICK_0;
     }
 
@@ -876,13 +877,11 @@ static int Demux( demux_t *p_demux )
         p_frame->i_pts = VLC_TICK_INVALID;
     else
     {
-        p_frame->i_pts = vlc_tick_from_frac( pkt.pts * p_stream->time_base.num, p_stream->time_base.den )
+        p_frame->i_pts = FROM_AVSCALE( pkt.pts, p_stream->time_base )
                 - i_start_time + VLC_TICK_0;
     }
     if( pkt.duration > 0 && p_frame->i_length <= 0 )
-        p_frame->i_length = vlc_tick_from_samples(pkt.duration *
-            p_stream->time_base.num,
-            p_stream->time_base.den );
+        p_frame->i_length = FROM_AVSCALE( pkt.duration, p_stream->time_base );
 
     /* Add here notoriously bugged file formats/samples */
     if( !strcmp( p_sys->fmt->name, "flv" ) )
@@ -970,21 +969,9 @@ static void ResetTime( demux_t *p_demux, int64_t i_time )
     vlc_tick_t t;
 
     if( p_sys->ic->start_time == (int64_t)AV_NOPTS_VALUE || i_time < 0 )
-    {
         t = VLC_TICK_INVALID;
-    }
     else
-    {
-#if CLOCK_FREQ == AV_TIME_BASE
-        t = FROM_AV_TS(i_time);
-#else
-        lldiv_t q = lldiv( i_time, AV_TIME_BASE );
-        t = vlc_tick_from_sec(q.quot) + FROM_AV_TS(q.rem);
-#endif
-
-        if( t == VLC_TICK_INVALID )
-            t = VLC_TICK_0;
-    }
+        t = VLC_TICK_0 + FROM_AV_TS( i_time );
 
     p_sys->i_pcr = t;
     for( unsigned i = 0; i < p_sys->i_tracks; i++ )
diff --git a/modules/demux/avformat/mux.c b/modules/demux/avformat/mux.c
index 258ad283f8..ae5639e6de 100644
--- a/modules/demux/avformat/mux.c
+++ b/modules/demux/avformat/mux.c
@@ -35,6 +35,8 @@
 
 #include <libavformat/avformat.h>
 
+#define USE_AV_RESCALEQ
+
 #include "avformat.h"
 #include "../../codec/avcodec/avcodec.h"
 #include "../../codec/avcodec/avcommon.h"
@@ -398,12 +400,12 @@ static int MuxBlock( sout_mux_t *p_mux, sout_input_t *p_input )
         pkt.flags |= AV_PKT_FLAG_KEY;
     }
 
-    if( p_data->i_pts > 0 )
-        pkt.pts = TO_AV_TS(p_data->i_pts * p_stream->time_base.den /
-            CLOCK_FREQ / p_stream->time_base.num);
-    if( p_data->i_dts > 0 )
-        pkt.dts = TO_AV_TS(p_data->i_dts * p_stream->time_base.den /
-            CLOCK_FREQ / p_stream->time_base.num);
+    if( p_data->i_pts >= VLC_TICK_0 )
+        pkt.pts = av_rescale_q( p_data->i_pts - VLC_TICK_0,
+                                VLC_TIME_BASE_Q, p_stream->time_base );
+    if( p_data->i_dts >= VLC_TICK_0 )
+        pkt.dts = av_rescale_q( p_data->i_dts - VLC_TICK_0,
+                                VLC_TIME_BASE_Q, p_stream->time_base );
 
     /* this is another hack to prevent libavformat from triggering the "non monotone timestamps" check in avformat/utils.c */
     p_stream->cur_dts = ( p_data->i_dts * p_stream->time_base.den /



More information about the vlc-commits mailing list