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

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


vlc/vlc-3.0 | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Mar 17 00:58:18 2020 +0100| [4a97dc4c104bca868f1b9e6a031fa62e9e09ac44] | committer: Francois Cartegnie

demux: adaptive: add timeoffset/timecomplete

(cherry picked from commit 1358f1da3fe3628c6412bf2963700078ccba8d2e)

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

 .../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 e551748086..e2a33c3ee1 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(mtime_t t)
+{
+    availabilityTimeOffset = t;
+}
+
+void AbstractPlaylist::setAvailabilityTimeComplete(bool b)
+{
+    availabilityTimeComplete = b;
+}
+
+mtime_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 11d9933456..4c8dd61851 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(mtime_t);
+                void    setAvailabilityTimeComplete(bool);
+                mtime_t getAvailabilityTimeOffset() const;
+                bool    getAvailabilityTimeComplete() const;
 
                 virtual Url         getUrlSegment() const; /* impl */
                 vlc_object_t *      getVLCObject()  const;
@@ -80,6 +84,10 @@ namespace adaptive
                 mtime_t                             minBufferTime;
                 mtime_t                             maxBufferTime;
                 bool                                b_needsUpdates;
+
+             private:
+                Undef<bool>                         availabilityTimeComplete;
+                Undef<mtime_t>                      availabilityTimeOffset;
         };
     }
 }
diff --git a/modules/demux/adaptive/playlist/SegmentInformation.cpp b/modules/demux/adaptive/playlist/SegmentInformation.cpp
index 3e387992d8..bdf7a24197 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(mtime_t t)
+{
+    availabilityTimeOffset = t;
+}
+
+void SegmentInformation::setAvailabilityTimeComplete(bool b)
+{
+    availabilityTimeComplete = b;
+}
+
+mtime_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 06f7a00875..49f45cfb50 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(mtime_t);
+                void setAvailabilityTimeComplete(bool);
 
             private:
                 void init();
                 SegmentBase *     inheritSegmentBase() const;
                 SegmentList *     inheritSegmentList() const;
                 MediaSegmentTemplate * inheritSegmentTemplate() const;
+                mtime_t           inheritAvailabilityTimeOffset() const;
+                bool              inheritAvailabilityTimeComplete() const;
 
                 SegmentBase     *segmentBase;
                 SegmentList     *segmentList;
                 MediaSegmentTemplate *mediaSegmentTemplate;
                 CommonEncryption commonEncryption;
+                Undef<bool>      availabilityTimeComplete;
+                Undef<mtime_t>   availabilityTimeOffset;
         };
     }
 }
diff --git a/modules/demux/dash/mpd/IsoffMainParser.cpp b/modules/demux/dash/mpd/IsoffMainParser.cpp
index 75d5e49a4c..82c44cf591 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");
@@ -149,7 +161,10 @@ void IsoffMainParser::parsePeriods(MPD *mpd, Node *root)
             period->duration.Set(IsoTime((*it)->getAttributeValue("duration")) * CLOCK_FREQ);
         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);
@@ -180,6 +195,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"))
@@ -206,6 +223,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
@@ -239,7 +258,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"))
@@ -292,7 +314,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")));
@@ -350,6 +375,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())
     {
@@ -381,6 +407,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