[vlc-commits] demux: adaptive: create low latency flag on playlist

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


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Mar 24 16:26:58 2020 +0100| [b39886dd8caf6335173d53c53ae2fa6dc752f7b0] | committer: Francois Cartegnie

demux: adaptive: create low latency flag on playlist

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

 .../demux/adaptive/playlist/AbstractPlaylist.cpp   |  5 +++
 .../demux/adaptive/playlist/AbstractPlaylist.hpp   |  1 +
 modules/demux/dash/mpd/IsoffMainParser.cpp         | 52 ++++++++++++----------
 modules/demux/dash/mpd/IsoffMainParser.h           | 12 ++---
 modules/demux/dash/mpd/MPD.cpp                     | 11 +++++
 modules/demux/dash/mpd/MPD.h                       |  3 ++
 6 files changed, 55 insertions(+), 29 deletions(-)

diff --git a/modules/demux/adaptive/playlist/AbstractPlaylist.cpp b/modules/demux/adaptive/playlist/AbstractPlaylist.cpp
index 0213d41419..52839a5dff 100644
--- a/modules/demux/adaptive/playlist/AbstractPlaylist.cpp
+++ b/modules/demux/adaptive/playlist/AbstractPlaylist.cpp
@@ -96,6 +96,11 @@ void AbstractPlaylist::addPeriod(BasePeriod *period)
     periods.push_back(period);
 }
 
+bool AbstractPlaylist::isLowLatency() const
+{
+    return false;
+}
+
 void AbstractPlaylist::setType(const std::string &type_)
 {
     type = type_;
diff --git a/modules/demux/adaptive/playlist/AbstractPlaylist.hpp b/modules/demux/adaptive/playlist/AbstractPlaylist.hpp
index e6279ba124..a7eb0fda22 100644
--- a/modules/demux/adaptive/playlist/AbstractPlaylist.hpp
+++ b/modules/demux/adaptive/playlist/AbstractPlaylist.hpp
@@ -41,6 +41,7 @@ namespace adaptive
                 virtual ~AbstractPlaylist();
 
                 virtual bool                    isLive() const = 0;
+                virtual bool                    isLowLatency() const;
                 void                            setType(const std::string &);
                 void                            setMinBuffering( vlc_tick_t );
                 void                            setMaxBuffering( vlc_tick_t );
diff --git a/modules/demux/dash/mpd/IsoffMainParser.cpp b/modules/demux/dash/mpd/IsoffMainParser.cpp
index 265dd6fdcb..3a09354c84 100644
--- a/modules/demux/dash/mpd/IsoffMainParser.cpp
+++ b/modules/demux/dash/mpd/IsoffMainParser.cpp
@@ -65,7 +65,7 @@ IsoffMainParser::~IsoffMainParser   ()
 }
 
 template <class T>
-static void parseAvailability(Node *node, T *s)
+static void parseAvailability(MPD *mpd, Node *node, T *s)
 {
     if(node->hasAttribute("availabilityTimeOffset"))
     {
@@ -73,7 +73,12 @@ static void parseAvailability(Node *node, T *s)
         s->setAvailabilityTimeOffset(val * CLOCK_FREQ);
     }
     if(node->hasAttribute("availabilityTimeComplete"))
-        s->setAvailabilityTimeComplete(node->getAttributeValue("availabilityTimeComplete") != "false");
+    {
+        bool b = (node->getAttributeValue("availabilityTimeComplete") == "false");
+        s->setAvailabilityTimeComplete(!b);
+        if(b)
+            mpd->setLowLatency(b);
+    }
 }
 
 void IsoffMainParser::parseMPDBaseUrl(MPD *mpd, Node *root)
@@ -156,7 +161,7 @@ void IsoffMainParser::parsePeriods(MPD *mpd, Node *root)
         Period *period = new (std::nothrow) Period(mpd);
         if (!period)
             continue;
-        parseSegmentInformation(*it, period, &nextid);
+        parseSegmentInformation(mpd, *it, period, &nextid);
         if((*it)->hasAttribute("start"))
             period->startTime.Set(IsoTime((*it)->getAttributeValue("start")));
         if((*it)->hasAttribute("duration"))
@@ -165,15 +170,15 @@ void IsoffMainParser::parsePeriods(MPD *mpd, Node *root)
         if(!baseUrls.empty())
         {
             period->baseUrl.Set( new Url( baseUrls.front()->getText() ) );
-            parseAvailability<Period>(baseUrls.front(), period);
+            parseAvailability<Period>(mpd, baseUrls.front(), period);
         }
 
-        parseAdaptationSets(*it, period);
+        parseAdaptationSets(mpd, *it, period);
         mpd->addPeriod(period);
     }
 }
 
-size_t IsoffMainParser::parseSegmentTemplate(Node *templateNode, SegmentInformation *info)
+size_t IsoffMainParser::parseSegmentTemplate(MPD *mpd, Node *templateNode, SegmentInformation *info)
 {
     size_t total = 0;
     if (templateNode == NULL)
@@ -197,7 +202,7 @@ size_t IsoffMainParser::parseSegmentTemplate(Node *templateNode, SegmentInformat
     if(templateNode->hasAttribute("duration"))
         mediaTemplate->duration.Set(Integer<stime_t>(templateNode->getAttributeValue("duration")));
 
-    parseAvailability<SegmentInformation>(templateNode, info);
+    parseAvailability<SegmentInformation>(mpd, templateNode, info);
 
     InitSegmentTemplate *initTemplate = NULL;
 
@@ -216,16 +221,17 @@ size_t IsoffMainParser::parseSegmentTemplate(Node *templateNode, SegmentInformat
     return mediaurl.empty() ? ++total : 0;
 }
 
-size_t IsoffMainParser::parseSegmentInformation(Node *node, SegmentInformation *info, uint64_t *nextid)
+size_t IsoffMainParser::parseSegmentInformation(MPD *mpd, Node *node,
+                                                SegmentInformation *info, uint64_t *nextid)
 {
     size_t total = 0;
-    total += parseSegmentBase(DOMHelper::getFirstChildElementByName(node, "SegmentBase"), info);
-    total += parseSegmentList(DOMHelper::getFirstChildElementByName(node, "SegmentList"), info);
-    total += parseSegmentTemplate(DOMHelper::getFirstChildElementByName(node, "SegmentTemplate" ), info);
+    total += parseSegmentBase(mpd, DOMHelper::getFirstChildElementByName(node, "SegmentBase"), info);
+    total += parseSegmentList(mpd, DOMHelper::getFirstChildElementByName(node, "SegmentList"), info);
+    total += parseSegmentTemplate(mpd, DOMHelper::getFirstChildElementByName(node, "SegmentTemplate" ), info);
     if(node->hasAttribute("timescale"))
         info->setTimescale(Integer<uint64_t>(node->getAttributeValue("timescale")));
 
-    parseAvailability<SegmentInformation>(node, info);
+    parseAvailability<SegmentInformation>(mpd, node, info);
 
     if(node->hasAttribute("id"))
         info->setID(ID(node->getAttributeValue("id")));
@@ -235,7 +241,7 @@ size_t IsoffMainParser::parseSegmentInformation(Node *node, SegmentInformation *
     return total;
 }
 
-void    IsoffMainParser::parseAdaptationSets  (Node *periodNode, Period *period)
+void    IsoffMainParser::parseAdaptationSets  (MPD *mpd, Node *periodNode, Period *period)
 {
     std::vector<Node *> adaptationSets = DOMHelper::getElementByTagName(periodNode, "AdaptationSet", false);
     std::vector<Node *>::const_iterator it;
@@ -261,7 +267,7 @@ void    IsoffMainParser::parseAdaptationSets  (Node *periodNode, Period *period)
         Node *baseUrl = DOMHelper::getFirstChildElementByName((*it), "BaseURL");
         if(baseUrl)
         {
-            parseAvailability<AdaptationSet>(baseUrl, adaptationSet);
+            parseAvailability<AdaptationSet>(mpd, baseUrl, adaptationSet);
             adaptationSet->baseUrl.Set(new Url(baseUrl->getText()));
         }
 
@@ -290,9 +296,9 @@ void    IsoffMainParser::parseAdaptationSets  (Node *periodNode, Period *period)
             }
         }
 
-        parseSegmentInformation(*it, adaptationSet, &nextid);
+        parseSegmentInformation(mpd, *it, adaptationSet, &nextid);
 
-        parseRepresentations((*it), adaptationSet);
+        parseRepresentations(mpd, (*it), adaptationSet);
 
 #ifdef ADAPTATIVE_ADVANCED_DEBUG
         if(adaptationSet->description.Get().empty())
@@ -305,7 +311,7 @@ void    IsoffMainParser::parseAdaptationSets  (Node *periodNode, Period *period)
             delete adaptationSet;
     }
 }
