[vlc-commits] mux: mp4: handle scaled conversion drift (fix #17219)

Francois Cartegnie git at videolan.org
Tue Aug 16 11:15:59 CEST 2016


vlc/vlc-2.2 | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Aug 16 11:09:20 2016 +0200| [4f12d2a2fd664c63da5cbd60f264167521a926d3] | committer: Felix Paul Kühne

mux: mp4: handle scaled conversion drift (fix #17219)

double loss in both microtime to time scale
then time scale to microtime

Signed-off-by: Felix Paul Kühne <fkuehne at videolan.org>

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

 modules/mux/mp4.c | 37 ++++++++++++++++++++++++++++++++-----
 1 file changed, 32 insertions(+), 5 deletions(-)

diff --git a/modules/mux/mp4.c b/modules/mux/mp4.c
index 409147f..1f96547 100644
--- a/modules/mux/mp4.c
+++ b/modules/mux/mp4.c
@@ -1363,6 +1363,20 @@ static bo_t *GetTextBox(void)
     return text;
 }
 
+static int64_t GetScaledEntryDuration( const mp4_entry_t *p_entry, uint32_t i_timescale,
+                                       mtime_t *pi_total_mtime, int64_t *pi_total_scaled )
+{
+    const mtime_t i_totalscaledtototalmtime = *pi_total_scaled * CLOCK_FREQ / i_timescale;
+    const mtime_t i_diff = *pi_total_mtime - i_totalscaledtototalmtime;
+
+    /* Ensure to compensate the drift due to loss from time, and from scale, conversions */
+    int64_t i_scaled = (p_entry->i_length + i_diff) * i_timescale / CLOCK_FREQ;
+    *pi_total_mtime += p_entry->i_length;
+    *pi_total_scaled += i_scaled;
+
+    return i_scaled;
+}
+
 static bo_t *GetStblBox(sout_mux_t *p_mux, mp4_stream_t *p_stream)
 {
     sout_mux_sys_t *p_sys = p_mux->p_sys;
@@ -1433,17 +1447,30 @@ static bo_t *GetStblBox(sout_mux_t *p_mux, mp4_stream_t *p_stream)
     bo_t *stts = box_full_new("stts", 0, 0);
     bo_add_32be(stts, 0);     // entry-count (fixed latter)
 
+    mtime_t i_total_mtime = 0;
+    int64_t i_total_scaled = 0;
     unsigned i_index = 0;
     for (unsigned i = 0; i < p_stream->i_entry_count; i_index++) {
         int     i_first = i;
-        mtime_t i_delta = p_stream->entry[i].i_length;
 
-        for (; i < p_stream->i_entry_count; ++i)
-            if (i == p_stream->i_entry_count || p_stream->entry[i].i_length != i_delta)
+        int64_t i_scaled = GetScaledEntryDuration(&p_stream->entry[i], p_stream->i_timescale,
+                                                  &i_total_mtime, &i_total_scaled);
+        for (unsigned j=i+1; j < p_stream->i_entry_count; j++)
+        {
+            mtime_t i_total_mtime_next = i_total_mtime;
+            int64_t i_total_scaled_next = i_total_scaled;
+            int64_t i_scalednext = GetScaledEntryDuration(&p_stream->entry[j], p_stream->i_timescale,
+                                                          &i_total_mtime_next, &i_total_scaled_next);
+            if( i_scalednext != i_scaled )
                 break;
 
-        bo_add_32be(stts, i - i_first); // sample-count
-        bo_add_32be(stts, i_delta * p_stream->i_timescale / CLOCK_FREQ ); // sample-delta
+            i_total_mtime = i_total_mtime_next;
+            i_total_scaled = i_total_scaled_next;
+            i = j;
+        }
+
+        bo_add_32be(stts, ++i - i_first); // sample-count
+        bo_add_32be(stts, i_scaled); // sample-delta
     }
     bo_fix_32be(stts, 12, i_index);
 



More information about the vlc-commits mailing list