Commit 697f59f9 authored by François Cartegnie's avatar François 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()))
{