-void    IsoffMainParser::parseRepresentations (Node *adaptationSetNode, AdaptationSet *adaptationSet)
+void    IsoffMainParser::parseRepresentations (MPD *mpd, Node *adaptationSetNode, AdaptationSet *adaptationSet)
 {
     std::vector<Node *> representations = DOMHelper::getElementByTagName(adaptationSetNode, "Representation", false);
     uint64_t nextid = 0;
@@ -319,7 +325,7 @@ void    IsoffMainParser::parseRepresentations (Node *adaptationSetNode, Adaptati
         if(!baseUrls.empty())
         {
             currentRepresentation->baseUrl.Set(new Url(baseUrls.front()->getText()));
-            parseAvailability<Representation>(baseUrls.front(), currentRepresentation);
+            parseAvailability<Representation>(mpd, baseUrls.front(), currentRepresentation);
         }
 
         if(repNode->hasAttribute("id"))
@@ -340,7 +346,7 @@ void    IsoffMainParser::parseRepresentations (Node *adaptationSetNode, Adaptati
         if(repNode->hasAttribute("codecs"))
             currentRepresentation->addCodecs(repNode->getAttributeValue("codecs"));
 
-        size_t i_total = parseSegmentInformation(repNode, currentRepresentation, &nextid);
+        size_t i_total = parseSegmentInformation(mpd, repNode, currentRepresentation, &nextid);
         /* Empty Representation with just baseurl (ex: subtitles) */
         if(i_total == 0 &&
            (currentRepresentation->baseUrl.Get() && !currentRepresentation->baseUrl.Get()->empty()) &&
@@ -354,7 +360,7 @@ void    IsoffMainParser::parseRepresentations (Node *adaptationSetNode, Adaptati
         adaptationSet->addRepresentation(currentRepresentation);
     }
 }
-size_t IsoffMainParser::parseSegmentBase(Node * segmentBaseNode, SegmentInformation *info)
+size_t IsoffMainParser::parseSegmentBase(MPD *mpd, Node * segmentBaseNode, SegmentInformation *info)
 {
     SegmentBase *base;
 
@@ -378,7 +384,7 @@ size_t IsoffMainParser::parseSegmentBase(Node * segmentBaseNode, SegmentInformat
     }
 
     parseInitSegment(DOMHelper::getFirstChildElementByName(segmentBaseNode, "Initialization"), base, info);
-    parseAvailability<SegmentInformation>(segmentBaseNode, info);
+    parseAvailability<SegmentInformation>(mpd, segmentBaseNode, info);
 
     if(!base->initialisationSegment.Get() && base->indexSegment.Get() && base->indexSegment.Get()->getOffset())
     {
@@ -393,7 +399,7 @@ size_t IsoffMainParser::parseSegmentBase(Node * segmentBaseNode, SegmentInformat
     return 1;
 }
 
-size_t IsoffMainParser::parseSegmentList(Node * segListNode, SegmentInformation *info)
+size_t IsoffMainParser::parseSegmentList(MPD *mpd, Node * segListNode, SegmentInformation *info)
 {
     size_t total = 0;
     if(segListNode)
@@ -410,7 +416,7 @@ size_t IsoffMainParser::parseSegmentList(Node * segListNode, SegmentInformation
             if(segListNode->hasAttribute("timescale"))
                 list->setTimescale(Integer<uint64_t>(segListNode->getAttributeValue("timescale")));
 
-            parseAvailability<SegmentInformation>(segListNode, info);
+            parseAvailability<SegmentInformation>(mpd, segListNode, info);
 
             uint64_t nzStartTime = 0;
             std::vector<Node *>::const_iterator it;
diff --git a/modules/demux/dash/mpd/IsoffMainParser.h b/modules/demux/dash/mpd/IsoffMainParser.h
index 3ff61d36f8..0bd0f59ae5 100644
--- a/modules/demux/dash/mpd/IsoffMainParser.h
+++ b/modules/demux/dash/mpd/IsoffMainParser.h
@@ -72,15 +72,15 @@ namespace dash
                 mpd::Profile getProfile     () const;
                 void    parseMPDBaseUrl     (MPD *, xml::Node *);
                 void    parseMPDAttributes  (MPD *, xml::Node *);
-                void    parseAdaptationSets (xml::Node *periodNode, Period *period);
-                void    parseRepresentations(xml::Node *adaptationSetNode, AdaptationSet *adaptationSet);
+                void    parseAdaptationSets (MPD *, xml::Node *periodNode, Period *period);
+                void    parseRepresentations(MPD *, xml::Node *adaptationSetNode, AdaptationSet *adaptationSet);
                 void    parseInitSegment    (xml::Node *, Initializable<Segment> *, SegmentInformation *);
                 void    parseTimeline       (xml::Node *, MediaSegmentTemplate *);
                 void    parsePeriods        (MPD *, xml::Node *);
-                size_t  parseSegmentInformation(xml::Node *, SegmentInformation *, uint64_t *);
-                size_t  parseSegmentBase    (xml::Node *, SegmentInformation *);
-                size_t  parseSegmentList    (xml::Node *, SegmentInformation *);
-                size_t  parseSegmentTemplate(xml::Node *, SegmentInformation *);
+                size_t  parseSegmentInformation(MPD *, xml::Node *, SegmentInformation *, uint64_t *);
+                size_t  parseSegmentBase    (MPD *, xml::Node *, SegmentInformation *);
+                size_t  parseSegmentList    (MPD *, xml::Node *, SegmentInformation *);
+                size_t  parseSegmentTemplate(MPD *, xml::Node *, SegmentInformation *);
                 void    parseProgramInformation(xml::Node *, MPD *);
 
                 xml::Node       *root;
diff --git a/modules/demux/dash/mpd/MPD.cpp b/modules/demux/dash/mpd/MPD.cpp
index 091764f413..adc1147c5a 100644
--- a/modules/demux/dash/mpd/MPD.cpp
+++ b/modules/demux/dash/mpd/MPD.cpp
@@ -42,6 +42,7 @@ MPD::MPD (vlc_object_t *p_object, Profile profile_) :
     profile( profile_ )
 {
     programInfo.Set( NULL );
+    lowLatency = false;
 }
 
 MPD::~MPD()
@@ -60,6 +61,16 @@ bool MPD::isLive() const
         return (type != "static");
 }
 
+bool MPD::isLowLatency() const
+{
+    return lowLatency;
+}
+
+void MPD::setLowLatency(bool b)
+{
+    lowLatency = b;
+}
+
 Profile MPD::getProfile() const
 {
     return profile;
diff --git a/modules/demux/dash/mpd/MPD.h b/modules/demux/dash/mpd/MPD.h
index fb06f52188..f95a04a645 100644
--- a/modules/demux/dash/mpd/MPD.h
+++ b/modules/demux/dash/mpd/MPD.h
@@ -48,12 +48,15 @@ namespace dash
 
                 Profile                         getProfile() const;
                 virtual bool                    isLive() const;
+                virtual bool                    isLowLatency() const;
+                void                            setLowLatency(bool);
                 virtual void                    debug();
 
                 Property<ProgramInformation *>      programInfo;
 
             private:
                 Profile                             profile;
+                bool                                lowLatency;
         };
     }
 }



More information about the vlc-commits mailing list