[vlc-commits] demux: adaptative: fix and replace timeline merging/pruning

Francois Cartegnie git at videolan.org
Tue Oct 27 19:13:55 CET 2015


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Mon Oct 26 20:35:00 2015 +0100| [8d8a63bcee14839a0b12af21535724cf032eebfb] | committer: Francois Cartegnie

demux: adaptative: fix and replace timeline merging/pruning

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

 .../adaptative/playlist/SegmentInformation.cpp     |    4 +-
 .../demux/adaptative/playlist/SegmentTemplate.cpp  |   19 ++++++-
 .../demux/adaptative/playlist/SegmentTemplate.h    |    1 +
 .../demux/adaptative/playlist/SegmentTimeline.cpp  |   60 +++++++++++---------
 .../demux/adaptative/playlist/SegmentTimeline.h    |    3 +-
 5 files changed, 53 insertions(+), 34 deletions(-)

diff --git a/modules/demux/adaptative/playlist/SegmentInformation.cpp b/modules/demux/adaptative/playlist/SegmentInformation.cpp
index 889774c..e31e1f3 100644
--- a/modules/demux/adaptative/playlist/SegmentInformation.cpp
+++ b/modules/demux/adaptative/playlist/SegmentInformation.cpp
@@ -332,9 +332,7 @@ void SegmentInformation::getDurationsRange(mtime_t *min, mtime_t *max) const
     {
         const mtime_t duration = mediaSegmentTemplate->segmentTimeline.Get()->end() -
                                  mediaSegmentTemplate->segmentTimeline.Get()->start();
-
-        if (!*min || duration < *min)
-            *min = duration;
+        *min = 0; /* fixme: get minimum ? */
 
         if(duration > *max)
             *max = duration;
diff --git a/modules/demux/adaptative/playlist/SegmentTemplate.cpp b/modules/demux/adaptative/playlist/SegmentTemplate.cpp
index 931ba2c..8ab948e 100644
--- a/modules/demux/adaptative/playlist/SegmentTemplate.cpp
+++ b/modules/demux/adaptative/playlist/SegmentTemplate.cpp
@@ -48,14 +48,27 @@ MediaSegmentTemplate::MediaSegmentTemplate( SegmentInformation *parent ) :
 
 void MediaSegmentTemplate::mergeWith(MediaSegmentTemplate *updated, mtime_t prunebarrier)
 {
-    if(segmentTimeline.Get() && updated->segmentTimeline.Get())
+    SegmentTimeline *timeline = segmentTimeline.Get();
+    if(timeline && updated->segmentTimeline.Get())
     {
-        segmentTimeline.Get()->mergeWith(*updated->segmentTimeline.Get());
+        timeline->mergeWith(*updated->segmentTimeline.Get());
         if(prunebarrier)
-            segmentTimeline.Get()->prune(prunebarrier);
+        {
+            const uint64_t timescale = timeline->inheritTimescale();
+            const uint64_t number =
+                    timeline->getElementNumberByScaledPlaybackTime(prunebarrier * timescale / CLOCK_FREQ);
+            timeline->pruneBySequenceNumber(number);
+        }
     }
 }
 
+size_t MediaSegmentTemplate::pruneBySequenceNumber(uint64_t number)
+{
+    if(segmentTimeline.Get())
+        return segmentTimeline.Get()->pruneBySequenceNumber(number);
+    return 0;
+}
+
 uint64_t MediaSegmentTemplate::getSequenceNumber() const
 {
     return startNumber.Get();
diff --git a/modules/demux/adaptative/playlist/SegmentTemplate.h b/modules/demux/adaptative/playlist/SegmentTemplate.h
index 69cdca7..e72a0f3 100644
--- a/modules/demux/adaptative/playlist/SegmentTemplate.h
+++ b/modules/demux/adaptative/playlist/SegmentTemplate.h
@@ -52,6 +52,7 @@ namespace adaptative
                 virtual void setSourceUrl( const std::string &url ); /* reimpl */
                 void mergeWith( MediaSegmentTemplate *, mtime_t );
                 virtual uint64_t getSequenceNumber() const; /* reimpl */
+                size_t pruneBySequenceNumber(uint64_t);
                 virtual void debug(vlc_object_t *, int = 0) const; /* reimpl */
                 Property<size_t>        startNumber;
         };
diff --git a/modules/demux/adaptative/playlist/SegmentTimeline.cpp b/modules/demux/adaptative/playlist/SegmentTimeline.cpp
index f83909f..da77382 100644
--- a/modules/demux/adaptative/playlist/SegmentTimeline.cpp
+++ b/modules/demux/adaptative/playlist/SegmentTimeline.cpp
@@ -128,21 +128,31 @@ uint64_t SegmentTimeline::minElementNumber() const
     return elements.front()->number;
 }
 
