[vlc-commits] demux: adaptive: split offsets setup in fake esout

Francois Cartegnie git at videolan.org
Mon Mar 30 16:16:03 CEST 2020


vlc/vlc-3.0 | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Wed Jun 26 21:58:47 2019 +0200| [72023a9e3955ebf9fa617e49e113b13db5fb407f] | committer: Francois Cartegnie

demux: adaptive: split offsets setup in fake esout

(cherry picked from commit 9e7c2b5960bd6104f7342e429ae98f93cdd0906a)

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

 modules/demux/adaptive/Streams.cpp            |   6 +-
 modules/demux/adaptive/plumbing/FakeESOut.cpp | 111 ++++++++++++++++++--------
 modules/demux/adaptive/plumbing/FakeESOut.hpp |  18 +++--
 modules/demux/hls/HLSStreams.cpp              |   2 +-
 4 files changed, 93 insertions(+), 44 deletions(-)

diff --git a/modules/demux/adaptive/Streams.cpp b/modules/demux/adaptive/Streams.cpp
index daa888116c..c2c5f5afc2 100644
--- a/modules/demux/adaptive/Streams.cpp
+++ b/modules/demux/adaptive/Streams.cpp
@@ -128,7 +128,7 @@ void AbstractStream::prepareRestart(bool b_discontinuity)
     {
         /* Enqueue Del Commands for all current ES */
         demuxer->drain();
-        setTimeOffset(true);
+        setTimeOffset(-1);
         /* Enqueue Del Commands for all current ES */
         fakeEsOut()->scheduleAllForDeletion();
         if(b_discontinuity)
@@ -591,11 +591,11 @@ void AbstractStream::setTimeOffset(mtime_t i_offset)
      * will start from zero from seek point */
     if(i_offset < 0) /* reset */
     {
-        fakeEsOut()->setExpectedTimestampOffset(0);
+        fakeEsOut()->setExpectedTimestamp(-1);
     }
     else
     {
-        fakeEsOut()->setExpectedTimestampOffset(i_offset);
+        fakeEsOut()->setExpectedTimestamp(i_offset);
     }
 }
 
diff --git a/modules/demux/adaptive/plumbing/FakeESOut.cpp b/modules/demux/adaptive/plumbing/FakeESOut.cpp
index e02d35322e..2c6a1da725 100644
--- a/modules/demux/adaptive/plumbing/FakeESOut.cpp
+++ b/modules/demux/adaptive/plumbing/FakeESOut.cpp
@@ -58,8 +58,6 @@ FakeESOut::FakeESOut( es_out_t *es, CommandsQueue *queue )
     , commandsqueue( queue )
     , fakeesout( new es_out_t )
     , timestamps_offset( 0 )
-    , timestamps_expected( 0 )
-    , timestamps_check_done( false )
 {
     fakeesout->pf_add = esOutAdd_Callback;
     fakeesout->pf_control = esOutControl_Callback;
@@ -67,6 +65,9 @@ FakeESOut::FakeESOut( es_out_t *es, CommandsQueue *queue )
     fakeesout->pf_destroy = esOutDestroy_Callback;
     fakeesout->pf_send = esOutSend_Callback;
     fakeesout->p_sys = (es_out_sys_t*) this;
+    associated.b_timestamp_set = false;
+    expected.b_timestamp_set = false;
+    timestamp_first = 0;
     priority = ES_PRIORITY_SELECTABLE_MIN;
 
     vlc_mutex_init(&lock);
@@ -97,17 +98,49 @@ FakeESOut::~FakeESOut()
     vlc_mutex_destroy(&lock);
 }
 
-void FakeESOut::setExpectedTimestampOffset(mtime_t offset)
+void FakeESOut::resetTimestamps()
 {
-    timestamps_offset = 0;
-    timestamps_expected = offset;
-    timestamps_check_done = false;
+    setExpectedTimestamp(-1);
+    setAssociatedTimestamp(-1);
 }
 
