diff --git a/modules/demux/Makefile.am b/modules/demux/Makefile.am
index 0d6e23ce662fb34527c7ce8f0abc2285dfa9c460..d87639d6ad4b451071236c79b7a3a3900603a9f0 100644
--- a/modules/demux/Makefile.am
+++ b/modules/demux/Makefile.am
@@ -315,10 +315,10 @@ libadaptive_plugin_la_SOURCES = \
     demux/adaptive/playlist/Segment.h \
     demux/adaptive/playlist/SegmentBase.cpp \
     demux/adaptive/playlist/SegmentBase.h \
+    demux/adaptive/playlist/SegmentBaseType.cpp \
+    demux/adaptive/playlist/SegmentBaseType.hpp \
     demux/adaptive/playlist/SegmentChunk.cpp \
     demux/adaptive/playlist/SegmentChunk.hpp \
-    demux/adaptive/playlist/SegmentInfoCommon.cpp \
-    demux/adaptive/playlist/SegmentInfoCommon.h \
     demux/adaptive/playlist/SegmentList.cpp \
     demux/adaptive/playlist/SegmentList.h \
     demux/adaptive/playlist/SegmentTimeline.cpp \
diff --git a/modules/demux/adaptive/logic/BufferingLogic.cpp b/modules/demux/adaptive/logic/BufferingLogic.cpp
index d4073dd976901f6bcf48f1f1b02a9aec62f1115c..5829a025b06c03a953e77f47f782bee5afd50350 100644
--- a/modules/demux/adaptive/logic/BufferingLogic.cpp
+++ b/modules/demux/adaptive/logic/BufferingLogic.cpp
@@ -80,24 +80,8 @@ uint64_t DefaultBufferingLogic::getStartSegmentNumber(BaseRepresentation *rep) c
     if(rep->getPlaylist()->isLive())
         return getLiveStartSegmentNumber(rep);
 
-    const MediaSegmentTemplate *segmentTemplate = rep->inheritSegmentTemplate();
-    if(segmentTemplate)
-    {
-        const SegmentTimeline *timeline = segmentTemplate->inheritSegmentTimeline();
-        if(timeline)
-            return timeline->minElementNumber();
-        return segmentTemplate->inheritStartNumber();
-    }
-
-    const SegmentList *list = rep->inheritSegmentList();
-    if(list)
-        return list->getStartIndex();
-
-    const SegmentBase *base = rep->inheritSegmentBase();
-    if(base)
-        return base->getSequenceNumber();
-
-    return 0;
+    const AbstractSegmentBaseType *profile = rep->inheritSegmentProfile();
+    return profile ? profile->getStartSegmentNumber() : 0;
 }
 
 vlc_tick_t DefaultBufferingLogic::getMinBuffering(const AbstractPlaylist *p) const
@@ -154,7 +138,7 @@ uint64_t DefaultBufferingLogic::getLiveStartSegmentNumber(BaseRepresentation *re
 
     SegmentList *segmentList = rep->inheritSegmentList();
     SegmentBase *segmentBase = rep->inheritSegmentBase();
-    MediaSegmentTemplate *mediaSegmentTemplate = rep->inheritSegmentTemplate();
+    SegmentTemplate *mediaSegmentTemplate = rep->inheritSegmentTemplate();
     if(mediaSegmentTemplate)
     {
         uint64_t start = 0;
@@ -347,8 +331,8 @@ uint64_t DefaultBufferingLogic::getLiveStartSegmentNumber(BaseRepresentation *re
         const stime_t bufferingstart = back->startTime.Get() + back->duration.Get() -
                                        timescale.ToScaled(i_buffering);
 
-        uint64_t start;
-        if(!SegmentInfoCommon::getSegmentNumberByScaledTime(list, bufferingstart, &start))
+        uint64_t start = AbstractSegmentBaseType::findSegmentNumberByScaledTime(list, bufferingstart);
+        if(start == std::numeric_limits<uint64_t>::max())
             return list.front()->getSequenceNumber();
 
         if(segmentBase->getSequenceNumber() + SAFETY_BUFFERING_EDGE_OFFSET <= start)
diff --git a/modules/demux/adaptive/playlist/BaseAdaptationSet.cpp b/modules/demux/adaptive/playlist/BaseAdaptationSet.cpp
index 01fb3c35923755715f49a151ac611e4add1b74f2..7afa7e9c794a7e33002276778ce008e522c22550 100644
--- a/modules/demux/adaptive/playlist/BaseAdaptationSet.cpp
+++ b/modules/demux/adaptive/playlist/BaseAdaptationSet.cpp
@@ -137,6 +137,9 @@ void BaseAdaptationSet::debug(vlc_object_t *obj, int indent) const
     text.append("BaseAdaptationSet ");
     text.append(id.str());
     msg_Dbg(obj, "%s", text.c_str());
+    const AbstractSegmentBaseType *profile = getProfile();
+    if(profile)
+        profile->debug(obj, indent + 1);
     std::vector<BaseRepresentation *>::const_iterator k;
     for(k = representations.begin(); k != representations.end(); ++k)
         (*k)->debug(obj, indent + 1);
diff --git a/modules/demux/adaptive/playlist/BasePeriod.cpp b/modules/demux/adaptive/playlist/BasePeriod.cpp
index 94295ff51da8c1a8390e7b3ea2f9e7ebd97ecf3d..16229771e2ad9cc7d4964e08e72cce3ef10cb670 100644
--- a/modules/demux/adaptive/playlist/BasePeriod.cpp
+++ b/modules/demux/adaptive/playlist/BasePeriod.cpp
@@ -28,6 +28,7 @@
 
 #include "BasePeriod.h"
 #include "AbstractPlaylist.hpp"
+#include "SegmentBaseType.hpp"
 #include "../Streams.hpp"
 
 #include <vlc_common.h>
@@ -90,6 +91,9 @@ void BasePeriod::debug(vlc_object_t *obj, int indent) const
     std::string text(indent, ' ');
     text.append("Period");
     msg_Dbg(obj, "%s", text.c_str());
+    const AbstractSegmentBaseType *profile = getProfile();
+    if(profile)
+        profile->debug(obj, indent + 1);
     std::vector<BaseAdaptationSet *>::const_iterator k;
     for(k = adaptationSets.begin(); k != adaptationSets.end(); ++k)
         (*k)->debug(obj, indent + 1);
diff --git a/modules/demux/adaptive/playlist/BaseRepresentation.cpp b/modules/demux/adaptive/playlist/BaseRepresentation.cpp
index c0c353b2f6513bdd8fea3156e75aa4ab364cefcc..e0529705e823a4fe748b060fc917cb819d2973e6 100644
--- a/modules/demux/adaptive/playlist/BaseRepresentation.cpp
+++ b/modules/demux/adaptive/playlist/BaseRepresentation.cpp
@@ -122,34 +122,13 @@ void BaseRepresentation::pruneByPlaybackTime(vlc_tick_t time)
 
 vlc_tick_t BaseRepresentation::getMinAheadTime(uint64_t curnum) const
 {
-    std::vector<Segment *> seglist;
-    getMediaSegments(seglist);
+    AbstractSegmentBaseType *profile = inheritSegmentTemplate();
+    if(!profile)
+        profile = inheritSegmentList();
+    if(!profile)
+        profile = inheritSegmentBase();
 
-    if(seglist.size() == 1 && seglist.front()->isTemplate())
-    {
-        const MediaSegmentTemplate *templ = dynamic_cast<MediaSegmentTemplate *>(seglist.front());
-        if(templ)
-        {
-            const Timescale timescale = templ->inheritTimescale();
-            stime_t i_length = templ->getMinAheadScaledTime(curnum);
-            return timescale.ToTime(i_length);
-        }
-
-        /* should not happen */
-        return VLC_TICK_FROM_SEC(1);
-    }
-
-    vlc_tick_t minTime = 0;
-    const Timescale timescale = inheritTimescale();
-    std::vector<Segment *>::const_iterator it;
-    for(it = seglist.begin(); it != seglist.end(); ++it)
-    {
-        const Segment *seg = *it;
-        if(seg->getSequenceNumber() > curnum)
-            minTime += timescale.ToTime(seg->duration.Get());
-    }
-
-    return minTime;
+    return profile ? profile->getMinAheadTime(curnum) : 0;
 }
 
 void BaseRepresentation::debug(vlc_object_t *obj, int indent) const
@@ -166,20 +145,13 @@ void BaseRepresentation::debug(vlc_object_t *obj, int indent) const
         text.append("]");
     }
     msg_Dbg(obj, "%s", text.c_str());
-    const ISegment *seg;
-    if((seg = getInitSegment()))
-        seg->debug(obj, indent + 1);
-    if((seg = getIndexSegment()))
-        seg->debug(obj, indent + 1);
-    std::vector<Segment *> list;
-    getMediaSegments(list);
-    std::vector<Segment *>::const_iterator l;
-    for(l = list.begin(); l != list.end(); ++l)
-        (*l)->debug(obj, indent + 1);
+    const AbstractSegmentBaseType *profile = getProfile();
+    if(profile)
+        profile->debug(obj, indent + 1);
 }
 
 std::string BaseRepresentation::contextualize(size_t, const std::string &component,
-                                              const BaseSegmentTemplate *) const
+                                              const SegmentTemplate *) const
 {
     return component;
 }
