3 *****************************************************************************
4 * Copyright (C) 2014 - VideoLAN Authors
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
21 #include "Representation.h"
22 #include "SegmentTemplate.h"
23 #include "SegmentTimeline.h"
27 using namespace dash::mpd;
33 Url::Url(const Component & comp)
38 Url::Url(const std::string &str)
40 prepend(Component(str));
43 Url & Url::prepend(const Component & comp)
45 components.insert(components.begin(), comp);
49 Url & Url::append(const Component & comp)
51 components.push_back(comp);
55 Url & Url::prepend(const Url &url)
57 components.insert(components.begin(), url.components.begin(), url.components.end());
61 Url & Url::append(const Url &url)
63 components.insert(components.end(), url.components.begin(), url.components.end());
67 std::string Url::toString() const
69 return toString(0, NULL);
72 std::string Url::toString(size_t index, const Representation *rep) const
75 std::vector<Component>::const_iterator it;
76 for(it = components.begin(); it != components.end(); it++)
78 ret.append((*it).contextualize(index, rep));
83 Url::Component::Component(const std::string & str, const MediaSegmentTemplate *templ_)
89 mtime_t Url::Component::getScaledTimeBySegmentNumber(size_t index, const Representation *) const
92 if(templ->segmentTimeline.Get())
94 time = templ->segmentTimeline.Get()->getScaledPlaybackTimeByElementNumber(index);
96 else if(templ->duration.Get())
98 time = templ->duration.Get() * index;
103 size_t Url::Component::getSegmentNumber(size_t index, const Representation *rep) const
105 index += templ->startNumber.Get();
106 /* live streams / templated */
107 if(rep->getMPD()->isLive())
109 if(templ->segmentTimeline.Get())
113 else if(templ->duration.Get())
115 mtime_t playbackstart = rep->getMPD()->playbackStart.Get();
116 mtime_t streamstart = rep->getMPD()->availabilityStartTime.Get();
117 streamstart += rep->getPeriodStart();
118 mtime_t duration = templ->duration.Get();
119 uint64_t timescale = templ->inheritTimescale();
120 if(duration && timescale)
121 index += (playbackstart - streamstart) * timescale / duration;
127 std::string Url::Component::contextualize(size_t index, const Representation *rep) const
129 std::string ret(component);
137 pos = ret.find("$Time$");
138 if(pos != std::string::npos)
140 std::stringstream ss;
141 ss << getScaledTimeBySegmentNumber(index, rep);
142 ret.replace(pos, std::string("$Time$").length(), ss.str());
145 pos = ret.find("$Number$");
146 if(pos != std::string::npos)
148 std::stringstream ss;
149 ss << getSegmentNumber(index, rep);
150 ret.replace(pos, std::string("$Number$").length(), ss.str());
154 pos = ret.find("$Number%");
155 size_t tokenlength = std::string("$Number%").length();
156 size_t fmtstart = pos + tokenlength;
157 if(pos != std::string::npos && fmtstart < ret.length())
159 size_t fmtend = ret.find('$', fmtstart);
160 if(fmtend != std::string::npos)
162 std::istringstream iss(ret.substr(fmtstart, fmtend - fmtstart + 1));
167 if (iss.peek() != '$')
169 std::stringstream oss;
170 oss.width(width); /* set format string length */
172 oss << getSegmentNumber(index, rep);
173 ret.replace(pos, fmtend - pos + 1, oss.str());
180 pos = ret.find("$Bandwidth$");
181 if(pos != std::string::npos)
183 std::stringstream ss;
184 ss << rep->getBandwidth();
185 ret.replace(pos, std::string("$Bandwidth$").length(), ss.str());
188 pos = ret.find("$RepresentationID$");
189 if(pos != std::string::npos)
191 std::stringstream ss;
193 ret.replace(pos, std::string("$RepresentationID$").length(), ss.str());