[vlc-commits] demux: avi: do 2 step rescaling

Francois Cartegnie git at videolan.org
Wed Dec 20 15:37:15 CET 2017


vlc/vlc-3.0 | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Wed Dec 20 11:19:57 2017 +0100| [1c7d261b35e94ac105762f391fbf581b7964a04a] | committer: Francois Cartegnie

demux: avi: do 2 step rescaling

(cherry picked from commit 8c59fc7af4ad5c52168cb12b8bd296c4494df345)

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

 modules/demux/avi/avi.c | 35 ++++++++++++++++++++++-------------
 1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/modules/demux/avi/avi.c b/modules/demux/avi/avi.c
index 109573850b..37ec78c89e 100644
--- a/modules/demux/avi/avi.c
+++ b/modules/demux/avi/avi.c
@@ -1796,26 +1796,38 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
  * Function to convert pts to chunk or byte
  *****************************************************************************/
 
+static int64_t AVI_Rescale( int64_t i_value, uint32_t i_timescale, uint32_t i_newscale )
+{
+    /* TODO: replace (and mp4) with better global helper (recursive checks) */
+    if( i_timescale == i_newscale )
+        return i_value;
+
+    if( (i_value >= 0 && i_value <= INT64_MAX / i_newscale) ||
+        (i_value < 0  && i_value >= INT64_MIN / i_newscale) )
+        return i_value * i_newscale / i_timescale;
+
+    /* overflow */
+    int64_t q = i_value / i_timescale;
+    int64_t r = i_value % i_timescale;
+    return q * i_newscale + r * i_newscale / i_timescale;
+}
+
 static int64_t AVI_PTSToChunk( avi_track_t *tk, mtime_t i_pts )
 {
     if( !tk->i_scale )
         return 0;
 
-    return i_pts *
-           tk->i_rate /
-           tk->i_scale /
-           CLOCK_FREQ;
+    i_pts = AVI_Rescale( i_pts, tk->i_scale, tk->i_rate );
+    return i_pts / CLOCK_FREQ;
 }
+
 static int64_t AVI_PTSToByte( avi_track_t *tk, mtime_t i_pts )
 {
     if( !tk->i_scale || !tk->i_samplesize )
         return 0;
 
-    return i_pts *
-           tk->i_rate /
-           tk->i_scale /
-           CLOCK_FREQ *
-           tk->i_samplesize;
+    i_pts = AVI_Rescale( i_pts, tk->i_scale, tk->i_rate );
+    return i_pts / CLOCK_FREQ * tk->i_samplesize;
 }
 
 static mtime_t AVI_GetDPTS( avi_track_t *tk, int64_t i_count )
@@ -1825,10 +1837,7 @@ static mtime_t AVI_GetDPTS( avi_track_t *tk, int64_t i_count )
     if( !tk->i_rate )
         return i_dpts;
 
-    i_dpts = CLOCK_FREQ *
-             i_count *
-             tk->i_scale /
-             tk->i_rate;
+    i_dpts = AVI_Rescale( CLOCK_FREQ * i_count, tk->i_rate, tk->i_scale );
 
     if( tk->i_samplesize )
     {



More information about the vlc-commits mailing list