@@ -205,64 +177,8 @@ uint64_t BaseRepresentation::translateSegmentNumber(uint64_t num, const BaseRepr
 
 bool BaseRepresentation::getSegmentNumberByTime(vlc_tick_t time, uint64_t *ret) const
 {
-    MediaSegmentTemplate *mediaSegmentTemplate = inheritSegmentTemplate();
-    if( mediaSegmentTemplate )
-    {
-        const SegmentTimeline *timeline = mediaSegmentTemplate->inheritSegmentTimeline();
-        if(timeline)
-        {
-            const Timescale timescale = timeline->getTimescale().isValid()
-                                      ? timeline->getTimescale()
-                                      : mediaSegmentTemplate->inheritTimescale();
-            stime_t st = timescale.ToScaled(time);
-            *ret = timeline->getElementNumberByScaledPlaybackTime(st);
-            return true;
-        }
-
-        const stime_t duration = mediaSegmentTemplate->duration.Get();
-        if( duration )
-        {
-            if( getPlaylist()->isLive() )
-            {
-                vlc_tick_t now = vlc_tick_from_sec(::time(NULL));
-                if(getPlaylist()->availabilityStartTime.Get())
-                {
-                    if(time >= getPlaylist()->availabilityStartTime.Get() && time < now)
-                        *ret = mediaSegmentTemplate->getLiveTemplateNumber(time, true);
-                    else if(now - getPlaylist()->availabilityStartTime.Get() > time)
-                        *ret = mediaSegmentTemplate->getLiveTemplateNumber(time, false);
-                }
-                else return false;
-            }
-            else
-            {
-                const Timescale timescale = mediaSegmentTemplate->inheritTimescale();
-                *ret = mediaSegmentTemplate->inheritStartNumber();
-                *ret += timescale.ToScaled(time) / duration;
-            }
-            return true;
-        }
-    }
-
-    SegmentList *segmentList = inheritSegmentList();
-    if ( segmentList && !segmentList->getSegments().empty() )
-    {
-        const Timescale timescale = segmentList->inheritTimescale();
-        stime_t st = timescale.ToScaled(time);
-        return segmentList->getSegmentNumberByScaledTime(st, ret);
-    }
-
-    SegmentBase *segmentBase = inheritSegmentBase();
-    if( segmentBase )
-    {
-        const Timescale timescale = inheritTimescale();
-        stime_t st = timescale.ToScaled(time);
-        *ret = 0;
-        const std::vector<Segment *> &list = segmentBase->subSegments();
-        return SegmentInfoCommon::getSegmentNumberByScaledTime(list, st, ret);
-    }
-
-    return false;
+    const AbstractSegmentBaseType *profile = inheritSegmentProfile();
+    return profile && profile->getSegmentNumberByTime(time, ret);
 }
 
 bool BaseRepresentation::getPlaybackTimeDurationBySegmentNumber(uint64_t number,
@@ -271,56 +187,15 @@ bool BaseRepresentation::getPlaybackTimeDurationBySegmentNumber(uint64_t number,
     if(number == std::numeric_limits<uint64_t>::max())
         return false;
 
-    MediaSegmentTemplate *mediaTemplate = inheritSegmentTemplate();
-    if( mediaTemplate )
-    {
-        const Timescale timescale = mediaTemplate->inheritTimescale();
-        const SegmentTimeline * timeline = mediaTemplate->inheritSegmentTimeline();
-
-        stime_t stime, sduration;
-        if(timeline)
-        {
-            if(!timeline->getScaledPlaybackTimeDurationBySegmentNumber(number, &stime, &sduration))
-                return false;
-        }
-        else
-        {
-            uint64_t startNumber = mediaTemplate->inheritStartNumber();
-            if(number < startNumber)
-                return false;
-            sduration = mediaTemplate->inheritDuration();
-            stime = (number - startNumber) * sduration;
-        }
-        *time = timescale.ToTime(stime);
-        *duration = timescale.ToTime(sduration);
-        return true;
-    }
-
-    SegmentList *segList = inheritSegmentList();
-    if ( segList )
-    {
-        return segList->getPlaybackTimeDurationBySegmentNumber(number, time, duration);
-    }
-    else
-    {
-        const Timescale timescale = inheritTimescale();
-        const ISegment *segment = getMediaSegment(number);
-        if( segment )
-        {
-            *time = timescale.ToTime(segment->startTime.Get());
-            *duration = timescale.ToTime(segment->duration.Get());
-            return true;
-        }
-    }
-
-    return false;
+    const AbstractSegmentBaseType *profile = inheritSegmentProfile();
+    return profile && profile->getPlaybackTimeDurationBySegmentNumber(number, time, duration);
 }
 
 bool BaseRepresentation::getMediaPlaybackRange(vlc_tick_t *rangeBegin,
                                                vlc_tick_t *rangeEnd,
                                                vlc_tick_t *rangeLength) const
 {
-    MediaSegmentTemplate *mediaSegmentTemplate = inheritSegmentTemplate();
+    SegmentTemplate *mediaSegmentTemplate = inheritSegmentTemplate();
     if( mediaSegmentTemplate )
     {
         const Timescale timescale = mediaSegmentTemplate->inheritTimescale();
diff --git a/modules/demux/adaptive/playlist/BaseRepresentation.h b/modules/demux/adaptive/playlist/BaseRepresentation.h
index 414e10920e308e434bd39cde6b4c2d09739f374f..fe86734e4fcb73e76115ba9e3520f4e6d87df927 100644
--- a/modules/demux/adaptive/playlist/BaseRepresentation.h
+++ b/modules/demux/adaptive/playlist/BaseRepresentation.h
@@ -40,7 +40,7 @@ namespace adaptive
     {
         class BaseAdaptationSet;
         class AbstractPlaylist;
-        class BaseSegmentTemplate;
+        class SegmentTemplateSegment;
 
         class BaseRepresentation : public CommonAttributesElements,
                                    public SegmentInformation
@@ -74,7 +74,7 @@ namespace adaptive
 
                 /* for segment templates */
                 virtual std::string contextualize(size_t, const std::string &,
-                                                  const BaseSegmentTemplate *) const;
+                                                  const SegmentTemplate *) const;
 
                 static bool         bwCompare(const BaseRepresentation *a,
                                               const BaseRepresentation *b);
diff --git a/modules/demux/adaptive/playlist/Segment.cpp b/modules/demux/adaptive/playlist/Segment.cpp
index 0bbe7c101bcb455d62d479e0d5ebb509ba7f66b5..090fb9ac1bd65d9efee2a1331761fb7fbb929abf 100644
--- a/modules/demux/adaptive/playlist/Segment.cpp
+++ b/modules/demux/adaptive/playlist/Segment.cpp
@@ -283,14 +283,4 @@ SubSegment::SubSegment(Segment *main, size_t start, size_t end) :
     classId = CLASSID_SUBSEGMENT;
 }
 
-SegmentChunk* SubSegment::createChunk(AbstractChunkSource *source, BaseRepresentation *rep)
-{
-     /* act as factory */
-    return new (std::nothrow) SegmentChunk(source, rep);
-}
-
-Url SubSegment::getUrlSegment() const
-{
-    return getParentUrlSegment();
-}
 
diff --git a/modules/demux/adaptive/playlist/Segment.h b/modules/demux/adaptive/playlist/Segment.h
index 11a1e8652c90f8de0acada9410ba451f6c3ec42d..0c6258b919a9c9c55b7e1ddaebf43d68648101cb 100644
--- a/modules/demux/adaptive/playlist/Segment.h
+++ b/modules/demux/adaptive/playlist/Segment.h
@@ -47,6 +47,7 @@ namespace adaptive
     {
         class BaseRepresentation;
         class SubSegment;
+        class Segment;
         class SegmentChunk;
 
         using namespace http;
@@ -131,8 +132,6 @@ namespace adaptive
         {
             public:
                 SubSegment(Segment *, size_t start, size_t end);
-                virtual SegmentChunk* createChunk(AbstractChunkSource *, BaseRepresentation *); /* impl */
-                virtual Url getUrlSegment() const; /* impl */
                 static const int CLASSID_SUBSEGMENT = 4;
         };
     }
diff --git a/modules/demux/adaptive/playlist/SegmentBase.cpp b/modules/demux/adaptive/playlist/SegmentBase.cpp
index 62f224daa4f7ffc5aee71142805ebab91d551513..16f3ff1c1faeaabc1cd08e33c3ee3c3a4679f2b1 100644
--- a/modules/demux/adaptive/playlist/SegmentBase.cpp
+++ b/modules/demux/adaptive/playlist/SegmentBase.cpp
@@ -26,13 +26,107 @@
 #endif
 
 #include "SegmentBase.h"
+#include "SegmentInformation.hpp"
+
+#include <limits>
 
 using namespace adaptive::playlist;
 
-SegmentBase::SegmentBase(ICanonicalUrl *parent) :
-             Segment(parent)
+SegmentBase::SegmentBase(SegmentInformation *parent) :
+             Segment(parent), AbstractSegmentBaseType(parent)
 {
+    this->parent = parent;
 }
 SegmentBase::~SegmentBase   ()
 {
 }
+
+vlc_tick_t SegmentBase::getMinAheadTime(uint64_t curnum) const
+{
+    const std::vector<Segment *> &segments = subSegments();
+
+    vlc_tick_t minTime = 0;
+    const Timescale timescale = inheritTimescale();
+    std::vector<Segment *>::const_iterator it;
+    for(it = segments.begin(); it != segments.end(); ++it)
+    {
+        const Segment *seg = *it;
+        if(seg->getSequenceNumber() > curnum)
+            minTime += timescale.ToTime(seg->duration.Get());
+    }
+    return minTime;
+}
+
+Segment * SegmentBase::getMediaSegment(uint64_t pos) const
+{
+    std::vector<Segment *>::const_iterator it;
+    for(it =  subsegments.begin(); it != subsegments.end(); ++it)
+    {
+        Segment *seg = *it;
+        if(seg->getSequenceNumber() >= pos)
+        {
+            if(seg->getSequenceNumber() == pos)
+                return seg;
+            else
+                return NULL;
+        }
+    }
+    return NULL;
+}
+
+Segment *  SegmentBase::getNextMediaSegment(uint64_t i_pos,uint64_t *pi_newpos,
+                                            bool *pb_gap) const
+{
+    std::vector<Segment *>::const_iterator it;
+    for(it = subsegments.begin(); it != subsegments.end(); ++it)
+    {
+        Segment *seg = *it;
+        if(seg->getSequenceNumber() >= i_pos)
+        {
+            *pi_newpos = seg->getSequenceNumber();
+            *pb_gap = (*pi_newpos != i_pos);
+            return seg;
+        }
+    }
+    *pb_gap = false;
+    *pi_newpos = i_pos;
+    return NULL;
+}
+
+uint64_t SegmentBase::getStartSegmentNumber() const
+{
+    return subsegments.empty() ? 0 : subsegments.front()->getSequenceNumber();
+}
+
+bool SegmentBase::getSegmentNumberByTime(vlc_tick_t time, uint64_t *ret) const
+{
+    const Timescale timescale = inheritTimescale();
+    if(!timescale.isValid())
+        return false;
+    stime_t st = timescale.ToScaled(time);
+    *ret = AbstractSegmentBaseType::findSegmentNumberByScaledTime(subsegments, st);
+    return *ret != std::numeric_limits<uint64_t>::max();
+}
+
+bool SegmentBase::getPlaybackTimeDurationBySegmentNumber(uint64_t number,
+                                                         vlc_tick_t *time,
+                                                         vlc_tick_t *dur) const
+{
+    const Timescale timescale = inheritTimescale();
+    const ISegment *segment = getMediaSegment(number);
+    if( segment )
+    {
+        *time = timescale.ToTime(segment->startTime.Get());
+        *dur = timescale.ToTime(segment->duration.Get());
+        return true;
+    }
+    return false;
+}
+
+void SegmentBase::debug(vlc_object_t *obj, int indent) const
+{
+    AbstractSegmentBaseType::debug(obj, indent);
+    std::vector<Segment *>::const_iterator it;
+    for(it = subsegments.begin(); it != subsegments.end(); ++it)
+        (*it)->debug(obj, indent);
+}
diff --git a/modules/demux/adaptive/playlist/SegmentBase.h b/modules/demux/adaptive/playlist/SegmentBase.h
index 4297b28be63b133c7df36f04608b3cd3ba548ee6..20e410178dfb20af88e5c294106220ba6143f536 100644
--- a/modules/demux/adaptive/playlist/SegmentBase.h
+++ b/modules/demux/adaptive/playlist/SegmentBase.h
@@ -26,21 +26,36 @@
 #define SEGMENTBASE_H_
 
 #include "Segment.h"
-#include "SegmentInfoCommon.h"
+#include "SegmentBaseType.hpp"
 #include "../tools/Properties.hpp"
 
 namespace adaptive
 {
     namespace playlist
     {
+        class SegmentInformation;
+
         /* SegmentBase can contain only one segment */
         class SegmentBase : public Segment,
-                            public Initializable<InitSegment>,
-                            public Indexable<IndexSegment>
+                            public AbstractSegmentBaseType
         {
             public:
-                SegmentBase             (ICanonicalUrl *);
+                SegmentBase             (SegmentInformation * = NULL);
                 virtual ~SegmentBase    ();
+
+                virtual vlc_tick_t getMinAheadTime(uint64_t curnum) const; /* impl */
+                virtual Segment *getMediaSegment(uint64_t number) const; /* impl */
+                virtual Segment *getNextMediaSegment(uint64_t, uint64_t *, bool *) const; /* impl */
+                virtual uint64_t getStartSegmentNumber() const; /* impl */
+
+                virtual bool getSegmentNumberByTime(vlc_tick_t time, uint64_t *ret) const; /* impl */
+                virtual bool getPlaybackTimeDurationBySegmentNumber(uint64_t number,
+                                            vlc_tick_t *time, vlc_tick_t *duration) const; /* impl */
+
+                virtual void debug(vlc_object_t *,int = 0) const; /* reimpl */
+
+            protected:
+                SegmentInformation *parent;
         };
     }
 }
diff --git a/modules/demux/adaptive/playlist/SegmentBaseType.cpp b/modules/demux/adaptive/playlist/SegmentBaseType.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..defc4910419e64e3ca39d9645ea4e777ed83f3aa
--- /dev/null
+++ b/modules/demux/adaptive/playlist/SegmentBaseType.cpp
@@ -0,0 +1,200 @@
+/*
+ * SegmentBaseType.cpp
+ *****************************************************************************
+ * Copyright (C) 2020 VideoLabs, VideoLAN and VLC 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.
+ *****************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "SegmentBaseType.hpp"
+#include "SegmentInformation.hpp"
+#include "SegmentTemplate.h"
+#include "SegmentTimeline.h"
+
+#include <limits>
+
+using namespace adaptive::playlist;
+
+Segment * AbstractSegmentBaseType::findSegmentByScaledTime(const std::vector<Segment *> &segments,
+                                                                 stime_t time)
+{
+    if(segments.empty() || (segments.size() > 1 && segments[1]->startTime.Get() == 0) )
+        return NULL;
+
+    Segment *ret = NULL;
+    std::vector<Segment *>::const_iterator it = segments.begin();
+    while(it != segments.end())
+    {
+        Segment *seg = *it;
+        if(seg->startTime.Get() > time)
+        {
+            if(it == segments.begin())
+                return NULL;
+            else
+                break;
+        }
+
+        ret = seg;
+        it++;
+    }
+
+    return ret;
+}
+
+uint64_t AbstractSegmentBaseType::findSegmentNumberByScaledTime(const std::vector<Segment *> &segments,
+                                                               stime_t time)
+{
+    Segment *s = findSegmentByScaledTime(segments, time);
+    if(!s)
+        return std::numeric_limits<uint64_t>::max();
+    return s->getSequenceNumber();
+}
+
+AbstractSegmentBaseType::AbstractSegmentBaseType(SegmentInformation *parent)
+                : TimescaleAble(parent)
+{
+    this->parent = parent;
+}
+
+AbstractSegmentBaseType::~AbstractSegmentBaseType()
+{
+}
+
+InitSegment *AbstractSegmentBaseType::getInitSegment() const
+{
+    return initialisationSegment.Get();
+}
+
+IndexSegment *AbstractSegmentBaseType::getIndexSegment() const
+{
+    return indexSegment.Get();
+}
+
+Timescale AbstractSegmentBaseType::inheritTimescale() const
+{
+    if(getTimescale().isValid())
+        return getTimescale();
+    if(parent)
+    {
+        if(parent->getTimescale().isValid())
+            return parent->getTimescale();
+        if(parent->getParent())
+        {
+            AbstractSegmentBaseType *bt =
+                dynamic_cast<AbstractSegmentBaseType *>(parent->getParent()->getProfile());
+            if(bt)
+                return bt->inheritTimescale();
+        }
+    }
+    return Timescale(1);
+}
+
+SegmentInformation *AbstractSegmentBaseType::getParent() const
+{
+    return parent;
+}
+
+void AbstractSegmentBaseType::debug(vlc_object_t *obj, int indent) const
+{
+    if(initialisationSegment.Get())
+        initialisationSegment.Get()->debug(obj, indent);
+    if(indexSegment.Get())
+        indexSegment.Get()->debug(obj, indent);
+}
+
+AbstractMultipleSegmentBaseType::AbstractMultipleSegmentBaseType(SegmentInformation *parent)
+                : AbstractSegmentBaseType(parent)
+{
+    startNumber = std::numeric_limits<uint64_t>::max();
+    segmentTimeline = NULL;
+    duration.Set(0);
+}
+
+AbstractMultipleSegmentBaseType::~AbstractMultipleSegmentBaseType()
+{
+    delete segmentTimeline;
+}
+
+void AbstractMultipleSegmentBaseType::setSegmentTimeline( SegmentTimeline *v )
+{
+    delete segmentTimeline;
+    segmentTimeline = v;
+}
+
+SegmentTimeline * AbstractMultipleSegmentBaseType::inheritSegmentTimeline() const
+{
+    if( segmentTimeline )
+        return segmentTimeline;
+    const SegmentInformation *ulevel = parent ? parent->getParent() : NULL;
+    for( ; ulevel ; ulevel = ulevel->getParent() )
+    {
+        AbstractMultipleSegmentBaseType *bt =
+            dynamic_cast<AbstractMultipleSegmentBaseType *>(ulevel->getProfile());
+        if( bt && bt->segmentTimeline )
+            return bt->segmentTimeline;
+    }
+    return NULL;
+}
+
+SegmentTimeline * AbstractMultipleSegmentBaseType::getSegmentTimeline() const
+{
+    return segmentTimeline;
+}
+
+void AbstractMultipleSegmentBaseType::setStartNumber( uint64_t v )
+{
+    startNumber = v;
+}
+
+uint64_t AbstractMultipleSegmentBaseType::inheritStartNumber() const
+{
+    if( startNumber != std::numeric_limits<uint64_t>::max() )
+        return startNumber;
+
+    const SegmentInformation *ulevel = parent ? parent->getParent() : NULL;
+    for( ; ulevel ; ulevel = ulevel->parent )
+    {
+        AbstractMultipleSegmentBaseType *bt =
+            dynamic_cast<AbstractMultipleSegmentBaseType *>(ulevel->getProfile());
+        if( bt && bt->startNumber != std::numeric_limits<uint64_t>::max() )
+            return bt->startNumber;
+    }
+    return std::numeric_limits<uint64_t>::max();
+}
+
+stime_t AbstractMultipleSegmentBaseType::inheritDuration() const
+{
+    if(duration.Get() > 0)
+        return duration.Get();
+    const SegmentInformation *ulevel = parent ? parent->getParent() : NULL;
+    for( ; ulevel ; ulevel = ulevel->parent )
+    {
+        AbstractMultipleSegmentBaseType *bt =
+            dynamic_cast<AbstractMultipleSegmentBaseType *>(ulevel->getProfile());
+        if( bt && bt->duration.Get() > 0 )
+            return bt->duration.Get();
+    }
+    return 0;
+}
+
+void AbstractMultipleSegmentBaseType::updateWith(AbstractMultipleSegmentBaseType *updated,
+                                                 bool)
+{
+    if(segmentTimeline && updated->segmentTimeline)
+        segmentTimeline->updateWith(*updated->segmentTimeline);
+}
diff --git a/modules/demux/adaptive/playlist/SegmentBaseType.hpp b/modules/demux/adaptive/playlist/SegmentBaseType.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..89432bcd41984d928e06bc301d82450c06dd3563
--- /dev/null
+++ b/modules/demux/adaptive/playlist/SegmentBaseType.hpp
@@ -0,0 +1,91 @@
+/*
+ * SegmentBaseType.hpp
+ *****************************************************************************
+ * Copyright (C) 2020 VideoLabs, VideoLAN and VLC 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 SEGMENTBASETYPE_H_
+#define SEGMENTBASETYPE_H_
+
+#include "Segment.h"
+#include "Inheritables.hpp"
+#include "Templates.hpp"
+#include "../tools/Properties.hpp"
+
+namespace adaptive
+{
+    namespace playlist
+    {
+        class SegmentInformation;
+        class SegmentTimeline;
+
+        class AbstractSegmentBaseType : public Initializable<InitSegment>,
+                                        public Indexable<IndexSegment>,
+                                        public TimescaleAble
+        {
+            public:
+                AbstractSegmentBaseType( SegmentInformation * );
+                virtual ~AbstractSegmentBaseType();
+
+                virtual vlc_tick_t getMinAheadTime(uint64_t) const = 0;
+                virtual Segment *getMediaSegment(uint64_t pos) const = 0;
+                virtual InitSegment *getInitSegment() const;
+                virtual IndexSegment *getIndexSegment() const;
+                virtual Segment *getNextMediaSegment(uint64_t, uint64_t *, bool *) const = 0;
+                virtual uint64_t getStartSegmentNumber() const = 0;
+
+                virtual bool getSegmentNumberByTime(vlc_tick_t time, uint64_t *ret) const = 0;
+                virtual bool getPlaybackTimeDurationBySegmentNumber(uint64_t number,
+                                                vlc_tick_t *time, vlc_tick_t *duration) const = 0;
+
+                Timescale inheritTimescale() const; /* reimpl */
+
+                virtual void debug(vlc_object_t *, int = 0) const;
+
+                static Segment * findSegmentByScaledTime(const std::vector<Segment *> &,
+                                                         stime_t);
+                static uint64_t findSegmentNumberByScaledTime(const std::vector<Segment *> &,
+                                                             stime_t);
+                SegmentInformation * getParent() const;
+
+            protected:
+                SegmentInformation *parent;
+        };
+
+        class AbstractMultipleSegmentBaseType : public AbstractSegmentBaseType
+        {
+            public:
+                AbstractMultipleSegmentBaseType( SegmentInformation * );
+                virtual ~AbstractMultipleSegmentBaseType();
+
+                void setSegmentTimeline( SegmentTimeline * );
+                SegmentTimeline * inheritSegmentTimeline() const;
+                SegmentTimeline * getSegmentTimeline() const;
+                void setStartNumber( uint64_t );
+                uint64_t inheritStartNumber() const;
+                stime_t inheritDuration() const;
+                virtual void updateWith(AbstractMultipleSegmentBaseType *, bool = false);
+                Property<stime_t>       duration;
+
+            protected:
+                uint64_t startNumber;
+                SegmentTimeline *segmentTimeline;
+
+        };
+    }
+}
+
+#endif /* SEGMENTBASETYPE_H_ */
diff --git a/modules/demux/adaptive/playlist/SegmentInfoCommon.cpp b/modules/demux/adaptive/playlist/SegmentInfoCommon.cpp
deleted file mode 100644
index f8c00708032dcffcb22506479cf7489ba8e2a606..0000000000000000000000000000000000000000
--- a/modules/demux/adaptive/playlist/SegmentInfoCommon.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*****************************************************************************
- * SegmentInfoCommon.cpp: Implement the common part for both SegmentInfoDefault
- *                        and SegmentInfo
- *****************************************************************************
- * Copyright (C) 1998-2007 VLC authors and VideoLAN
- *
- * Authors: Hugo Beauzée-Luyssen <hugo@beauzee.fr>
- *
- * 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.
- *****************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "SegmentInfoCommon.h"
-
-using namespace adaptive::playlist;
-
-SegmentInfoCommon::SegmentInfoCommon( ICanonicalUrl *parent ) :
-    ICanonicalUrl( parent ),
-    startIndex( 0 )
-{
-    duration.Set(0);
-}
-
-SegmentInfoCommon::~SegmentInfoCommon()
-{
-}
-
-int         SegmentInfoCommon::getStartIndex() const
-{
-    return this->startIndex;
-}
-
-void        SegmentInfoCommon::setStartIndex(int startIndex)
-{
-    if ( startIndex >= 0 )
-        this->startIndex = startIndex;
-}
-
-void SegmentInfoCommon::appendBaseURL(const std::string &url)
-{
-    this->baseURLs.push_back( url );
-}
-
-Url SegmentInfoCommon::getUrlSegment() const
-{
-    Url ret = getParentUrlSegment();
-    if (!baseURLs.empty())
-        ret.append(baseURLs.front());
-    return ret;
-}
-
-bool SegmentInfoCommon::getSegmentNumberByScaledTime(const std::vector<Segment *> &segments,
-                                                      stime_t time, uint64_t *ret)
-{
-    if(segments.empty() || (segments.size() > 1 && segments[1]->startTime.Get() == 0) )
-        return false;
-
-    *ret = 0;
-
-    std::vector<Segment *>::const_iterator it = segments.begin();
-    while(it != segments.end())
-    {
-        const Segment *seg = *it;
-        if(seg->startTime.Get() > time)
-        {
-            if(it == segments.begin())
-                return false;
-            else
-                break;
-        }
-
-        *ret = seg->getSequenceNumber();
-        it++;
-    }
-
-    return true;
-}
diff --git a/modules/demux/adaptive/playlist/SegmentInfoCommon.h b/modules/demux/adaptive/playlist/SegmentInfoCommon.h
deleted file mode 100644
index 0498a4b75f4f17246102486218363269367b633c..0000000000000000000000000000000000000000
--- a/modules/demux/adaptive/playlist/SegmentInfoCommon.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*****************************************************************************
- * SegmentInfoCommon.h: Implement the common part for both SegmentInfoDefault
- *                      and SegmentInfo
- *****************************************************************************
- * Copyright (C) 1998-2007 VLC authors and VideoLAN
- *
- * Authors: Hugo Beauzée-Luyssen <hugo@beauzee.fr>
- *
- * 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 SEGMENTINFOCOMMON_H
-#define SEGMENTINFOCOMMON_H
-
-#include <string>
-#include <list>
-#include "Inheritables.hpp"
-#include "Templates.hpp"
-#include "Segment.h"
-#include "ICanonicalUrl.hpp"
-#include "../tools/Properties.hpp"
-
-namespace adaptive
-{
-    namespace playlist
-    {
-        class Segment;
-
-        class SegmentInfoCommon : public ICanonicalUrl,
-                                  public Initializable<InitSegment>,
-                                  public Indexable<IndexSegment>
-        {
-            public:
-                SegmentInfoCommon( ICanonicalUrl *parent = NULL );
-                virtual ~SegmentInfoCommon();
-                int                     getStartIndex() const;
-                void                    setStartIndex( int startIndex );
-                void                    appendBaseURL( const std::string& url );
-                virtual Url             getUrlSegment() const; /* impl */
-                Property<stime_t>      duration;
-                static bool             getSegmentNumberByScaledTime(const std::vector<Segment *> &,
-                                                                     stime_t, uint64_t *);
-
-            private:
-                int                     startIndex;
-                std::list<std::string>  baseURLs;
-        };
-    }
-}
-
-#endif // SEGMENTINFOCOMMON_H
diff --git a/modules/demux/adaptive/playlist/SegmentInformation.cpp b/modules/demux/adaptive/playlist/SegmentInformation.cpp
index 6867529924fb08b20dd8d0e5a4dd728ebe467623..e046d60f5753c1ec73ebefbdb36cfb0fca4f1e89 100644
--- a/modules/demux/adaptive/playlist/SegmentInformation.cpp
+++ b/modules/demux/adaptive/playlist/SegmentInformation.cpp
@@ -81,7 +81,7 @@ std::size_t SegmentInformation::getMediaSegments(std::vector<Segment *> &retSegm
 {
     if( mediaSegmentTemplate )
     {
-        retSegments.push_back( mediaSegmentTemplate );
+        retSegments.push_back( mediaSegmentTemplate->getMediaSegment(0) );
     }
     else if ( segmentList && !segmentList->getSegments().empty() )
     {
@@ -100,144 +100,49 @@ std::size_t SegmentInformation::getMediaSegments(std::vector<Segment *> &retSegm
     return retSegments.size();
 }
 
+const AbstractSegmentBaseType * SegmentInformation::inheritSegmentProfile() const
+{
+    const AbstractSegmentBaseType *profile = inheritSegmentTemplate();
+    if(!profile)
+        profile = inheritSegmentList();
+    if(!profile)
+        profile = inheritSegmentBase();
+    return profile;
+}
+
+
 /* Returns wanted segment, or next in sequence if not found */
 Segment *  SegmentInformation::getNextMediaSegment(uint64_t i_pos,uint64_t *pi_newpos,
                                                    bool *pb_gap) const
 {
-    *pb_gap = false;
-    *pi_newpos = i_pos;
-
-    std::vector<Segment *> retSegments;
-    const size_t size = getMediaSegments( retSegments );
-    if( size )
-    {
-        std::vector<Segment *>::const_iterator it;
-        for(it = retSegments.begin(); it != retSegments.end(); ++it)
-        {
-            Segment *seg = *it;
-            if(seg->isTemplate()) /* we don't care about seq number */
-            {
-                /* Check if we don't exceed timeline */
-                MediaSegmentTemplate *templ = dynamic_cast<MediaSegmentTemplate*>(retSegments[0]);
-                const SegmentTimeline *timeline = (templ) ? templ->inheritSegmentTimeline() : NULL;
-                if(timeline)
-                {
-                    *pi_newpos = std::max(timeline->minElementNumber(), i_pos);
-                    if(timeline->maxElementNumber() < i_pos)
-                        return NULL;
-                }
-                else
-                {
-                    /* check template upper bound */
-                    if(!getPlaylist()->isLive())
-                    {
-                        const Timescale timescale = templ->inheritTimescale();
-                        const stime_t segmentduration = templ->inheritDuration();
-                        vlc_tick_t totalduration = getPeriodDuration();
-                        if(totalduration == 0)
-                            totalduration = getPlaylist()->duration.Get();
-                        if(totalduration && segmentduration)
-                        {
-                            uint64_t endnum = templ->inheritStartNumber() +
-                                    (timescale.ToScaled(totalduration) + segmentduration - 1) / segmentduration;
-                            if(i_pos >= endnum)
-                            {
-                                *pi_newpos = i_pos;
-                                return NULL;
-                            }
-                        }
-                    }
-                    *pi_newpos = i_pos;
-                    /* start number */
-                    *pi_newpos = std::max(templ->inheritStartNumber(), i_pos);
-                }
-                return seg;
-            }
-            else if(seg->getSequenceNumber() >= i_pos)
-            {
-                *pi_newpos = seg->getSequenceNumber();
-                *pb_gap = (*pi_newpos != i_pos);
-                return seg;
-            }
-        }
-    }
-
-    return NULL;
+    const AbstractSegmentBaseType *profile = inheritSegmentProfile();
+    if(!profile)
+        return NULL;
+    return profile->getNextMediaSegment(i_pos, pi_newpos, pb_gap);
 }
 
 InitSegment * SegmentInformation::getInitSegment() const
 {
-    if( segmentBase && segmentBase->initialisationSegment.Get() )
-    {
-        return segmentBase->initialisationSegment.Get();
-    }
-    else if( segmentList && segmentList->initialisationSegment.Get() )
-    {
-        return segmentList->initialisationSegment.Get();
-    }
-    else if( mediaSegmentTemplate && mediaSegmentTemplate->initialisationSegment.Get() )
-    {
-        return mediaSegmentTemplate->initialisationSegment.Get();
-    }
-    else if( parent )
-    {
-        return parent->getInitSegment();
-    }
-    else return NULL;
+    const AbstractSegmentBaseType *profile = inheritSegmentProfile();
+    if(!profile)
+        return NULL;
+    return profile->getInitSegment();
 }
 
 IndexSegment *SegmentInformation::getIndexSegment() const
 {
-    if( segmentBase && segmentBase->indexSegment.Get() )
-    {
-        return segmentBase->indexSegment.Get();
-    }
-    else if( segmentList && segmentList->indexSegment.Get() )
-    {
-        return segmentList->indexSegment.Get();
-    }
-    else if( parent )
-    {
-        return parent->getIndexSegment();
-    }
-    else return NULL;
+    const AbstractSegmentBaseType *profile = inheritSegmentProfile();
+    if(!profile)
+        return NULL;
+    return profile->getIndexSegment();
 }
 
 Segment * SegmentInformation::getMediaSegment(uint64_t pos) const
 {
-    if( mediaSegmentTemplate )
-    {
-        const SegmentTimeline *tl = mediaSegmentTemplate->inheritSegmentTimeline();
-        if(tl == NULL || tl->maxElementNumber() > pos)
-            return mediaSegmentTemplate;
-    }
-    else if( segmentList )
-    {
-        return segmentList->getSegmentByNumber( pos );
-    }
-    else if( segmentBase )
-    {
-        /* FIXME add getSegmentByNumber */
-        const std::vector<Segment *> &retSegments = segmentBase->subSegments();
-        std::vector<Segment *>::const_iterator it;
-        for(it = retSegments.begin(); it != retSegments.end(); ++it)
-        {
-            Segment *seg = *it;
-            if(seg->getSequenceNumber() >= pos)
-            {
-                if(seg->getSequenceNumber() == pos)
-                    return seg;
-                else
-                    return NULL;
-            }
-        }
+    const AbstractSegmentBaseType *profile = inheritSegmentProfile();
+    if(!profile)
         return NULL;
-    }
-    else if( parent )
-    {
-        return parent->getMediaSegment(pos);
-    }
-    return NULL;
+    return profile->getMediaSegment(pos);
 }
 
 SegmentInformation * SegmentInformation::getChildByID(const adaptive::ID &id)
@@ -271,17 +176,6 @@ void SegmentInformation::updateWith(SegmentInformation *updated)
     /* FIXME: handle difference */
 }
 
-void SegmentInformation::mergeWithTimeline(SegmentTimeline *updated)
-{
-    MediaSegmentTemplate *templ = inheritSegmentTemplate();
-    if(templ)
-    {
-        SegmentTimeline *timeline = templ->inheritSegmentTimeline();
-        if(timeline)
-            timeline->updateWith(*updated);
-    }
-}
-
 void SegmentInformation::pruneByPlaybackTime(vlc_tick_t time)
 {
     if(segmentList)
@@ -334,6 +228,23 @@ vlc_tick_t SegmentInformation::getPeriodDuration() const
         return 0;
 }
 
+SegmentInformation * SegmentInformation::getParent() const
+{
+    return parent;
+}
+
+AbstractSegmentBaseType * SegmentInformation::getProfile() const
+{
+    if(mediaSegmentTemplate)
+        return mediaSegmentTemplate;
+    else if(segmentList)
+        return segmentList;
+    else if(segmentBase)
+        return segmentBase;
+    else
+        return NULL;
+}
+
 void SegmentInformation::updateSegmentList(SegmentList *list, bool restamp)
 {
     if(segmentList && restamp)
@@ -355,7 +266,7 @@ void SegmentInformation::setSegmentBase(SegmentBase *base)
     segmentBase = base;
 }
 
-void SegmentInformation::setSegmentTemplate(MediaSegmentTemplate *templ)
+void SegmentInformation::setSegmentTemplate(SegmentTemplate *templ)
 {
     if(mediaSegmentTemplate)
     {
@@ -456,7 +367,7 @@ SegmentList * SegmentInformation::inheritSegmentList() const
         return NULL;
 }
 
-MediaSegmentTemplate * SegmentInformation::inheritSegmentTemplate() const
+SegmentTemplate * SegmentInformation::inheritSegmentTemplate() const
 {
     if(mediaSegmentTemplate)
         return mediaSegmentTemplate;
diff --git a/modules/demux/adaptive/playlist/SegmentInformation.hpp b/modules/demux/adaptive/playlist/SegmentInformation.hpp
index 3d3ac27046478d6297184ab40a86fb9b14dbaeec..465999852f19484133a7771c96e85320b873e2f3 100644
--- a/modules/demux/adaptive/playlist/SegmentInformation.hpp
+++ b/modules/demux/adaptive/playlist/SegmentInformation.hpp
@@ -21,9 +21,10 @@
 #define SEGMENTINFORMATION_HPP
 
 #include "ICanonicalUrl.hpp"
+#include "Inheritables.hpp"
+#include "Segment.h"
 #include "../tools/Properties.hpp"
 #include "../encryption/CommonEncryption.hpp"
-#include "SegmentInfoCommon.h"
 #include <vlc_common.h>
 #include <vector>
 
@@ -31,11 +32,12 @@ namespace adaptive
 {
     namespace playlist
     {
+        class AbstractSegmentBaseType;
         class SegmentBase;
         class SegmentList;
         class SegmentTimeline;
         class SegmentTemplate;
-        class MediaSegmentTemplate;
+        class SegmentTemplate;
         class AbstractPlaylist;
         class ISegment;
 
@@ -45,7 +47,8 @@ namespace adaptive
                                    public TimescaleAble,
                                    public Unique
         {
-            friend class MediaSegmentTemplate;
+            friend class AbstractMultipleSegmentBaseType;
+
             public:
                 SegmentInformation( SegmentInformation * = 0 );
                 explicit SegmentInformation( AbstractPlaylist * );
@@ -70,7 +73,6 @@ namespace adaptive
                 virtual Segment *     getNextMediaSegment(uint64_t, uint64_t *, bool *) const;
 
                 virtual void updateWith(SegmentInformation *);
-                virtual void mergeWithTimeline(SegmentTimeline *); /* ! don't use with global merge */
                 virtual void pruneBySegmentNumber(uint64_t);
                 virtual void pruneByPlaybackTime(vlc_tick_t);
                 void setEncryption(const CommonEncryption &);
@@ -83,16 +85,19 @@ namespace adaptive
                 SegmentInformation *parent;
 
             public:
+                SegmentInformation *getParent() const;
+                AbstractSegmentBaseType *getProfile() const;
                 void updateSegmentList(SegmentList *, bool = false);
                 void setSegmentBase(SegmentBase *);
-                void setSegmentTemplate(MediaSegmentTemplate *);
+                void setSegmentTemplate(SegmentTemplate *);
                 virtual Url getUrlSegment() const; /* impl */
                 Property<Url *> baseUrl;
                 void setAvailabilityTimeOffset(vlc_tick_t);
                 void setAvailabilityTimeComplete(bool);
+                const AbstractSegmentBaseType * inheritSegmentProfile() const;
                 SegmentBase *     inheritSegmentBase() const;
                 SegmentList *     inheritSegmentList() const;
-                MediaSegmentTemplate * inheritSegmentTemplate() const;
+                SegmentTemplate * inheritSegmentTemplate() const;
                 vlc_tick_t        inheritAvailabilityTimeOffset() const;
                 bool              inheritAvailabilityTimeComplete() const;
 
@@ -100,7 +105,7 @@ namespace adaptive
                 void init();
                 SegmentBase     *segmentBase;
                 SegmentList     *segmentList;
-                MediaSegmentTemplate *mediaSegmentTemplate;
+                SegmentTemplate *mediaSegmentTemplate;
                 CommonEncryption commonEncryption;
                 Undef<bool>      availabilityTimeComplete;
                 Undef<vlc_tick_t>availabilityTimeOffset;
diff --git a/modules/demux/adaptive/playlist/SegmentList.cpp b/modules/demux/adaptive/playlist/SegmentList.cpp
index 16efe98c8e99ccbb2d6c078935fb4be70177a9fc..211b9ef80ce4ae254f1fded6726cd4d3b966105f 100644
--- a/modules/demux/adaptive/playlist/SegmentList.cpp
+++ b/modules/demux/adaptive/playlist/SegmentList.cpp
@@ -28,11 +28,14 @@
 #include "SegmentList.h"
 #include "Segment.h"
 #include "SegmentInformation.hpp"
+#include "SegmentTimeline.h"
+
+#include <limits>
 
 using namespace adaptive::playlist;
 
 SegmentList::SegmentList( SegmentInformation *parent ):
-    SegmentInfoCommon( parent ), TimescaleAble( parent )
+    AbstractMultipleSegmentBaseType( parent )
 {
     totalLength = 0;
 }
@@ -48,8 +51,17 @@ const std::vector<Segment*>& SegmentList::getSegments() const
     return segments;
 }
 
-Segment * SegmentList::getSegmentByNumber(uint64_t number)
+Segment * SegmentList::getMediaSegment(uint64_t number) const
 {
+    const SegmentTimeline *timeline = inheritSegmentTimeline();
+    if(timeline)
+    {
+        uint64_t listindex = timeline->getElementIndexBySequence(number);
+        if(listindex >= segments.size())
+            return NULL;
+        return segments.at(listindex);
+    }
+
     std::vector<Segment *>::const_iterator it = segments.begin();
     for(it = segments.begin(); it != segments.end(); ++it)
     {
@@ -68,19 +80,23 @@ Segment * SegmentList::getSegmentByNumber(uint64_t number)
 
 void SegmentList::addSegment(Segment *seg)
 {
-    seg->setParent(this);
+    seg->setParent(parent);
     segments.push_back(seg);
     totalLength += seg->duration.Get();
 }
 
-void SegmentList::updateWith(SegmentList *updated, bool b_restamp)
+void SegmentList::updateWith(AbstractMultipleSegmentBaseType *updated_,
+                             bool b_restamp)
 {
-    const Segment * lastSegment = (segments.empty()) ? NULL : segments.back();
-    const Segment * prevSegment = lastSegment;
+    AbstractMultipleSegmentBaseType::updateWith(updated_);
 
-    if(updated->segments.empty())
+    SegmentList *updated = dynamic_cast<SegmentList *>(updated_);
+    if(!updated || updated->segments.empty())
         return;
 
+    const Segment * lastSegment = (segments.empty()) ? NULL : segments.back();
+    const Segment * prevSegment = lastSegment;
+
     uint64_t firstnumber = updated->segments.front()->getSequenceNumber();
 
     std::vector<Segment *>::iterator it;
@@ -111,9 +127,9 @@ void SegmentList::updateWith(SegmentList *updated, bool b_restamp)
 
 void SegmentList::pruneByPlaybackTime(vlc_tick_t time)
 {
-    uint64_t num;
     const Timescale timescale = inheritTimescale();
-    if(getSegmentNumberByScaledTime(timescale.ToScaled(time), &num))
+    uint64_t num = findSegmentNumberByScaledTime(segments, timescale.ToScaled(time));
+    if(num != std::numeric_limits<uint64_t>::max())
         pruneBySegmentNumber(num);
 }
 
@@ -133,56 +149,159 @@ void SegmentList::pruneBySegmentNumber(uint64_t tobelownum)
     }
 }
 
-bool SegmentList::getSegmentNumberByScaledTime(stime_t time, uint64_t *ret) const
+bool SegmentList::getPlaybackTimeDurationBySegmentNumber(uint64_t number,
+                                                         vlc_tick_t *time, vlc_tick_t *dur) const
 {
-    return SegmentInfoCommon::getSegmentNumberByScaledTime(segments, time, ret);
+    if(number == std::numeric_limits<uint64_t>::max())
+        return false;
+
+    Timescale timescale;
+    stime_t stime, sduration;
+
+    const SegmentTimeline * timeline = inheritSegmentTimeline();
+    if(timeline)
+    {
+        timescale = timeline->inheritTimescale();
+        if(!timeline->getScaledPlaybackTimeDurationBySegmentNumber(number, &stime, &sduration))
+            return false;
+    }
+    else
+    {
+        *time = *dur = VLC_TICK_INVALID;
+        timescale = inheritTimescale();
+
+        if(segments.empty())
+            return false;
+
+        const ISegment *first = segments.front();
+        if(first->getSequenceNumber() > number)
+            return false;
+
+        bool found = false;
+        stime_t stime = first->startTime.Get();
+        stime_t sduration = 0;
+        std::vector<Segment *>::const_iterator it = segments.begin();
+        for(it = segments.begin(); it != segments.end(); ++it)
+        {
+            const Segment *seg = *it;
+
+            if(seg->duration.Get())
+                sduration = seg->duration.Get();
+            else
+                sduration = duration.Get();
+
+            /* Assuming there won't be any discontinuity in sequence */
+            if(seg->getSequenceNumber() == number)
+            {
+                found = true;
+                break;
+            }
+
+            stime += sduration;
+        }
+
+        if(!found)
+            return false;
+    }
+
+    *time = VLC_TICK_0 + timescale.ToTime(stime);
+    *dur = VLC_TICK_0 + timescale.ToTime(sduration);
+    return true;
 }
 
-bool SegmentList::getPlaybackTimeDurationBySegmentNumber(uint64_t number,
-                                                         vlc_tick_t *time, vlc_tick_t *dur) const
+stime_t SegmentList::getTotalLength() const
 {
-    *time = *dur = VLC_TICK_INVALID;
+    const SegmentTimeline *timeline = inheritSegmentTimeline();
+    if(timeline)
+        return timeline->getTotalLength();
+    return totalLength;
+}
 
-    if(segments.empty())
-        return false;
+vlc_tick_t SegmentList::getMinAheadTime(uint64_t curnum) const
+{
+    const SegmentTimeline *timeline = inheritSegmentTimeline();
+    if( timeline )
+    {
+        const Timescale timescale = timeline->inheritTimescale();
+        return timescale.ToTime(timeline->getMinAheadScaledTime(curnum));
+    }
 
+    vlc_tick_t minTime = 0;
     const Timescale timescale = inheritTimescale();
-    const ISegment *first = segments.front();
-    if(first->getSequenceNumber() > number)
-        return false;
-
-    bool found = false;
-    stime_t seg_start = first->startTime.Get();
-    stime_t seg_dura = 0;
-    std::vector<Segment *>::const_iterator it = segments.begin();
+    std::vector<Segment *>::const_iterator it;
     for(it = segments.begin(); it != segments.end(); ++it)
     {
         const Segment *seg = *it;
+        if(seg->getSequenceNumber() > curnum)
+            minTime += timescale.ToTime(seg->duration.Get());
+    }
+    return minTime;
+}
 
-        if(seg->duration.Get())
-            seg_dura = seg->duration.Get();
-        else
-            seg_dura = duration.Get();
+Segment *  SegmentList::getNextMediaSegment(uint64_t i_pos,uint64_t *pi_newpos,
+                                            bool *pb_gap) const
+{
+    *pb_gap = false;
+    *pi_newpos = i_pos;
 
-        /* Assuming there won't be any discontinuity in sequence */
-        if(seg->getSequenceNumber() == number)
+    const SegmentTimeline *timeline = inheritSegmentTimeline();
+    if(timeline)
+    {
+        uint64_t listindex = timeline->getElementIndexBySequence(i_pos);
+        if(listindex >= segments.size())
+            return NULL;
+        return segments.at(listindex);
+    }
+
+    std::vector<Segment *>::const_iterator it;
+    for(it = segments.begin(); it != segments.end(); ++it)
+    {
+        Segment *seg = *it;
+        if(seg->getSequenceNumber() >= i_pos)
         {
-            found = true;
-            break;
+            *pi_newpos = seg->getSequenceNumber();
+            *pb_gap = (*pi_newpos != i_pos);
+            return seg;
         }
+    }
+    return NULL;
+}
+
+uint64_t SegmentList::getStartSegmentNumber() const
+{
+    const SegmentTimeline *timeline = inheritSegmentTimeline();
+    if( timeline )
+        return timeline->minElementNumber();
+    return !segments.empty() ? segments.front()->getSequenceNumber() : inheritStartNumber();
+}
 
-        seg_start += seg_dura;
+bool SegmentList::getSegmentNumberByTime(vlc_tick_t time, uint64_t *ret) const
+{
+    const SegmentTimeline *timeline = inheritSegmentTimeline();
+    if(timeline)
+    {
+        const Timescale timescale = timeline->getTimescale().isValid()
+                                  ? timeline->getTimescale()
+                                  : inheritTimescale();
+        stime_t st = timescale.ToScaled(time);
+        *ret = timeline->getElementNumberByScaledPlaybackTime(st);
+        return true;
     }
 
-    if(!found)
+    const Timescale timescale = inheritTimescale();
+    if(!timescale.isValid())
         return false;
-
-    *time = VLC_TICK_0 + timescale.ToTime(seg_start);
-    *dur = VLC_TICK_0 + timescale.ToTime(seg_dura);
-    return true;
+    stime_t st = timescale.ToScaled(time);
+    *ret = AbstractSegmentBaseType::findSegmentNumberByScaledTime(segments, st);
+    return *ret != std::numeric_limits<uint64_t>::max();
 }
 
-stime_t SegmentList::getTotalLength() const
+void SegmentList::debug(vlc_object_t *obj, int indent) const
 {
-    return totalLength;
+    AbstractSegmentBaseType::debug(obj, indent);
+    std::vector<Segment *>::const_iterator it;
+    for(it = segments.begin(); it != segments.end(); ++it)
+        (*it)->debug(obj, indent);
+    if(segmentTimeline)
+        segmentTimeline->debug(obj, indent + 1);
 }
diff --git a/modules/demux/adaptive/playlist/SegmentList.h b/modules/demux/adaptive/playlist/SegmentList.h
index 6fd1a0083692295623d0ab447bb9db799371ec4b..f67d64ad8a2566a3770172476245673bb48337da 100644
--- a/modules/demux/adaptive/playlist/SegmentList.h
+++ b/modules/demux/adaptive/playlist/SegmentList.h
@@ -25,7 +25,7 @@
 #ifndef SEGMENTLIST_H_
 #define SEGMENTLIST_H_
 
-#include "SegmentInfoCommon.h"
+#include "SegmentBaseType.hpp"
 
 namespace adaptive
 {
@@ -34,23 +34,30 @@ namespace adaptive
         class SegmentInformation;
         class Segment;
 
-        class SegmentList : public SegmentInfoCommon,
-                            public TimescaleAble
+        class SegmentList : public AbstractMultipleSegmentBaseType
         {
             public:
                 SegmentList             ( SegmentInformation * = NULL );
                 virtual ~SegmentList    ();
 
                 const std::vector<Segment *>&   getSegments() const;
-                Segment *               getSegmentByNumber(uint64_t);
                 void                    addSegment(Segment *seg);
-                void                    updateWith(SegmentList *, bool = false);
+                virtual void            updateWith(AbstractMultipleSegmentBaseType *,
+                                                   bool = false); /* reimpl */
                 void                    pruneBySegmentNumber(uint64_t);
                 void                    pruneByPlaybackTime(vlc_tick_t);
-                bool                    getSegmentNumberByScaledTime(stime_t, uint64_t *) const;
-                bool                    getPlaybackTimeDurationBySegmentNumber(uint64_t, vlc_tick_t *, vlc_tick_t *) const;
                 stime_t                 getTotalLength() const;
 
+                virtual vlc_tick_t  getMinAheadTime(uint64_t) const; /* impl */
+                virtual Segment * getMediaSegment(uint64_t pos) const; /* impl */
+                virtual Segment * getNextMediaSegment(uint64_t, uint64_t *, bool *) const; /* impl */
+                virtual uint64_t  getStartSegmentNumber() const; /* impl */
+                virtual bool getSegmentNumberByTime(vlc_tick_t time, uint64_t *ret) const; /* impl */
+                virtual bool getPlaybackTimeDurationBySegmentNumber(uint64_t number,
+                                            vlc_tick_t *time, vlc_tick_t *duration) const; /* impl */
+
+                virtual void debug(vlc_object_t *, int = 0) const; /* reimpl */
+
             private:
                 std::vector<Segment *>  segments;
                 stime_t totalLength;
diff --git a/modules/demux/adaptive/playlist/SegmentTemplate.cpp b/modules/demux/adaptive/playlist/SegmentTemplate.cpp
index 04b70557c2b0accec0e70d18b0129a67495b1ea0..f66fe7eb024f1e5aaf571d0e6171f0c2074f1997 100644
--- a/modules/demux/adaptive/playlist/SegmentTemplate.cpp
+++ b/modules/demux/adaptive/playlist/SegmentTemplate.cpp
@@ -31,127 +31,58 @@
 
 using namespace adaptive::playlist;
 
-BaseSegmentTemplate::BaseSegmentTemplate( ICanonicalUrl *parent ) :
+SegmentTemplateSegment::SegmentTemplateSegment( SegmentTemplate *templ_,
+                                                ICanonicalUrl *parent ) :
     Segment( parent )
 {
+    debugName = "SegmentTemplateSegment";
+    classId = Segment::CLASSID_SEGMENT;
+    templated = true;
+    templ = templ_;
 }
 
-BaseSegmentTemplate::~BaseSegmentTemplate()
+SegmentTemplateSegment::~SegmentTemplateSegment()
 {
 
 }
 
-void BaseSegmentTemplate::setSourceUrl(const std::string &url)
+void SegmentTemplateSegment::setSourceUrl(const std::string &url)
 {
-    sourceUrl = Url(Url::Component(url, this));
+    sourceUrl = Url(Url::Component(url, templ));
 }
 
-MediaSegmentTemplate::MediaSegmentTemplate( SegmentInformation *parent ) :
-    BaseSegmentTemplate( parent ),
-    TimescaleAble( NULL ) /* we don't want auto inherit */
+SegmentTemplate::SegmentTemplate( SegmentInformation *parent ) :
+    AbstractMultipleSegmentBaseType( NULL ) /* we don't want auto inherit */
 {
-    debugName = "SegmentTemplate";
-    classId = Segment::CLASSID_SEGMENT;
-    startNumber = std::numeric_limits<uint64_t>::max();
-    segmentTimeline = NULL;
     initialisationSegment.Set( NULL );
-    templated = true;
     parentSegmentInformation = parent;
+    segments.push_back( new SegmentTemplateSegment( this, parent ) );
 }
 
-MediaSegmentTemplate::~MediaSegmentTemplate()
+SegmentTemplate::~SegmentTemplate()
 {
-    delete segmentTimeline;
+    delete *segments.begin();
 }
 
-void MediaSegmentTemplate::updateWith(MediaSegmentTemplate *updated)
+void SegmentTemplate::setSourceUrl( const std::string &url )
 {
-    SegmentTimeline *timeline = segmentTimeline;
-    if(timeline && updated->segmentTimeline)
-    {
-        timeline->updateWith(*updated->segmentTimeline);
-        /*if(prunebarrier)
-        {
-            const Timescale timescale = timeline->inheritTimescale();
-            const uint64_t number =
-                    timeline->getElementNumberByScaledPlaybackTime(timescale.ToScaled(prunebarrier));
-            timeline->pruneBySequenceNumber(number);
-        }*/
-    }
+    (*segments.begin())->setSourceUrl(url);
 }
 
-void MediaSegmentTemplate::pruneByPlaybackTime(vlc_tick_t time)
+void SegmentTemplate::pruneByPlaybackTime(vlc_tick_t time)
 {
     if(segmentTimeline)
         return segmentTimeline->pruneByPlaybackTime(time);
 }
 
-size_t MediaSegmentTemplate::pruneBySequenceNumber(uint64_t number)
+size_t SegmentTemplate::pruneBySequenceNumber(uint64_t number)
 {
     if(segmentTimeline)
         return segmentTimeline->pruneBySequenceNumber(number);
     return 0;
 }
 
-uint64_t MediaSegmentTemplate::inheritStartNumber() const
-{
-    if( startNumber != std::numeric_limits<uint64_t>::max() )
-        return startNumber;
-
-    const SegmentInformation *ulevel = parentSegmentInformation ? parentSegmentInformation
-                                                                : NULL;
-    for( ; ulevel ; ulevel = ulevel->parent )
-    {
-        if( ulevel->mediaSegmentTemplate &&
-            ulevel->mediaSegmentTemplate->startNumber !=
-                std::numeric_limits<uint64_t>::max() )
-            return ulevel->mediaSegmentTemplate->startNumber;
-    }
-    return 1;
-}
-
-Timescale MediaSegmentTemplate::inheritTimescale() const
-{
-    const SegmentInformation *ulevel = parentSegmentInformation ? parentSegmentInformation
-                                                                : NULL;
-    for( ; ulevel ; ulevel = ulevel->parent )
-    {
-        if( ulevel->mediaSegmentTemplate &&
-            ulevel->mediaSegmentTemplate->getTimescale().isValid() )
-            return ulevel->mediaSegmentTemplate->getTimescale();
-        if( ulevel->getTimescale().isValid() )
-            return ulevel->getTimescale();
-    }
-    return Timescale(1);
-}
-
-stime_t MediaSegmentTemplate::inheritDuration() const
-{
-    const SegmentInformation *ulevel = parentSegmentInformation ? parentSegmentInformation
-                                                                : NULL;
-    for( ; ulevel ; ulevel = ulevel->parent )
-    {
-        if( ulevel->mediaSegmentTemplate &&
-            ulevel->mediaSegmentTemplate->duration.Get() > 0 )
-            return ulevel->mediaSegmentTemplate->duration.Get();
-    }
-    return 0;
-}
-
-SegmentTimeline * MediaSegmentTemplate::inheritSegmentTimeline() const
-{
-    const SegmentInformation *ulevel = parentSegmentInformation ? parentSegmentInformation
-                                                          : NULL;
-    for( ; ulevel ; ulevel = ulevel->parent )
-    {
-        if( ulevel->mediaSegmentTemplate &&
-            ulevel->mediaSegmentTemplate->segmentTimeline )
-            return ulevel->mediaSegmentTemplate->segmentTimeline;
-    }
-    return NULL;
-}
-
-uint64_t MediaSegmentTemplate::getLiveTemplateNumber(vlc_tick_t playbacktime, bool abs) const
+uint64_t SegmentTemplate::getLiveTemplateNumber(vlc_tick_t playbacktime, bool abs) const
 {
     uint64_t number = inheritStartNumber();
     /* live streams / templated */
@@ -176,53 +107,181 @@ uint64_t MediaSegmentTemplate::getLiveTemplateNumber(vlc_tick_t playbacktime, bo
     return number;
 }
 
-stime_t MediaSegmentTemplate::getMinAheadScaledTime(uint64_t number) const
+void SegmentTemplate::debug(vlc_object_t *obj, int indent) const
+{
+    AbstractSegmentBaseType::debug(obj, indent);
+    (*segments.begin())->debug(obj, indent);
+    if(segmentTimeline)
+        segmentTimeline->debug(obj, indent + 1);
+}
+
+vlc_tick_t SegmentTemplate::getMinAheadTime(uint64_t number) const
 {
     if( segmentTimeline )
-        return segmentTimeline->getMinAheadScaledTime(number);
+    {
+        const Timescale timescale = segmentTimeline->inheritTimescale();
+        return timescale.ToTime(segmentTimeline->getMinAheadScaledTime(number));
+    }
+    else
+    {
+        const Timescale timescale = inheritTimescale();
+        uint64_t current = getLiveTemplateNumber(vlc_tick_from_sec(time(NULL)));
+        stime_t i_length = (current - number) * inheritDuration();
+        return timescale.ToTime(i_length);
+    }
+}
 
-    uint64_t current = getLiveTemplateNumber(vlc_tick_from_sec(time(NULL)));
-    return (current - number) * inheritDuration();
+Segment * SegmentTemplate::getMediaSegment(uint64_t number) const
+{
+    const SegmentTimeline *tl = inheritSegmentTimeline();
+    if(tl == NULL || tl->maxElementNumber() > number)
+        return *segments.begin();
+    return NULL;
 }
 
-uint64_t MediaSegmentTemplate::getSequenceNumber() const
+InitSegment * SegmentTemplate::getInitSegment() const
 {
-    return inheritStartNumber();
+    return initialisationSegment.Get();
 }
 
-void MediaSegmentTemplate::setStartNumber( uint64_t v )
+Segment *  SegmentTemplate::getNextMediaSegment(uint64_t i_pos,uint64_t *pi_newpos,
+                                                     bool *pb_gap) const
 {
-    startNumber = v;
+    *pb_gap = false;
+    *pi_newpos = i_pos;
+    /* Check if we don't exceed timeline */
+    const SegmentTimeline *timeline = inheritSegmentTimeline();
+    if(timeline)
+    {
+        *pi_newpos = std::max(timeline->minElementNumber(), i_pos);
+        if (timeline->maxElementNumber() < i_pos)
+            return NULL;
+    }
+    else
+    {
+        /* check template upper bound */
+        const AbstractPlaylist *playlist = parentSegmentInformation->getPlaylist();
+        if(!playlist->isLive())
+        {
+            const Timescale timescale = inheritTimescale();
+            const stime_t segmentduration = inheritDuration();
+            vlc_tick_t totalduration = parentSegmentInformation->getPeriodDuration();
+            if(totalduration == 0)
+                totalduration = playlist->duration.Get();
+            if(totalduration && segmentduration)
+            {
+                uint64_t endnum = inheritStartNumber() +
+                        (timescale.ToScaled(totalduration) + segmentduration - 1) / segmentduration;
+                if(i_pos >= endnum)
+                {
+                    *pi_newpos = i_pos;
+                    return NULL;
+                }
+            }
+        }
+        *pi_newpos = i_pos;
+        /* start number */
+        *pi_newpos = std::max(inheritStartNumber(), i_pos);
+    }
+    return *segments.begin();
 }
 
-void MediaSegmentTemplate::setSegmentTimeline( SegmentTimeline *v )
+uint64_t SegmentTemplate::getStartSegmentNumber() const
 {
-    delete segmentTimeline;
-    segmentTimeline = v;
+    const SegmentTimeline *timeline = inheritSegmentTimeline();
+    return timeline ? timeline->minElementNumber() : inheritStartNumber();
 }
 
-void MediaSegmentTemplate::debug(vlc_object_t *obj, int indent) const
+bool SegmentTemplate::getSegmentNumberByTime(vlc_tick_t time, uint64_t *ret) const
 {
-    Segment::debug(obj, indent);
-    if(segmentTimeline)
-        segmentTimeline->debug(obj, indent + 1);
+    const SegmentTimeline *timeline = inheritSegmentTimeline();
+    if(timeline)
+    {
+        const Timescale timescale = timeline->getTimescale().isValid()
+                                  ? timeline->getTimescale()
+                                  : inheritTimescale();
+        stime_t st = timescale.ToScaled(time);
+        *ret = timeline->getElementNumberByScaledPlaybackTime(st);
+        return true;
+    }
+
+    const stime_t duration = inheritDuration();
+    if( duration && parent )
+    {
+        AbstractPlaylist *playlist = parent->getPlaylist();
+        if( playlist->isLive() )
+        {
+            vlc_tick_t now = vlc_tick_from_sec(::time(NULL));
+            if(playlist->availabilityStartTime.Get())
+            {
+                if(time >= playlist->availabilityStartTime.Get() && time < now)
+                    *ret = getLiveTemplateNumber(time, true);
+                else if(now - playlist->availabilityStartTime.Get() > time)
+                    *ret = getLiveTemplateNumber(time, false);
+            }
+            else return false;
+        }
+        else
+        {
+            const Timescale timescale = inheritTimescale();
+            *ret = inheritStartNumber();
+            *ret += timescale.ToScaled(time) / duration;
+        }
+        return true;
+    }
+
+    return false;
+}
+
+
+bool SegmentTemplate::getPlaybackTimeDurationBySegmentNumber(uint64_t number,
+                                                             vlc_tick_t *time,
+                                                             vlc_tick_t *duration) const
+{
+    if(number == std::numeric_limits<uint64_t>::max())
+        return false;
+
+    Timescale timescale;
+    stime_t stime, sduration;
+
+    const SegmentTimeline * timeline = inheritSegmentTimeline();
+    if(timeline)
+    {
+        timescale = timeline->inheritTimescale();
+        if(!timeline->getScaledPlaybackTimeDurationBySegmentNumber(number, &stime, &sduration))
+            return false;
+    }
+    else
+    {
+        timescale = inheritTimescale();
+        uint64_t startNumber = inheritStartNumber();
+        if(number < startNumber)
+            return false;
+        sduration = inheritDuration();
+        stime = (number - startNumber) * sduration;
+    }
+
+    *time = timescale.ToTime(stime);
+    *duration = timescale.ToTime(sduration);
+    return true;
+
 }
 
-InitSegmentTemplate::InitSegmentTemplate( ICanonicalUrl *parent,
-                                          MediaSegmentTemplate *templ ) :
+SegmentTemplateInit::SegmentTemplateInit( SegmentTemplate *templ_,
+                                          ICanonicalUrl *parent ) :
     InitSegment(parent)
 {
     debugName = "InitSegmentTemplate";
     classId = InitSegment::CLASSID_INITSEGMENT;
-    maintempl = templ;
+    templ = templ_;
 }
 
-InitSegmentTemplate::~InitSegmentTemplate()
+SegmentTemplateInit::~SegmentTemplateInit()
 {
 
 }
 
-void InitSegmentTemplate::setSourceUrl(const std::string &url)
+void SegmentTemplateInit::setSourceUrl(const std::string &url)
 {
-    sourceUrl = Url(Url::Component(url, maintempl));
+    sourceUrl = Url(Url::Component(url, templ));
 }
diff --git a/modules/demux/adaptive/playlist/SegmentTemplate.h b/modules/demux/adaptive/playlist/SegmentTemplate.h
index cac4dbf3b353c635476f15f2fa9678e75d6d1276..6c864e0f024b0b5e4112b26b47bf5394b7591a7a 100644
--- a/modules/demux/adaptive/playlist/SegmentTemplate.h
+++ b/modules/demux/adaptive/playlist/SegmentTemplate.h
@@ -25,61 +25,64 @@
 
 #include "Segment.h"
 #include "../tools/Properties.hpp"
-#include "SegmentInfoCommon.h"
+#include "SegmentBaseType.hpp"
 
 namespace adaptive
 {
     namespace playlist
     {
         class ICanonicalUrl;
-        class InitSegmentTemplate;
+        class SegmentTemplateInit;
         class SegmentInformation;
-        class SegmentTimeline;
+        class SegmentTemplate;
 
-        class BaseSegmentTemplate : public Segment
+        class SegmentTemplateSegment : public Segment
         {
             public:
-                BaseSegmentTemplate( ICanonicalUrl * = NULL );
-                virtual ~BaseSegmentTemplate();
+                SegmentTemplateSegment( SegmentTemplate *, ICanonicalUrl * = NULL );
+                virtual ~SegmentTemplateSegment();
                 virtual void setSourceUrl( const std::string &url ); /* reimpl */
+
+            protected:
+                const SegmentTemplate *templ;
         };
 
-        class MediaSegmentTemplate : public BaseSegmentTemplate,
-                                     public Initializable<InitSegmentTemplate>,
-                                     public TimescaleAble
+        class SegmentTemplate : public AbstractMultipleSegmentBaseType
         {
             public:
-                MediaSegmentTemplate( SegmentInformation * = NULL );
-                virtual ~MediaSegmentTemplate();
-                void setStartNumber( uint64_t );
-                void setSegmentTimeline( SegmentTimeline * );
-                void updateWith( MediaSegmentTemplate * );
-                virtual uint64_t getSequenceNumber() const; /* reimpl */
+                SegmentTemplate( SegmentInformation * = NULL );
+                virtual ~SegmentTemplate();
+                void setSourceUrl( const std::string &url );
                 uint64_t getLiveTemplateNumber(vlc_tick_t, bool = true) const;
-                stime_t getMinAheadScaledTime(uint64_t) const;
                 void pruneByPlaybackTime(vlc_tick_t);
                 size_t pruneBySequenceNumber(uint64_t);
-                virtual Timescale inheritTimescale() const; /* reimpl */
-                virtual uint64_t inheritStartNumber() const;
-                stime_t inheritDuration() const;
-                SegmentTimeline * inheritSegmentTimeline() const;
+
+                virtual vlc_tick_t getMinAheadTime(uint64_t curnum) const; /* impl */
+                virtual Segment * getMediaSegment(uint64_t number) const; /* impl */
+                virtual Segment * getNextMediaSegment(uint64_t, uint64_t *, bool *) const; /* impl */
+                virtual InitSegment *getInitSegment() const;/* reimpl */
+                virtual uint64_t getStartSegmentNumber() const; /* impl */
+
+                virtual bool getSegmentNumberByTime(vlc_tick_t time, uint64_t *ret) const; /* impl */
+                virtual bool getPlaybackTimeDurationBySegmentNumber(uint64_t number,
+                                            vlc_tick_t *time, vlc_tick_t *duration) const; /* impl */
+
                 virtual void debug(vlc_object_t *, int = 0) const; /* reimpl */
 
             protected:
-                uint64_t startNumber;
-                SegmentTimeline *segmentTimeline;
                 SegmentInformation *parentSegmentInformation;
+                std::vector<SegmentTemplateSegment *> segments; /* should have only 1 */
         };
 
-        class InitSegmentTemplate : public InitSegment
+        class SegmentTemplateInit : public InitSegment
         {
             public:
-                InitSegmentTemplate( ICanonicalUrl * = NULL, MediaSegmentTemplate * = NULL );
-                virtual ~InitSegmentTemplate();
+                SegmentTemplateInit( SegmentTemplate *, ICanonicalUrl * = NULL );
+                virtual ~SegmentTemplateInit();
                 virtual void setSourceUrl( const std::string &url ); /* reimpl */
 
             protected:
-                const MediaSegmentTemplate *maintempl;
+                const SegmentTemplate *templ;
         };
     }
 }
diff --git a/modules/demux/adaptive/playlist/SegmentTimeline.cpp b/modules/demux/adaptive/playlist/SegmentTimeline.cpp
index e1c530a7677b3810d6faebff5babbf0aa316cd84..a8e60ccc66be7adcd6437d78d9d8af0596cfb998 100644
--- a/modules/demux/adaptive/playlist/SegmentTimeline.cpp
+++ b/modules/demux/adaptive/playlist/SegmentTimeline.cpp
@@ -24,15 +24,19 @@
 #endif
 
 #include "SegmentTimeline.h"
+#include "SegmentBaseType.hpp"
+#include "SegmentInformation.hpp"
 
 #include <algorithm>
+#include <sstream>
 
 using namespace adaptive::playlist;
 
-SegmentTimeline::SegmentTimeline(TimescaleAble *parent)
-    :TimescaleAble(parent)
+SegmentTimeline::SegmentTimeline(AbstractMultipleSegmentBaseType *parent_)
+    :TimescaleAble(NULL)
 {
     totalLength = 0;
+    parent = parent_;
 }
 
 SegmentTimeline::SegmentTimeline(uint64_t scale)
@@ -40,6 +44,7 @@ SegmentTimeline::SegmentTimeline(uint64_t scale)
 {
     setTimescale(scale);
     totalLength = 0;
+    parent = NULL;
 }
 
 SegmentTimeline::~SegmentTimeline()
@@ -88,6 +93,33 @@ stime_t SegmentTimeline::getMinAheadScaledTime(uint64_t number) const
     return totalscaledtime;
 }
 
+Timescale SegmentTimeline::inheritTimescale() const
+{
+    if(getTimescale().isValid())
+        return getTimescale();
+
+    if(parent && parent->getTimescale().isValid())
+        return parent->getTimescale();
+
+    SegmentInformation *info = NULL;
+    if(parent && parent->getParent() && parent->getParent()->getParent())
+        info = parent->getParent()->getParent();
+    else
+        info = NULL;
+
+    AbstractMultipleSegmentBaseType *bt;
+    for(; info; info = info->getParent())
+    {
+        bt = dynamic_cast<AbstractMultipleSegmentBaseType *>(info->getProfile());
+        if(bt && bt->getSegmentTimeline() && bt->getSegmentTimeline()->getTimescale().isValid())
+            return bt->getSegmentTimeline()->getTimescale();
+        if(info->getTimescale().isValid())
+            return info->getTimescale();
+    }
+
+    return Timescale(1);
+}
+
 uint64_t SegmentTimeline::getElementNumberByScaledPlaybackTime(stime_t scaled) const
 {
     const Element *prevel = NULL;
@@ -167,6 +199,21 @@ uint64_t SegmentTimeline::minElementNumber() const
     return elements.front()->number;
 }
 
+uint64_t SegmentTimeline::getElementIndexBySequence(uint64_t number) const
+{
+    std::list<Element *>::const_iterator it;
+    for(it = elements.begin(); it != elements.end(); ++it)
+    {
+        const Element *el = *it;
+        if(number >= el->number)
+        {
+            if(number <= el->number + el->r)
+                return std::distance(elements.begin(), it);
+        }
+    }
+    return std::numeric_limits<uint64_t>::max();
+}
+
 void SegmentTimeline::pruneByPlaybackTime(vlc_tick_t time)
 {
     const Timescale timescale = inheritTimescale();
diff --git a/modules/demux/adaptive/playlist/SegmentTimeline.h b/modules/demux/adaptive/playlist/SegmentTimeline.h
index 7489e7a7406691eccc714be24f3b9591ee1d8d19..668f7d53897cfd306c35afb9e5bf61af07dfef09 100644
--- a/modules/demux/adaptive/playlist/SegmentTimeline.h
+++ b/modules/demux/adaptive/playlist/SegmentTimeline.h
@@ -23,7 +23,8 @@
 #ifndef SEGMENTTIMELINE_H
 #define SEGMENTTIMELINE_H
 
-#include "SegmentInfoCommon.h"
+#include "Inheritables.hpp"
+
 #include <vlc_common.h>
 #include <list>
 
@@ -31,12 +32,14 @@ namespace adaptive
 {
     namespace playlist
     {
+        class AbstractMultipleSegmentBaseType;
+
         class SegmentTimeline : public TimescaleAble
         {
             class Element;
 
             public:
-                SegmentTimeline(TimescaleAble *);
+                SegmentTimeline(AbstractMultipleSegmentBaseType *);
                 SegmentTimeline(uint64_t);
                 virtual ~SegmentTimeline();
                 void addElement(uint64_t, stime_t d, uint64_t r = 0, stime_t t = 0);
@@ -44,9 +47,11 @@ namespace adaptive
                 bool    getScaledPlaybackTimeDurationBySegmentNumber(uint64_t, stime_t *, stime_t *) const;
                 stime_t getScaledPlaybackTimeByElementNumber(uint64_t) const;
                 stime_t getMinAheadScaledTime(uint64_t) const;
+                Timescale inheritTimescale() const; /* reimpl */
                 stime_t getTotalLength() const;
                 uint64_t maxElementNumber() const;
                 uint64_t minElementNumber() const;
+                uint64_t getElementIndexBySequence(uint64_t) const;
                 void pruneByPlaybackTime(vlc_tick_t);
                 size_t pruneBySequenceNumber(uint64_t);
                 void updateWith(SegmentTimeline &);
@@ -55,6 +60,7 @@ namespace adaptive
             private:
                 std::list<Element *> elements;
                 stime_t totalLength;
+                AbstractMultipleSegmentBaseType *parent;
 
                 class Element
                 {
diff --git a/modules/demux/adaptive/playlist/Url.cpp b/modules/demux/adaptive/playlist/Url.cpp
index 86385b1afe09026d0baf82ed9b076a90559e160a..0b8fb5c6e21b3730171f3823ef286688ceb73456 100644
--- a/modules/demux/adaptive/playlist/Url.cpp
+++ b/modules/demux/adaptive/playlist/Url.cpp
@@ -140,7 +140,7 @@ std::string Url::toString(size_t index, const BaseRepresentation *rep) const
     return ret;
 }
 
-Url::Component::Component(const std::string & str, const BaseSegmentTemplate *templ_)
+Url::Component::Component(const std::string & str, const SegmentTemplate *templ_)
  : component(str), templ(templ_), b_scheme(false), b_dir(false), b_absolute(false)
 {
     if(!component.empty())
diff --git a/modules/demux/adaptive/playlist/Url.hpp b/modules/demux/adaptive/playlist/Url.hpp
index 6650eff0e08f884e8dcf9d9f9d1fe59133a97a6e..d91cf47caf1ca8a4d720aca2abb13607727b5049 100644
--- a/modules/demux/adaptive/playlist/Url.hpp
+++ b/modules/demux/adaptive/playlist/Url.hpp
@@ -28,7 +28,7 @@ namespace adaptive
 {
     namespace playlist
     {
-        class BaseSegmentTemplate;
+        class SegmentTemplate;
         class BaseRepresentation;
 
         class Url
@@ -38,11 +38,11 @@ namespace adaptive
                 {
                     friend class Url;
                     public:
-                        Component(const std::string &, const BaseSegmentTemplate * = NULL);
+                        Component(const std::string &, const SegmentTemplate * = NULL);
 
                     protected:
                         std::string component;
-                        const BaseSegmentTemplate *templ;
+                        const SegmentTemplate *templ;
 
                     private:
                         bool b_scheme;
diff --git a/modules/demux/dash/mpd/IsoffMainParser.cpp b/modules/demux/dash/mpd/IsoffMainParser.cpp
index 3188fba343d07b37009561a799bee3228b6154bb..6f158a81aa5373f7ebd57a8a3bd0df07b1f3ac5d 100644
--- a/modules/demux/dash/mpd/IsoffMainParser.cpp
+++ b/modules/demux/dash/mpd/IsoffMainParser.cpp
@@ -182,6 +182,49 @@ void IsoffMainParser::parsePeriods(MPD *mpd, Node *root)
     }
 }
 
+void IsoffMainParser::parseSegmentBaseType(MPD *, Node *node,
+                                           AbstractSegmentBaseType *base,
+                                           SegmentInformation *parent)
+{
+    parseInitSegment(DOMHelper::getFirstChildElementByName(node, "Initialization"), base, parent);
+
+    if(node->hasAttribute("indexRange"))
+    {
+        size_t start = 0, end = 0;
+        if (std::sscanf(node->getAttributeValue("indexRange").c_str(), "%zu-%zu", &start, &end) == 2)
+        {
+            IndexSegment *index = new (std::nothrow) DashIndexSegment(parent);
+            if(index)
+            {
+                index->setByteRange(start, end);
+                base->indexSegment.Set(index);
+                /* index must be before data, so data starts at index end */
+                if(dynamic_cast<SegmentBase *>(base))
+                    dynamic_cast<SegmentBase *>(base)->setByteRange(end + 1, 0);
+            }
+        }
+    }
+
+    if(node->hasAttribute("timescale"))
+        base->setTimescale(Integer<uint64_t>(node->getAttributeValue("timescale")));
+
+}
+
+void IsoffMainParser::parseMultipleSegmentBaseType(MPD *mpd, Node *node,
+                                                   AbstractMultipleSegmentBaseType *base,
+                                                   SegmentInformation *parent)
+{
+    parseSegmentBaseType(mpd, node, base, parent);
+
+    if(node->hasAttribute("duration"))
+        base->duration.Set(Integer<stime_t>(node->getAttributeValue("duration")));
+
+    if(node->hasAttribute("startNumber"))
+        base->setStartNumber(Integer<uint64_t>(node->getAttributeValue("startNumber")));
+
+    parseTimeline(DOMHelper::getFirstChildElementByName(node, "SegmentTimeline"), base);
+}
+
 size_t IsoffMainParser::parseSegmentTemplate(MPD *mpd, Node *templateNode, SegmentInformation *info)
 {
     size_t total = 0;
@@ -192,33 +235,26 @@ size_t IsoffMainParser::parseSegmentTemplate(MPD *mpd, Node *templateNode, Segme
     if(templateNode->hasAttribute("media"))
         mediaurl = templateNode->getAttributeValue("media");
 
-    MediaSegmentTemplate *mediaTemplate = NULL;
-    if( !(mediaTemplate = new (std::nothrow) MediaSegmentTemplate(info)) )
+    SegmentTemplate *mediaTemplate = new (std::nothrow) SegmentTemplate(info);
+    if(!mediaTemplate)
         return total;
     mediaTemplate->setSourceUrl(mediaurl);
 
-    if(templateNode->hasAttribute("startNumber"))
-        mediaTemplate->setStartNumber(Integer<uint64_t>(templateNode->getAttributeValue("startNumber")));
-
-    if(templateNode->hasAttribute("timescale"))
-        mediaTemplate->setTimescale(Integer<uint64_t>(templateNode->getAttributeValue("timescale")));
-
-    if(templateNode->hasAttribute("duration"))
-        mediaTemplate->duration.Set(Integer<stime_t>(templateNode->getAttributeValue("duration")));
+    parseMultipleSegmentBaseType(mpd, templateNode, mediaTemplate, info);
 
     parseAvailability<SegmentInformation>(mpd, templateNode, info);
 
-    InitSegmentTemplate *initTemplate = NULL;
-
-    if(templateNode->hasAttribute("initialization"))
+    if(templateNode->hasAttribute("initialization")) /* /!\ != Initialization */
     {
+        SegmentTemplateInit *initTemplate;
         std::string initurl = templateNode->getAttributeValue("initialization");
-        if(!initurl.empty() && (initTemplate = new (std::nothrow) InitSegmentTemplate(info, mediaTemplate)))
+        if(!initurl.empty() && (initTemplate = new (std::nothrow) SegmentTemplateInit(mediaTemplate, info)))
+        {
             initTemplate->setSourceUrl(initurl);
+            delete mediaTemplate->initialisationSegment.Get();
+            mediaTemplate->initialisationSegment.Set(initTemplate);
+        }
     }
-    mediaTemplate->initialisationSegment.Set(initTemplate);
-
-    parseTimeline(DOMHelper::getFirstChildElementByName(templateNode, "SegmentTimeline"), mediaTemplate);
 
     info->setSegmentTemplate(mediaTemplate);
 
@@ -371,23 +407,8 @@ size_t IsoffMainParser::parseSegmentBase(MPD *mpd, Node * segmentBaseNode, Segme
     if(!segmentBaseNode || !(base = new (std::nothrow) SegmentBase(info)))
         return 0;
 
-    if(segmentBaseNode->hasAttribute("indexRange"))
-    {
-        size_t start = 0, end = 0;
-        if (std::sscanf(segmentBaseNode->getAttributeValue("indexRange").c_str(), "%zu-%zu", &start, &end) == 2)
-        {
-            IndexSegment *index = new (std::nothrow) DashIndexSegment(info);
-            if(index)
-            {
-                index->setByteRange(start, end);
-                base->indexSegment.Set(index);
-                /* index must be before data, so data starts at index end */
-                base->setByteRange(end + 1, 0);
-            }
-        }
-    }
+    parseSegmentBaseType(mpd, segmentBaseNode, base, info);
 
-    parseInitSegment(DOMHelper::getFirstChildElementByName(segmentBaseNode, "Initialization"), base, info);
     parseAvailability<SegmentInformation>(mpd, segmentBaseNode, info);
 
     if(!base->initialisationSegment.Get() && base->indexSegment.Get() && base->indexSegment.Get()->getOffset())
@@ -412,13 +433,7 @@ size_t IsoffMainParser::parseSegmentList(MPD *mpd, Node * segListNode, SegmentIn
         SegmentList *list;
         if((list = new (std::nothrow) SegmentList(info)))
         {
-            parseInitSegment(DOMHelper::getFirstChildElementByName(segListNode, "Initialization"), list, info);
-
-            if(segListNode->hasAttribute("duration"))
-                list->duration.Set(Integer<stime_t>(segListNode->getAttributeValue("duration")));
-
-            if(segListNode->hasAttribute("timescale"))
-                list->setTimescale(Integer<uint64_t>(segListNode->getAttributeValue("timescale")));
+            parseMultipleSegmentBaseType(mpd, segListNode, list, info);
 
             parseAvailability<SegmentInformation>(mpd, segListNode, info);
 
@@ -480,7 +495,7 @@ void IsoffMainParser::parseInitSegment(Node *initNode, Initializable<InitSegment
     init->initialisationSegment.Set(seg);
 }
 
-void IsoffMainParser::parseTimeline(Node *node, MediaSegmentTemplate *templ)
+void IsoffMainParser::parseTimeline(Node *node, AbstractMultipleSegmentBaseType *base)
 {
     if(!node)
         return;
@@ -488,10 +503,10 @@ void IsoffMainParser::parseTimeline(Node *node, MediaSegmentTemplate *templ)
     uint64_t number = 0;
     if(node->hasAttribute("startNumber"))
         number = Integer<uint64_t>(node->getAttributeValue("startNumber"));
-    else if(templ->inheritStartNumber())
-        number = templ->inheritStartNumber();
+    else if(base->inheritStartNumber())
+        number = base->inheritStartNumber();
 
-    SegmentTimeline *timeline = new (std::nothrow) SegmentTimeline(templ);
+    SegmentTimeline *timeline = new (std::nothrow) SegmentTimeline(base);
     if(timeline)
     {
         std::vector<Node *> elements = DOMHelper::getElementByTagName(node, "S", false);
@@ -519,7 +534,7 @@ void IsoffMainParser::parseTimeline(Node *node, MediaSegmentTemplate *templ)
 
             number += (1 + r);
         }
-        templ->setSegmentTimeline(timeline);
+        base->setSegmentTimeline(timeline);
     }
 }
 
diff --git a/modules/demux/dash/mpd/IsoffMainParser.h b/modules/demux/dash/mpd/IsoffMainParser.h
index 0856bfb132adf856a872213c7426a52e6ce384da..88a6e253f8474d46d5592e670e2448a247154bab 100644
--- a/modules/demux/dash/mpd/IsoffMainParser.h
+++ b/modules/demux/dash/mpd/IsoffMainParser.h
@@ -29,7 +29,7 @@
 # include "config.h"
 #endif
 
-#include "../../adaptive/playlist/SegmentInfoCommon.h"
+#include "../../adaptive/playlist/SegmentBaseType.hpp"
 #include "Profile.hpp"
 
 #include <cstdlib>
@@ -41,7 +41,7 @@ namespace adaptive
     namespace playlist
     {
         class SegmentInformation;
-        class MediaSegmentTemplate;
+        class SegmentTemplate;
     }
     namespace xml
     {
@@ -75,13 +75,19 @@ namespace dash
                 void    parseAdaptationSets (MPD *, xml::Node *periodNode, Period *period);
                 void    parseRepresentations(MPD *, xml::Node *adaptationSetNode, AdaptationSet *adaptationSet);
                 void    parseInitSegment    (xml::Node *, Initializable<InitSegment> *, SegmentInformation *);
-                void    parseTimeline       (xml::Node *, MediaSegmentTemplate *);
+                void    parseTimeline       (xml::Node *, AbstractMultipleSegmentBaseType *);
                 void    parsePeriods        (MPD *, xml::Node *);
                 size_t  parseSegmentInformation(MPD *, xml::Node *, SegmentInformation *, uint64_t *);
                 size_t  parseSegmentBase    (MPD *, xml::Node *, SegmentInformation *);
                 size_t  parseSegmentList    (MPD *, xml::Node *, SegmentInformation *);
                 size_t  parseSegmentTemplate(MPD *, xml::Node *, SegmentInformation *);
                 void    parseProgramInformation(xml::Node *, MPD *);
+                void    parseSegmentBaseType(MPD *mpd, xml::Node *node,
+                                             AbstractSegmentBaseType *base,
+                                             SegmentInformation *parent);
+                void    parseMultipleSegmentBaseType(MPD *mpd, xml::Node *node,
+                                             AbstractMultipleSegmentBaseType *base,
+                                             SegmentInformation *parent);
 
                 xml::Node       *root;
                 vlc_object_t    *p_object;
diff --git a/modules/demux/dash/mpd/Representation.cpp b/modules/demux/dash/mpd/Representation.cpp
index a1acf7986c6c95c09007da267443467f8ba28e90..9f936fe4ef31a2da17b9bdc1d50884037c49ad78 100644
--- a/modules/demux/dash/mpd/Representation.cpp
+++ b/modules/demux/dash/mpd/Representation.cpp
@@ -54,14 +54,12 @@ StreamFormat Representation::getStreamFormat() const
 }
 
 std::string Representation::contextualize(size_t number, const std::string &component,
-                                          const BaseSegmentTemplate *basetempl) const
+                                          const SegmentTemplate *templ) const
 {
     std::string str(component);
-    if(!basetempl)
+    if(!templ)
         return str;
 
-    const MediaSegmentTemplate *templ = dynamic_cast<const MediaSegmentTemplate *>(basetempl);
-
     std::string::size_type pos = 0;
     while(pos < str.length())
     {
@@ -103,7 +101,7 @@ std::string Representation::contextualize(size_t number, const std::string &comp
     return str;
 }
 
-stime_t Representation::getScaledTimeBySegmentNumber(uint64_t index, const MediaSegmentTemplate *templ) const
+stime_t Representation::getScaledTimeBySegmentNumber(uint64_t index, const SegmentTemplate *templ) const
 {
     stime_t time = 0;
     const SegmentTimeline *tl = templ->inheritSegmentTimeline();
diff --git a/modules/demux/dash/mpd/Representation.h b/modules/demux/dash/mpd/Representation.h
index ac0c5e1aa25431f9e6d92cdeb668f496a71dbc91..2d66fa5d5dffce5100edc20eac4d159bb3f4e758 100644
--- a/modules/demux/dash/mpd/Representation.h
+++ b/modules/demux/dash/mpd/Representation.h
@@ -26,7 +26,7 @@
 #define DASHREPRESENTATION_H_
 
 #include "DASHCommonAttributesElements.h"
-#include "../../adaptive/playlist/SegmentInfoCommon.h"
+#include "../../adaptive/playlist/SegmentBaseType.hpp"
 #include "../../adaptive/playlist/BaseRepresentation.h"
 
 namespace dash
@@ -50,12 +50,12 @@ namespace dash
 
                 /* for segment templates */
                 virtual std::string contextualize(size_t, const std::string &,
-                                                  const BaseSegmentTemplate *) const; // reimpl
+                                                  const SegmentTemplate *) const; // reimpl
 
             private:
 
                 /* for contextualize() */
-                stime_t getScaledTimeBySegmentNumber(uint64_t, const MediaSegmentTemplate *) const;
+                stime_t getScaledTimeBySegmentNumber(uint64_t, const SegmentTemplate *) const;
         };
     }
 }
diff --git a/modules/demux/hls/playlist/Parser.hpp b/modules/demux/hls/playlist/Parser.hpp
index fc0ac6314f4736219200677a32825669cb2cdc88..6bcc1b6d040c3d993ee4b0e375854794e0b3be40 100644
--- a/modules/demux/hls/playlist/Parser.hpp
+++ b/modules/demux/hls/playlist/Parser.hpp
@@ -20,10 +20,11 @@
 #ifndef PARSER_HPP
 #define PARSER_HPP
 
-#include "../../adaptive/playlist/SegmentInfoCommon.h"
+#include "../../adaptive/playlist/SegmentBaseType.hpp"
 
 #include <cstdlib>
 #include <sstream>
+#include <list>
 
 #include <vlc_common.h>
 
@@ -34,7 +35,7 @@ namespace adaptive
     namespace playlist
     {
         class SegmentInformation;
-        class MediaSegmentTemplate;
+        class SegmentTemplate;
         class BasePeriod;
         class BaseAdaptationSet;
     }
diff --git a/modules/demux/hls/playlist/Representation.cpp b/modules/demux/hls/playlist/Representation.cpp
index 97ce41883beee8cdfb063040960510cc0d37ea66..08f7b40249444b4b383fb137e53c8eaa40d14b35 100644
--- a/modules/demux/hls/playlist/Representation.cpp
+++ b/modules/demux/hls/playlist/Representation.cpp
@@ -172,9 +172,8 @@ uint64_t Representation::translateSegmentNumber(uint64_t num, const BaseRepresen
     const vlc_tick_t utcTime = fromHlsSeg->getUTCTime() +
                                getTimescale().ToTime(fromHlsSeg->duration.Get()) / 2;
 
-    std::vector<Segment *> list;
+    const std::vector<Segment *> &list = inheritSegmentList()->getSegments();
     std::vector<Segment *>::const_iterator it;
-    getMediaSegments(list);
     for(it=list.begin(); it != list.end(); ++it)
     {
         const HLSSegment *hlsSeg = dynamic_cast<HLSSegment *>(*it);
diff --git a/modules/demux/smooth/mp4/IndexReader.cpp b/modules/demux/smooth/mp4/IndexReader.cpp
index 60ac7c08252a4530a3bd86f6e11165bfb556ad6a..ef3e363030d8d6cde80259bc69c1a85cbe602180 100644
--- a/modules/demux/smooth/mp4/IndexReader.cpp
+++ b/modules/demux/smooth/mp4/IndexReader.cpp
@@ -71,7 +71,9 @@ bool IndexReader::parseIndex(block_t *p_block, BaseRepresentation *rep)
             timelineadd->addElement(i+1, dur, 0, stime);
         }
 
-        rep->mergeWithTimeline(timelineadd);
+        rep->inheritSegmentTemplate()->
+             inheritSegmentTimeline()->
+             updateWith(*timelineadd);
         delete timelineadd;
 
 #ifndef NDEBUG
diff --git a/modules/demux/smooth/playlist/Parser.cpp b/modules/demux/smooth/playlist/Parser.cpp
index 9d2286bcfba9d426979ff948dd4041f47ab3f77a..4ca85add22f86049ac7009f9bc7ddb9ae1b1501f 100644
--- a/modules/demux/smooth/playlist/Parser.cpp
+++ b/modules/demux/smooth/playlist/Parser.cpp
@@ -232,7 +232,7 @@ static void ParseStreamIndex(BasePeriod *period, Node *streamIndexNode, unsigned
         if(!url.empty())
         {
             /* SmoothSegment is a template holder */
-            SmoothSegment *templ = new SmoothSegment(adaptSet);
+            SmoothSegmentTemplate *templ = new SmoothSegmentTemplate(adaptSet);
             if(templ)
             {
                 templ->setSourceUrl(url);
diff --git a/modules/demux/smooth/playlist/Parser.hpp b/modules/demux/smooth/playlist/Parser.hpp
index 70ee526283f050b283c44c956e8eaf136d07a788..ee93e4b45a8c4129d3b28f799d30317b899f3786 100644
--- a/modules/demux/smooth/playlist/Parser.hpp
+++ b/modules/demux/smooth/playlist/Parser.hpp
@@ -20,7 +20,7 @@
 #ifndef MANIFESTPARSER_HPP
 #define MANIFESTPARSER_HPP
 
-#include "../../adaptive/playlist/SegmentInfoCommon.h"
+#include "../../adaptive/playlist/SegmentBaseType.hpp"
 
 #include <cstdlib>
 #include <sstream>
@@ -32,7 +32,7 @@ namespace adaptive
     namespace playlist
     {
         class SegmentInformation;
-        class MediaSegmentTemplate;
+        class SegmentTemplate;
         class BasePeriod;
         class BaseAdaptationSet;
     }
diff --git a/modules/demux/smooth/playlist/Representation.cpp b/modules/demux/smooth/playlist/Representation.cpp
index eae39dded9d139360a16b50e9b4e2103826e239f..91c57182dd7a4a5fee6e6bec4e82c89b0a0dd98f 100644
--- a/modules/demux/smooth/playlist/Representation.cpp
+++ b/modules/demux/smooth/playlist/Representation.cpp
@@ -52,16 +52,14 @@ InitSegment * Representation::getInitSegment() const
 }
 
 std::string Representation::contextualize(size_t number, const std::string &component,
-                                          const BaseSegmentTemplate *basetempl) const
+                                          const SegmentTemplate *templ) const
 {
     std::string ret(component);
     size_t pos;
 
-    if(!basetempl)
+    if(!templ)
         return ret;
 
-    const MediaSegmentTemplate *templ = dynamic_cast<const MediaSegmentTemplate *>(basetempl);
-
     if(templ)
     {
         pos = ret.find("{start time}");
diff --git a/modules/demux/smooth/playlist/Representation.hpp b/modules/demux/smooth/playlist/Representation.hpp
index 09eb6927f879779b227eb3526c55e68d8b8ee693..e708fc14a81a009b5916c8bb9f77203abba2e750 100644
--- a/modules/demux/smooth/playlist/Representation.hpp
+++ b/modules/demux/smooth/playlist/Representation.hpp
@@ -20,7 +20,7 @@
 #ifndef SMOOTHREPRESENTATION_HPP
 #define SMOOTHREPRESENTATION_HPP
 
-#include "../../adaptive/playlist/SegmentInfoCommon.h"
+#include "../../adaptive/playlist/SegmentBaseType.hpp"
 #include "../../adaptive/playlist/BaseRepresentation.h"
 
 namespace adaptive
@@ -50,7 +50,7 @@ namespace smooth
 
                 /* for segment templates */
                 virtual std::string contextualize(size_t, const std::string &,
-                                                  const BaseSegmentTemplate *) const; // reimpl
+                                                  const SegmentTemplate *) const; // reimpl
         };
     }
 }
diff --git a/modules/demux/smooth/playlist/SmoothSegment.cpp b/modules/demux/smooth/playlist/SmoothSegment.cpp
index fc4eb7ac565b5e9b04ccca23a880b4d45fcec37b..9371353bfc9da96e4bc6515cbe3c8f17e7aca685 100644
--- a/modules/demux/smooth/playlist/SmoothSegment.cpp
+++ b/modules/demux/smooth/playlist/SmoothSegment.cpp
@@ -64,18 +64,18 @@ void SmoothSegmentChunk::onDownload(block_t **pp_block)
     }
 }
 
-SmoothSegment::SmoothSegment(SegmentInformation *parent) :
-    MediaSegmentTemplate( parent )
+SmoothSegmentTemplate::SmoothSegmentTemplate(SegmentInformation *parent) :
+    SegmentTemplate( parent )
 {
 
 }
 
-SmoothSegment::~SmoothSegment()
+SmoothSegmentTemplate::~SmoothSegmentTemplate()
 {
 
 }
 
-SegmentChunk* SmoothSegment::createChunk(AbstractChunkSource *source, BaseRepresentation *rep)
+SegmentChunk* SmoothSegmentTemplate::createChunk(AbstractChunkSource *source, BaseRepresentation *rep)
 {
      /* act as factory */
     return new (std::nothrow) SmoothSegmentChunk(source, rep);
diff --git a/modules/demux/smooth/playlist/SmoothSegment.hpp b/modules/demux/smooth/playlist/SmoothSegment.hpp
index 3849e38034673ba6125aa00e8bb79da3815a3a0c..44261b147bff0026a842805808a3c57324337bf4 100644
--- a/modules/demux/smooth/playlist/SmoothSegment.hpp
+++ b/modules/demux/smooth/playlist/SmoothSegment.hpp
@@ -37,11 +37,11 @@ namespace smooth
                 virtual void onDownload(block_t **); /* reimpl */
         };
 
-        class SmoothSegment : public MediaSegmentTemplate
+        class SmoothSegmentTemplate : public SegmentTemplate
         {
             public:
-                SmoothSegment(SegmentInformation * = NULL);
-                ~SmoothSegment();
+                SmoothSegmentTemplate(SegmentInformation * = NULL);
+                ~SmoothSegmentTemplate();
                 virtual SegmentChunk* createChunk(AbstractChunkSource *, BaseRepresentation *); /* reimpl */
         };
     }