stream_filter/dash/mpd/SegmentInfoCommon.h \
stream_filter/dash/mpd/SegmentInfoDefault.cpp \
stream_filter/dash/mpd/SegmentInfoDefault.h \
+ stream_filter/dash/mpd/SegmentInformation.cpp \
+ stream_filter/dash/mpd/SegmentInformation.hpp \
stream_filter/dash/mpd/SegmentList.cpp \
stream_filter/dash/mpd/SegmentList.h \
stream_filter/dash/mpd/SegmentTemplate.cpp \
if(!currentPeriod)
return NULL;
- const Representation *rep = getCurrentRepresentation(type);
+ Representation *rep = getCurrentRepresentation(type);
if ( rep == NULL )
return NULL;
{
}
-const Representation *AlwaysBestAdaptationLogic::getCurrentRepresentation(Streams::Type type) const
+Representation *AlwaysBestAdaptationLogic::getCurrentRepresentation(Streams::Type type) const
{
RepresentationSelector selector;
return selector.select(currentPeriod, type);
public:
AlwaysBestAdaptationLogic (mpd::MPD *mpd);
- virtual const mpd::Representation *getCurrentRepresentation(Streams::Type) const;
+ virtual mpd::Representation *getCurrentRepresentation(Streams::Type) const;
};
}
}
{
}
-const Representation *AlwaysLowestAdaptationLogic::getCurrentRepresentation(Streams::Type type) const
+Representation *AlwaysLowestAdaptationLogic::getCurrentRepresentation(Streams::Type type) const
{
RepresentationSelector selector;
return selector.select(currentPeriod, type, 0);
public:
AlwaysLowestAdaptationLogic(mpd::MPD *mpd);
- virtual const dash::mpd::Representation* getCurrentRepresentation(Streams::Type) const;
+ virtual dash::mpd::Representation* getCurrentRepresentation(Streams::Type) const;
};
}
}
};
virtual dash::http::Chunk* getNextChunk (Streams::Type) = 0;
- virtual const dash::mpd::Representation* getCurrentRepresentation(Streams::Type) const = 0;
+ virtual dash::mpd::Representation* getCurrentRepresentation(Streams::Type) const = 0;
};
}
}
height = var_InheritInteger(mpd->getVLCObject(), "dash-prefheight");
}
-const Representation *RateBasedAdaptationLogic::getCurrentRepresentation(Streams::Type type) const
+Representation *RateBasedAdaptationLogic::getCurrentRepresentation(Streams::Type type) const
{
if(currentPeriod == NULL)
return NULL;
public:
RateBasedAdaptationLogic (mpd::MPD *mpd);
- const dash::mpd::Representation *getCurrentRepresentation(Streams::Type) const;
+ dash::mpd::Representation *getCurrentRepresentation(Streams::Type) const;
virtual void updateDownloadRate(size_t, mtime_t);
private:
using namespace dash::mp4;
using namespace dash::mpd;
-AtomsReader::AtomsReader(ISegment *segment_)
+AtomsReader::AtomsReader(vlc_object_t *object_)
{
- segment = segment_;
+ object = object_;
rootbox = NULL;
}
AtomsReader::~AtomsReader()
{
- vlc_object_t *object = segment->getRepresentation()->getMPD()->getVLCObject();
while(rootbox && rootbox->p_first)
{
MP4_Box_t *p_next = rootbox->p_first->p_next;
delete rootbox;
}
-bool AtomsReader::parseBlock(void *buffer, size_t size)
+bool AtomsReader::parseBlock(void *buffer, size_t size, Representation *rep)
{
- if(!segment->getRepresentation())
+ if(!rep)
return false;
- vlc_object_t *object = segment->getRepresentation()->getMPD()->getVLCObject();
+
stream_t *stream = stream_MemoryNew( object, (uint8_t *)buffer, size, true);
if (stream)
{
point.offset += sidx->p_items[i].i_referenced_size;
point.time += sidx->p_items[i].i_subsegment_duration;
}
- segment->getRepresentation()->SplitUsingIndex(splitlist);
+ rep->SplitUsingIndex(splitlist);
}
}
stream_Delete(stream);
# include "config.h"
#endif
-#include "mpd/Segment.h"
#include <vlc_common.h>
#include <vlc_stream.h>
extern "C" {
namespace dash
{
+ namespace mpd
+ {
+ class Representation;
+ }
namespace mp4
{
class AtomsReader
{
public:
- AtomsReader(dash::mpd::ISegment *);
+ AtomsReader(vlc_object_t *);
~AtomsReader();
- bool parseBlock(void *, size_t);
+ bool parseBlock(void *, size_t, dash::mpd::Representation *);
protected:
- dash::mpd::ISegment *segment;
+ vlc_object_t *object;
MP4_Box_t *rootbox;
};
}
using namespace dash::mpd;
AdaptationSet::AdaptationSet(Period *period) :
- ICanonicalUrl( period ),
+ SegmentInformation( period ),
subsegmentAlignmentFlag( false ),
segmentInfoDefault( NULL ),
- isBitstreamSwitching( false ),
- mediaTemplate( NULL ),
- initTemplate( NULL )
+ isBitstreamSwitching( false )
{
}
{
delete this->segmentInfoDefault;
vlc_delete_all( this->representations );
- delete mediaTemplate;
- delete initTemplate;
}
const std::string& AdaptationSet::getMimeType() const
this->representations.push_back(rep);
}
-void AdaptationSet::setTemplates(SegmentTemplate *media, SegmentTemplate *init)
-{
- mediaTemplate = media;
- initTemplate = init;
-}
-
-std::vector<SegmentTemplate *> AdaptationSet::getTemplates() const
-{
- std::vector<SegmentTemplate *> ret;
- if(mediaTemplate)
- {
- if(initTemplate)
- ret.push_back(initTemplate);
- ret.push_back(mediaTemplate);
- }
- return ret;
-}
void AdaptationSet::setBitstreamSwitching (bool value)
{
#include "mpd/Representation.h"
#include "mpd/CommonAttributesElements.h"
-#include "mpd/ICanonicalUrl.hpp"
+#include "mpd/SegmentInformation.hpp"
namespace dash
{
class Period;
class SegmentTemplate;
- class AdaptationSet : public CommonAttributesElements, public ICanonicalUrl
+ class AdaptationSet : public CommonAttributesElements,
+ public SegmentInformation
{
public:
AdaptationSet(Period *);
const SegmentInfoDefault* getSegmentInfoDefault() const;
void setSegmentInfoDefault( const SegmentInfoDefault* seg );
void setBitstreamSwitching(bool value);
- void setTemplates( SegmentTemplate *, SegmentTemplate * = NULL );
- std::vector<SegmentTemplate *> getTemplates() const;
bool getBitstreamSwitching() const;
void addRepresentation( Representation *rep );
virtual Url getUrlSegment() const; /* reimpl */
std::vector<Representation *> representations;
const SegmentInfoDefault* segmentInfoDefault;
bool isBitstreamSwitching;
- SegmentTemplate * mediaTemplate;
- SegmentTemplate * initTemplate;
};
}
}
}
}
-void IMPDParser::setPeriods(Node *root_)
-{
- std::vector<Node *> periods = DOMHelper::getElementByTagName(root_, "Period", false);
-
- for(size_t i = 0; i < periods.size(); i++)
- {
- Period *period = new Period(mpd);
- setAdaptationSets(periods.at(i), period);
- mpd->addPeriod(period);
- }
-}
-
MPD* IMPDParser::getMPD()
{
return mpd;
virtual MPD* getMPD ();
virtual void setMPDBaseUrl(dash::xml::Node *root);
virtual void setAdaptationSets(dash::xml::Node *periodNode, Period *period) = 0;
- virtual void setPeriods(dash::xml::Node *root);
protected:
dash::xml::Node *root;
mpd = new MPD(p_stream, profile);
setMPDAttributes();
setMPDBaseUrl(root);
- setPeriods(root);
+ parsePeriods(root);
+
print();
return true;
}
mpd->setType(it->second);
}
-void IsoffMainParser::parseTemplate(Node *templateNode, AdaptationSet *set)
+void IsoffMainParser::parsePeriods(Node *root)
{
+ std::vector<Node *> periods = DOMHelper::getElementByTagName(root, "Period", false);
+ std::vector<Node *>::const_iterator it;
+
+ for(it = periods.begin(); it != periods.end(); it++)
+ {
+ Period *period = new (std::nothrow) Period(mpd);
+ if (!period)
+ continue;
+ parseSegmentInformation(*it, period);
+ setAdaptationSets(*it, period);
+ mpd->addPeriod(period);
+ }
+}
+
+size_t IsoffMainParser::parseSegmentTemplate(Node *templateNode, SegmentInformation *info)
+{
+ size_t total = 0;
if (templateNode == NULL || !templateNode->hasAttribute("media"))
- return;
+ return total;
std::string mediaurl = templateNode->getAttributeValue("media");
SegmentTemplate *mediaTemplate = NULL;
- if(mediaurl.empty() || !(mediaTemplate = new (std::nothrow) SegmentTemplate(set)) )
- return;
+ if(mediaurl.empty() || !(mediaTemplate = new (std::nothrow) SegmentTemplate(info)) )
+ return total;
mediaTemplate->setSourceUrl(mediaurl);
if(templateNode->hasAttribute("startNumber"))
if(templateNode->hasAttribute("initialization"))
{
std::string initurl = templateNode->getAttributeValue("initialization");
- if(!initurl.empty() && (initTemplate = new (std::nothrow) InitSegmentTemplate(set)))
+ if(!initurl.empty() && (initTemplate = new (std::nothrow) InitSegmentTemplate(info)))
initTemplate->setSourceUrl(initurl);
}
- set->setTemplates(mediaTemplate, initTemplate);
+ info->setSegmentTemplate(mediaTemplate, SegmentInformation::INFOTYPE_MEDIA);
+ info->setSegmentTemplate(initTemplate, SegmentInformation::INFOTYPE_INIT);
+
+ total += ( mediaTemplate != NULL );
+
+ return total;
+}
+
+size_t IsoffMainParser::parseSegmentInformation(Node *node, SegmentInformation *info)
+{
+ size_t total = 0;
+ parseSegmentBase(DOMHelper::getFirstChildElementByName(node, "SegmentBase"), info);
+ total += parseSegmentList(DOMHelper::getFirstChildElementByName(node, "SegmentList"), info);
+ total += parseSegmentTemplate(DOMHelper::getFirstChildElementByName(node, "SegmentTemplate" ), info);
+ return total;
}
void IsoffMainParser::setAdaptationSets (Node *periodNode, Period *period)
if((*it)->hasAttribute("mimeType"))
adaptationSet->setMimeType((*it)->getAttributeValue("mimeType"));
- parseTemplate(DOMHelper::getFirstChildElementByName( *it, "SegmentTemplate" ), adaptationSet);
+ parseSegmentInformation( *it, adaptationSet );
setRepresentations((*it), adaptationSet);
period->addAdaptationSet(adaptationSet);
if(repNode->hasAttribute("mimeType"))
currentRepresentation->setMimeType(repNode->getAttributeValue("mimeType"));
- std::vector<Node *> segmentBase = DOMHelper::getElementByTagName(repNode, "SegmentBase", false);
- std::vector<Node *> segmentList = DOMHelper::getElementByTagName(repNode, "SegmentList", false);
-
- setSegmentBase(segmentBase, currentRepresentation);
- setSegmentList(segmentList, currentRepresentation);
-
- if(segmentBase.empty() && segmentList.empty() && adaptationSet->getTemplates().empty())
+ size_t totalmediasegments = parseSegmentInformation(repNode, currentRepresentation);
+ if(!totalmediasegments)
{
/* unranged & segment less representation, add fake segment */
SegmentList *list = new SegmentList();
}
}
-void IsoffMainParser::setSegmentBase (std::vector<Node *> &segmentBase, Representation *rep)
+void IsoffMainParser::parseSegmentBase(Node * segmentBaseNode, SegmentInformation *info)
{
- if(segmentBase.empty())
+ if(!segmentBaseNode)
return;
- else if(segmentBase.front()->hasAttribute("indexRange"))
+ else if(segmentBaseNode->hasAttribute("indexRange"))
{
SegmentList *list = new SegmentList();
Segment *seg;
size_t start = 0, end = 0;
- if (std::sscanf(segmentBase.front()->getAttributeValue("indexRange").c_str(), "%"PRIu64"-%"PRIu64, &start, &end) == 2)
+ if (std::sscanf(segmentBaseNode->getAttributeValue("indexRange").c_str(), "%"PRIu64"-%"PRIu64, &start, &end) == 2)
{
- seg = new IndexSegment(rep);
+ seg = new IndexSegment(info);
seg->setByteRange(start, end);
list->addSegment(seg);
/* index must be before data, so data starts at index end */
- seg = new Segment(rep);
+ seg = new Segment(info);
seg->setByteRange(end + 1, 0);
}
else
{
- seg = new Segment(rep);
+ seg = new Segment(info);
}
list->addSegment(seg);
- rep->setSegmentList(list);
+ info->setSegmentList(list);
- std::vector<Node *> initSeg = DOMHelper::getElementByTagName(segmentBase.front(), "Initialization", false);
+ std::vector<Node *> initSeg = DOMHelper::getElementByTagName(segmentBaseNode, "Initialization", false);
if(!initSeg.empty())
{
SegmentBase *base = new SegmentBase();
- setInitSegment(segmentBase.front(), base);
- rep->setSegmentBase(base);
+ setInitSegment(segmentBaseNode, base);
+ info->setSegmentBase(base);
}
}
else
{
SegmentBase *base = new SegmentBase();
- setInitSegment(segmentBase.front(), base);
- rep->setSegmentBase(base);
+ setInitSegment(segmentBaseNode, base);
+ info->setSegmentBase(base);
}
}
-void IsoffMainParser::setSegmentList (std::vector<Node *> &segmentList, Representation *rep)
+
+size_t IsoffMainParser::parseSegmentList(Node * segListNode, SegmentInformation *info)
{
- if(segmentList.size() > 0)
+ size_t total = 0;
+ if(segListNode)
{
+ std::vector<Node *> segments = DOMHelper::getElementByTagName(segListNode, "SegmentURL", false);
SegmentList *list = new SegmentList();
- this->setSegments(segmentList.at(0), list);
- rep->setSegmentList(list);
- }
+ if(!segments.empty() && (list = new (std::nothrow) SegmentList()))
+ {
+ std::vector<Node *>::const_iterator it;
+ for(it = segments.begin(); it != segments.end(); it++)
+ {
+ Node *segmentURL = *it;
+ std::string mediaUrl = segmentURL->getAttributeValue("media");
+ if(mediaUrl.empty())
+ continue;
+ Segment *seg = new (std::nothrow) Segment(info);
+ if(!seg)
+ continue;
+
+ seg->setSourceUrl(segmentURL->getAttributeValue("media"));
+
+ if(segmentURL->hasAttribute("mediaRange"))
+ {
+ std::string range = segmentURL->getAttributeValue("mediaRange");
+ size_t pos = range.find("-");
+ seg->setByteRange(atoi(range.substr(0, pos).c_str()), atoi(range.substr(pos + 1, range.size()).c_str()));
+ }
+
+ list->addSegment(seg);
+ total++;
+ }
+
+ info->setSegmentList(list);
+ }
+ }
+ return total;
}
+
void IsoffMainParser::setInitSegment (dash::xml::Node *segBaseNode, SegmentBase *base)
{
std::vector<Node *> initSeg = DOMHelper::getElementByTagName(segBaseNode, "Initialisation", false);
base->addInitSegment(seg);
}
}
-void IsoffMainParser::setSegments (dash::xml::Node *segListNode, SegmentList *list)
-{
- std::vector<Node *> segments = DOMHelper::getElementByTagName(segListNode, "SegmentURL", false);
-
- for(size_t i = 0; i < segments.size(); i++)
- {
- Segment *seg = new Segment( this->currentRepresentation );
- seg->setSourceUrl(segments.at(i)->getAttributeValue("media"));
- if(segments.at(i)->hasAttribute("mediaRange"))
- {
- std::string range = segments.at(i)->getAttributeValue("mediaRange");
- size_t pos = range.find("-");
- seg->setByteRange(atoi(range.substr(0, pos).c_str()), atoi(range.substr(pos + 1, range.size()).c_str()));
- }
-
- list->addSegment(seg);
- }
-}
void IsoffMainParser::print ()
{
if(mpd)
void setMPDAttributes ();
void setAdaptationSets (dash::xml::Node *periodNode, Period *period);
void setRepresentations (dash::xml::Node *adaptationSetNode, AdaptationSet *adaptationSet);
- void setSegmentBase (std::vector<xml::Node *> &, Representation *rep);
- void setSegmentList (std::vector<xml::Node *> &, Representation *rep);
void setInitSegment (dash::xml::Node *segBaseNode, SegmentBase *base);
- void setSegments (dash::xml::Node *segListNode, SegmentList *list);
- void parseTemplate (dash::xml::Node *templateNode, AdaptationSet *);
+ void parsePeriods (dash::xml::Node *);
+ size_t parseSegmentInformation(dash::xml::Node *, SegmentInformation *);
+ void parseSegmentBase (dash::xml::Node *, SegmentInformation *);
+ size_t parseSegmentList (dash::xml::Node *, SegmentInformation *);
+ size_t parseSegmentTemplate(dash::xml::Node *, SegmentInformation *);
};
}
}
using namespace dash::mpd;
Period::Period(MPD *mpd) :
- ICanonicalUrl( mpd )
+ SegmentInformation( mpd )
{
}
#include "mpd/AdaptationSet.h"
#include "mpd/ICanonicalUrl.hpp"
+#include "mpd/SegmentInformation.hpp"
#include "Streams.hpp"
namespace dash
namespace mpd
{
class MPD;
- class Period : public ICanonicalUrl
+
+ class Period : public SegmentInformation
{
public:
Period(MPD *);
using namespace dash::mpd;
Representation::Representation ( AdaptationSet *set, MPD *mpd_ ) :
- ICanonicalUrl ( set ),
+ SegmentInformation( set ),
mpd ( mpd_ ),
adaptationSet ( set ),
bandwidth (0),
qualityRanking ( -1 ),
- segmentInfo ( NULL ),
trickModeType ( NULL ),
- segmentBase ( NULL ),
- segmentList ( NULL ),
baseUrl ( NULL ),
width (0),
height (0)
Representation::~Representation ()
{
- delete(this->segmentInfo);
delete(this->trickModeType);
- delete segmentBase;
- delete segmentList;
delete baseUrl;
}
this->bandwidth = bandwidth;
}
-SegmentInfo* Representation::getSegmentInfo() const
-{
- return this->segmentInfo;
-}
TrickModeType* Representation::getTrickModeType () const
{
this->trickModeType = trickModeType;
}
-void Representation::setSegmentInfo (SegmentInfo *info)
-{
- this->segmentInfo = info;
-}
int Representation::getQualityRanking() const
this->dependencies.push_back( dep );
}
-std::vector<ISegment *> Representation::getSegments() const
-{
- std::vector<ISegment *> retSegments;
-
- if ( segmentInfo )
- {
- /* init segments are always single segment */
- retSegments.push_back( segmentInfo->getInitialisationSegment() );
-
- if ( !segmentInfo->getSegments().empty() )
- {
- std::vector<Segment *>::const_iterator it;
- for(it=segmentInfo->getSegments().begin();
- it!=segmentInfo->getSegments().end(); it++)
- {
- std::vector<ISegment *> list = (*it)->subSegments();
- retSegments.insert( retSegments.end(), list.begin(), list.end() );
- }
- }
- }
- else
- {
- /* init segments are always single segment */
- if( segmentBase && segmentBase->getInitSegment() )
- retSegments.push_back( segmentBase->getInitSegment() );
-
- if ( segmentList && !segmentList->getSegments().empty() )
- {
- std::vector<Segment *>::const_iterator it;
- for(it=segmentList->getSegments().begin();
- it!=segmentList->getSegments().end(); it++)
- {
- std::vector<ISegment *> list = (*it)->subSegments();
- retSegments.insert( retSegments.end(), list.begin(), list.end() );
- }
- }
- }
-
- if(retSegments.empty())
- {
- std::vector<SegmentTemplate *> list = adaptationSet->getTemplates();
- retSegments.insert( retSegments.end(), list.begin(), list.end() );
- }
-
- return retSegments;
-}
-
-void Representation::setSegmentList (SegmentList *list)
-{
- this->segmentList = list;
-}
-
-void Representation::setSegmentBase (SegmentBase *base)
-{
- this->segmentBase = base;
-}
void Representation::setBaseUrl(BaseUrl *base)
{
{
return mpd;
}
-
-static void insertIntoSegment(std::vector<Segment *> &seglist, size_t start,
- size_t end, mtime_t time)
-{
- std::vector<Segment *>::iterator segIt;
- for(segIt = seglist.begin(); segIt < seglist.end(); segIt++)
- {
- Segment *segment = *segIt;
- if(segment->getClassId() == Segment::CLASSID_SEGMENT &&
- segment->contains(end + segment->getOffset()))
- {
- SubSegment *subsegment = new SubSegment(segment,
- start + segment->getOffset(),
- end + segment->getOffset());
- segment->addSubSegment(subsegment);
- segment->setStartTime(time);
- break;
- }
- }
-}
-
-void Representation::SplitUsingIndex(std::vector<SplitPoint> &splitlist)
-{
- std::vector<Segment *> seglist = segmentList->getSegments();
- std::vector<SplitPoint>::const_iterator splitIt;
- size_t start = 0, end = 0;
- mtime_t time = 0;
-
- for(splitIt = splitlist.begin(); splitIt < splitlist.end(); splitIt++)
- {
- start = end;
- SplitPoint split = *splitIt;
- end = split.offset;
- if(splitIt == splitlist.begin() && split.offset == 0)
- continue;
- time = split.time;
- insertIntoSegment(seglist, start, end, time);
- end++;
- }
-
- if(start != 0)
- {
- start = end;
- end = 0;
- insertIntoSegment(seglist, start, end, time);
- }
-}
#include "mpd/TrickModeType.h"
#include "mpd/SegmentBase.h"
#include "mpd/SegmentList.h"
+#include "mpd/SegmentInformation.hpp"
#include "mpd/BaseUrl.h"
-#include "mpd/ICanonicalUrl.hpp"
namespace dash
{
class MPD;
class Representation : public CommonAttributesElements,
- public ICanonicalUrl
+ public SegmentInformation
{
public:
Representation( AdaptationSet *, MPD *mpd );
* It cannot be NULL, or without any Segments in it.
* It can however have a NULL InitSegment
*/
- SegmentInfo* getSegmentInfo () const;
TrickModeType* getTrickModeType () const;
- void setSegmentInfo( SegmentInfo *info );
void setTrickMode( TrickModeType *trickModeType );
- std::vector<ISegment*> getSegments ()const;
- void setSegmentList (SegmentList *list);
- void setSegmentBase (SegmentBase *base);
void setWidth (int width);
int getWidth () const;
void setHeight (int height);
std::vector<std::string> toString() const;
virtual Url getUrlSegment () const; /* impl */
- class SplitPoint
- {
- public:
- size_t offset;
- mtime_t time;
- };
- void SplitUsingIndex(std::vector<SplitPoint>&);
-
private:
MPD *mpd;
AdaptationSet *adaptationSet;
std::string id;
int qualityRanking;
std::list<const Representation*> dependencies;
- SegmentInfo *segmentInfo;
TrickModeType *trickModeType;
- SegmentBase *segmentBase;
- SegmentList *segmentList;
BaseUrl *baseUrl;
int width;
int height;
return new (std::nothrow) SegmentChunk(this, url);
}
-dash::http::Chunk* ISegment::toChunk(size_t index, const Representation *ctxrep)
+dash::http::Chunk* ISegment::toChunk(size_t index, Representation *ctxrep)
{
Chunk *chunk;
try
}
Segment::Segment(ICanonicalUrl *parent) :
- ISegment(parent),
- parentRepresentation( NULL )
+ ISegment(parent)
{
size = -1;
classId = CLASSID_SEGMENT;
}
-Segment::Segment(Representation *parent) :
- ISegment(parent),
- parentRepresentation( parent )
-{
- if ( parent && parent->getSegmentInfo() != NULL && parent->getSegmentInfo()->getDuration() >= 0 )
- this->size = parent->getBandwidth() * parent->getSegmentInfo()->getDuration();
- else
- this->size = -1;
- classId = CLASSID_SEGMENT;
-}
-
void Segment::addSubSegment(SubSegment *subsegment)
{
subsegments.push_back(subsegment);
this->sourceUrl = url;
}
-Representation *Segment::getRepresentation() const
-{
- return parentRepresentation;
-}
-
-
std::string Segment::toString() const
{
if (subsegments.empty())
return ret;
}
-dash::http::Chunk* Segment::toChunk(size_t index, const Representation *ctxrep)
+dash::http::Chunk* Segment::toChunk(size_t index, Representation *ctxrep)
{
Chunk *chunk = ISegment::toChunk(index, ctxrep);
- if (chunk && parentRepresentation)
- chunk->setBitrate(parentRepresentation->getBandwidth());
+ if (chunk && ctxrep)
+ chunk->setBitrate(ctxrep->getBandwidth());
return chunk;
}
return list;
}
-InitSegment::InitSegment(Representation *parent) :
+InitSegment::InitSegment(ICanonicalUrl *parent) :
Segment(parent)
{
debugName = "InitSegment";
classId = CLASSID_INITSEGMENT;
}
-IndexSegment::IndexSegment(Representation *parent) :
+IndexSegment::IndexSegment(ICanonicalUrl *parent) :
Segment(parent)
{
debugName = "IndexSegment";
classId = CLASSID_INDEXSEGMENT;
}
+dash::http::Chunk* IndexSegment::toChunk(size_t index, Representation *ctxrep)
+{
+ IndexSegmentChunk *chunk = dynamic_cast<IndexSegmentChunk *>(Segment::toChunk(index, ctxrep));
+ chunk->setIndexRepresentation(ctxrep);
+ return chunk;
+}
+
dash::http::Chunk * IndexSegment::getChunk(const std::string &url)
{
return new IndexSegmentChunk(this, url);
}
+void IndexSegment::IndexSegmentChunk::setIndexRepresentation(Representation *rep_)
+{
+ rep = rep_;
+}
+
void IndexSegment::IndexSegmentChunk::onDownload(void *buffer, size_t size)
{
- dash::mp4::AtomsReader br(segment);
- br.parseBlock(buffer, size);
+ if(!rep)
+ return;
+
+ dash::mp4::AtomsReader br(rep->getMPD()->getVLCObject());
+ br.parseBlock(buffer, size, rep);
}
SubSegment::SubSegment(Segment *main, size_t start, size_t end) :
list.push_back(this);
return list;
}
-
-Representation *SubSegment::getRepresentation() const
-{
- return parent->getRepresentation();
-}
{
class Representation;
class SubSegment;
+ class SegmentInformation;
class ISegment : public ICanonicalUrl
{
*/
virtual bool isSingleShot () const;
virtual void done ();
- virtual dash::http::Chunk* toChunk (size_t, const Representation * = NULL);
+ virtual dash::http::Chunk* toChunk (size_t, Representation * = NULL);
virtual void setByteRange (size_t start, size_t end);
virtual void setStartTime (mtime_t ztime);
virtual mtime_t getStartTime () const;
virtual size_t getOffset () const;
virtual std::vector<ISegment*> subSegments () = 0;
virtual std::string toString () const;
- virtual Representation* getRepresentation() const = 0;
virtual bool contains (size_t byte) const;
int getClassId () const;
class Segment : public ISegment
{
public:
- Segment( Representation *parent );
- explicit Segment( ICanonicalUrl *parent );
+ Segment( ICanonicalUrl *parent );
~Segment();
virtual void setSourceUrl( const std::string &url );
virtual Url getUrlSegment() const; /* impl */
- virtual dash::http::Chunk* toChunk(size_t, const Representation * = NULL);
+ virtual dash::http::Chunk* toChunk(size_t, Representation * = NULL);
virtual std::vector<ISegment*> subSegments();
- virtual Representation* getRepresentation() const;
virtual std::string toString() const;
virtual void addSubSegment(SubSegment *);
static const int CLASSID_SEGMENT = 1;
protected:
- Representation* parentRepresentation;
std::vector<SubSegment *> subsegments;
std::string sourceUrl;
int size;
class InitSegment : public Segment
{
public:
- InitSegment( Representation *parent );
+ InitSegment( ICanonicalUrl *parent );
static const int CLASSID_INITSEGMENT = 2;
};
class IndexSegment : public Segment
{
public:
- IndexSegment( Representation *parent );
+ IndexSegment( ICanonicalUrl *parent );
+ virtual dash::http::Chunk* toChunk(size_t, Representation * = NULL);
static const int CLASSID_INDEXSEGMENT = 3;
protected:
{
public:
IndexSegmentChunk(ISegment *segment, const std::string &);
+ void setIndexRepresentation(Representation *);
virtual void onDownload(void *, size_t);
+
+ private:
+ Representation *rep;
};
virtual dash::http::Chunk * getChunk(const std::string &);
SubSegment(Segment *, size_t start, size_t end);
virtual Url getUrlSegment() const; /* impl */
virtual std::vector<ISegment*> subSegments();
- virtual Representation* getRepresentation() const;
static const int CLASSID_SUBSEGMENT = 4;
private:
Segment *parent;
--- /dev/null
+/*
+ * SegmentInformation.cpp
+ *****************************************************************************
+ * Copyright (C) 2014 - VideoLAN 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.
+ *****************************************************************************/
+#include "SegmentInformation.hpp"
+
+#include "Segment.h"
+#include "SegmentBase.h"
+#include "SegmentList.h"
+#include "SegmentTemplate.h"
+
+using namespace dash::mpd;
+using namespace std;
+
+SegmentInformation::SegmentInformation(SegmentInformation *parent_) :
+ ICanonicalUrl( parent_ )
+{
+ parent = parent_;
+ segmentBase = NULL;
+ segmentList = NULL;
+ for(int i=0; i<InfoTypeCount; i++)
+ segmentTemplate[i] = NULL;
+}
+
+SegmentInformation::SegmentInformation(ICanonicalUrl * parent_) :
+ ICanonicalUrl( parent_ )
+{
+ parent = NULL;
+ segmentBase = NULL;
+ segmentList = NULL;
+ for(int i=0; i<InfoTypeCount; i++)
+ segmentTemplate[i] = NULL;
+}
+
+SegmentInformation::~SegmentInformation()
+{
+ delete segmentBase;
+ delete segmentList;
+ for(int i=0; i<InfoTypeCount; i++)
+ delete segmentTemplate[i];
+}
+
+vector<ISegment *> SegmentInformation::getSegments() const
+{
+ vector<ISegment *> retSegments;
+
+ SegmentBase *segBase = inheritSegmentBase();
+ SegmentList *segList = inheritSegmentList();
+
+ /* init segments are always single segment */
+ if( segBase && segBase->getInitSegment() )
+ {
+ retSegments.push_back( segBase->getInitSegment() );
+ }
+ else if ( segList && segList->getInitialisationSegment() )
+ {
+ retSegments.push_back( segList->getInitialisationSegment() );
+ }
+ else if( inheritSegmentTemplate(INFOTYPE_INIT) )
+ {
+ retSegments.push_back( inheritSegmentTemplate(INFOTYPE_INIT) );
+ }
+
+ if( inheritSegmentTemplate(INFOTYPE_MEDIA) )
+ {
+ retSegments.push_back( inheritSegmentTemplate(INFOTYPE_MEDIA) );
+ }
+ else if ( segList && !segList->getSegments().empty() )
+ {
+ std::vector<Segment *>::const_iterator it;
+ for(it=segList->getSegments().begin();
+ it!=segList->getSegments().end(); it++)
+ {
+ std::vector<ISegment *> list = (*it)->subSegments();
+ retSegments.insert( retSegments.end(), list.begin(), list.end() );
+ }
+ }
+
+ return retSegments;
+}
+
+void SegmentInformation::setSegmentList(SegmentList *list)
+{
+ segmentList = list;
+}
+
+void SegmentInformation::setSegmentBase(SegmentBase *base)
+{
+ segmentBase = base;
+}
+
+void SegmentInformation::setSegmentTemplate(SegmentTemplate *templ, SegmentInfoType type)
+{
+ segmentTemplate[type] = templ;
+}
+
+static void insertIntoSegment(std::vector<Segment *> &seglist, size_t start,
+ size_t end, mtime_t time)
+{
+ std::vector<Segment *>::iterator segIt;
+ for(segIt = seglist.begin(); segIt < seglist.end(); segIt++)
+ {
+ Segment *segment = *segIt;
+ if(segment->getClassId() == Segment::CLASSID_SEGMENT &&
+ segment->contains(end + segment->getOffset()))
+ {
+ SubSegment *subsegment = new SubSegment(segment,
+ start + segment->getOffset(),
+ end + segment->getOffset());
+ segment->addSubSegment(subsegment);
+ segment->setStartTime(time);
+ break;
+ }
+ }
+}
+
+void SegmentInformation::SplitUsingIndex(std::vector<SplitPoint> &splitlist)
+{
+ std::vector<Segment *> seglist = segmentList->getSegments();
+ std::vector<SplitPoint>::const_iterator splitIt;
+ size_t start = 0, end = 0;
+ mtime_t time = 0;
+
+ for(splitIt = splitlist.begin(); splitIt < splitlist.end(); splitIt++)
+ {
+ start = end;
+ SplitPoint split = *splitIt;
+ end = split.offset;
+ if(splitIt == splitlist.begin() && split.offset == 0)
+ continue;
+ time = split.time;
+ insertIntoSegment(seglist, start, end, time);
+ end++;
+ }
+
+ if(start != 0)
+ {
+ start = end;
+ end = 0;
+ insertIntoSegment(seglist, start, end, time);
+ }
+}
+
+SegmentBase * SegmentInformation::inheritSegmentBase() const
+{
+ if(segmentBase)
+ return segmentBase;
+ else if (parent)
+ return parent->inheritSegmentBase();
+ else
+ return NULL;
+}
+
+SegmentList * SegmentInformation::inheritSegmentList() const
+{
+ if(segmentList)
+ return segmentList;
+ else if (parent)
+ return parent->inheritSegmentList();
+ else
+ return NULL;
+}
+
+SegmentTemplate * SegmentInformation::inheritSegmentTemplate(SegmentInfoType type) const
+{
+ if(segmentTemplate[type])
+ return segmentTemplate[type];
+ else if (parent)
+ return parent->inheritSegmentTemplate(type);
+ else
+ return NULL;
+}
--- /dev/null
+/*
+ * SegmentInformation.hpp
+ *****************************************************************************
+ * Copyright (C) 2014 - VideoLAN 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 SEGMENTINFORMATION_HPP
+#define SEGMENTINFORMATION_HPP
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "ICanonicalUrl.hpp"
+#include <vlc_common.h>
+#include <vector>
+
+namespace dash
+{
+ namespace mpd
+ {
+ class ISegment;
+ class SegmentBase;
+ class SegmentList;
+ class SegmentTemplate;
+
+ /* common segment elements for period/adaptset/rep 5.3.9.1,
+ * with properties inheritance */
+ class SegmentInformation : public ICanonicalUrl
+ {
+ friend class IsoffMainParser;
+
+ public:
+ SegmentInformation( SegmentInformation * = 0 );
+ explicit SegmentInformation( ICanonicalUrl * );
+ virtual ~SegmentInformation();
+ std::vector<ISegment *> getSegments() const;
+
+ class SplitPoint
+ {
+ public:
+ size_t offset;
+ mtime_t time;
+ };
+ void SplitUsingIndex(std::vector<SplitPoint>&);
+
+ enum SegmentInfoType
+ {
+ INFOTYPE_INIT = 0,
+ INFOTYPE_MEDIA,
+ INFOTYPE_INDEX
+ };
+ static const int InfoTypeCount = INFOTYPE_INDEX + 1;
+
+ private:
+ void setSegmentList(SegmentList *);
+ void setSegmentBase(SegmentBase *);
+ void setSegmentTemplate(SegmentTemplate *, SegmentInfoType);
+
+ SegmentBase * inheritSegmentBase() const;
+ SegmentList * inheritSegmentList() const;
+ SegmentTemplate * inheritSegmentTemplate(SegmentInfoType) const;
+
+ SegmentInformation *parent;
+ SegmentBase *segmentBase;
+ SegmentList *segmentList;
+ SegmentTemplate *segmentTemplate[InfoTypeCount];
+ };
+ }
+}
+
+#endif // SEGMENTINFORMATION_HPP