[vlc-commits] demux: adaptive: add timeoffset/timecomplete

Francois Cartegnie git at videolan.org
Tue Mar 24 23:35:11 CET 2020


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Mar 17 00:58:18 2020 +0100| [1358f1da3fe3628c6412bf2963700078ccba8d2e] | committer: Francois Cartegnie

demux: adaptive: add timeoffset/timecomplete

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

 .../demux/adaptive/playlist/AbstractPlaylist.cpp   | 20 +++++++++++++++
 .../demux/adaptive/playlist/AbstractPlaylist.hpp   |  8 ++++++
 .../demux/adaptive/playlist/SegmentInformation.cpp | 30 ++++++++++++++++++++++
 .../demux/adaptive/playlist/SegmentInformation.hpp |  6 +++++
 modules/demux/dash/mpd/IsoffMainParser.cpp         | 28 ++++++++++++++++++++
 5 files changed, 92 insertions(+)

diff --git a/modules/demux/adaptive/playlist/AbstractPlaylist.cpp b/modules/demux/adaptive/playlist/AbstractPlaylist.cpp
index 43b98f9d69..0213d41419 100644
--- a/modules/demux/adaptive/playlist/AbstractPlaylist.cpp
+++ b/modules/demux/adaptive/playlist/AbstractPlaylist.cpp
@@ -71,6 +71,26 @@ void AbstractPlaylist::setPlaylistUrl(const std::string &url)
     playlistUrl = url;
 }
 
+void AbstractPlaylist::setAvailabilityTimeOffset(vlc_tick_t t)
+{
+    availabilityTimeOffset = t;
+}
+
+void AbstractPlaylist::setAvailabilityTimeComplete(bool b)
+{
+    availabilityTimeComplete = b;
+}
+
+vlc_tick_t AbstractPlaylist::getAvailabilityTimeOffset() const
+{
+    return availabilityTimeOffset.isSet() ? availabilityTimeOffset.value() : 0;
+}
+
+bool AbstractPlaylist::getAvailabilityTimeComplete() const
+{
+    return !availabilityTimeComplete.isSet() || availabilityTimeComplete.value();
+}
+
 void AbstractPlaylist::addPeriod(BasePeriod *period)
 {
     periods.push_back(period);
diff --git a/modules/demux/adaptive/playlist/AbstractPlaylist.hpp b/modules/demux/adaptive/playlist/AbstractPlaylist.hpp
index 45d2b1f98f..e6279ba124 100644
--- a/modules/demux/adaptive/playlist/AbstractPlaylist.hpp
+++ b/modules/demux/adaptive/playlist/AbstractPlaylist.hpp
@@ -51,6 +51,10 @@ namespace adaptive
                 void    addPeriod               (BasePeriod *period);
                 void    addBaseUrl              (const std::string &);
                 void    setPlaylistUrl          (const std::string &);
+                void    setAvailabilityTimeOffset(vlc_tick_t);
+                void    setAvailabilityTimeComplete(bool);
+                vlc_tick_t getAvailabilityTimeOffset() const;
+                bool    getAvailabilityTimeComplete() const;
 
                 virtual Url         getUrlSegment() const; /* impl */
                 vlc_object_t *      getVLCObject()  const;
@@ -80,6 +84,10 @@ namespace adaptive
                 vlc_tick_t                          minBufferTime;
                 vlc_tick_t                          maxBufferTime;
                 bool                                b_needsUpdates;
+
+             private:
+                Undef<bool>                         availabilityTimeComplete;
+                Undef<vlc_tick_t>                   availabilityTimeOffset;
         };
     }
 }
diff --git a/modules/demux/adaptive/playlist/SegmentInformation.cpp b/modules/demux/adaptive/playlist/SegmentInformation.cpp
index 889cb8524d..3e3a24baf8 100644
--- a/modules/demux/adaptive/playlist/SegmentInformation.cpp
+++ b/modules/demux/adaptive/playlist/SegmentInformation.cpp
@@ -761,3 +761,33 @@ MediaSegmentTemplate * SegmentInformation::inheritSegmentTemplate() const
     else
         return NULL;
 }
+
+void SegmentInformation::setAvailabilityTimeOffset(vlc_tick_t t)
+{
+    availabilityTimeOffset = t;
+}
+
+void SegmentInformation::setAvailabilityTimeComplete(bool b)
+{
+    availabilityTimeComplete = b;
+}
+
+vlc_tick_t SegmentInformation::inheritAvailabilityTimeOffset() const
+{
+    for(const SegmentInformation *p = this; p; p = p->parent)
+    {
+        if(availabilityTimeOffset.isSet())
+            return availabilityTimeOffset.value();
+    }
+    return getPlaylist()->getAvailabilityTimeOffset();
+}
+
+bool SegmentInformation::inheritAvailabilityTimeComplete() const
+{
+    for(const SegmentInformation *p = this; p; p = p->parent)
+    {
+        if(availabilityTimeComplete.isSet())
+            return availabilityTimeComplete.value();
+    }
+    return getPlaylist()->getAvailabilityTimeComplete();
+}
diff --git a/modules/demux/adaptive/playlist/SegmentInformation.hpp b/modules/demux/adaptive/playlist/SegmentInformation.hpp
index 5691d1e862..af142cadd9 100644
--- a/modules/demux/adaptive/playlist/SegmentInformation.hpp
+++ b/modules/demux/adaptive/playlist/SegmentInformation.hpp
@@ -99,17 +99,23 @@ namespace adaptive
                 void setSegmentTemplate(MediaSegmentTemplate *);
                 virtual Url getUrlSegment() const; /* impl */
                 Property<Url *> baseUrl;
