]> git.sesse.net Git - vlc/blob - modules/stream_filter/dash/mpd/BasicCMParser.cpp
dash: Adding some basic getters to Representation
[vlc] / modules / stream_filter / dash / mpd / BasicCMParser.cpp
1 /*
2  * BasicCMParser.cpp
3  *****************************************************************************
4  * Copyright (C) 2010 - 2011 Klagenfurt University
5  *
6  * Created on: Aug 10, 2010
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
11  * it 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 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
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
27
28 #include "BasicCMParser.h"
29
30 #include <cstdlib>
31 #include <sstream>
32
33 using namespace dash::mpd;
34 using namespace dash::xml;
35
36 BasicCMParser::BasicCMParser    (Node *root) : root(root), mpd(NULL)
37 {
38 }
39
40 BasicCMParser::~BasicCMParser   ()
41 {
42 }
43
44 bool    BasicCMParser::parse                ()
45 {
46     this->setMPD();
47     return true;
48 }
49 void    BasicCMParser::setMPD               ()
50 {
51     this->mpd = new MPD(this->root->getAttributes());
52     this->setMPDBaseUrl(this->root);
53     this->setPeriods(this->root);
54 }
55 void    BasicCMParser::setMPDBaseUrl        (Node *root)
56 {
57     std::vector<Node *> baseUrls = DOMHelper::getChildElementByTagName(root, "BaseURL");
58
59     for(size_t i = 0; i < baseUrls.size(); i++)
60     {
61         BaseUrl *url = new BaseUrl(baseUrls.at(i)->getText());
62         this->mpd->addBaseUrl(url);
63     }
64 }
65 void    BasicCMParser::setPeriods           (Node *root)
66 {
67     std::vector<Node *> periods = DOMHelper::getElementByTagName(root, "Period", false);
68
69     for(size_t i = 0; i < periods.size(); i++)
70     {
71         Period *period = new Period(periods.at(i)->getAttributes());
72         this->setGroups(periods.at(i), period);
73         this->mpd->addPeriod(period);
74     }
75 }
76
77 void    BasicCMParser::setGroups            (Node *root, Period *period)
78 {
79     std::vector<Node *> groups = DOMHelper::getElementByTagName(root, "Group", false);
80
81     for(size_t i = 0; i < groups.size(); i++)
82     {
83         Group *group = new Group(groups.at(i)->getAttributes());
84         if ( this->parseCommonAttributesElements( groups.at( i ), group ) == false )
85         {
86             delete group;
87             continue ;
88         }
89         this->setRepresentations(groups.at(i), group);
90         period->addGroup(group);
91     }
92 }
93
94 void    BasicCMParser::setRepresentations   (Node *root, Group *group)
95 {
96     std::vector<Node *> representations = DOMHelper::getElementByTagName(root, "Representation", false);
97
98     for(size_t i = 0; i < representations.size(); i++)
99     {
100         const std::map<std::string, std::string>    attributes = representations.at(i)->getAttributes();
101
102         //FIXME: handle @dependencyId afterward
103         Representation *rep = new Representation( attributes );
104         if ( this->parseCommonAttributesElements( representations.at( i ), rep ) == false )
105         {
106             delete rep;
107             continue ;
108         }
109         this->setSegmentInfo(representations.at(i), rep);
110         if ( rep->getSegmentInfo() && rep->getSegmentInfo()->getSegments().size() > 0 )
111             group->addRepresentation(rep);
112     }
113 }
114 void    BasicCMParser::setSegmentInfo       (Node *root, Representation *rep)
115 {
116     Node    *segmentInfo = DOMHelper::getFirstChildElementByName( root, "SegmentInfo");
117
118     if ( segmentInfo )
119     {
120         SegmentInfo *info = new SegmentInfo( segmentInfo->getAttributes() );
121         this->setInitSegment( segmentInfo, info );
122         this->setSegments(segmentInfo, info );
123         rep->setSegmentInfo(info);
124     }
125 }
126
127 void    BasicCMParser::setInitSegment       (Node *root, SegmentInfo *info)
128 {
129     std::vector<Node *> initSeg = DOMHelper::getChildElementByTagName(root, "InitialisationSegmentURL");
130
131     for(size_t i = 0; i < initSeg.size(); i++)
132     {
133         InitSegment *seg = new InitSegment(initSeg.at(i)->getAttributes());
134         info->setInitSegment(seg);
135         return;
136     }
137 }
138 void    BasicCMParser::setSegments          (Node *root, SegmentInfo *info)
139 {
140     std::vector<Node *> segments = DOMHelper::getElementByTagName(root, "Url", false);
141
142     for(size_t i = 0; i < segments.size(); i++)
143     {
144         Segment *seg = new Segment(segments.at(i)->getAttributes());
145         info->addSegment(seg);
146     }
147 }
148 MPD*    BasicCMParser::getMPD               ()
149 {
150     return this->mpd;
151 }
152
153 bool    BasicCMParser::parseCommonAttributesElements( Node *node, CommonAttributesElements *common) const
154 {
155     const std::map<std::string, std::string>                &attr = node->getAttributes();
156     std::map<std::string, std::string>::const_iterator      it;
157     //Parse mandatory elements first.
158     it = attr.find( "mimeType" );
159     if ( it == attr.end() )
160     {
161         std::cerr << "Missing mandatory attribute: @mimeType" << std::endl;
162         return false;
163     }
164     common->setMimeType( it->second );
165     //Everything else is optionnal.
166     it = attr.find( "width" );
167     if ( it != attr.end() )
168         common->setWidth( atoi( it->second.c_str() ) );
169     it = attr.find( "height" );
170     if ( it != attr.end() )
171         common->setHeight( atoi( it->second.c_str() ) );
172     it = attr.find( "parx" );
173     if ( it != attr.end() )
174         common->setParX( atoi( it->second.c_str() ) );
175     it = attr.find( "pary" );
176     if ( it != attr.end() )
177         common->setParY( atoi( it->second.c_str() ) );
178     it = attr.find( "frameRate" );
179     if ( it != attr.end() )
180         common->setFrameRate( atoi( it->second.c_str() ) );
181     it = attr.find( "lang" );
182
183     if ( it != attr.end() && it->second.empty() == false )
184     {
185         std::istringstream  s( it->second );
186         while ( s )
187         {
188             std::string     lang;
189             s >> lang;
190             common->addLang( lang );
191         }
192     }
193     it = attr.find( "numberOfChannels" );
194     if ( it != attr.end() )
195     {
196         std::istringstream  s( it->second );
197         while ( s )
198         {
199             std::string     channel;
200             s >> channel;
201             common->addChannel( channel );
202         }
203     }
204     it = attr.find( "samplingRate" );
205     if ( it != attr.end() )
206     {
207         std::istringstream  s( it->second );
208         while ( s )
209         {
210             int         rate;
211             s >> rate;
212             common->addSampleRate( rate );
213         }
214     }
215     //FIXME: Handle : group, maximumRAPPeriod startWithRAP attributes
216     //FIXME: Handle : ContentProtection Accessibility Rating Viewpoing MultipleViews elements
217     return true;
218 }