]> git.sesse.net Git - vlc/blob - modules/stream_filter/dash/mpd/IsoffMainParser.cpp
stream_filter: dash: deduplicate parser code
[vlc] / modules / stream_filter / dash / mpd / IsoffMainParser.cpp
1 /*
2  * IsoffMainParser.cpp
3  *****************************************************************************
4  * Copyright (C) 2010 - 2012 Klagenfurt University
5  *
6  * Created on: Jan 27, 2012
7  * Authors: Christopher Mueller <christopher.mueller@itec.uni-klu.ac.at>
8  *          Christian Timmerer  <christian.timmerer@itec.uni-klu.ac.at>
9  *
10  * This program is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU Lesser General Public License as published
12  * by the Free Software Foundation; either version 2.1 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program; if not, write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include "IsoffMainParser.h"
30 #include "xml/DOMHelper.h"
31 #include <vlc_strings.h>
32
33 using namespace dash::mpd;
34 using namespace dash::xml;
35
36 IsoffMainParser::IsoffMainParser    (Node *root, stream_t *p_stream) :
37                  IMPDParser(root, NULL, p_stream, NULL)
38 {
39 }
40 IsoffMainParser::~IsoffMainParser   ()
41 {
42 }
43
44 bool    IsoffMainParser::parse              ()
45 {
46     mpd = new MPD();
47     setMPDAttributes();
48     setMPDBaseUrl(root);
49     setPeriods(root);
50     print();
51     return true;
52 }
53
54 void    IsoffMainParser::setMPDAttributes   ()
55 {
56     const std::map<std::string, std::string> attr = this->root->getAttributes();
57
58     std::map<std::string, std::string>::const_iterator it;
59
60     it = attr.find("mediaPresentationDuration");
61     if(it != attr.end())
62         this->mpd->setDuration(str_duration(it->second.c_str()));
63
64     it = attr.find("minBufferTime");
65     if(it != attr.end())
66         this->mpd->setMinBufferTime(str_duration( it->second.c_str()));
67
68 }
69
70 void    IsoffMainParser::setAdaptationSets  (Node *periodNode, Period *period)
71 {
72     std::vector<Node *> adaptationSets = DOMHelper::getElementByTagName(periodNode, "AdaptationSet", false);
73
74     for(size_t i = 0; i < adaptationSets.size(); i++)
75     {
76         AdaptationSet *adaptationSet = new AdaptationSet();
77         this->setRepresentations(adaptationSets.at(i), adaptationSet);
78         period->addAdaptationSet(adaptationSet);
79     }
80 }
81 void    IsoffMainParser::setRepresentations (Node *adaptationSetNode, AdaptationSet *adaptationSet)
82 {
83     std::vector<Node *> representations = DOMHelper::getElementByTagName(adaptationSetNode, "Representation", false);
84
85     for(size_t i = 0; i < representations.size(); i++)
86     {
87         this->currentRepresentation = new Representation;
88         Node *repNode = representations.at(i);
89
90         if(repNode->hasAttribute("width"))
91             this->currentRepresentation->setWidth(atoi(repNode->getAttributeValue("width").c_str()));
92
93         if(repNode->hasAttribute("height"))
94             this->currentRepresentation->setHeight(atoi(repNode->getAttributeValue("height").c_str()));
95
96         if(repNode->hasAttribute("bandwidth"))
97             this->currentRepresentation->setBandwidth(atoi(repNode->getAttributeValue("bandwidth").c_str()));
98
99         this->setSegmentBase(repNode, this->currentRepresentation);
100         this->setSegmentList(repNode, this->currentRepresentation);
101         adaptationSet->addRepresentation(this->currentRepresentation);
102     }
103 }
104 void    IsoffMainParser::setSegmentBase     (dash::xml::Node *repNode, Representation *rep)
105 {
106     std::vector<Node *> segmentBase = DOMHelper::getElementByTagName(repNode, "SegmentBase", false);
107
108     if(segmentBase.size() > 0)
109     {
110         SegmentBase *base = new SegmentBase();
111         this->setInitSegment(segmentBase.at(0), base);
112         rep->setSegmentBase(base);
113     }
114 }
115 void    IsoffMainParser::setSegmentList     (dash::xml::Node *repNode, Representation *rep)
116 {
117     std::vector<Node *> segmentList = DOMHelper::getElementByTagName(repNode, "SegmentList", false);
118
119     if(segmentList.size() > 0)
120     {
121         SegmentList *list = new SegmentList();
122         this->setSegments(segmentList.at(0), list);
123         rep->setSegmentList(list);
124     }
125
126 }
127 void    IsoffMainParser::setInitSegment     (dash::xml::Node *segBaseNode, SegmentBase *base)
128 {
129     std::vector<Node *> initSeg = DOMHelper::getElementByTagName(segBaseNode, "Initialisation", false);
130
131     if(initSeg.size() == 0)
132         initSeg = DOMHelper::getElementByTagName(segBaseNode, "Initialization", false);
133
134     if(initSeg.size() > 0)
135     {
136         Segment *seg = new Segment( this->currentRepresentation );
137         seg->setSourceUrl(initSeg.at(0)->getAttributeValue("sourceURL"));
138
139         if(initSeg.at(0)->hasAttribute("range"))
140         {
141             std::string range = initSeg.at(0)->getAttributeValue("range");
142             size_t pos = range.find("-");
143             seg->setByteRange(atoi(range.substr(0, pos).c_str()), atoi(range.substr(pos + 1, range.size()).c_str()));
144         }
145
146         for(size_t i = 0; i < this->mpd->getBaseUrls().size(); i++)
147             seg->addBaseUrl(this->mpd->getBaseUrls().at(i));
148
149         base->addInitSegment(seg);
150     }
151 }
152 void    IsoffMainParser::setSegments        (dash::xml::Node *segListNode, SegmentList *list)
153 {
154     std::vector<Node *> segments = DOMHelper::getElementByTagName(segListNode, "SegmentURL", false);
155
156     for(size_t i = 0; i < segments.size(); i++)
157     {
158         Segment *seg = new Segment( this->currentRepresentation );
159         seg->setSourceUrl(segments.at(i)->getAttributeValue("media"));
160
161         if(segments.at(i)->hasAttribute("mediaRange"))
162         {
163             std::string range = segments.at(i)->getAttributeValue("mediaRange");
164             size_t pos = range.find("-");
165             seg->setByteRange(atoi(range.substr(0, pos).c_str()), atoi(range.substr(pos + 1, range.size()).c_str()));
166         }
167
168         for(size_t j = 0; j < this->mpd->getBaseUrls().size(); j++)
169             seg->addBaseUrl(this->mpd->getBaseUrls().at(j));
170
171         list->addSegment(seg);
172     }
173 }
174 void    IsoffMainParser::print              ()
175 {
176     if(mpd)
177     {
178         msg_Dbg(p_stream, "MPD profile=%d mediaPresentationDuration=%ld minBufferTime=%ld", mpd->getProfile(),
179                                                                                                   mpd->getDuration(),
180                                                                                                   mpd->getMinBufferTime());
181         std::vector<BaseUrl *>::const_iterator h;
182         for(h = mpd->getBaseUrls().begin(); h != mpd->getBaseUrls().end(); h++)
183             msg_Dbg(p_stream, "BaseUrl=%s", (*h)->getUrl().c_str());
184
185         std::vector<Period *>::const_iterator i;
186         for(i = mpd->getPeriods().begin(); i != mpd->getPeriods().end(); i++)
187         {
188             msg_Dbg(p_stream, " Period");
189             std::vector<AdaptationSet *>::const_iterator j;
190             for(j = (*i)->getAdaptationSets().begin(); j != (*i)->getAdaptationSets().end(); j++)
191             {
192                 msg_Dbg(p_stream, "  AdaptationSet");
193                 std::vector<Representation *>::const_iterator k;
194                 for(k = (*j)->getRepresentations().begin(); k != (*j)->getRepresentations().begin(); k++)
195                 {
196                     msg_Dbg(p_stream, "   Representation");
197                     msg_Dbg(p_stream, "    InitSeg url=%s", (*k)->getSegmentBase()->getInitSegment()->getSourceUrl().c_str());
198                     std::vector<Segment *>::const_iterator l;
199                     for(l = (*k)->getSegmentList()->getSegments().begin();
200                         l < (*k)->getSegmentList()->getSegments().end(); l++)
201                     {
202                         msg_Dbg(p_stream, "    Segment url=%s", (*l)->getSourceUrl().c_str());
203                     }
204                 }
205             }
206         }
207     }
208 }