[vlc-commits] demux: adaptive: inherit template defaults (fix #22047)

Francois Cartegnie git at videolan.org
Mon Apr 15 18:26:05 CEST 2019


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Mon Apr 15 18:20:14 2019 +0200| [7ff23c447d942c4bd4f88bbcd680892d57643b9e] | committer: Francois Cartegnie

demux: adaptive: inherit template defaults (fix #22047)

not the complete and efficient way.
we'll need a better inheritance fix at parsing level.

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

 modules/demux/adaptive/playlist/Inheritables.hpp   |   4 +-
 .../demux/adaptive/playlist/SegmentInformation.cpp |  26 ++---
 .../demux/adaptive/playlist/SegmentInformation.hpp |   1 +
 .../demux/adaptive/playlist/SegmentTemplate.cpp    | 106 +++++++++++++++++----
 modules/demux/adaptive/playlist/SegmentTemplate.h  |  10 +-
 modules/demux/dash/mpd/IsoffMainParser.cpp         |  19 ++--
 modules/demux/dash/mpd/Representation.cpp          |   5 +-
 modules/demux/smooth/playlist/Parser.cpp           |   2 +-
 modules/demux/smooth/playlist/Representation.cpp   |   8 +-
 9 files changed, 132 insertions(+), 49 deletions(-)

diff --git a/modules/demux/adaptive/playlist/Inheritables.hpp b/modules/demux/adaptive/playlist/Inheritables.hpp
index a1dc597fdf..833c7478ae 100644
--- a/modules/demux/adaptive/playlist/Inheritables.hpp
+++ b/modules/demux/adaptive/playlist/Inheritables.hpp
@@ -34,9 +34,9 @@ namespace adaptive
         {
             public:
                 TimescaleAble( TimescaleAble * = NULL );
-                ~TimescaleAble();
+                virtual ~TimescaleAble();
                 void setParentTimescaleAble( TimescaleAble * );
-                Timescale inheritTimescale() const;
+                virtual Timescale inheritTimescale() const;
                 void setTimescale( const Timescale & );
                 void setTimescale( uint64_t );
                 const Timescale & getTimescale() const;
diff --git a/modules/demux/adaptive/playlist/SegmentInformation.cpp b/modules/demux/adaptive/playlist/SegmentInformation.cpp
index 8dc6bcf297..09740fd6d8 100644
--- a/modules/demux/adaptive/playlist/SegmentInformation.cpp
+++ b/modules/demux/adaptive/playlist/SegmentInformation.cpp
@@ -176,7 +176,7 @@ uint64_t SegmentInformation::getLiveStartSegmentNumber(uint64_t def) const
         uint64_t end = 0;
         const Timescale timescale = mediaSegmentTemplate->inheritTimescale();
 
-        SegmentTimeline *timeline = mediaSegmentTemplate->segmentTimeline.Get();
+        const SegmentTimeline *timeline = mediaSegmentTemplate->inheritSegmentTimeline();
         if( timeline )
         {
             start = timeline->minElementNumber();
@@ -206,7 +206,7 @@ uint64_t SegmentInformation::getLiveStartSegmentNumber(uint64_t def) const
             if( i_delay < getPlaylist()->getMinBuffering() )
                 i_delay = getPlaylist()->getMinBuffering();
 
-            const uint64_t startnumber = mediaSegmentTemplate->startNumber.Get();
+            const uint64_t startnumber = mediaSegmentTemplate->inheritStartNumber();
             end = mediaSegmentTemplate->getCurrentLiveTemplateNumber();
 
             const uint64_t count = timescale.ToScaled( i_delay ) / mediaSegmentTemplate->duration.Get();
@@ -283,7 +283,7 @@ ISegment * SegmentInformation::getNextSegment(SegmentInfoType type, uint64_t i_p
             {
                 /* Check if we don't exceed timeline */
                 MediaSegmentTemplate *templ = dynamic_cast<MediaSegmentTemplate*>(retSegments[0]);
-                SegmentTimeline *timeline = (templ) ? templ->segmentTimeline.Get() : NULL;
+                const SegmentTimeline *timeline = (templ) ? templ->inheritSegmentTimeline() : NULL;
                 if(timeline)
                 {
                     *pi_newpos = std::max(timeline->minElementNumber(), i_pos);
@@ -294,7 +294,7 @@ ISegment * SegmentInformation::getNextSegment(SegmentInfoType type, uint64_t i_p
                 {
                     *pi_newpos = i_pos;
                     /* start number */
-                    *pi_newpos = std::max((uint64_t)templ->startNumber.Get(), i_pos);
+                    *pi_newpos = std::max(templ->inheritStartNumber(), i_pos);
                 }
                 return seg;
             }
@@ -319,8 +319,8 @@ ISegment * SegmentInformation::getSegment(SegmentInfoType type, uint64_t pos) co
         if(size == 1 && retSegments[0]->isTemplate())
         {
             MediaSegmentTemplate *templ = dynamic_cast<MediaSegmentTemplate*>(retSegments[0]);
-            if(!templ || templ->segmentTimeline.Get() == NULL ||
-               templ->segmentTimeline.Get()->maxElementNumber() > pos)
+            const SegmentTimeline *tl = templ->inheritSegmentTimeline();
+            if(!templ || tl == NULL || tl->maxElementNumber() > pos)
                 return templ;
         }
         else
@@ -349,7 +349,7 @@ bool SegmentInformation::getSegmentNumberByTime(vlc_tick_t time, uint64_t *ret)
     {
         const Timescale timescale = mediaSegmentTemplate->inheritTimescale();
 
-        SegmentTimeline *timeline = mediaSegmentTemplate->segmentTimeline.Get();
+        const SegmentTimeline *timeline = mediaSegmentTemplate->inheritSegmentTimeline();
         if(timeline)
         {
             stime_t st = timescale.ToScaled(time);
@@ -362,11 +362,11 @@ bool SegmentInformation::getSegmentNumberByTime(vlc_tick_t time, uint64_t *ret)
         {
             if( getPlaylist()->isLive() )
             {
-                *ret = getLiveStartSegmentNumber( mediaSegmentTemplate->startNumber.Get() );
+                *ret = getLiveStartSegmentNumber( mediaSegmentTemplate->inheritStartNumber() );
             }
             else
             {
-                *ret = mediaSegmentTemplate->startNumber.Get();
+                *ret = mediaSegmentTemplate->inheritStartNumber();
                 *ret += timescale.ToScaled(time) / duration;
             }
             return true;
@@ -402,12 +402,12 @@ bool SegmentInformation::getPlaybackTimeDurationBySegmentNumber(uint64_t number,
     if( (mediaTemplate = inheritSegmentTemplate()) )
     {
         const Timescale timescale = mediaTemplate->inheritTimescale();
+        const SegmentTimeline * timeline = mediaTemplate->inheritSegmentTimeline();
 
         stime_t stime, sduration;
-        if(mediaTemplate->segmentTimeline.Get())
+        if(timeline)
         {
-            mediaTemplate->segmentTimeline.Get()->
-                getScaledPlaybackTimeDurationBySegmentNumber(number, &stime, &sduration);
+            timeline->getScaledPlaybackTimeDurationBySegmentNumber(number, &stime, &sduration);
         }
         else
         {
@@ -473,7 +473,7 @@ void SegmentInformation::mergeWithTimeline(SegmentTimeline *updated)
     MediaSegmentTemplate *templ = inheritSegmentTemplate();
     if(templ)
     {
-        SegmentTimeline *timeline = templ->segmentTimeline.Get();
+        SegmentTimeline *timeline = templ->inheritSegmentTimeline();
         if(timeline)
             timeline->mergeWith(*updated);
     }
diff --git a/modules/demux/adaptive/playlist/SegmentInformation.hpp b/modules/demux/adaptive/playlist/SegmentInformation.hpp
index d74764fde7..74633b033b 100644
--- a/modules/demux/adaptive/playlist/SegmentInformation.hpp
+++ b/modules/demux/adaptive/playlist/SegmentInformation.hpp
@@ -43,6 +43,7 @@ namespace adaptive
                                    public TimescaleAble,
                                    public Unique
         {
+            friend class MediaSegmentTemplate;
             public:
                 SegmentInformation( SegmentInformation * = 0 );
                 explicit SegmentInformation( AbstractPlaylist * );
diff --git a/modules/demux/adaptive/playlist/SegmentTemplate.cpp b/modules/demux/adaptive/playlist/SegmentTemplate.cpp
index f1437bbadd..d0aef9f33d 100644
--- a/modules/demux/adaptive/playlist/SegmentTemplate.cpp
+++ b/modules/demux/adaptive/playlist/SegmentTemplate.cpp
@@ -27,6 +27,7 @@
 #include "SegmentTimeline.h"
 #include "SegmentInformation.hpp"
 #include "AbstractPlaylist.hpp"
+#include <limits>
 
 using namespace adaptive::playlist;
 
@@ -37,12 +38,13 @@ BaseSegmentTemplate::BaseSegmentTemplate( ICanonicalUrl *parent ) :
 
 
 MediaSegmentTemplate::MediaSegmentTemplate( SegmentInformation *parent ) :
-    BaseSegmentTemplate( parent ), TimescaleAble( parent )
+    BaseSegmentTemplate( parent ),
+    TimescaleAble( NULL ) /* we don't want auto inherit */
 {
     debugName = "SegmentTemplate";
     classId = Segment::CLASSID_SEGMENT;
-    startNumber.Set( 1 );
-    segmentTimeline.Set( NULL );
+    startNumber = std::numeric_limits<uint64_t>::max();
+    segmentTimeline = NULL;
     initialisationSegment.Set( NULL );
     templated = true;
     parentSegmentInformation = parent;
@@ -50,15 +52,15 @@ MediaSegmentTemplate::MediaSegmentTemplate( SegmentInformation *parent ) :
 
 MediaSegmentTemplate::~MediaSegmentTemplate()
 {
-    delete segmentTimeline.Get();
+    delete segmentTimeline;
 }
 
 void MediaSegmentTemplate::mergeWith(MediaSegmentTemplate *updated, vlc_tick_t prunebarrier)
 {
-    SegmentTimeline *timeline = segmentTimeline.Get();
-    if(timeline && updated->segmentTimeline.Get())
+    SegmentTimeline *timeline = segmentTimeline;
+    if(timeline && updated->segmentTimeline)
     {
-        timeline->mergeWith(*updated->segmentTimeline.Get());
+        timeline->mergeWith(*updated->segmentTimeline);
         if(prunebarrier)
         {
             const Timescale timescale = timeline->inheritTimescale();
@@ -71,22 +73,77 @@ void MediaSegmentTemplate::mergeWith(MediaSegmentTemplate *updated, vlc_tick_t p
 
 void MediaSegmentTemplate::pruneByPlaybackTime(vlc_tick_t time)
 {
-    if(segmentTimeline.Get())
-        return segmentTimeline.Get()->pruneByPlaybackTime(time);
+    if(segmentTimeline)
+        return segmentTimeline->pruneByPlaybackTime(time);
 }
 
 size_t MediaSegmentTemplate::pruneBySequenceNumber(uint64_t number)
 {
-    if(segmentTimeline.Get())
-        return segmentTimeline.Get()->pruneBySequenceNumber(number);
+    if(segmentTimeline)
+        return segmentTimeline->pruneBySequenceNumber(number);
     return 0;
 }
 
+uint64_t MediaSegmentTemplate::inheritStartNumber() const
+{
+    const SegmentInformation *ulevel = parentSegmentInformation ? parentSegmentInformation
+                                                                : NULL;
+    for( ; ulevel ; ulevel = ulevel->parent )
+    {
+        if( ulevel->mediaSegmentTemplate &&
+            ulevel->mediaSegmentTemplate->startNumber !=
+                std::numeric_limits<uint64_t>::max() )
+            return ulevel->mediaSegmentTemplate->startNumber;
+    }
+    return 1;
+}
+
+Timescale MediaSegmentTemplate::inheritTimescale() const
+{
+    const SegmentInformation *ulevel = parentSegmentInformation ? parentSegmentInformation
+                                                                : NULL;
+    for( ; ulevel ; ulevel = ulevel->parent )
+    {
+        if( ulevel->mediaSegmentTemplate &&
+            ulevel->mediaSegmentTemplate->getTimescale().isValid() )
+            return ulevel->mediaSegmentTemplate->getTimescale();
+        if( ulevel->getTimescale().isValid() )
+            return ulevel->mediaSegmentTemplate->getTimescale();
+    }
+    return Timescale(1);
+}
+
+stime_t MediaSegmentTemplate::inheritDuration() const
+{
+    const SegmentInformation *ulevel = parentSegmentInformation ? parentSegmentInformation
+                                                                : NULL;
+    for( ; ulevel ; ulevel = ulevel->parent )
+    {
+        if( ulevel->mediaSegmentTemplate &&
+            ulevel->mediaSegmentTemplate->duration.Get() > 0 )
+            return ulevel->mediaSegmentTemplate->duration.Get();
+    }
+    return 0;
+}
+
+SegmentTimeline * MediaSegmentTemplate::inheritSegmentTimeline() const
+{
+    const SegmentInformation *ulevel = parentSegmentInformation ? parentSegmentInformation
+                                                          : NULL;
+    for( ; ulevel ; ulevel = ulevel->parent )
+    {
+        if( ulevel->mediaSegmentTemplate &&
+            ulevel->mediaSegmentTemplate->segmentTimeline )
+            return ulevel->mediaSegmentTemplate->segmentTimeline;
+    }
+    return NULL;
+}
+
 uint64_t MediaSegmentTemplate::getCurrentLiveTemplateNumber() const
 {
-    uint64_t number = startNumber.Get();
+    uint64_t number = inheritStartNumber();
     /* live streams / templated */
-    const stime_t dur = duration.Get();
+    const stime_t dur = inheritDuration();
     if(dur)
     {
         /* compute, based on current time */
@@ -103,16 +160,16 @@ uint64_t MediaSegmentTemplate::getCurrentLiveTemplateNumber() const
 
 stime_t MediaSegmentTemplate::getMinAheadScaledTime(uint64_t number) const
 {
-    if( segmentTimeline.Get() )
-        return segmentTimeline.Get()->getMinAheadScaledTime(number);
+    if( segmentTimeline )
+        return segmentTimeline->getMinAheadScaledTime(number);
 
     uint64_t current = getCurrentLiveTemplateNumber();
-    return (current - number) * duration.Get();
+    return (current - number) * inheritDuration();
 }
 
 uint64_t MediaSegmentTemplate::getSequenceNumber() const
 {
-    return startNumber.Get();
+    return inheritStartNumber();
 }
 
 void MediaSegmentTemplate::setSourceUrl(const std::string &url)
@@ -120,11 +177,22 @@ void MediaSegmentTemplate::setSourceUrl(const std::string &url)
     sourceUrl = Url(Url::Component(url, this));
 }
 
+void MediaSegmentTemplate::setStartNumber( uint64_t v )
+{
+    startNumber = v;
+}
+
+void MediaSegmentTemplate::setSegmentTimeline( SegmentTimeline *v )
+{
+    delete segmentTimeline;
+    segmentTimeline = v;
+}
+
 void MediaSegmentTemplate::debug(vlc_object_t *obj, int indent) const
 {
     Segment::debug(obj, indent);
-    if(segmentTimeline.Get())
-        segmentTimeline.Get()->debug(obj, indent + 1);
+    if(segmentTimeline)
+        segmentTimeline->debug(obj, indent + 1);
 }
 
 InitSegmentTemplate::InitSegmentTemplate( ICanonicalUrl *parent ) :
diff --git a/modules/demux/adaptive/playlist/SegmentTemplate.h b/modules/demux/adaptive/playlist/SegmentTemplate.h
index b5608e29c0..974bc41f66 100644
--- a/modules/demux/adaptive/playlist/SegmentTemplate.h
+++ b/modules/demux/adaptive/playlist/SegmentTemplate.h
@@ -50,17 +50,23 @@ namespace adaptive
                 MediaSegmentTemplate( SegmentInformation * = NULL );
                 virtual ~MediaSegmentTemplate();
                 virtual void setSourceUrl( const std::string &url ); /* reimpl */
+                void setStartNumber( uint64_t );
+                void setSegmentTimeline( SegmentTimeline * );
                 void mergeWith( MediaSegmentTemplate *, vlc_tick_t );
                 virtual uint64_t getSequenceNumber() const; /* reimpl */
                 uint64_t getCurrentLiveTemplateNumber() const;
                 stime_t getMinAheadScaledTime(uint64_t) const;
                 void pruneByPlaybackTime(vlc_tick_t);
                 size_t pruneBySequenceNumber(uint64_t);
+                virtual Timescale inheritTimescale() const; /* reimpl */
+                virtual uint64_t inheritStartNumber() const;
+                stime_t inheritDuration() const;
+                SegmentTimeline * inheritSegmentTimeline() const;
                 virtual void debug(vlc_object_t *, int = 0) const; /* reimpl */
-                Property<size_t>        startNumber;
-                Property<SegmentTimeline *> segmentTimeline;
 
             protected:
+                uint64_t startNumber;
+                SegmentTimeline *segmentTimeline;
                 SegmentInformation *parentSegmentInformation;
         };
 
diff --git a/modules/demux/dash/mpd/IsoffMainParser.cpp b/modules/demux/dash/mpd/IsoffMainParser.cpp
index 1ec3402496..d378c4e548 100644
--- a/modules/demux/dash/mpd/IsoffMainParser.cpp
+++ b/modules/demux/dash/mpd/IsoffMainParser.cpp
@@ -161,17 +161,20 @@ void IsoffMainParser::parsePeriods(MPD *mpd, Node *root)
 size_t IsoffMainParser::parseSegmentTemplate(Node *templateNode, SegmentInformation *info)
 {
     size_t total = 0;
-    if (templateNode == NULL || !templateNode->hasAttribute("media"))
+    if (templateNode == NULL)
         return total;
 
-    std::string mediaurl = templateNode->getAttributeValue("media");
+    std::string mediaurl;
+    if(templateNode->hasAttribute("media"))
+        mediaurl = templateNode->getAttributeValue("media");
+
     MediaSegmentTemplate *mediaTemplate = NULL;
-    if(mediaurl.empty() || !(mediaTemplate = new (std::nothrow) MediaSegmentTemplate(info)) )
+    if( !(mediaTemplate = new (std::nothrow) MediaSegmentTemplate(info)) )
         return total;
     mediaTemplate->setSourceUrl(mediaurl);
 
     if(templateNode->hasAttribute("startNumber"))
-        mediaTemplate->startNumber.Set(Integer<uint64_t>(templateNode->getAttributeValue("startNumber")));
+        mediaTemplate->setStartNumber(Integer<uint64_t>(templateNode->getAttributeValue("startNumber")));
 
     if(templateNode->hasAttribute("timescale"))
         mediaTemplate->setTimescale(Integer<uint64_t>(templateNode->getAttributeValue("timescale")));
@@ -193,7 +196,7 @@ size_t IsoffMainParser::parseSegmentTemplate(Node *templateNode, SegmentInformat
 
     info->setSegmentTemplate(mediaTemplate);
 
-    return ++total;
+    return mediaurl.empty() ? ++total : 0;
 }
 
 size_t IsoffMainParser::parseSegmentInformation(Node *node, SegmentInformation *info, uint64_t *nextid)
@@ -452,8 +455,8 @@ void IsoffMainParser::parseTimeline(Node *node, MediaSegmentTemplate *templ)
     uint64_t number = 0;
     if(node->hasAttribute("startNumber"))
         number = Integer<uint64_t>(node->getAttributeValue("startNumber"));
-    else if(templ->startNumber.Get())
-        number = templ->startNumber.Get();
+    else if(templ->inheritStartNumber())
+        number = templ->inheritStartNumber();
 
     SegmentTimeline *timeline = new (std::nothrow) SegmentTimeline(templ);
     if(timeline)
@@ -483,7 +486,7 @@ void IsoffMainParser::parseTimeline(Node *node, MediaSegmentTemplate *templ)
 
             number += (1 + r);
         }
-        templ->segmentTimeline.Set(timeline);
+        templ->setSegmentTimeline(timeline);
     }
 }
 
diff --git a/modules/demux/dash/mpd/Representation.cpp b/modules/demux/dash/mpd/Representation.cpp
index 0080699dbc..a37d911c2c 100644
--- a/modules/demux/dash/mpd/Representation.cpp
+++ b/modules/demux/dash/mpd/Representation.cpp
@@ -104,9 +104,10 @@ std::string Representation::contextualize(size_t number, const std::string &comp
 stime_t Representation::getScaledTimeBySegmentNumber(uint64_t index, const MediaSegmentTemplate *templ) const
 {
     stime_t time = 0;
-    if(templ->segmentTimeline.Get())
+    const SegmentTimeline *tl = templ->inheritSegmentTimeline();
+    if(tl)
     {
-        time = templ->segmentTimeline.Get()->getScaledPlaybackTimeByElementNumber(index);
+        time = tl->getScaledPlaybackTimeByElementNumber(index);
     }
     else if(templ->duration.Get())
     {
diff --git a/modules/demux/smooth/playlist/Parser.cpp b/modules/demux/smooth/playlist/Parser.cpp
index 3868125823..fd14bcbd20 100644
--- a/modules/demux/smooth/playlist/Parser.cpp
+++ b/modules/demux/smooth/playlist/Parser.cpp
@@ -237,7 +237,7 @@ static void ParseStreamIndex(BasePeriod *period, Node *streamIndexNode, unsigned
             {
                 templ->setSourceUrl(url);
                 SegmentTimeline *timeline = createTimeline(streamIndexNode, period->inheritTimescale());
-                templ->segmentTimeline.Set(timeline);
+                templ->setSegmentTimeline(timeline);
                 adaptSet->setSegmentTemplate(templ);
             }
 
diff --git a/modules/demux/smooth/playlist/Representation.cpp b/modules/demux/smooth/playlist/Representation.cpp
index 58234cb146..98ba66816e 100644
--- a/modules/demux/smooth/playlist/Representation.cpp
+++ b/modules/demux/smooth/playlist/Representation.cpp
@@ -61,8 +61,12 @@ std::string Representation::contextualize(size_t number, const std::string &comp
         {
             std::stringstream ss;
             ss.imbue(std::locale("C"));
-            ss << templ->segmentTimeline.Get()->getScaledPlaybackTimeByElementNumber(number);
-            ret.replace(pos, std::string("{start_time}").length(), ss.str());
+            const SegmentTimeline *tl = templ->inheritSegmentTimeline();
+            if(tl)
+            {
+                ss << tl->getScaledPlaybackTimeByElementNumber(number);
+                ret.replace(pos, std::string("{start_time}").length(), ss.str());
+            }
         }
     }
 



More information about the vlc-commits mailing list