Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
fb83bc0f by François Cartegnie at 2024-04-03T19:10:26+00:00
demux: adaptive: remove unused xml node code

- - - - -
f06b9059 by François Cartegnie at 2024-04-03T19:10:26+00:00
demux: adaptive: remove unneeded vtable destructor

- - - - -
ba9e7df6 by François Cartegnie at 2024-04-03T19:10:26+00:00
demux: adaptive: add shared namespaces

- - - - -
a65d6118 by François Cartegnie at 2024-04-03T19:10:26+00:00
demux: adaptive: split and remove attributes map

- - - - -
f8b95a03 by François Cartegnie at 2024-04-03T19:10:26+00:00
demux: adaptive: match namespaces

- - - - -


15 changed files:

- modules/demux/Makefile.am
- modules/demux/adaptive/xml/DOMHelper.cpp
- modules/demux/adaptive/xml/DOMHelper.h
- modules/demux/adaptive/xml/DOMParser.cpp
- modules/demux/adaptive/xml/DOMParser.h
- + modules/demux/adaptive/xml/Namespaces.cpp
- + modules/demux/adaptive/xml/Namespaces.hpp
- modules/demux/adaptive/xml/Node.cpp
- modules/demux/adaptive/xml/Node.h
- modules/demux/dash/DASHManager.cpp
- modules/demux/dash/mpd/IsoffMainParser.cpp
- modules/demux/dash/mpd/IsoffMainParser.h
- modules/demux/meson.build
- modules/demux/smooth/playlist/Manifest.hpp
- modules/demux/smooth/playlist/SmoothParser.cpp


Changes:

=====================================
modules/demux/Makefile.am
=====================================
@@ -414,6 +414,8 @@ libvlc_adaptive_la_SOURCES = \
     demux/adaptive/xml/DOMHelper.h \
     demux/adaptive/xml/DOMParser.cpp \
     demux/adaptive/xml/DOMParser.h \
+    demux/adaptive/xml/Namespaces.cpp \
+    demux/adaptive/xml/Namespaces.hpp \
     demux/adaptive/xml/Node.cpp \
     demux/adaptive/xml/Node.h
 libvlc_adaptive_la_SOURCES += \


=====================================
modules/demux/adaptive/xml/DOMHelper.cpp
=====================================
@@ -29,53 +29,56 @@
 
 using namespace adaptive::xml;
 
-std::vector<Node *> DOMHelper::getElementByTagName      (Node *root, const 
std::string& name, bool selfContain)
+std::vector<Node *> DOMHelper::getElementByTagName(Node *root, const 
std::string& name,
+                                                   const std::string& ns, bool 
selfContain)
 {
     std::vector<Node *> elements;
 
     for(size_t i = 0; i < root->getSubNodes().size(); i++)
     {
-        getElementsByTagName(root->getSubNodes().at(i), name, &elements, 
selfContain);
+        getElementsByTagName(root->getSubNodes().at(i), name, ns, &elements, 
selfContain);
     }
 
     return elements;
 }
 
-std::vector<Node *> DOMHelper::getChildElementByTagName (Node *root, const 
std::string& name)
+std::vector<Node *> DOMHelper::getChildElementByTagName(Node *root, const 
std::string& name,
+                                                        const std::string& ns)
 {
     std::vector<Node *> elements;
 
     for(size_t i = 0; i < root->getSubNodes().size(); i++)
     {
-        if( root->getSubNodes().at(i)->getName() == name )
+        if(root->getSubNodes().at(i)->matches(name, ns))
             elements.push_back(root->getSubNodes().at(i));
     }
 
     return elements;
 }
 
-void                DOMHelper::getElementsByTagName     (Node *root, const 
std::string& name, std::vector<Node*> *elements, bool selfContain)
+void DOMHelper::getElementsByTagName(Node *root, const std::string& name, 
const std::string &ns,
+                                     std::vector<Node*> *elements, bool 
selfContain)
 {
-    if(!selfContain && !root->getName().compare(name))
+    if(!selfContain && root->matches(name, ns))
     {
         elements->push_back(root);
         return;
     }
 
-    if(!root->getName().compare(name))
+    if(root->matches(name, ns))
         elements->push_back(root);
 
     for(size_t i = 0; i < root->getSubNodes().size(); i++)
     {
-        getElementsByTagName(root->getSubNodes().at(i), name, elements, 
selfContain);
+        getElementsByTagName(root->getSubNodes().at(i), name, ns, elements, 
selfContain);
     }
 }
 