-void FakeESOut::setTimestampOffset(mtime_t offset)
+bool FakeESOut::getStartTimestamps( mtime_t *pi_mediats, mtime_t *pi_demuxts )
 {
-    timestamps_offset = offset;
-    timestamps_check_done = true;
+    if(!expected.b_timestamp_set)
+        return false;
+    *pi_demuxts = timestamp_first;
+    *pi_mediats = expected.timestamp;
+    return true;
+}
+
+void FakeESOut::setExpectedTimestamp(mtime_t ts)
+{
+    if(ts < 0)
+    {
+        expected.b_timestamp_set = false;
+        timestamps_offset = 0;
+    }
+    else if(!expected.b_timestamp_set)
+    {
+        expected.b_timestamp_set = true;
+        expected.timestamp = ts;
+        expected.b_offset_calculated = false;
+    }
+}
+
+void FakeESOut::setAssociatedTimestamp(mtime_t ts)
+{
+    if(ts < 0)
+    {
+        associated.b_timestamp_set = false;
+        timestamps_offset = 0;
+    }
+    else if(!associated.b_timestamp_set)
+    {
+        associated.b_timestamp_set = true;
+        associated.timestamp = ts;
+        associated.b_offset_calculated = false;
+    }
 }
 
 void FakeESOut::setExtraInfoProvider( ExtraFMTInfoInterface *extra )
@@ -188,12 +221,6 @@ void FakeESOut::setPriority(int p)
     priority = p;
 }
 
-mtime_t FakeESOut::getTimestampOffset() const
-{
-    mtime_t time = timestamps_offset;
-    return time;
-}
-
 size_t FakeESOut::esCount() const
 {
     if(!declared.empty())
@@ -299,17 +326,40 @@ void FakeESOut::recycle( FakeESOutID *id )
     recycle_candidates.push_back( id );
 }
 
-void FakeESOut::checkTimestampsStart(mtime_t i_start)
+mtime_t FakeESOut::fixTimestamp(mtime_t ts)
 {
-    if( i_start == VLC_TS_INVALID )
-        return;
-
-    if( !timestamps_check_done )
+    if(ts != VLC_TS_INVALID)
     {
-        if( i_start < CLOCK_FREQ ) /* Starts 0 */
-            timestamps_offset = timestamps_expected;
-        timestamps_check_done = true;
+        if(associated.b_timestamp_set)
+        {
+            /* Some streams (ex: HLS) have a timestamp mapping
+               embedded in some header or metadata (ID3 crap for HLS).
+               In that case it needs to remap original timestamp. */
+            if(!associated.b_offset_calculated)
+            {
+                timestamps_offset = associated.timestamp - ts;
+                associated.b_offset_calculated = true;
+                timestamp_first = ts + timestamps_offset;
+            }
+        }
+        else if(expected.b_timestamp_set)
+        {
+            /* Some streams (ex: smooth mp4 without TFDT)
+             * do not have proper timestamps and will always start 0.
+             * In that case we need to enforce playlist time */
+            if(!expected.b_offset_calculated)
+            {
+                if(ts < CLOCK_FREQ) /* Starting 0 */
+                    timestamps_offset = expected.timestamp - ts;
+                else
+                    timestamps_offset = 0;
+                expected.b_offset_calculated = true;
+                timestamp_first = ts + timestamps_offset;
+            }
+        }
+        ts += timestamps_offset;
     }
+    return ts;
 }
 
 void FakeESOut::declareEs(const es_format_t *fmt)
