]> git.sesse.net Git - vlc/blob - modules/demux/dash/mpd/Segment.cpp
demux: dash: move everything under demux/
[vlc] / modules / demux / dash / mpd / Segment.cpp
1 /*
2  * Segment.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 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 #define __STDC_CONSTANT_MACROS
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include "Segment.h"
31 #include "Representation.h"
32 #include "MPD.h"
33 #include "mp4/AtomsReader.hpp"
34
35 #include <cassert>
36
37 using namespace dash::mpd;
38 using namespace dash::http;
39
40 ISegment::ISegment(const ICanonicalUrl *parent):
41     ICanonicalUrl( parent ),
42     startByte  (0),
43     endByte    (0)
44 {
45     debugName = "Segment";
46     classId = CLASSID_ISEGMENT;
47     startTime.Set(VLC_TS_INVALID);
48     duration.Set(0);
49 }
50
51 dash::http::Chunk * ISegment::getChunk(const std::string &url)
52 {
53     return new (std::nothrow) SegmentChunk(this, url);
54 }
55
56 dash::http::Chunk* ISegment::toChunk(size_t index, Representation *ctxrep)
57 {
58     Chunk *chunk;
59     try
60     {
61         chunk = getChunk(getUrlSegment().toString(index, ctxrep));
62         if (!chunk)
63             return NULL;
64     }
65     catch (int)
66     {
67         return NULL;
68     }
69
70     if(startByte != endByte)
71     {
72         chunk->setStartByte(startByte);
73         chunk->setEndByte(endByte);
74     }
75
76     return chunk;
77 }
78
79 bool ISegment::isSingleShot() const
80 {
81     return true;
82 }
83 void ISegment::done()
84 {
85     //Only used for a SegmentTemplate.
86 }
87
88 void ISegment::setByteRange(size_t start, size_t end)
89 {
90     startByte = start;
91     endByte   = end;
92 }
93
94 size_t ISegment::getOffset() const
95 {
96     return startByte;
97 }
98
99 std::string ISegment::toString(int indent) const
100 {
101     std::stringstream ss;
102     ss << std::string(indent, ' ') << debugName << " url=" << getUrlSegment().toString();
103     if(startByte!=endByte)
104         ss << " @" << startByte << ".." << endByte;
105     return ss.str();
106 }
107
108 bool ISegment::contains(size_t byte) const
109 {
110     if (startByte == endByte)
111         return false;
112     return (byte >= startByte &&
113             (!endByte || byte <= endByte) );
114 }
115
116 int ISegment::getClassId() const
117 {
118     return classId;
119 }
120
121 ISegment::SegmentChunk::SegmentChunk(ISegment *segment_, const std::string &url) :
122     dash::http::Chunk(url)
123 {
124     segment = segment_;
125 }
126
127 void ISegment::SegmentChunk::onDownload(void *, size_t)
128 {
129
130 }
131
132 Segment::Segment(ICanonicalUrl *parent) :
133         ISegment(parent)
134 {
135     size = -1;
136     classId = CLASSID_SEGMENT;
137 }
138
139 void Segment::addSubSegment(SubSegment *subsegment)
140 {
141     subsegments.push_back(subsegment);
142 }
143
144 Segment::~Segment()
145 {
146     std::vector<SubSegment*>::iterator it;
147     for(it=subsegments.begin();it!=subsegments.end();it++)
148         delete *it;
149 }
150
151 void                    Segment::setSourceUrl   ( const std::string &url )
152 {
153     if ( url.empty() == false )
154         this->sourceUrl = url;
155 }
156
157 std::string Segment::toString(int indent) const
158 {
159     if (subsegments.empty())
160     {
161         return ISegment::toString(indent);
162     }
163     else
164     {
165         std::string ret;
166         std::vector<SubSegment *>::const_iterator l;
167         for(l = subsegments.begin(); l != subsegments.end(); l++)
168         {
169             ret.append( (*l)->toString(indent + 1) );
170         }
171         return ret;
172     }
173 }
174
175 Url Segment::getUrlSegment() const
176 {
177     Url ret = getParentUrlSegment();
178     if (!sourceUrl.empty())
179         ret.append(sourceUrl);
180     return ret;
181 }
182
183 dash::http::Chunk* Segment::toChunk(size_t index, Representation *ctxrep)
184 {
185     Chunk *chunk = ISegment::toChunk(index, ctxrep);
186     if (chunk && ctxrep)
187         chunk->setBitrate(ctxrep->getBandwidth());
188     return chunk;
189 }
190
191 std::vector<ISegment*> Segment::subSegments()
192 {
193     std::vector<ISegment*> list;
194     if(!subsegments.empty())
195     {
196         std::vector<SubSegment*>::iterator it;
197         for(it=subsegments.begin();it!=subsegments.end();it++)
198             list.push_back(*it);
199     }
200     else
201     {
202         list.push_back(this);
203     }
204     return list;
205 }
206
207 InitSegment::InitSegment(ICanonicalUrl *parent) :
208     Segment(parent)
209 {
210     debugName = "InitSegment";
211     classId = CLASSID_INITSEGMENT;
212 }
213
214 IndexSegment::IndexSegment(ICanonicalUrl *parent) :
215     Segment(parent)
216 {
217     debugName = "IndexSegment";
218     classId = CLASSID_INDEXSEGMENT;
219 }
220
221 dash::http::Chunk* IndexSegment::toChunk(size_t index, Representation *ctxrep)
222 {
223     IndexSegmentChunk *chunk = dynamic_cast<IndexSegmentChunk *>(Segment::toChunk(index, ctxrep));
224     chunk->setIndexRepresentation(ctxrep);
225     return chunk;
226 }
227
228 dash::http::Chunk * IndexSegment::getChunk(const std::string &url)
229 {
230     return new IndexSegmentChunk(this, url);
231 }
232
233 IndexSegment::IndexSegmentChunk::IndexSegmentChunk(ISegment *segment, const std::string &url)
234     : SegmentChunk(segment, url)
235 {
236     rep = NULL;
237 }
238
239 void IndexSegment::IndexSegmentChunk::setIndexRepresentation(Representation *rep_)
240 {
241     rep = rep_;
242 }
243
244 void IndexSegment::IndexSegmentChunk::onDownload(void *buffer, size_t size)
245 {
246     if(!rep)
247         return;
248
249     dash::mp4::AtomsReader br(rep->getMPD()->getVLCObject());
250     br.parseBlock(buffer, size, rep);
251 }
252
253 SubSegment::SubSegment(Segment *main, size_t start, size_t end) :
254     ISegment(main), parent(main)
255 {
256     setByteRange(start, end);
257     debugName = "SubSegment";
258     classId = CLASSID_SUBSEGMENT;
259 }
260
261 Url SubSegment::getUrlSegment() const
262 {
263     return getParentUrlSegment();
264 }
265
266 std::vector<ISegment*> SubSegment::subSegments()
267 {
268     std::vector<ISegment*> list;
269     list.push_back(this);
270     return list;
271 }