-Node*           DOMHelper::getFirstChildElementByName( Node *root, const 
std::string &name )
+Node* DOMHelper::getFirstChildElementByName(Node *root, const std::string 
&name, const std::string& ns)
 {
     for(size_t i = 0; i < root->getSubNodes().size(); i++)
     {
-        if( root->getSubNodes().at( i )->getName() == name )
+        if(root->getSubNodes().at(i)->matches(name, ns))
             return root->getSubNodes().at( i );
     }
     return nullptr;


=====================================
modules/demux/adaptive/xml/DOMHelper.h
=====================================
@@ -37,12 +37,16 @@ namespace adaptive
         class DOMHelper
         {
             public:
-                static std::vector<Node *> getElementByTagName      (Node 
*root, const std::string& name, bool selfContain);
-                static std::vector<Node *> getChildElementByTagName (Node 
*root, const std::string& name);
-                static Node*               getFirstChildElementByName( Node 
*root, const std::string& name );
+                static std::vector<Node *> getElementByTagName      (Node 
*root, const std::string& name,
+                                                                     const 
std::string& ns, bool selfContain);
+                static std::vector<Node *> getChildElementByTagName (Node 
*root, const std::string& name,
+                                                                     const 
std::string& ns);
+                static Node*               getFirstChildElementByName(Node 
*root, const std::string& name,
+                                                                      const 
std::string& ns);
 
             private:
-                static void getElementsByTagName(Node *root, const 
std::string& name, std::vector<Node *> *elements, bool selfContain);
+                static void getElementsByTagName(Node *root, const 
std::string& name, const std::string &ns,
+                                                 std::vector<Node *> 
*elements, bool selfContain);
         };
     }
 }


=====================================
modules/demux/adaptive/xml/DOMParser.cpp
=====================================
@@ -29,6 +29,7 @@
 
 #include <vector>
 #include <stack>
+#include <cstring>
 #include <vlc_xml.h>
 
 using namespace adaptive::xml;
