]> git.sesse.net Git - vlc/commitdiff
demux: dash: regroup under SegmentInformation
authorFrancois Cartegnie <fcvlcdev@free.fr>
Wed, 17 Dec 2014 15:47:43 +0000 (16:47 +0100)
committerFrancois Cartegnie <fcvlcdev@free.fr>
Thu, 18 Dec 2014 21:38:08 +0000 (22:38 +0100)
25 files changed:
modules/stream_filter/Makefile.am
modules/stream_filter/dash/adaptationlogic/AbstractAdaptationLogic.cpp
modules/stream_filter/dash/adaptationlogic/AlwaysBestAdaptationLogic.cpp
modules/stream_filter/dash/adaptationlogic/AlwaysBestAdaptationLogic.h
modules/stream_filter/dash/adaptationlogic/AlwaysLowestAdaptationLogic.cpp
modules/stream_filter/dash/adaptationlogic/AlwaysLowestAdaptationLogic.hpp
modules/stream_filter/dash/adaptationlogic/IAdaptationLogic.h
modules/stream_filter/dash/adaptationlogic/RateBasedAdaptationLogic.cpp
modules/stream_filter/dash/adaptationlogic/RateBasedAdaptationLogic.h
modules/stream_filter/dash/mp4/AtomsReader.cpp
modules/stream_filter/dash/mp4/AtomsReader.hpp
modules/stream_filter/dash/mpd/AdaptationSet.cpp
modules/stream_filter/dash/mpd/AdaptationSet.h
modules/stream_filter/dash/mpd/IMPDParser.cpp
modules/stream_filter/dash/mpd/IMPDParser.h
modules/stream_filter/dash/mpd/IsoffMainParser.cpp
modules/stream_filter/dash/mpd/IsoffMainParser.h
modules/stream_filter/dash/mpd/Period.cpp
modules/stream_filter/dash/mpd/Period.h
modules/stream_filter/dash/mpd/Representation.cpp
modules/stream_filter/dash/mpd/Representation.h
modules/stream_filter/dash/mpd/Segment.cpp
modules/stream_filter/dash/mpd/Segment.h
modules/stream_filter/dash/mpd/SegmentInformation.cpp [new file with mode: 0644]
modules/stream_filter/dash/mpd/SegmentInformation.hpp [new file with mode: 0644]

index 48ad6b34607826c04edd592eb8259617c01a9d4e..89090c0af5cab968e1f12cb7da5a393d6bd1c17d 100644 (file)
@@ -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 \
index 2b10a2865c27cacb73bcdc40db85a7c4c8ea7789..43ac0f6ff5798cb9b00ed5edf1a67879f0bbe271 100644 (file)
@@ -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;
 
index 137cadaf4216c687b230233fbbda8a3c22bbfcfa..a4cbbecd3f904d9a2a62d4ed103d0bc8ef8cef0f 100644 (file)
@@ -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);
index 9ee0a080bd1577a159391dfc91389464afa6b1fe..c3b21eac7324322cb3c4edad19f1b59d0201a563 100644 (file)
@@ -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;
         };
     }
 }
index a4a91f401c2552c3fa0ca2673212d5c416ed2fb8..1d4a1c20fd521b7a0036bccad8c94666b8c73d0e 100644 (file)
@@ -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);
index bf47caa4f235c93bd67c1618758593ad544ff8d5..2ff7ae51cf39611054bb89b43c55ac4eec7c5987 100644 (file)
@@ -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;
         };
     }
 }
index 55477d64c5b14a592e5d198191df8dd01f80eefb..e712291eabc6c0503c7c6d432627c520de3265a4 100644 (file)
@@ -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;
         };
     }
 }
index 38892904ee188143125c2e15f27c0bbb4c621f22..e831522b523dba6784e7007d6e369c00d6711b68 100644 (file)
@@ -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;
index a693accb4394d320a0a789d5dcc2e7b594754530..a962be47b7898f04732593ad43d2904d18b55190 100644 (file)
@@ -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:
index 5d544f951cd1936eb23980f5178b8fddf5b157c6..d7333d7c4396303d250f504e95216f952ba453c6 100644 (file)
 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);
index 6114393ad10c7171f093b5531b7d96f3182403e4..507e98a549b36ac5c87ee3c5f7b2d53c5d5cf4e2 100644 (file)
@@ -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;
         };
     }
index a133f732466c32260ffbe896f6956db64875d3fc..090ac3190cc9bbb4e93cb75cf82cdd2b11a2c5cd 100644 (file)
 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)
 {
index 5393760d55d2ec9cc2cb17276bca2c6efd4653a8..8f20d9f602acbdab822343e96618f4f0b74d1bdd 100644 (file)
@@ -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;
         };
     }
 }
index a51045d065c4af3b28c60bea3a9848f0aa5f2796..898c3a45c0df891278de968eb415ca81a00e3acf 100644 (file)
@@ -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;
index 2b5becfb85833f2c1b7bb3cec1d85fe1ec422230..f7f0c4bf47704aef7c0915abf5c9c87f9c57d569 100644 (file)
@@ -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;
index ae58f5b01fa09854b518f50c99c0461706482e0f..db67a9fdabfbb1a72b2827e28738646406daba11 100644 (file)
@@ -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)
index 1d349d6b5d3ba64701804fe528f3d2b2143fd400..e7eafd3502f50fb73601f54b3b9536472087ed46 100644 (file)
@@ -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 *);
         };
     }
 }
index 26b3ec5ef569d553171465be15dc89bbd225709f..00a6ebeb4f575aa39d06f90388dd5b6f10691df1 100644 (file)
@@ -35,7 +35,7 @@
 using namespace dash::mpd;
 
 Period::Period(MPD *mpd) :
-    ICanonicalUrl( mpd )
+    SegmentInformation( mpd )
 {
 }
 
index 794022f9239c4b203868c71d4c0ce09386387e10..0a16d358e75a8fba83caf44d59e4cec302872e21 100644 (file)
@@ -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 *);
index c8575a9c8df3765c24f2ef69daf6fd07221ef142..227d99073b92478a533f853e6032e58f3ef7e7b3 100644 (file)
 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);
-    }
-}
index 2bd86510f67c61f5b24292c65aef3b59451b90f4..10c88f769746a5718b2d30ad96fea21968b627f4 100644 (file)
@@ -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;
index 5752efa984353dcb19c8f81513eb3d1f6cc63837..28cd1af500d0ce4466c73cf8873be3c68b432076 100644 (file)
@@ -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();
-}
index 13e18650269cf6fea8c000c934746f476c4387dc..9cfb3669925ec8fe2499a04fe756ae96fc40d87e 100644 (file)
@@ -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;
diff --git a/modules/stream_filter/dash/mpd/SegmentInformation.cpp b/modules/stream_filter/dash/mpd/SegmentInformation.cpp
new file mode 100644 (file)
index 0000000..315600c
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * 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;
+}
diff --git a/modules/stream_filter/dash/mpd/SegmentInformation.hpp b/modules/stream_filter/dash/mpd/SegmentInformation.hpp
new file mode 100644 (file)
index 0000000..50db1c3
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * 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