-size_t SegmentTimeline::prune(mtime_t time)
+size_t SegmentTimeline::pruneBySequenceNumber(uint64_t number)
 {
-    stime_t scaled = time * inheritTimescale() / CLOCK_FREQ;
     size_t prunednow = 0;
     while(elements.size())
     {
         Element *el = elements.front();
-        if(el->t + (el->d * (stime_t)(el->r + 1)) < scaled)
+        if(el->number >= number)
+        {
+            break;
+        }
+        else if(el->number + el->r >= number)
+        {
+            uint64_t count = el->number + el->r + 1 - number;
+            el->number += count;
+            el->t += count * el->d;
+            el->r -= count;
+            prunednow += count;
+            break;
+        }
+        else
         {
-            prunednow += el->r + 1;
             delete el;
             elements.pop_front();
+            prunednow += el->r + 1;
         }
-        else
-            break;
     }
 
     return prunednow;
@@ -165,33 +175,22 @@ void SegmentTimeline::mergeWith(SegmentTimeline &other)
     {
         Element *el = other.elements.front();
         other.elements.pop_front();
-        if(el->t == last->t) /* Same element, but prev could have been middle of repeat */
+
+        if(last->contains(el->t)) /* Same element, but prev could have been middle of repeat */
         {
-            last->r = std::max(last->r, el->r);
+            const uint64_t count = (el->t - last->t) / last->d;
+            last->r = std::max(last->r, el->r + count);
             delete el;
         }
-        else if(el->t > last->t) /* Did not exist in previous list */
+        else if(el->t < last->t)
         {
-            if( el->t - last->t >= last->d * (stime_t)(last->r + 1) )
-            {
-                elements.push_back(el);
-                last = el;
-            }
-            else if(last->d == el->d) /* should always be in that case */
-            {
-                last->r = ((el->t - last->t) / last->d) - 1;
-                elements.push_back(el);
-                last = el;
-            }
-            else
-            {
-                /* borked: skip */
-                delete el;
-            }
+            delete el;
         }
-        else
+        else /* Did not exist in previous list */
         {
-            delete el;
+            elements.push_back(el);
+            el->number = last->number + last->r + 1;
+            last = el;
         }
     }
 }
@@ -231,6 +230,13 @@ SegmentTimeline::Element::Element(uint64_t number_, stime_t d_, uint64_t r_, sti
     r = r_;
 }
 
+bool SegmentTimeline::Element::contains(stime_t time) const
+{
+    if(time >= t && time < t + (stime_t)(r + 1) * d)
+        return true;
+    return false;
+}
+
 void SegmentTimeline::Element::debug(vlc_object_t *obj, int indent) const
 {
     std::stringstream ss;
diff --git a/modules/demux/adaptative/playlist/SegmentTimeline.h b/modules/demux/adaptative/playlist/SegmentTimeline.h
index 6cdc409..5cb2834 100644
--- a/modules/demux/adaptative/playlist/SegmentTimeline.h
+++ b/modules/demux/adaptative/playlist/SegmentTimeline.h
@@ -49,7 +49,7 @@ namespace adaptative
                 stime_t getScaledPlaybackTimeByElementNumber(uint64_t) const;
                 uint64_t maxElementNumber() const;
                 uint64_t minElementNumber() const;
-                size_t prune(mtime_t);
+                size_t pruneBySequenceNumber(uint64_t);
                 void mergeWith(SegmentTimeline &);
                 mtime_t start() const;
                 mtime_t end() const;
@@ -63,6 +63,7 @@ namespace adaptative
                     public:
                         Element(uint64_t, stime_t, uint64_t, stime_t);
                         void debug(vlc_object_t *, int = 0) const;
+                        bool contains(stime_t) const;
                         stime_t  t;
                         stime_t  d;
                         uint64_t r;



More information about the vlc-commits mailing list