@@ -92,25 +93,28 @@ bool DOMParser::reset(stream_t *s)
 
 Node* DOMParser::processNode(bool b_strict)
 {
-    const char *data;
+    const char *data, *ns;
     int type;
     std::stack<Node *> lifo;
 
-    while( (type = xml_ReaderNextNode(vlc_reader, &data)) > 0 )
+    while( (type = xml_ReaderNextNodeNS(vlc_reader, &data, &ns)) > 0 )
     {
         switch(type)
         {
             case XML_READER_STARTELEM:
             {
+                Namespaces::Ptr ptr = nss.registerNamespace(ns);
                 bool empty = xml_ReaderIsEmptyElement(vlc_reader);
-                Node *node = new (std::nothrow) Node();
+                const char *unprefixed = std::strchr(data, ':');
+                data = unprefixed ? unprefixed + 1 : data;
+                auto name = std::make_unique<std::string>(data);
+                Node *node = new (std::nothrow) Node(std::move(name), ptr);
                 if(node)
                 {
                     if(!lifo.empty())
                         lifo.top()->addSubNode(node);
                     lifo.push(node);
 
-                    node->setName(std::string(data));
                     addAttributesToNode(node);
                 }
 
@@ -160,12 +164,14 @@ void    DOMParser::addAttributesToNode      (Node *node)
 {
     const char *attrValue;
     const char *attrName;
+    const char *ns;
 
-    while((attrName = xml_ReaderNextAttr(this->vlc_reader, &attrValue)) != 
nullptr)
+    while((attrName = xml_ReaderNextAttrNS(this->vlc_reader, &attrValue, &ns)) 
!= nullptr)
     {
+        Namespaces::Ptr ptr = nss.registerNamespace(ns ? ns : "");
         std::string key     = attrName;
         std::string value   = attrValue;
-        node->addAttribute(key, value);
+        node->addAttribute(key, ptr, value);
     }
 }
 void    DOMParser::print                    (Node *node, int offset)
@@ -175,10 +181,10 @@ void    DOMParser::print                    (Node *node, 
int offset)
 
     msg_Dbg(this->stream, "%s", node->getName().c_str());
 
-    std::vector<std::string> keys = node->getAttributeKeys();
+    const Node::Attributes &attributes = node->getAttributes();
 
-    for(size_t i = 0; i < keys.size(); i++)
-        msg_Dbg(this->stream, " %s=%s", keys.at(i).c_str(), 
node->getAttributeValue(keys.at(i)).c_str());
+    for(auto attr : attributes)
+        msg_Dbg(this->stream, " %s=%s", attr.name.c_str(), attr.value.c_str());
 
     msg_Dbg(this->stream, "\n");
 


=====================================
modules/demux/adaptive/xml/DOMParser.h
=====================================
@@ -47,6 +47,7 @@ namespace adaptive
                 void                print       ();
 
             private:
+                Namespaces          nss;
                 Node                *root;
                 stream_t            *stream;
 


=====================================
modules/demux/adaptive/xml/Namespaces.cpp
=====================================
@@ -0,0 +1,53 @@
+/*
+ * Namespaces.cpp
+ *****************************************************************************
+ * Copyright (C) 2024 - VideoLabs, VideoLAN and VLC Authors
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "Namespaces.hpp"
+
+#include <algorithm>
+#include <cstring>
+
+using namespace adaptive::xml;
+
+Namespaces::Ptr Namespaces::registerNamespace(const char *ns)
+{
+    if(ns == nullptr)
+        ns = "";
+    Ptr ptr = getNamespace(ns);
+    if(ptr == nullptr)
+        ptr = std::make_shared<Entry>(std::string(ns));
+    return ptr;
+}
+
+Namespaces::Ptr Namespaces::getNamespace(const std::string &ns)
+{
+    auto it = std::find_if(nss.begin(), nss.end(),
+                        [ns](Ptr &e){ return *e == ns; });
+    return it != nss.end() ? *it : nullptr;
+}
+
+Namespaces::Ptr Namespaces::getNamespace(const char *ns)
+{
+    auto it = std::find_if(nss.begin(), nss.end(),
+                        [ns](Ptr &e){ return !std::strcmp(e.get()->c_str(), 
ns); });
+    return it != nss.end() ? *it : nullptr;
+}


=====================================
modules/demux/adaptive/xml/Namespaces.hpp
=====================================
@@ -0,0 +1,48 @@
+/*
+ * Namespaces.hpp
+ *****************************************************************************
+ * Copyright (C) 2024 - VideoLabs, VideoLAN and VLC Authors
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#ifndef NAMESPACES_H_
+#define NAMESPACES_H_
+
+#include <vector>
+#include <string>
+#include <memory>
+
+namespace adaptive
+{
+    namespace xml
+    {
+        class Namespaces
+        {
+            public:
+                using Entry = std::string;
+                using Ptr = std::shared_ptr<Entry>;
+
+                Namespaces() = default;
+                Ptr registerNamespace(const char *);
+                Ptr getNamespace(const std::string &);
+                Ptr getNamespace(const char *);
+
+            private:
+                std::vector<Ptr> nss;
+        };
+    }
+}
+
+#endif /* NAMESPACES_HPP_ */


=====================================
modules/demux/adaptive/xml/Node.cpp
=====================================
@@ -28,6 +28,7 @@
 #include "Node.h"
 
 #include <cassert>
+#include <algorithm>
 #include <vlc_common.h>
 #include <vlc_xml.h>
 
@@ -35,10 +36,17 @@ using namespace adaptive::xml;
 
 const std::string   Node::EmptyString = "";
 
-Node::Node() :
-    type( -1 )
+bool Node::Attribute::matches(const std::string &name, const std::string &ns) 
const
 {
+    return *this->ns == ns && this->name == name;
 }
+
+Node::Node(std::unique_ptr<std::string> name, Namespaces::Ptr ns)
+{
+    this->name = std::move(name);
+    this->ns = ns;
+}
+
 Node::~Node ()
 {
     for(size_t i = 0; i < this->subNodes.size(); i++)
@@ -55,43 +63,51 @@ void                                Node::addSubNode        
    (Node *node)
 }
 const std::string&                  Node::getName               () const
 {
-    return this->name;
+    return *name;
 }
-void                                Node::setName               (const 
std::string& name)
+
+const std::string & Node::getNamespace() const
 {
-    this->name = name;
+    if(ns != nullptr)
+        return *ns;
+    return EmptyString;
 }
 
-bool                                Node::hasAttribute        (const 
std::string& name) const
+bool Node::hasAttribute(const std::string& name) const
 {
-    if(this->attributes.find(name) != this->attributes.end())
-        return true;
-
-    return false;
+    return hasAttribute(name, EmptyString);
 }
-const std::string&                  Node::getAttributeValue     (const 
std::string& key) const
-{
-    std::map<std::string, std::string>::const_iterator  it = 
this->attributes.find( key );
 
-    if ( it != this->attributes.end() )
-        return it->second;
-    return EmptyString;
+bool Node::hasAttribute(const std::string& name, const std::string &ns) const
+{
+    auto it = std::find_if(attributes.cbegin(),attributes.cend(),
+                           [name, ns](const struct Attribute &a)
+                                {return a.name == name && ns == *a.ns;});
+    return it != attributes.cend();
 }
 
-void                                Node::addAttribute          ( const 
std::string& key, const std::string& value)
+const std::string& Node::getAttributeValue(const std::string& key) const
 {
-    this->attributes[key] = value;
+    return getAttributeValue(key, EmptyString);
 }
-std::vector<std::string>            Node::getAttributeKeys      () const
+
+const std::string& Node::getAttributeValue(const std::string& key, const 
std::string &ns) const
 {
-    std::vector<std::string> keys;
-    std::map<std::string, std::string>::const_iterator it;
+    auto it = std::find_if(attributes.cbegin(),attributes.cend(),
+                           [key, ns](const struct Attribute &a)
+                                {return a.name == key && ns == *a.ns;});
+    if (it != attributes.cend())
+        return (*it).value;
+    return EmptyString;
+}
 
-    for(it = this->attributes.begin(); it != this->attributes.end(); ++it)
-    {
-        keys.push_back(it->first);
-    }
-    return keys;
+void Node::addAttribute(const std::string& key, Namespaces::Ptr ns, const 
std::string& value)
+{
+    struct Attribute attr;
+    attr.name = key;
+    attr.ns = ns;
+    attr.value = value;
+    attributes.push_back(std::move(attr));
 }
 
 const std::string&                         Node::getText               () const
@@ -104,32 +120,12 @@ void Node::setText(const std::string &text)
     this->text = text;
 }
 
-const std::map<std::string,std::string>&   Node::getAttributes         () const
+const Node::Attributes& Node::getAttributes() const
 {
     return this->attributes;
 }
 
-int Node::getType() const
-{
-    return this->type;
-}
-
-void Node::setType(int type)
-{
-    this->type = type;
-}
-
-std::vector<std::string> Node::toString(int indent) const
+bool Node::matches(const std::string &name, const std::string &ns) const
 {
-    std::vector<std::string> ret;
-    std::string text(indent, ' ');
-    text.append(getName());
-    ret.push_back(text);
-    std::vector<Node *>::const_iterator l;
-    for(l = subNodes.begin(); l < subNodes.end(); ++l)
-    {
-        std::vector<std::string> sub = (*l)->toString(indent + 1);
-        ret.insert(ret.end(), sub.begin(), sub.end());
-    }
-    return ret;
+    return *this->ns == ns && *this->name == name;
 }


=====================================
modules/demux/adaptive/xml/Node.h
=====================================
@@ -25,9 +25,10 @@
 #ifndef NODE_H_
 #define NODE_H_
 
+#include "Namespaces.hpp"
+
 #include <vector>
 #include <string>
-#include <map>
 
 namespace adaptive
 {
@@ -36,32 +37,42 @@ namespace adaptive
         class Node
         {
             public:
-                Node            ();
-                virtual ~Node   ();
+                class Attribute
+                {
+                    public:
+                        std::string name;
+                        std::string value;
+                        Namespaces::Ptr ns;
+                        bool matches(const std::string &name, const 
std::string &ns) const;
+                };
+
+                using Attributes = std::vector<struct Attribute>;
+
+                Node            () = delete;
+                Node(std::unique_ptr<std::string>, Namespaces::Ptr);
+                ~Node   ();
 
                 const std::vector<Node *>&          getSubNodes         () 
const;
                 void                                addSubNode          (Node 
*node);
                 const std::string&                  getName             () 
const;
-                void                                setName             (const 
std::string& name);
-                bool                                hasAttribute        (const 
std::string& name) const;
-                void                                addAttribute        (const 
std::string& key, const std::string& value);
+                const std::string&                  getNamespace        () 
const;
+                bool                                hasAttribute        (const 
std::string& key) const;
+                bool                                hasAttribute        (const 
std::string& key, const std::string &ns) const;
+                void                                addAttribute        (const 
std::string& key, Namespaces::Ptr, const std::string& value);
                 const std::string&                  getAttributeValue   (const 
std::string& key) const;
-                std::vector<std::string>            getAttributeKeys    () 
const;
+                const std::string&                  getAttributeValue   (const 
std::string& key, const std::string &ns) const;
                 const std::string&                  getText             () 
const;
                 void                                setText( const std::string 
&text );
-                const std::map<std::string, std::string>& getAttributes () 
const;
-                int                                 getType() const;
-                void                                setType( int type );
-                std::vector<std::string>            toString(int) const;
+                const Attributes&                   getAttributes () const;
+                bool                                matches(const std::string 
&name, const std::string &ns) const;
 
             private:
                 static const std::string            EmptyString;
                 std::vector<Node *>                 subNodes;
-                std::map<std::string, std::string>  attributes;
-                std::string                         name;
+                Attributes                          attributes;
+                std::unique_ptr<std::string>        name;
+                Namespaces::Ptr                     ns;
                 std::string                         text;
-                int                                 type;
-
         };
     }
 }


=====================================
modules/demux/dash/DASHManager.cpp
=====================================
@@ -168,23 +168,16 @@ int DASHManager::doControl(int i_query, va_list args)
 bool DASHManager::isDASH(xml::Node *root)
 {
     static const std::string namespaces[] = {
-        "urn:mpeg:mpegB:schema:DASH:MPD:DIS2011",
-        "urn:mpeg:schema:dash:mpd:2011",
+        "urn:mpeg:dash:schema:mpd:2011",
         "urn:mpeg:DASH:schema:MPD:2011",
-        "urn:mpeg:mpegB:schema:DASH:MPD:DIS2011",
         "urn:mpeg:schema:dash:mpd:2011",
-        "urn:mpeg:DASH:schema:MPD:2011",
+        "urn:mpeg:mpegB:schema:DASH:MPD:DIS2011",
     };
 
-    if(root->getName() != "MPD")
-        return false;
-
-    const std::string &ns = root->getAttributeValue("xmlns");
     for( size_t i=0; i<ARRAY_SIZE(namespaces); i++ )
-    {
-        if ( adaptive::Helper::ifind(ns, namespaces[i]) )
+        if(root->matches("MPD", namespaces[i]))
             return true;
-    }
+
     return false;
 }
 


=====================================
modules/demux/dash/mpd/IsoffMainParser.cpp
=====================================
@@ -83,7 +83,7 @@ static void parseAvailability(MPD *mpd, Node *node, T *s)
 
 void IsoffMainParser::parseMPDBaseUrl(MPD *mpd, Node *root)
 {
-    std::vector<Node *> baseUrls = DOMHelper::getChildElementByTagName(root, 
"BaseURL");
+    std::vector<Node *> baseUrls = DOMHelper::getChildElementByTagName(root, 
"BaseURL", getDASHNamespace());
 
     for(size_t i = 0; i < baseUrls.size(); i++)
         mpd->addBaseUrl(baseUrls.at(i)->getText());
@@ -97,7 +97,7 @@ MPD * IsoffMainParser::parse()
     if(mpd)
     {
         parseMPDAttributes(mpd, root);
-        parseProgramInformation(DOMHelper::getFirstChildElementByName(root, 
"ProgramInformation"), mpd);
+        parseProgramInformation(DOMHelper::getFirstChildElementByName(root, 
"ProgramInformation", getDASHNamespace()), mpd);
         parseMPDBaseUrl(mpd, root);
         parsePeriods(mpd, root);
         mpd->addAttribute(new StartnumberAttr(1));
@@ -108,56 +108,60 @@ MPD * IsoffMainParser::parse()
 
 void    IsoffMainParser::parseMPDAttributes   (MPD *mpd, xml::Node *node)
 {
-    const std::map<std::string, std::string> & attr = node->getAttributes();
+    const Node::Attributes& attributes = node->getAttributes();
 
-    std::map<std::string, std::string>::const_iterator it;
+    mpd->b_needsUpdates = false;
 
-    it = attr.find("mediaPresentationDuration");
-    if(it != attr.end())
-        mpd->duration.Set(IsoTime(it->second));
-
-    it = attr.find("minBufferTime");
-    if(it != attr.end())
-        mpd->setMinBuffering(IsoTime(it->second));
-
-    it = attr.find("minimumUpdatePeriod");
-    if(it != attr.end())
+    for(auto attr: attributes)
     {
-        mpd->b_needsUpdates = true;
-        vlc_tick_t minupdate = IsoTime(it->second);
-        if(minupdate > 0)
-            mpd->minUpdatePeriod.Set(minupdate);
-    }
-    else mpd->b_needsUpdates = false;
-
-    it = attr.find("maxSegmentDuration");
-    if(it != attr.end())
-        mpd->maxSegmentDuration.Set(IsoTime(it->second));
-
-    it = attr.find("type");
-    if(it != attr.end())
-        mpd->setType(it->second);
-
-    it = attr.find("availabilityStartTime");
-    if(it != attr.end())
-        mpd->availabilityStartTime.Set(UTCTime(it->second).mtime());
-
-    it = attr.find("availabilityEndTime");
-    if(it != attr.end())
-        mpd->availabilityEndTime.Set(UTCTime(it->second).mtime());
-
-    it = attr.find("timeShiftBufferDepth");
-        if(it != attr.end())
-            mpd->timeShiftBufferDepth.Set(IsoTime(it->second));
+        if(*attr.ns != NS_DASH)
+            continue;
 
-    it = attr.find("suggestedPresentationDelay");
-    if(it != attr.end())
-        mpd->suggestedPresentationDelay.Set(IsoTime(it->second));
+        if(attr.name == "mediaPresentationDuration")
+        {
+            mpd->duration.Set(IsoTime(attr.value));
+        }
+        else if(attr.name == "minBufferTime")
+        {
+            mpd->setMinBuffering(IsoTime(attr.value));
+        }
+        else if(attr.name == "minimumUpdatePeriod")
+        {
+            mpd->b_needsUpdates = true;
+            vlc_tick_t minupdate = IsoTime(attr.value);
+            if(minupdate > 0)
+                mpd->minUpdatePeriod.Set(minupdate);
+        }
+        else if(attr.name == "maxSegmentDuration")
+        {
+            mpd->maxSegmentDuration.Set(IsoTime(attr.value));
+        }
+        else if(attr.name == "type")
+        {
+            mpd->setType(attr.value);
+        }
+        else if(attr.name == "availabilityStartTime")
+        {
+            mpd->availabilityStartTime.Set(UTCTime(attr.value).mtime());
+        }
+        else if(attr.name == "availabilityEndTime")
+        {
+            mpd->availabilityEndTime.Set(UTCTime(attr.value).mtime());
+        }
+        else if(attr.name == "timeShiftBufferDepth")
+        {
+            mpd->timeShiftBufferDepth.Set(IsoTime(attr.value));
+        }
+        else if(attr.name == "suggestedPresentationDelay")
+        {
+            mpd->suggestedPresentationDelay.Set(IsoTime(attr.value));
+        }
+    }
 }
 
 void IsoffMainParser::parsePeriods(MPD *mpd, Node *root)
 {
-    std::vector<Node *> periods = DOMHelper::getElementByTagName(root, 
"Period", false);
+    std::vector<Node *> periods = DOMHelper::getElementByTagName(root, 
"Period", getDASHNamespace(), false);
     std::vector<Node *>::const_iterator it;
     uint64_t nextid = 0;
 
@@ -171,7 +175,7 @@ void IsoffMainParser::parsePeriods(MPD *mpd, Node *root)
             period->startTime.Set(IsoTime((*it)->getAttributeValue("start")));
         if((*it)->hasAttribute("duration"))
             
period->duration.Set(IsoTime((*it)->getAttributeValue("duration")));
-        std::vector<Node *> baseUrls = 
DOMHelper::getChildElementByTagName(*it, "BaseURL");
+        std::vector<Node *> baseUrls = 
DOMHelper::getChildElementByTagName(*it, "BaseURL", getDASHNamespace());
         if(!baseUrls.empty())
         {
             period->baseUrl.Set( new Url( baseUrls.front()->getText() ) );
@@ -187,7 +191,7 @@ void IsoffMainParser::parseSegmentBaseType(MPD *, Node 
*node,
                                            AbstractSegmentBaseType *base,
                                            SegmentInformation *parent)
 {
-    parseInitSegment(DOMHelper::getFirstChildElementByName(node, 
"Initialization"), base, parent);
+    parseInitSegment(DOMHelper::getFirstChildElementByName(node, 
"Initialization", getDASHNamespace()), base, parent);
 
     if(node->hasAttribute("indexRange"))
     {
@@ -225,7 +229,7 @@ void IsoffMainParser::parseMultipleSegmentBaseType(MPD 
*mpd, Node *node,
     if(node->hasAttribute("startNumber"))
         base->addAttribute(new 
StartnumberAttr(Integer<uint64_t>(node->getAttributeValue("startNumber"))));
 
-    parseTimeline(DOMHelper::getFirstChildElementByName(node, 
"SegmentTimeline"), base);
+    parseTimeline(DOMHelper::getFirstChildElementByName(node, 
"SegmentTimeline", getDASHNamespace()), base);
 }
 
 size_t IsoffMainParser::parseSegmentTemplate(MPD *mpd, Node *templateNode, 
SegmentInformation *info)
@@ -268,9 +272,9 @@ size_t IsoffMainParser::parseSegmentInformation(MPD *mpd, 
Node *node,
                                                 SegmentInformation *info, 
uint64_t *nextid)
 {
     size_t total = 0;
-    total += parseSegmentBase(mpd, DOMHelper::getFirstChildElementByName(node, 
"SegmentBase"), info);
-    total += parseSegmentList(mpd, DOMHelper::getFirstChildElementByName(node, 
"SegmentList"), info);
-    total += parseSegmentTemplate(mpd, 
DOMHelper::getFirstChildElementByName(node, "SegmentTemplate" ), info);
+    total += parseSegmentBase(mpd, DOMHelper::getFirstChildElementByName(node, 
"SegmentBase", getDASHNamespace()), info);
+    total += parseSegmentList(mpd, DOMHelper::getFirstChildElementByName(node, 
"SegmentList", getDASHNamespace()), info);
+    total += parseSegmentTemplate(mpd, 
DOMHelper::getFirstChildElementByName(node, "SegmentTemplate", 
getDASHNamespace()), info);
     if(node->hasAttribute("timescale"))
         info->addAttribute(new 
TimescaleAttr(Timescale(Integer<uint64_t>(node->getAttributeValue("timescale")))));
 
@@ -286,7 +290,7 @@ size_t IsoffMainParser::parseSegmentInformation(MPD *mpd, 
Node *node,
 
 void    IsoffMainParser::parseAdaptationSets  (MPD *mpd, Node *periodNode, 
BasePeriod *period)
 {
-    std::vector<Node *> adaptationSets = 
DOMHelper::getElementByTagName(periodNode, "AdaptationSet", false);
+    std::vector<Node *> adaptationSets = 
DOMHelper::getElementByTagName(periodNode, "AdaptationSet", getDASHNamespace(), 
false);
     std::vector<Node *>::const_iterator it;
     uint64_t nextid = 0;
 
@@ -307,14 +311,14 @@ void    IsoffMainParser::parseAdaptationSets  (MPD *mpd, 
Node *periodNode, BaseP
         if((*it)->hasAttribute("segmentAlignment"))
             
adaptationSet->setSegmentAligned((*it)->getAttributeValue("segmentAlignment") 
== "true");
 
-        Node *baseUrl = DOMHelper::getFirstChildElementByName((*it), 
"BaseURL");
+        Node *baseUrl = DOMHelper::getFirstChildElementByName((*it), 
"BaseURL", getDASHNamespace());
         if(baseUrl)
         {
             parseAvailability<AdaptationSet>(mpd, baseUrl, adaptationSet);
             adaptationSet->baseUrl.Set(new Url(baseUrl->getText()));
         }
 
-        Node *role = DOMHelper::getFirstChildElementByName((*it), "Role");
+        Node *role = DOMHelper::getFirstChildElementByName((*it), "Role", 
getDASHNamespace());
         if(role && role->hasAttribute("schemeIdUri") && 
role->hasAttribute("value"))
         {
             const std::string &uri = role->getAttributeValue("schemeIdUri");
@@ -370,7 +374,7 @@ void IsoffMainParser::parseCommonAttributesElements(Node 
*node,
 
 void    IsoffMainParser::parseRepresentations (MPD *mpd, Node 
*adaptationSetNode, AdaptationSet *adaptationSet)
 {
-    std::vector<Node *> representations = 
DOMHelper::getElementByTagName(adaptationSetNode, "Representation", false);
+    std::vector<Node *> representations = 
DOMHelper::getElementByTagName(adaptationSetNode, "Representation", 
getDASHNamespace(), false);
     uint64_t nextid = 0;
 
     for(size_t i = 0; i < representations.size(); i++)
@@ -378,7 +382,7 @@ void    IsoffMainParser::parseRepresentations (MPD *mpd, 
Node *adaptationSetNode
         Representation *currentRepresentation = new 
Representation(adaptationSet);
         Node *repNode = representations.at(i);
 
-        std::vector<Node *> baseUrls = 
DOMHelper::getChildElementByTagName(repNode, "BaseURL");
+        std::vector<Node *> baseUrls = 
DOMHelper::getChildElementByTagName(repNode, "BaseURL", getDASHNamespace());
         if(!baseUrls.empty())
         {
             currentRepresentation->baseUrl.Set(new 
Url(baseUrls.front()->getText()));
@@ -439,7 +443,7 @@ size_t IsoffMainParser::parseSegmentList(MPD *mpd, Node * 
segListNode, SegmentIn
     size_t total = 0;
     if(segListNode)
     {
-        std::vector<Node *> segments = 
DOMHelper::getElementByTagName(segListNode, "SegmentURL", false);
+        std::vector<Node *> segments = 
DOMHelper::getElementByTagName(segListNode, "SegmentURL", getDASHNamespace(), 
false);
         SegmentList *list;
         if((list = new (std::nothrow) SegmentList(info)))
         {
@@ -523,7 +527,7 @@ void IsoffMainParser::parseTimeline(Node *node, 
AbstractMultipleSegmentBaseType
     SegmentTimeline *timeline = new (std::nothrow) SegmentTimeline(base);
     if(timeline)
     {
-        std::vector<Node *> elements = DOMHelper::getElementByTagName(node, 
"S", false);
+        std::vector<Node *> elements = DOMHelper::getElementByTagName(node, 
"S", getDASHNamespace(), false);
         std::vector<Node *>::const_iterator it;
         for(it = elements.begin(); it != elements.end(); ++it)
         {
@@ -561,15 +565,15 @@ void IsoffMainParser::parseProgramInformation(Node * 
node, MPD *mpd)
     ProgramInformation *info = new (std::nothrow) ProgramInformation();
     if (info)
     {
-        Node *child = DOMHelper::getFirstChildElementByName(node, "Title");
+        Node *child = DOMHelper::getFirstChildElementByName(node, "Title", 
getDASHNamespace());
         if(child)
             info->setTitle(child->getText());
 
-        child = DOMHelper::getFirstChildElementByName(node, "Source");
+        child = DOMHelper::getFirstChildElementByName(node, "Source", 
getDASHNamespace());
         if(child)
             info->setSource(child->getText());
 
-        child = DOMHelper::getFirstChildElementByName(node, "Copyright");
+        child = DOMHelper::getFirstChildElementByName(node, "Copyright", 
getDASHNamespace());
         if(child)
             info->setCopyright(child->getText());
 
@@ -602,3 +606,8 @@ Profile IsoffMainParser::getProfile() const
 
     return res;
 }
+
+const std::string & IsoffMainParser::getDASHNamespace() const
+{
+    return root->getNamespace();
+}


=====================================
modules/demux/dash/mpd/IsoffMainParser.h
=====================================
@@ -61,6 +61,8 @@ namespace dash
         using namespace adaptive::playlist;
         using namespace adaptive;
 
+        static const std::string NS_DASH("urn:mpeg:dash:schema:mpd:2011");
+
         class IsoffMainParser
         {
             public:
@@ -71,6 +73,7 @@ namespace dash
 
             private:
                 mpd::Profile getProfile     () const;
+                const std::string & getDASHNamespace() const;
                 void    parseMPDBaseUrl     (MPD *, xml::Node *);
                 void    parseMPDAttributes  (MPD *, xml::Node *);
                 void    parseAdaptationSets (MPD *, xml::Node *periodNode, 
BasePeriod *period);


=====================================
modules/demux/meson.build
=====================================
@@ -571,6 +571,8 @@ vlc_modules += {
         'adaptive/xml/DOMHelper.h',
         'adaptive/xml/DOMParser.cpp',
         'adaptive/xml/DOMParser.h',
+        'adaptive/xml/Namespaces.cpp',
+        'adaptive/xml/Namespaces.hpp',
         'adaptive/xml/Node.cpp',
         'adaptive/xml/Node.h',
 


=====================================
modules/demux/smooth/playlist/Manifest.hpp
=====================================
@@ -28,6 +28,8 @@ namespace smooth
     {
         using namespace adaptive::playlist;
 
+        static std::string NS_SMOOTH = "";
+
         class Manifest : public BasePlaylist
         {
             friend class ManifestParser;


=====================================
modules/demux/smooth/playlist/SmoothParser.cpp
=====================================
@@ -58,7 +58,7 @@ static SegmentTimeline *createTimeline(Node *streamIndexNode)
     SegmentTimeline *timeline = new (std::nothrow) SegmentTimeline(nullptr);
     if(timeline)
     {
-        std::vector<Node *> chunks = 
DOMHelper::getElementByTagName(streamIndexNode, "c", true);
+        std::vector<Node *> chunks = 
DOMHelper::getElementByTagName(streamIndexNode, "c", NS_SMOOTH, true);
         std::vector<Node *>::const_iterator it;
 
         struct
@@ -253,7 +253,7 @@ static void ParseStreamIndex(BasePeriod *period, Node 
*streamIndexNode, unsigned
 
             unsigned nextid = 1;
             const std::string &type = 
streamIndexNode->getAttributeValue("Type");
-            std::vector<Node *> qualLevels = 
DOMHelper::getElementByTagName(streamIndexNode, "QualityLevel", true);
+            std::vector<Node *> qualLevels = 
DOMHelper::getElementByTagName(streamIndexNode, "QualityLevel", NS_SMOOTH, 
true);
             std::vector<Node *>::const_iterator it;
             for(it = qualLevels.begin(); it != qualLevels.end(); ++it)
                 ParseQualityLevel(adaptSet, *it, type, nextid++, id, 
timescale);
@@ -302,7 +302,7 @@ Manifest * ManifestParser::parse()
     {
         period->duration.Set(manifest->duration.Get());
         unsigned nextid = 1;
-        std::vector<Node *> streamIndexes = 
DOMHelper::getElementByTagName(root, "StreamIndex", true);
+        std::vector<Node *> streamIndexes = 
DOMHelper::getElementByTagName(root, "StreamIndex", NS_SMOOTH, true);
         std::vector<Node *>::const_iterator it;
         for(it = streamIndexes.begin(); it != streamIndexes.end(); ++it)
             ParseStreamIndex(period, *it, nextid++);



View it on GitLab: 
https://code.videolan.org/videolan/vlc/-/compare/e4d39d64c54cca9707e3c28ca12c749688f1fdb2...f8b95a0383001c74fe9da51cde0614153186b9f7

-- 
View it on GitLab: 
https://code.videolan.org/videolan/vlc/-/compare/e4d39d64c54cca9707e3c28ca12c749688f1fdb2...f8b95a0383001c74fe9da51cde0614153186b9f7
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance
_______________________________________________
vlc-commits mailing list
vlc-commits@videolan.org
https://mailman.videolan.org/listinfo/vlc-commits

Reply via email to