Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • videolan/vlc
  • chouquette/vlc
  • bakiewicz.marek122/vlc
  • devnexen/vlc
  • rohanrajpal/vlc
  • blurrrb/vlc
  • gsoc/gsoc2019/darkapex/vlc
  • b1ue/vlc
  • fkuehne/vlc
  • magsoft/vlc
  • chub/vlc
  • cramiro9/vlc
  • robUx4/vlc
  • rom1v/vlc
  • akshayaky/vlc
  • tmk907/vlc
  • akymaster/vlc
  • govind.sharma/vlc
  • psilokos/vlc
  • xjbeta/vlc
  • jahan/vlc
  • 1480c1/vlc
  • amanchande/vlc
  • aaqib/vlc
  • rist/vlc
  • apol/vlc
  • mindfreeze/vlc
  • alexandre-janniaux/vlc
  • sandsmark/vlc
  • jagannatharjun/vlc
  • gsoc/gsoc2020/matiaslgonzalez/vlc
  • gsoc/gsoc2020/jagannatharjun/vlc
  • mstorsjo/vlc
  • gsoc/gsoc2020/vedenta/vlc
  • gsoc/gsoc2020/arnav-ishaan/vlc
  • gsoc/gsoc2020/andreduong/vlc
  • fuzun/vlc
  • gsoc/gsoc2020/vatsin/vlc
  • gsoc/gsoc2020/sagid/vlc
  • yaron/vlc
  • Phoenix/vlc
  • Garf/vlc
  • ePiratWorkarounds/vlc
  • tguillem/vlc
  • jnqnfe/vlc
  • mdc/vlc
  • Vedaa/vlc
  • rasa/vlc
  • quink/vlc
  • yealo/vlc
  • aleksey_ak/vlc
  • ePirat/vlc
  • ilya.yanok/vlc
  • asenat/vlc
  • m/vlc
  • bunjee/vlc
  • BLumia/vlc
  • sagudev/vlc
  • hamedmonji30/vlc
  • nullgemm/vlc
  • DivyamAhuja/vlc
  • thesamesam/vlc
  • dag7/vlc
  • snehil101/vlc
  • haasn/vlc
  • jbk/vlc
  • ValZapod/vlc
  • mfkl/vlc
  • WangChuan/vlc
  • core1024/vlc
  • GhostVaibhav/vlc
  • dfuhrmann/vlc
  • davide.prade/vlc
  • tmatth/vlc
  • Courmisch/vlc
  • zouya/vlc
  • hpi/vlc
  • EwoutH/vlc
  • aleung27/vlc
  • hengwu0/vlc
  • saladin/vlc
  • ashuio/vlc
  • richselwood/vlc
  • verma16Ayush/vlc
  • chemicalflash/vlc
  • PoignardAzur/vlc
  • huangjieNT/vlc
  • Blake-Haydon/vlc
  • AnuthaDev/vlc
  • gsoc/gsoc2021/mpd/vlc
  • nicolas_lequec/vlc
  • sambassaly/vlc
  • thresh/vlc
  • bonniegong/vlc
  • myaashish/vlc
  • stavros.vagionitis/vlc
  • ileoo/vlc
  • louis-santucci/vlc
  • cchristiansen/vlc
  • sabyasachi07/vlc
  • AbduAmeen/vlc
  • ashishb0410/vlc
  • urbanhusky/vlc
  • davidepietrasanta/vlc
  • riksleutelstad/vlc
  • jeremyVignelles/vlc
  • komh/vlc
  • iamjithinjohn/vlc
  • JohannesKauffmann/vlc2
  • kunglao/vlc
  • natzberg/vlc
  • jill/vlc
  • cwendling/vlc
  • adufou/vlc
  • ErwanAirone/vlc
  • HasinduDilshan10/vlc
  • vagrantc/vlc
  • rafiv/macos-bigsur-icon
  • Aymeriic/vlc
  • saranshg20/vlc
  • metzlove24/vlc
  • linkfanel/vlc
  • Ds886/vlc
  • metehan-arslan/vlc
  • Skantes/vlc
  • kgsandundananjaya96/vlc
  • mitchcapper/vlc
  • advaitgupta/vlc
  • StefanBruens/vlc
  • ratajs/vlc
  • T.M.F.B.3761/vlc
  • m222059/vlc
  • casemerrick/vlc
  • joshuaword2alt/vlc
  • sjwaddy/vlc
  • dima/vlc
  • Ybalrid/vlc
  • umxprime/vlc
  • eschmidt/vlc
  • vannieuwenhuysenmichelle/vlc
  • badcf00d/vlc
  • wesinator/vlc
  • louis/vlc
  • xqq/vlc
  • EmperorYP7/vlc
  • NicoLiam/vlc
  • loveleen/vlc
  • rofferom/vlc
  • rbultje/vlc
  • TheUnamed/vlc
  • pratiksharma341/vlc
  • Saurab17/vlc
  • purist.coder/vlc
  • Shuicheng/vlc
  • mdrrubel292/vlc
  • silverbleu00/vlc
  • metif12/vlc
  • asher-m/vlc
  • jeffk/vlc
  • Brandonbr1/vlc
  • beautyyuyanli/vlc
  • rego21/vlc
  • muyangren907/vlc
  • collectionbylawrencejason/vlc
  • evelez/vlc
  • GSMgeeth/vlc
  • Oneric/vlc
  • TJ5/vlc
  • XuanTung95/vlc
  • darrenjenny21/vlc
  • Trenly/vlc
  • RockyTDR/vlc
  • mjakubowski/vlc
  • caprica/vlc
  • ForteFrankie/vlc
  • seannamiller19/vlc
  • junlon2006/vlc
  • kiwiren6666/vlc
  • iuseiphonexs/vlc
  • fenngtun/vlc
  • Rajdutt999/vlc
  • typx/vlc
  • leon.vitanos/vlc
  • robertogarci0938/vlc
  • gsoc/gsoc2022/luc65r/vlc-mpd
  • skeller/vlc
  • MCJack123/vlc
  • luc65r/vlc-mpd
  • popov895/vlc
  • claucambra/vlc
  • brad/vlc
  • matthewmurua88/vlc
  • Tomas8874/vlc
  • philenotfound/vlc
  • makita-do3/vlc
  • LZXCorp/vlc
  • mar0x/vlc
  • senojetkennedy0102/vlc
  • shaneb243/vlc
  • ahmadbader/vlc
  • rajduttcse26/vlc-audio-filters
  • Juniorzito8415/vlc
  • achernyakov/vlc
  • lucasjetgroup/vlc
  • pupdoggy666/vlc
  • gmde9363/vlc
  • alexnwayne/vlc
  • bahareebrahimi781/vlc
  • hamad633666/vlc
  • umghof3112/vlc
  • joe0199771874/vlc
  • Octocats66666666/vlc
  • jjm_223/vlc
  • btech10110.19/vlc
  • sunnykfc028/vlc-audio-filters
  • loic/vlc
  • nguyenminhducmx1/vlc
  • JanekKrueger/vlc
  • bstubbington2/vlc
  • rcombs/vlc
  • Ordissimo/vlc
  • king7532/vlc
  • noobsauce101/vlc
  • schong0525/vlc
  • myQwil/vlc
  • apisbg91/vlc
  • geeboy0101017/vlc
  • kim.faughey/vlc
  • nurupo/vlc
  • yyusea/vlc
  • 0711235879.khco/vlc
  • ialo/vlc
  • iloveyeye2/vlc
  • gdtdftdqtd/vlc
  • leandroconsiglio/vlc
  • AndyHTML2012/vlc
  • ncz/vlc
  • lucenticus/vlc
  • knr1931/vlc
  • kjoonlee/vlc
  • chandrakant100/vlc-qt
  • johge42/vlc
  • polter/vlc
  • hexchain/vlc
  • Tushwrld/vlc
  • mztea928/vlc
  • jbelloncastro/vlc
  • alvinhochun/vlc
  • ghostpiratecrow/vlc
  • ujjwaltwitx/vlc
  • alexsonarin06/vlc
  • adrianbon76/vlc
  • altsod/vlc
  • damien.lucas44/vlc
  • dmytrivtaisa/vlc
  • utk202/vlc
  • aaxhrj/vlc
  • thomas.hermes/vlc
  • structurenewworldorder/vlc
  • slomo/vlc
  • wantlamy/vlc
  • musc.o3cminc/vlc
  • thebarshablog/vlc
  • kerrick/vlc
  • kratos142518/vlc
  • leogps/vlc
  • vacantron/vlc
  • luna_koly/vlc
  • Ratio2/vlc
  • anuoshemohammad/vlc
  • apsun/vlc
  • aaa1115910/vlc
  • alimotmoyo/vlc
  • Ambossmann/vlc
  • Sam-LearnsToCode/vlc
  • Chilledheart/vlc
  • Labnann/vlc
  • ktcoooot1/vlc
  • mohit-marathe/vlc
  • johnddx/vlc
  • manstabuk/vlc
  • Omar-ahmed314/vlc
  • vineethkm/vlc
  • 9Enemi86/vlc
  • radoslav.m.panteleev/vlc
  • ashishami2002/vlc
  • Corbax/vlc
  • firnasahmed/vlc
  • pelayarmalam4/vlc
  • c0ff330k/vlc
  • shikhindahikar/vlc
  • l342723951/vlc
  • christianschwandner/vlc
  • douniwan5788/vlc
  • 7damian7/vlc
  • ferdnyc/vlc
  • f.ales1/vlc
  • pandagby/vlc
  • BaaBaa/vlc
  • jewe37/vlc
  • w00drow/vlc
  • russelltg/vlc
  • ironicallygod/vlc
  • soumyaDghosh/vlc
  • linzihao1999/vlc
  • deyayush6/vlc
  • mibi88/vlc
  • newabdallah10/vlc
  • jhorbincolombia/vlc
  • rimvihaqueshupto/vlc
  • andrewkhon98/vlc
  • fab78/vlc
  • lapaz17/vlc
  • amanna13/vlc
  • mdakram28/vlc
  • 07jw1980/vlc
  • sohamgupta/vlc
  • Eson-Jia1/vlc
  • Sumou/vlc
  • vikram-kangotra/vlc
  • chalice191/vlc
  • olivercalder/vlc
  • aaasg4001/vlc
  • zipdox/vlc
  • kwizart/vlc
  • Dragon-S/vlc
  • jdemeule/vlc
  • gabriel_lt/vlc
  • locutusofborg/vlc
  • sammirata/vlc-librist
  • another/vlc
  • Benjamin_Loison/vlc
  • ahmedmoselhi/vlc
  • petergaal/vlc
  • huynhsontung/vlc
  • dariusmihut/vlc
  • tvermaashutosh/vlc
  • buti/vlc
  • Niram7777/vlc
  • rohan-here/vlc
  • balaji-sivasakthi/vlc
  • rlindner81/vlc
  • Kakadus/vlc
  • djain/vlc
  • ABBurmeister/vlc
  • craighuggins/vlc
  • orbea/vlc
  • maxos/vlc
  • aakarshmj/vlc
  • kblaschke/vlc
  • ankitm/vlc
  • advait-0/vlc
  • mohak2003/vlc
  • yselkowitz/vlc
  • AZM999/vlc-azm
  • andrey.turkin/vlc
  • Disha-Baghel/vlc
  • nowrep/vlc
  • Apeng/vlc
  • Choucroute_melba/vlc
  • autra/vlc
  • eclipseo/vlc
  • fhuber/vlc
  • olafhering/vlc
  • sdasda7777/vlc
  • 1div0/vlc
  • skosnits/vlc-extended-playlist-support
  • dnicolson/vlc
  • Timshel/vlc
  • octopols/vlc
  • MangalK/vlc
  • nima64/vlc
  • misawai/vlc
  • Alexander-Wilms/vlc
  • Maxime2/vlc-fork-for-visualizer
  • ww/vlc
  • jeske/vlc
  • sgross-emlix/vlc
  • morenonatural/vlc
  • freakingLovesVLC/vlc
  • borisgolovnev/vlc
  • mpromonet/vlc
  • diogo.simao-marques/vlc
  • masstock/vlc
  • pratikpatel8982/vlc
  • hugok79/vlc
  • longervision/vlc
  • abhiudaysurya/vlc
  • rishabhgarg/vlc
  • tumic/vlc
  • cart/vlc
  • shubham442/vlc
  • Aditya692005/vlc
  • sammirata/vlc4
  • syrykh/vlc
  • Vvorcun/macos-new-icon
  • AyaanshC/vlc
  • nasso/vlc
  • Quark/vlc
  • sebastinas/vlc
  • rhstone/vlc
  • talregev/vlc
  • Managor/vlc
403 results
Show changes
Commits on Source (5)
Showing
with 294 additions and 161 deletions
......@@ -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 += \
......
......@@ -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;
......
......@@ -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);
};
}
}
......
......@@ -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");
......
......@@ -47,6 +47,7 @@ namespace adaptive
void print ();
private:
Namespaces nss;
Node *root;
stream_t *stream;
......
/*
* 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;
}
/*
* 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_ */
......@@ -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;
}
......@@ -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;
};
}
}
......
......@@ -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;
}
......
......@@ -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();
}
......@@ -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);
......
......@@ -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',
......
......@@ -28,6 +28,8 @@ namespace smooth
{
using namespace adaptive::playlist;
static std::string NS_SMOOTH = "";
class Manifest : public BasePlaylist
{
friend class ManifestParser;
......
......@@ -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++);
......