@@ -375,15 +425,9 @@ int FakeESOut::esOutSend_Callback(es_out_t *fakees, es_out_id_t *p_es, block_t *
     FakeESOutID *es_id = reinterpret_cast<FakeESOutID *>( p_es );
     assert(!es_id->scheduledForDeletion());
 
-    me->checkTimestampsStart( p_block->i_dts );
+    p_block->i_dts = me->fixTimestamp( p_block->i_dts );
+    p_block->i_pts = me->fixTimestamp( p_block->i_pts );
 
-    mtime_t offset = me->getTimestampOffset();
-    if( p_block->i_dts > VLC_TS_INVALID )
-    {
-        p_block->i_dts += offset;
-        if( p_block->i_pts > VLC_TS_INVALID )
-                p_block->i_pts += offset;
-    }
     AbstractCommand *command = me->commandsqueue->factory()->createEsOutSendCommand( es_id, p_block );
     if( likely(command) )
     {
@@ -422,9 +466,8 @@ int FakeESOut::esOutControl_Callback(es_out_t *fakees, int i_query, va_list args
                 i_group = va_arg( args, int );
             else
                 i_group = 0;
-            int64_t  pcr = va_arg( args, int64_t );
-            me->checkTimestampsStart( pcr );
-            pcr += me->getTimestampOffset();
+            mtime_t  pcr = va_arg( args, mtime_t );
+            pcr = me->fixTimestamp( pcr );
             AbstractCommand *command = me->commandsqueue->factory()->createEsOutControlPCRCommand( i_group, pcr );
             if( likely(command) )
             {
diff --git a/modules/demux/adaptive/plumbing/FakeESOut.hpp b/modules/demux/adaptive/plumbing/FakeESOut.hpp
index cc1e1fc248..0c1d874c34 100644
--- a/modules/demux/adaptive/plumbing/FakeESOut.hpp
+++ b/modules/demux/adaptive/plumbing/FakeESOut.hpp
@@ -53,14 +53,16 @@ namespace adaptive
             es_out_t * getEsOut();
             LockedFakeEsOut WithLock();
             CommandsQueue * commandsQueue();
-            void setTimestampOffset( mtime_t );
-            void setExpectedTimestampOffset(mtime_t);
+            void setAssociatedTimestamp( mtime_t );
+            void setExpectedTimestamp( mtime_t );
+            void resetTimestamps();
+            bool getStartTimestamps( mtime_t *, mtime_t * );
             size_t esCount() const;
             bool hasSelectedEs() const;
             bool decodersDrained();
             bool restarting() const;
             void setExtraInfoProvider( ExtraFMTInfoInterface * );
-            void checkTimestampsStart(mtime_t);
+            mtime_t fixTimestamp( mtime_t );
             void declareEs( const es_format_t * );
 
             /* Used by FakeES ID */
@@ -87,12 +89,16 @@ namespace adaptive
             es_out_t *real_es_out;
             FakeESOutID * createNewID( const es_format_t * );
             ExtraFMTInfoInterface *extrainfo;
-            mtime_t getTimestampOffset() const;
             CommandsQueue *commandsqueue;
             es_out_t *fakeesout;
+            struct
+            {
+                mtime_t timestamp;
+                bool b_timestamp_set;
+                bool b_offset_calculated;
+            } associated, expected;
+            mtime_t timestamp_first;
             mtime_t timestamps_offset;
-            mtime_t timestamps_expected;
-            bool timestamps_check_done;
             int priority;
             std::list<FakeESOutID *> fakeesidlist;
             std::list<FakeESOutID *> recycle_candidates;
diff --git a/modules/demux/hls/HLSStreams.cpp b/modules/demux/hls/HLSStreams.cpp
index 6e4f7035a7..2bec05c619 100644
--- a/modules/demux/hls/HLSStreams.cpp
+++ b/modules/demux/hls/HLSStreams.cpp
@@ -55,7 +55,7 @@ void HLSStream::setTimeOffset(mtime_t i_offset)
         {
             if(!b_id3_timestamps_offset_set)
             {
-                fakeEsOut()->setTimestampOffset(i_offset);
+                fakeEsOut()->setAssociatedTimestamp(i_offset);
             }
             return;
         }



More information about the vlc-commits mailing list