+                void setAvailabilityTimeOffset(vlc_tick_t);
+                void setAvailabilityTimeComplete(bool);
 
             private:
                 void init();
                 SegmentBase *     inheritSegmentBase() const;
                 SegmentList *     inheritSegmentList() const;
                 MediaSegmentTemplate * inheritSegmentTemplate() const;
+                vlc_tick_t        inheritAvailabilityTimeOffset() const;
+                bool              inheritAvailabilityTimeComplete() const;
 
                 SegmentBase     *segmentBase;
                 SegmentList     *segmentList;
                 MediaSegmentTemplate *mediaSegmentTemplate;
                 CommonEncryption commonEncryption;
+                Undef<bool>      availabilityTimeComplete;
+                Undef<vlc_tick_t>availabilityTimeOffset;
         };
     }
 }
diff --git a/modules/demux/dash/mpd/IsoffMainParser.cpp b/modules/demux/dash/mpd/IsoffMainParser.cpp
index b05ba1f189..265dd6fdcb 100644
--- a/modules/demux/dash/mpd/IsoffMainParser.cpp
+++ b/modules/demux/dash/mpd/IsoffMainParser.cpp
@@ -64,6 +64,18 @@ IsoffMainParser::~IsoffMainParser   ()
 {
 }
 
+template <class T>
+static void parseAvailability(Node *node, T *s)
+{
+    if(node->hasAttribute("availabilityTimeOffset"))
+    {
+        double val = Integer<double>(node->getAttributeValue("availabilityTimeOffset"));
+        s->setAvailabilityTimeOffset(val * CLOCK_FREQ);
+    }
+    if(node->hasAttribute("availabilityTimeComplete"))
+        s->setAvailabilityTimeComplete(node->getAttributeValue("availabilityTimeComplete") != "false");
+}
+
 void IsoffMainParser::parseMPDBaseUrl(MPD *mpd, Node *root)
 {
     std::vector<Node *> baseUrls = DOMHelper::getChildElementByTagName(root, "BaseURL");
@@ -151,7 +163,10 @@ void IsoffMainParser::parsePeriods(MPD *mpd, Node *root)
             period->duration.Set(IsoTime((*it)->getAttributeValue("duration")));
         std::vector<Node *> baseUrls = DOMHelper::getChildElementByTagName(*it, "BaseURL");
         if(!baseUrls.empty())
+        {
             period->baseUrl.Set( new Url( baseUrls.front()->getText() ) );
+            parseAvailability<Period>(baseUrls.front(), period);
+        }
 
         parseAdaptationSets(*it, period);
         mpd->addPeriod(period);
@@ -182,6 +197,8 @@ size_t IsoffMainParser::parseSegmentTemplate(Node *templateNode, SegmentInformat
     if(templateNode->hasAttribute("duration"))
         mediaTemplate->duration.Set(Integer<stime_t>(templateNode->getAttributeValue("duration")));
 
+    parseAvailability<SegmentInformation>(templateNode, info);
+
     InitSegmentTemplate *initTemplate = NULL;
 
     if(templateNode->hasAttribute("initialization"))
@@ -208,6 +225,8 @@ size_t IsoffMainParser::parseSegmentInformation(Node *node, SegmentInformation *
     if(node->hasAttribute("timescale"))
         info->setTimescale(Integer<uint64_t>(node->getAttributeValue("timescale")));
 
+    parseAvailability<SegmentInformation>(node, info);
+
     if(node->hasAttribute("id"))
         info->setID(ID(node->getAttributeValue("id")));
     else
@@ -241,7 +260,10 @@ void    IsoffMainParser::parseAdaptationSets  (Node *periodNode, Period *period)
 
         Node *baseUrl = DOMHelper::getFirstChildElementByName((*it), "BaseURL");
         if(baseUrl)
+        {
+            parseAvailability<AdaptationSet>(baseUrl, adaptationSet);
             adaptationSet->baseUrl.Set(new Url(baseUrl->getText()));
+        }
 
         Node *role = DOMHelper::getFirstChildElementByName((*it), "Role");
         if(role && role->hasAttribute("schemeIdUri") && role->hasAttribute("value"))
@@ -295,7 +317,10 @@ void    IsoffMainParser::parseRepresentations (Node *adaptationSetNode, Adaptati
 
         std::vector<Node *> baseUrls = DOMHelper::getChildElementByTagName(repNode, "BaseURL");
         if(!baseUrls.empty())
+        {
             currentRepresentation->baseUrl.Set(new Url(baseUrls.front()->getText()));
+            parseAvailability<Representation>(baseUrls.front(), currentRepresentation);
+        }
 
         if(repNode->hasAttribute("id"))
             currentRepresentation->setID(ID(repNode->getAttributeValue("id")));
@@ -353,6 +378,7 @@ size_t IsoffMainParser::parseSegmentBase(Node * segmentBaseNode, SegmentInformat
     }
 
     parseInitSegment(DOMHelper::getFirstChildElementByName(segmentBaseNode, "Initialization"), base, info);
+    parseAvailability<SegmentInformation>(segmentBaseNode, info);
 
     if(!base->initialisationSegment.Get() && base->indexSegment.Get() && base->indexSegment.Get()->getOffset())
     {
@@ -384,6 +410,8 @@ size_t IsoffMainParser::parseSegmentList(Node * segListNode, SegmentInformation
             if(segListNode->hasAttribute("timescale"))
                 list->setTimescale(Integer<uint64_t>(segListNode->getAttributeValue("timescale")));
 
+            parseAvailability<SegmentInformation>(segListNode, info);
+
             uint64_t nzStartTime = 0;
             std::vector<Node *>::const_iterator it;
             for(it = segments.begin(); it != segments.end(); ++it)



More information about the vlc-commits mailing list