Commit 697f59f9 authored by Francois Cartegnie's avatar Francois Cartegnie

demux: dash: regroup under SegmentInformation

parent 738ebc3c
......@@ -70,6 +70,8 @@ libdash_plugin_la_SOURCES = \
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 \
......
......@@ -50,7 +50,7 @@ Chunk* AbstractAdaptationLogic::getNextChunk(Streams::Type type)
if(!currentPeriod)
return NULL;
const Representation *rep = getCurrentRepresentation(type);
Representation *rep = getCurrentRepresentation(type);
if ( rep == NULL )
return NULL;
......
......@@ -36,7 +36,7 @@ AlwaysBestAdaptationLogic::AlwaysBestAdaptationLogic (MPD *mpd) :
{
}
const Representation *AlwaysBestAdaptationLogic::getCurrentRepresentation(Streams::Type type) const
Representation *AlwaysBestAdaptationLogic::getCurrentRepresentation(Streams::Type type) const
{
RepresentationSelector selector;
return selector.select(currentPeriod, type);
......
......@@ -36,7 +36,7 @@ namespace dash
public:
AlwaysBestAdaptationLogic (mpd::MPD *mpd);
virtual const mpd::Representation *getCurrentRepresentation(Streams::Type) const;
virtual mpd::Representation *getCurrentRepresentation(Streams::Type) const;
};
}
}
......
......@@ -28,7 +28,7 @@ AlwaysLowestAdaptationLogic::AlwaysLowestAdaptationLogic(mpd::MPD *mpd):
{
}
const Representation *AlwaysLowestAdaptationLogic::getCurrentRepresentation(Streams::Type type) const
Representation *AlwaysLowestAdaptationLogic::getCurrentRepresentation(Streams::Type type) const
{
RepresentationSelector selector;
return selector.select(currentPeriod, type, 0);
......
......@@ -31,7 +31,7 @@ namespace dash
public:
AlwaysLowestAdaptationLogic(mpd::MPD *mpd);
virtual const dash::mpd::Representation* getCurrentRepresentation(Streams::Type) const;
virtual dash::mpd::Representation* getCurrentRepresentation(Streams::Type) const;
};
}
}
......
......@@ -48,7 +48,7 @@ namespace dash
};
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;
};
}
}
......
......@@ -43,7 +43,7 @@ RateBasedAdaptationLogic::RateBasedAdaptationLogic (MPD *mpd) :
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;
......
......@@ -38,7 +38,7 @@ namespace dash
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:
......
......@@ -24,15 +24,14 @@
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;
......@@ -42,11 +41,11 @@ AtomsReader::~AtomsReader()
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)
{
......@@ -78,7 +77,7 @@ bool AtomsReader::parseBlock(void *buffer, size_t size)
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);
......
......@@ -24,7 +24,6 @@
# include "config.h"
#endif
#include "mpd/Segment.h"
#include <vlc_common.h>
#include <vlc_stream.h>
extern "C" {
......@@ -33,17 +32,21 @@ 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;
};
}
......
......@@ -38,12 +38,10 @@
using namespace dash::mpd;
AdaptationSet::AdaptationSet(Period *period) :
ICanonicalUrl( period ),
SegmentInformation( period ),
subsegmentAlignmentFlag( false ),
segmentInfoDefault( NULL ),
isBitstreamSwitching( false ),
mediaTemplate( NULL ),
initTemplate( NULL )
isBitstreamSwitching( false )
{
}
......@@ -51,8 +49,6 @@ AdaptationSet::~AdaptationSet ()
{
delete this->segmentInfoDefault;
vlc_delete_all( this->representations );
delete mediaTemplate;
delete initTemplate;
}
const std::string& AdaptationSet::getMimeType() const
......@@ -108,23 +104,6 @@ void AdaptationSet::addRepresentation (Represe
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)
{
......
......@@ -31,7 +31,7 @@
#include "mpd/Representation.h"
#include "mpd/CommonAttributesElements.h"
#include "mpd/ICanonicalUrl.hpp"
#include "mpd/SegmentInformation.hpp"
namespace dash
{
......@@ -41,7 +41,8 @@ namespace dash
class Period;
class SegmentTemplate;
class AdaptationSet : public CommonAttributesElements, public ICanonicalUrl
class AdaptationSet : public CommonAttributesElements,
public SegmentInformation
{
public:
AdaptationSet(Period *);
......@@ -55,8 +56,6 @@ namespace dash
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 */
......@@ -66,8 +65,6 @@ namespace dash
std::vector<Representation *> representations;
const SegmentInfoDefault* segmentInfoDefault;
bool isBitstreamSwitching;
SegmentTemplate * mediaTemplate;
SegmentTemplate * initTemplate;
};
}
}
......
......@@ -42,18 +42,6 @@ void IMPDParser::setMPDBaseUrl(Node *root)
}
}
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;
......
......@@ -47,7 +47,6 @@ namespace dash
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;
......
......@@ -51,7 +51,8 @@ bool IsoffMainParser::parse (Profile profile)
mpd = new MPD(p_stream, profile);
setMPDAttributes();
setMPDBaseUrl(root);
setPeriods(root);
parsePeriods(root);
print();
return true;
}
......@@ -75,15 +76,32 @@ void IsoffMainParser::setMPDAttributes ()
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"))
......@@ -107,11 +125,25 @@ void IsoffMainParser::parseTemplate(Node *templateNode, AdaptationSet *set)
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)
......@@ -127,7 +159,7 @@ 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);
......@@ -161,13 +193,8 @@ void IsoffMainParser::setRepresentations (Node *adaptationSetNode, Adaptation
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();
......@@ -188,59 +215,90 @@ void IsoffMainParser::setRepresentations (Node *adaptationSetNode, Adaptation
}
}
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);
......@@ -263,25 +321,7 @@ void IsoffMainParser::setInitSegment (dash::xml::Node *segBaseNode, Segme
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)
......
......@@ -53,11 +53,12 @@ namespace dash
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 *);
};
}
}
......
......@@ -35,7 +35,7 @@
using namespace dash::mpd;
Period::Period(MPD *mpd) :
ICanonicalUrl( mpd )
SegmentInformation( mpd )
{
}
......
......@@ -29,6 +29,7 @@
#include "mpd/AdaptationSet.h"
#include "mpd/ICanonicalUrl.hpp"
#include "mpd/SegmentInformation.hpp"
#include "Streams.hpp"
namespace dash
......@@ -36,7 +37,8 @@ namespace dash
namespace mpd
{
class MPD;
class Period : public ICanonicalUrl
class Period : public SegmentInformation
{
public:
Period(MPD *);
......
......@@ -35,15 +35,12 @@
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)
......@@ -52,10 +49,7 @@ Representation::Representation ( AdaptationSet *set, MPD *mpd_ ) :
Representation::~Representation ()
{
delete(this->segmentInfo);
delete(this->trickModeType);
delete segmentBase;
delete segmentList;
delete baseUrl;
}
......@@ -80,10 +74,6 @@ void Representation::setBandwidth( uint64_t bandwidth )
this->bandwidth = bandwidth;
}
SegmentInfo* Representation::getSegmentInfo() const
{
return this->segmentInfo;
}
TrickModeType* Representation::getTrickModeType () const
{
......@@ -95,10 +85,6 @@ void Representation::setTrickMode (TrickModeType *trickMod
this->trickModeType = trickModeType;
}
void Representation::setSegmentInfo (SegmentInfo *info)
{
this->segmentInfo = info;
}
int Representation::getQualityRanking() const
......@@ -123,62 +109,6 @@ void Representation::addDependency(const Representation *dep)
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)
{
......@@ -226,50 +156,3 @@ MPD * Representation::getMPD() const
{
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);
}
}
......@@ -32,8 +32,8 @@
#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
{
......@@ -43,7 +43,7 @@ namespace dash
class MPD;
class Representation : public CommonAttributesElements,
public ICanonicalUrl
public SegmentInformation
{
public:
Representation( AdaptationSet *, MPD *mpd );
......@@ -68,15 +68,10 @@ namespace dash
* 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);
......@@ -87,14 +82,6 @@ namespace dash
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;
......@@ -102,10 +89,7 @@ namespace dash
std::string id;
int qualityRanking;
std::list<const Representation*> dependencies;
SegmentInfo *segmentInfo;
TrickModeType *trickModeType;
SegmentBase *segmentBase;
SegmentList *segmentList;
BaseUrl *baseUrl;
int width;
int height;
......
......@@ -53,7 +53,7 @@ dash::http::Chunk * ISegment::getChunk(const std::string &url)
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
......@@ -150,24 +150,12 @@ void ISegment::SegmentChunk::onDownload(void *, size_t)
}
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);
......@@ -186,12 +174,6 @@ void Segment::setSourceUrl ( const std::string &url )
this->sourceUrl = url;
}
Representation *Segment::getRepresentation() const
{
return parentRepresentation;
}
std::string Segment::toString() const
{
if (subsegments.empty())
......@@ -218,11 +200,11 @@ Url Segment::getUrlSegment() const
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;
}
......@@ -242,20 +224,27 @@ std::vector<ISegment*> Segment::subSegments()
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);
......@@ -267,10 +256,18 @@ IndexSegment::IndexSegmentChunk::IndexSegmentChunk(ISegment *segment, const std:
}
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) :
......@@ -292,8 +289,3 @@ std::vector<ISegment*> SubSegment::subSegments()
list.push_back(this);
return list;
}
Representation *SubSegment::getRepresentation() const
{
return parent->getRepresentation();
}
......@@ -38,6 +38,7 @@ namespace dash
{
class Representation;
class SubSegment;
class SegmentInformation;
class ISegment : public ICanonicalUrl
{
......@@ -51,7 +52,7 @@ namespace dash
*/
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;
......@@ -60,7 +61,6 @@ namespace dash
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;
......@@ -90,20 +90,17 @@ namespace dash
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;
......@@ -112,14 +109,15 @@ namespace dash
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:
......@@ -127,7 +125,11 @@ namespace dash
{
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 &);
......@@ -139,7 +141,6 @@ namespace dash
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;
......
/*
* 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;
}
/*
* 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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment