Commit 5ada7fd6 authored by Francois Cartegnie's avatar Francois Cartegnie

demux: dash: split dash and adaptative specific code

also fixes includes, forward declarations
parent 6462aa5c
......@@ -245,37 +245,14 @@ demux_LTLIBRARIES += libts_plugin.la
endif
libdash_plugin_la_SOURCES = \
demux/dash/adaptationlogic/AbstractAdaptationLogic.cpp \
demux/dash/adaptationlogic/AbstractAdaptationLogic.h \
demux/dash/adaptationlogic/AdaptationLogicFactory.cpp \
demux/dash/adaptationlogic/AdaptationLogicFactory.h \
demux/dash/adaptationlogic/AlwaysBestAdaptationLogic.cpp \
demux/dash/adaptationlogic/AlwaysBestAdaptationLogic.h \
demux/dash/adaptationlogic/AlwaysLowestAdaptationLogic.cpp \
demux/dash/adaptationlogic/AlwaysLowestAdaptationLogic.hpp \
demux/dash/adaptationlogic/IDownloadRateObserver.h \
demux/dash/adaptationlogic/RateBasedAdaptationLogic.h \
demux/dash/adaptationlogic/RateBasedAdaptationLogic.cpp \
demux/dash/adaptationlogic/Representationselectors.hpp \
demux/dash/adaptationlogic/Representationselectors.cpp \
demux/dash/http/Chunk.cpp \
demux/dash/http/Chunk.h \
demux/dash/http/HTTPConnection.cpp \
demux/dash/http/HTTPConnection.h \
demux/dash/http/HTTPConnectionManager.cpp \
demux/dash/http/HTTPConnectionManager.h \
demux/dash/http/IHTTPConnection.cpp \
demux/dash/http/IHTTPConnection.h \
demux/dash/http/PersistentConnection.cpp \
demux/dash/http/PersistentConnection.h \
demux/dash/mpd/AdaptationSet.cpp \
demux/dash/mpd/AdaptationSet.h \
demux/dash/mpd/BaseUrl.h \
demux/dash/mpd/CommonAttributesElements.cpp \
demux/dash/mpd/CommonAttributesElements.h \
demux/dash/mpd/DASHCommonAttributesElements.cpp \
demux/dash/mpd/DASHCommonAttributesElements.h \
demux/dash/mpd/DASHSegment.cpp \
demux/dash/mpd/DASHSegment.h \
demux/dash/mpd/ContentDescription.cpp \
demux/dash/mpd/ContentDescription.h \
demux/dash/mpd/ICanonicalUrl.hpp \
demux/dash/mpd/IMPDParser.cpp \
demux/dash/mpd/IMPDParser.h \
demux/dash/mpd/IsoffMainParser.cpp \
......@@ -292,24 +269,8 @@ libdash_plugin_la_SOURCES = \
demux/dash/mpd/ProgramInformation.h \
demux/dash/mpd/Representation.cpp \
demux/dash/mpd/Representation.h \
demux/dash/mpd/Segment.cpp \
demux/dash/mpd/Segment.h \
demux/dash/mpd/SegmentBase.cpp \
demux/dash/mpd/SegmentBase.h \
demux/dash/mpd/SegmentInfoCommon.cpp \
demux/dash/mpd/SegmentInfoCommon.h \
demux/dash/mpd/SegmentInformation.cpp \
demux/dash/mpd/SegmentInformation.hpp \
demux/dash/mpd/SegmentList.cpp \
demux/dash/mpd/SegmentList.h \
demux/dash/mpd/SegmentTemplate.cpp \
demux/dash/mpd/SegmentTemplate.h \
demux/dash/mpd/SegmentTimeline.cpp \
demux/dash/mpd/SegmentTimeline.h \
demux/dash/mpd/TrickModeType.cpp \
demux/dash/mpd/TrickModeType.h \
demux/dash/mpd/Url.cpp \
demux/dash/mpd/Url.hpp \
demux/dash/mp4/AtomsReader.cpp \
demux/dash/mp4/AtomsReader.hpp \
demux/dash/xml/DOMHelper.cpp \
......@@ -321,15 +282,68 @@ libdash_plugin_la_SOURCES = \
demux/dash/dash.cpp \
demux/dash/dash.hpp \
demux/dash/DASHManager.cpp \
demux/dash/DASHManager.h \
demux/dash/Helper.cpp \
demux/dash/Helper.h \
demux/dash/Properties.hpp \
demux/dash/SegmentTracker.cpp \
demux/dash/SegmentTracker.hpp \
demux/dash/StreamsType.hpp \
demux/dash/Streams.cpp \
demux/dash/Streams.hpp
demux/dash/DASHManager.h
libdash_plugin_la_SOURCES += \
demux/adaptative/playlist/AbstractPlaylist.cpp \
demux/adaptative/playlist/AbstractPlaylist.hpp \
demux/adaptative/playlist/BaseAdaptationSet.cpp \
demux/adaptative/playlist/BaseAdaptationSet.h \
demux/adaptative/playlist/BasePeriod.cpp \
demux/adaptative/playlist/BasePeriod.h \
demux/adaptative/playlist/BaseRepresentation.cpp \
demux/adaptative/playlist/BaseRepresentation.h \
demux/adaptative/playlist/BaseUrl.h \
demux/adaptative/playlist/CommonAttributesElements.cpp \
demux/adaptative/playlist/CommonAttributesElements.h \
demux/adaptative/playlist/ICanonicalUrl.hpp \
demux/adaptative/playlist/Segment.cpp \
demux/adaptative/playlist/Segment.h \
demux/adaptative/playlist/SegmentBase.cpp \
demux/adaptative/playlist/SegmentBase.h \
demux/adaptative/playlist/SegmentInfoCommon.cpp \
demux/adaptative/playlist/SegmentInfoCommon.h \
demux/adaptative/playlist/SegmentList.cpp \
demux/adaptative/playlist/SegmentList.h \
demux/adaptative/playlist/SegmentTimeline.cpp \
demux/adaptative/playlist/SegmentTimeline.h \
demux/adaptative/playlist/SegmentInformation.cpp \
demux/adaptative/playlist/SegmentInformation.hpp \
demux/adaptative/playlist/SegmentTemplate.cpp \
demux/adaptative/playlist/SegmentTemplate.h \
demux/adaptative/playlist/Url.cpp \
demux/adaptative/playlist/Url.hpp \
demux/adaptative/logic/AbstractAdaptationLogic.cpp \
demux/adaptative/logic/AbstractAdaptationLogic.h \
demux/adaptative/logic/AlwaysBestAdaptationLogic.cpp \
demux/adaptative/logic/AlwaysBestAdaptationLogic.h \
demux/adaptative/logic/AlwaysLowestAdaptationLogic.cpp \
demux/adaptative/logic/AlwaysLowestAdaptationLogic.hpp \
demux/adaptative/logic/IDownloadRateObserver.h \
demux/adaptative/logic/RateBasedAdaptationLogic.h \
demux/adaptative/logic/RateBasedAdaptationLogic.cpp \
demux/adaptative/logic/Representationselectors.hpp \
demux/adaptative/logic/Representationselectors.cpp \
demux/adaptative/http/Chunk.cpp \
demux/adaptative/http/Chunk.h \
demux/adaptative/http/HTTPConnection.cpp \
demux/adaptative/http/HTTPConnection.h \
demux/adaptative/http/HTTPConnectionManager.cpp \
demux/adaptative/http/HTTPConnectionManager.h \
demux/adaptative/http/IHTTPConnection.cpp \
demux/adaptative/http/IHTTPConnection.h \
demux/adaptative/http/PersistentConnection.cpp \
demux/adaptative/http/PersistentConnection.h \
demux/adaptative/PlaylistManager.cpp \
demux/adaptative/PlaylistManager.h \
demux/adaptative/SegmentTracker.cpp \
demux/adaptative/SegmentTracker.hpp \
demux/adaptative/Streams.cpp \
demux/adaptative/Streams.hpp \
demux/adaptative/StreamsType.hpp \
demux/adaptative/tools/Helper.cpp \
demux/adaptative/tools/Helper.h \
demux/adaptative/tools/Properties.hpp
libdash_plugin_la_SOURCES += demux/mp4/libmp4.c demux/mp4/libmp4.h
......
/*
* PlaylistManager.cpp
*****************************************************************************
* Copyright © 2010 - 2011 Klagenfurt University
* 2015 VideoLAN Authors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/* config.h may include inttypes.h, so make sure we define that option
* early enough. */
#define __STDC_FORMAT_MACROS
#define __STDC_CONSTANT_MACROS
#define __STDC_LIMIT_MACROS
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "PlaylistManager.h"
#include "SegmentTracker.hpp"
#include "playlist/AbstractPlaylist.hpp"
#include "playlist/BasePeriod.h"
#include "playlist/BaseAdaptationSet.h"
#include "http/HTTPConnectionManager.h"
#include "logic/AlwaysBestAdaptationLogic.h"
#include "logic/RateBasedAdaptationLogic.h"
#include "logic/AlwaysLowestAdaptationLogic.hpp"
#include <vlc_stream.h>
using namespace adaptative::http;
using namespace adaptative::logic;
using namespace adaptative;
PlaylistManager::PlaylistManager( AbstractPlaylist *pl,
AbstractAdaptationLogic::LogicType type,
stream_t *stream) :
conManager ( NULL ),
logicType ( type ),
playlist ( pl ),
stream ( stream ),
nextPlaylistupdate ( 0 )
{
for(int i=0; i<Streams::count; i++)
streams[i] = NULL;
}
PlaylistManager::~PlaylistManager ()
{
delete conManager;
for(int i=0; i<Streams::count; i++)
delete streams[i];
}
bool PlaylistManager::start(demux_t *demux)
{
const BasePeriod *period = playlist->getFirstPeriod();
if(!period)
return false;
for(int i=0; i<Streams::count; i++)
{
Streams::Type type = static_cast<Streams::Type>(i);
const BaseAdaptationSet *set = period->getAdaptationSet(type);
if(set)
{
streams[type] = new (std::nothrow) Streams::Stream(set->getMimeType());
if(!streams[type])
continue;
AbstractAdaptationLogic *logic = createLogic(logicType);
if(!logic)
{
delete streams[type];
streams[type] = NULL;
continue;
}
SegmentTracker *tracker = new (std::nothrow) SegmentTracker(logic, playlist);
try
{
if(!tracker)
throw VLC_ENOMEM;
streams[type]->create(demux, logic, tracker);
} catch (int) {
delete streams[type];
delete logic;
delete tracker;
streams[type] = NULL;
}
}
}
conManager = new (std::nothrow) HTTPConnectionManager(stream);
if(!conManager)
return false;
playlist->playbackStart.Set(time(NULL));
nextPlaylistupdate = playlist->playbackStart.Get();
return true;
}
size_t PlaylistManager::read()
{
size_t i_ret = 0;
for(int type=0; type<Streams::count; type++)
{
if(!streams[type])
continue;
i_ret += streams[type]->read(conManager);
}
return i_ret;
}
mtime_t PlaylistManager::getPCR() const
{
mtime_t pcr = VLC_TS_INVALID;
for(int type=0; type<Streams::count; type++)
{
if(!streams[type])
continue;
if(pcr == VLC_TS_INVALID || pcr > streams[type]->getPCR())
pcr = streams[type]->getPCR();
}
return pcr;
}
int PlaylistManager::getGroup() const
{
for(int type=0; type<Streams::count; type++)
{
if(!streams[type])
continue;
return streams[type]->getGroup();
}
return -1;
}
int PlaylistManager::esCount() const
{
int es = 0;
for(int type=0; type<Streams::count; type++)
{
if(!streams[type])
continue;
es += streams[type]->esCount();
}
return es;
}
mtime_t PlaylistManager::getDuration() const
{
if (playlist->isLive())
return 0;
else
return CLOCK_FREQ * playlist->duration.Get();
}
bool PlaylistManager::setPosition(mtime_t time)
{
bool ret = true;
for(int real = 0; real < 2; real++)
{
/* Always probe if we can seek first */
for(int type=0; type<Streams::count; type++)
{
if(!streams[type])
continue;
ret &= streams[type]->setPosition(time, !real);
}
if(!ret)
break;
}
return ret;
}
bool PlaylistManager::seekAble() const
{
if(playlist->isLive())
return false;
for(int type=0; type<Streams::count; type++)
{
if(!streams[type])
continue;
if(!streams[type]->seekAble())
return false;
}
return true;
}
bool PlaylistManager::updatePlaylist()
{
return true;
}
AbstractAdaptationLogic *PlaylistManager::createLogic(AbstractAdaptationLogic::LogicType type)
{
switch(type)
{
case AbstractAdaptationLogic::AlwaysBest:
return new (std::nothrow) AlwaysBestAdaptationLogic();
case AbstractAdaptationLogic::FixedRate:
case AbstractAdaptationLogic::AlwaysLowest:
return new (std::nothrow) AlwaysLowestAdaptationLogic();
case AbstractAdaptationLogic::Default:
case AbstractAdaptationLogic::RateBased:
return new (std::nothrow) RateBasedAdaptationLogic(0, 0);
default:
return NULL;
}
}
/*
* PlaylistManager.h
*****************************************************************************
* Copyright © 2010 - 2011 Klagenfurt University
* 2015 VideoLAN Authors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef PLAYLISTMANAGER_H_
#define PLAYLISTMANAGER_H_
#include "logic/AbstractAdaptationLogic.h"
#include "Streams.hpp"
namespace adaptative
{
namespace playlist
{
class AbstractPlaylist;
}
namespace http
{
class HTTPConnectionManager;
}
using namespace playlist;
using namespace logic;
using namespace http;
class PlaylistManager
{
public:
PlaylistManager( AbstractPlaylist *,
AbstractAdaptationLogic::LogicType type, stream_t *stream);
virtual ~PlaylistManager ();
bool start (demux_t *);
size_t read();
mtime_t getDuration() const;
mtime_t getPCR() const;
int getGroup() const;
int esCount() const;
bool setPosition(mtime_t);
bool seekAble() const;
virtual bool updatePlaylist();
protected:
virtual AbstractAdaptationLogic *createLogic(AbstractAdaptationLogic::LogicType);
HTTPConnectionManager *conManager;
AbstractAdaptationLogic::LogicType logicType;
AbstractPlaylist *playlist;
stream_t *stream;
Streams::Stream *streams[Streams::count];
mtime_t nextPlaylistupdate;
};
}
#endif /* PLAYLISTMANAGER_H_ */
......@@ -18,21 +18,22 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "SegmentTracker.hpp"
#include "mpd/MPD.h"
#include "playlist/AbstractPlaylist.hpp"
#include "playlist/BaseRepresentation.h"
#include "logic/AbstractAdaptationLogic.h"
using namespace dash;
using namespace dash::logic;
using namespace dash::http;
using namespace dash::mpd;
using namespace adaptative;
using namespace adaptative::logic;
using namespace adaptative::playlist;
SegmentTracker::SegmentTracker(AbstractAdaptationLogic *logic_, mpd::MPD *mpd_)
SegmentTracker::SegmentTracker(AbstractAdaptationLogic *logic_, AbstractPlaylist *playlist_)
{
count = 0;
initializing = true;
prevRepresentation = NULL;
currentPeriod = mpd_->getFirstPeriod();
setAdaptationLogic(logic_);
mpd = mpd_;
playlist = playlist_;
currentPeriod = playlist->getFirstPeriod();
}
SegmentTracker::~SegmentTracker()
......@@ -53,7 +54,7 @@ void SegmentTracker::resetCounter()
Chunk * SegmentTracker::getNextChunk(Streams::Type type)
{
Representation *rep;
BaseRepresentation *rep;
ISegment *segment;
if(!currentPeriod)
......@@ -76,15 +77,15 @@ Chunk * SegmentTracker::getNextChunk(Streams::Type type)
if(initializing)
{
initializing = false;
segment = rep->getSegment(Representation::INFOTYPE_INIT);
segment = rep->getSegment(BaseRepresentation::INFOTYPE_INIT);
if(segment)
return segment->toChunk(count, rep);
}
segment = rep->getSegment(Representation::INFOTYPE_MEDIA, count);
segment = rep->getSegment(BaseRepresentation::INFOTYPE_MEDIA, count);
if(!segment)
{
currentPeriod = mpd->getNextPeriod(currentPeriod);
currentPeriod = playlist->getNextPeriod(currentPeriod);
resetCounter();
return getNextChunk(type);
}
......
......@@ -27,16 +27,8 @@
#include "StreamsType.hpp"
#include <vlc_common.h>
namespace dash
namespace adaptative
{
namespace mpd
{
class MPD;
class Period;
class Representation;
class Segment;
}
namespace logic
{
class AbstractAdaptationLogic;
......@@ -47,25 +39,36 @@ namespace dash
class Chunk;
}
namespace playlist
{
class AbstractPlaylist;
class BasePeriod;
class BaseRepresentation;
}
using namespace playlist;
using namespace logic;
using namespace http;
class SegmentTracker
{
public:
SegmentTracker(logic::AbstractAdaptationLogic *, mpd::MPD *);
SegmentTracker(AbstractAdaptationLogic *, AbstractPlaylist *);
~SegmentTracker();
void setAdaptationLogic(logic::AbstractAdaptationLogic *);
void setAdaptationLogic(AbstractAdaptationLogic *);
void resetCounter();
http::Chunk* getNextChunk(Streams::Type);
Chunk* getNextChunk(Streams::Type);
bool setPosition(mtime_t, bool);
mtime_t getSegmentStart() const;
private:
bool initializing;
uint64_t count;
logic::AbstractAdaptationLogic *logic;
mpd::MPD *mpd;
mpd::Period *currentPeriod;
mpd::Representation *prevRepresentation;
AbstractAdaptationLogic *logic;
AbstractPlaylist *playlist;
BasePeriod *currentPeriod;
BaseRepresentation *prevRepresentation;
};
}
......
......@@ -19,15 +19,20 @@
*****************************************************************************/
#define __STDC_CONSTANT_MACROS
#include "Streams.hpp"
#include "adaptationlogic/AbstractAdaptationLogic.h"
#include "adaptationlogic/AdaptationLogicFactory.h"
#include "StreamsType.hpp"
#include "http/HTTPConnection.h"
#include "http/HTTPConnectionManager.h"
#include "http/Chunk.h"
#include "logic/AbstractAdaptationLogic.h"
#include "SegmentTracker.hpp"
#include <vlc_stream.h>
#include <vlc_demux.h>
using namespace dash::Streams;
using namespace dash::http;
using namespace dash::logic;
using namespace adaptative::Streams;
using namespace adaptative::http;
using namespace adaptative::logic;
using namespace adaptative::Streams;
Stream::Stream(const std::string &mime)
{
......@@ -87,14 +92,14 @@ Format Stream::mimeToFormat(const std::string &mime)
return format;
}
void Stream::create(demux_t *demux, AbstractAdaptationLogic *logic, dash::SegmentTracker *tracker)
void Stream::create(demux_t *demux, AbstractAdaptationLogic *logic, SegmentTracker *tracker)
{
switch(format)
{
case dash::Streams::MP4:
case adaptative::Streams::MP4:
output = new MP4StreamOutput(demux);
break;
case dash::Streams::MPEG2TS:
case adaptative::Streams::MPEG2TS:
output = new MPEG2TSStreamOutput(demux);
break;
default:
......
......@@ -27,18 +27,29 @@
#include <string>
#include <vlc_common.h>
#include "StreamsType.hpp"
#include "adaptationlogic/AbstractAdaptationLogic.h"
#include "http/HTTPConnectionManager.h"
#include "http/Chunk.h"
namespace dash
namespace adaptative
{
class SegmentTracker;
namespace http
{
class HTTPConnectionManager;
class Chunk;
}
namespace logic
{
class AbstractAdaptationLogic;
}
namespace Streams
{
class AbstractStreamOutput;
using namespace http;
using namespace logic;
class Stream
{
public:
......@@ -48,23 +59,23 @@ namespace dash
bool operator==(const Stream &) const;
static Type mimeToType(const std::string &mime);
static Format mimeToFormat(const std::string &mime);
void create(demux_t *, logic::AbstractAdaptationLogic *, SegmentTracker *);
void create(demux_t *, AbstractAdaptationLogic *, SegmentTracker *);
bool isEOF() const;
mtime_t getPCR() const;
int getGroup() const;
int esCount() const;
bool seekAble() const;
size_t read(http::HTTPConnectionManager *);
size_t read(HTTPConnectionManager *);
bool setPosition(mtime_t, bool);
mtime_t getPosition() const;
private:
http::Chunk *getChunk();
Chunk *getChunk();
void init(const Type, const Format);
Type type;
Format format;
AbstractStreamOutput *output;
logic::AbstractAdaptationLogic *adaptationLogic;
AbstractAdaptationLogic *adaptationLogic;
SegmentTracker *segmentTracker;
http::Chunk *currentChunk;
bool eof;
......
......@@ -20,7 +20,7 @@
#ifndef STREAMSTYPE_HPP
#define STREAMSTYPE_HPP
namespace dash
namespace adaptative
{
namespace Streams
{
......
......@@ -27,7 +27,10 @@
#include "Chunk.h"
using namespace dash::http;
#include <vlc_common.h>
#include <vlc_url.h>
using namespace adaptative::http;
Chunk::Chunk (const std::string& url) :
startByte (0),
......
......@@ -25,23 +25,16 @@
#ifndef CHUNK_H_
#define CHUNK_H_
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_url.h>
#include "HTTPConnection.h"
#include <vector>
#include <string>
#include <stdint.h>
namespace dash
namespace adaptative
{
namespace http
{
class HTTPConnection;
class Chunk
{
public:
......
......@@ -30,7 +30,7 @@
#include <sstream>
using namespace dash::http;
using namespace adaptative::http;
HTTPConnection::HTTPConnection (stream_t *stream, Chunk *chunk_) :
IHTTPConnection (stream)
......
......@@ -27,10 +27,10 @@
#include <string>
#include "http/IHTTPConnection.h"
#include "Helper.h"
#include "IHTTPConnection.h"
//#include "Helper.h"
namespace dash
namespace adaptative
{
namespace http
{
......
......@@ -26,11 +26,12 @@
#endif
#include "HTTPConnectionManager.h"
#include "http/Chunk.h"
#include "PersistentConnection.h"
#include "Chunk.h"
#include <vlc_stream.h>
using namespace dash::http;
using namespace adaptative::http;
const uint64_t HTTPConnectionManager::CHUNKDEFAULTBITRATE = 1;
......
......@@ -29,16 +29,17 @@
# include "config.h"
#endif
#include "http/PersistentConnection.h"
#include "adaptationlogic/IDownloadRateObserver.h"
#include <vlc_common.h>
#include <vector>
#include <string>
namespace dash
namespace adaptative
{
namespace http
{
class PersistentConnection;
class Chunk;
class HTTPConnectionManager
{
public:
......
......@@ -20,15 +20,14 @@
#include "IHTTPConnection.h"
#include "Chunk.h"
#include "Helper.h"
#include "dash.hpp"
#include "../adaptative/tools/Helper.h"
#include <vlc_network.h>
#include <vlc_stream.h>
#include <sstream>
using namespace dash::http;
using namespace adaptative::http;
IHTTPConnection::IHTTPConnection(stream_t *stream_)
{
......
......@@ -32,7 +32,7 @@
#include <vlc_common.h>
#include <string>
namespace dash
namespace adaptative
{
namespace http
{
......
......@@ -30,7 +30,7 @@
#include <vlc_network.h>
using namespace dash::http;
using namespace adaptative::http;
PersistentConnection::PersistentConnection (stream_t *stream, Chunk *chunk) :
HTTPConnection (stream, chunk)
......
......@@ -28,7 +28,7 @@
#include "HTTPConnection.h"
#include <deque>
namespace dash
namespace adaptative
{
namespace http
{
......
......@@ -27,11 +27,9 @@
#include "AbstractAdaptationLogic.h"
using namespace dash::logic;
using namespace dash::mpd;
using namespace adaptative::logic;
AbstractAdaptationLogic::AbstractAdaptationLogic (MPD *mpd_) :
mpd (mpd_)
AbstractAdaptationLogic::AbstractAdaptationLogic ()
{
}
......
......@@ -25,29 +25,28 @@
#ifndef ABSTRACTADAPTATIONLOGIC_H_
#define ABSTRACTADAPTATIONLOGIC_H_
#include <adaptationlogic/IDownloadRateObserver.h>
#include "StreamsType.hpp"
#include "IDownloadRateObserver.h"
#include "../StreamsType.hpp"
//struct stream_t;
namespace dash
namespace adaptative
{
namespace mpd
namespace playlist
{
class MPD;
class Period;
class Representation;
class BaseRepresentation;
class BasePeriod;
}
namespace logic
{
using namespace playlist;
class AbstractAdaptationLogic : public IDownloadRateObserver
{
public:
AbstractAdaptationLogic (mpd::MPD *mpd);
AbstractAdaptationLogic ();
virtual ~AbstractAdaptationLogic ();
virtual mpd::Representation* getCurrentRepresentation(Streams::Type, mpd::Period *) const = 0;
virtual BaseRepresentation* getCurrentRepresentation(Streams::Type, BasePeriod *) const = 0;
virtual void updateDownloadRate (size_t, mtime_t);
enum LogicType
......@@ -58,9 +57,6 @@ namespace dash
RateBased,
FixedRate
};
protected:
dash::mpd::MPD *mpd;
};
}
}
......
......@@ -28,15 +28,15 @@
#include "AlwaysBestAdaptationLogic.h"
#include "Representationselectors.hpp"
using namespace dash::logic;
using namespace dash::mpd;
using namespace adaptative::logic;
using namespace adaptative::playlist;
AlwaysBestAdaptationLogic::AlwaysBestAdaptationLogic (MPD *mpd) :
AbstractAdaptationLogic (mpd)
AlwaysBestAdaptationLogic::AlwaysBestAdaptationLogic () :
AbstractAdaptationLogic ()
{
}
Representation *AlwaysBestAdaptationLogic::getCurrentRepresentation(dash::Streams::Type type, Period *period) const
BaseRepresentation *AlwaysBestAdaptationLogic::getCurrentRepresentation(Streams::Type type, BasePeriod *period) const
{
RepresentationSelector selector;
return selector.select(period, type);
......
......@@ -25,18 +25,18 @@
#ifndef ALWAYSBESTADAPTATIONLOGIC_H_
#define ALWAYSBESTADAPTATIONLOGIC_H_
#include "adaptationlogic/AbstractAdaptationLogic.h"
#include "AbstractAdaptationLogic.h"
namespace dash
namespace adaptative
{
namespace logic
{
class AlwaysBestAdaptationLogic : public AbstractAdaptationLogic
{
public:
AlwaysBestAdaptationLogic (mpd::MPD *mpd);
AlwaysBestAdaptationLogic ();
virtual mpd::Representation *getCurrentRepresentation(Streams::Type, mpd::Period *) const;
virtual BaseRepresentation *getCurrentRepresentation(Streams::Type, BasePeriod *) const;
};
}
}
......
......@@ -20,15 +20,15 @@
#include "AlwaysLowestAdaptationLogic.hpp"
#include "Representationselectors.hpp"
using namespace dash::logic;
using namespace dash::mpd;
using namespace adaptative::logic;
using namespace adaptative::playlist;
AlwaysLowestAdaptationLogic::AlwaysLowestAdaptationLogic(MPD *mpd):
AbstractAdaptationLogic(mpd)
AlwaysLowestAdaptationLogic::AlwaysLowestAdaptationLogic():
AbstractAdaptationLogic()
{
}
Representation *AlwaysLowestAdaptationLogic::getCurrentRepresentation(dash::Streams::Type type, Period *period) const
BaseRepresentation *AlwaysLowestAdaptationLogic::getCurrentRepresentation(Streams::Type type, BasePeriod *period) const
{
RepresentationSelector selector;
return selector.select(period, type, 0);
......
......@@ -22,16 +22,16 @@
#include "AbstractAdaptationLogic.h"
namespace dash
namespace adaptative
{
namespace logic
{
class AlwaysLowestAdaptationLogic : public AbstractAdaptationLogic
{
public:
AlwaysLowestAdaptationLogic(mpd::MPD *mpd);
AlwaysLowestAdaptationLogic();
virtual dash::mpd::Representation* getCurrentRepresentation(Streams::Type, mpd::Period *) const;
virtual BaseRepresentation* getCurrentRepresentation(Streams::Type, BasePeriod *) const;
};
}
}
......
......@@ -31,7 +31,7 @@
#include <vlc_common.h>
namespace dash
namespace adaptative
{
namespace logic
{
......
......@@ -27,30 +27,28 @@
#include "RateBasedAdaptationLogic.h"
#include "Representationselectors.hpp"
#include "mpd/MPD.h"
#include <vlc_common.h>
#include <vlc_variables.h>
#include "../playlist/BaseRepresentation.h"
#include "../playlist/BasePeriod.h"
using namespace dash::logic;
using namespace dash::mpd;
using namespace adaptative::logic;
RateBasedAdaptationLogic::RateBasedAdaptationLogic (MPD *mpd) :
AbstractAdaptationLogic (mpd),
RateBasedAdaptationLogic::RateBasedAdaptationLogic (int w, int h) :
AbstractAdaptationLogic (),
bpsAvg(0), bpsSamplecount(0),
currentBps(0)
{
width = var_InheritInteger(mpd->getVLCObject(), "dash-prefwidth");
height = var_InheritInteger(mpd->getVLCObject(), "dash-prefheight");
width = w;
height = h;
}
Representation *RateBasedAdaptationLogic::getCurrentRepresentation(dash::Streams::Type type, Period *period) const
BaseRepresentation *RateBasedAdaptationLogic::getCurrentRepresentation(Streams::Type type, BasePeriod *period) const
{
if(period == NULL)
return NULL;
RepresentationSelector selector;
Representation *rep = selector.select(period, type, currentBps, width, height);
BaseRepresentation *rep = selector.select(period, type, currentBps, width, height);
if ( rep == NULL )
{
rep = selector.select(period, type);
......@@ -78,19 +76,19 @@ void RateBasedAdaptationLogic::updateDownloadRate(size_t size, mtime_t time)
currentBps = bpsAvg;
}
FixedRateAdaptationLogic::FixedRateAdaptationLogic(MPD *mpd) :
AbstractAdaptationLogic(mpd)
FixedRateAdaptationLogic::FixedRateAdaptationLogic(size_t bps) :
AbstractAdaptationLogic()
{
currentBps = var_InheritInteger( mpd->getVLCObject(), "dash-prefbw" ) * 8192;
currentBps = bps;
}
Representation *FixedRateAdaptationLogic::getCurrentRepresentation(dash::Streams::Type type, Period *period) const
BaseRepresentation *FixedRateAdaptationLogic::getCurrentRepresentation(Streams::Type type, BasePeriod *period) const
{
if(period == NULL)
return NULL;
RepresentationSelector selector;
Representation *rep = selector.select(period, type, currentBps);
BaseRepresentation *rep = selector.select(period, type, currentBps);
if ( rep == NULL )
{
rep = selector.select(period, type);
......
......@@ -25,20 +25,21 @@
#ifndef RATEBASEDADAPTATIONLOGIC_H_
#define RATEBASEDADAPTATIONLOGIC_H_
#include "adaptationlogic/AbstractAdaptationLogic.h"
#include "AbstractAdaptationLogic.h"
#define MINBUFFER 30
namespace dash
namespace adaptative
{
namespace logic
{
class RateBasedAdaptationLogic : public AbstractAdaptationLogic
{
public:
RateBasedAdaptationLogic (mpd::MPD *mpd);
RateBasedAdaptationLogic (int, int);
dash::mpd::Representation *getCurrentRepresentation(Streams::Type, mpd::Period *) const;
BaseRepresentation *getCurrentRepresentation(Streams::Type, BasePeriod *) const;
virtual void updateDownloadRate(size_t, mtime_t);
private:
......@@ -52,9 +53,9 @@ namespace dash
class FixedRateAdaptationLogic : public AbstractAdaptationLogic
{
public:
FixedRateAdaptationLogic(mpd::MPD *mpd);
FixedRateAdaptationLogic(size_t);
dash::mpd::Representation *getCurrentRepresentation(Streams::Type, mpd::Period *) const;
BaseRepresentation *getCurrentRepresentation(Streams::Type, BasePeriod *) const;
private:
size_t currentBps;
......
......@@ -18,31 +18,34 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "Representationselectors.hpp"
#include "../playlist/BaseRepresentation.h"
#include "../playlist/BaseAdaptationSet.h"
#include "../playlist/BasePeriod.h"
#include <limits>
using namespace dash::logic;
using namespace adaptative::logic;
RepresentationSelector::RepresentationSelector()
{
}
Representation * RepresentationSelector::select(Period *period, dash::Streams::Type type) const
BaseRepresentation * RepresentationSelector::select(BasePeriod *period, Streams::Type type) const
{
return select(period, type, std::numeric_limits<uint64_t>::max());
}
Representation * RepresentationSelector::select(Period *period, dash::Streams::Type type, uint64_t bitrate) const
BaseRepresentation * RepresentationSelector::select(BasePeriod *period, Streams::Type type, uint64_t bitrate) const
{
if (period == NULL)
return NULL;
std::vector<AdaptationSet *> adaptSets = period->getAdaptationSets(type);
Representation *best = NULL;
std::vector<BaseAdaptationSet *> adaptSets = period->getAdaptationSets(type);
BaseRepresentation *best = NULL;
std::vector<AdaptationSet *>::const_iterator adaptIt;
std::vector<BaseAdaptationSet *>::const_iterator adaptIt;
for(adaptIt=adaptSets.begin(); adaptIt!=adaptSets.end(); adaptIt++)
{
std::vector<Representation *> reps = (*adaptIt)->getRepresentations();
Representation *candidate = select(reps, (best)?best->getBandwidth():0, bitrate);
std::vector<BaseRepresentation *> reps = (*adaptIt)->getRepresentations();
BaseRepresentation *candidate = select(reps, (best)?best->getBandwidth():0, bitrate);
if (candidate)
{
if (candidate->getBandwidth() > bitrate) /* none matched, returned lowest */
......@@ -53,21 +56,21 @@ Representation * RepresentationSelector::select(Period *period, dash::Streams::T
return best;
}
Representation * RepresentationSelector::select(Period *period, dash::Streams::Type type, uint64_t bitrate,
BaseRepresentation * RepresentationSelector::select(BasePeriod *period, Streams::Type type, uint64_t bitrate,
int width, int height) const
{
if(period == NULL)
return NULL;
std::vector<Representation *> resMatchReps;
std::vector<BaseRepresentation *> resMatchReps;
/* subset matching WxH */
std::vector<AdaptationSet *> adaptSets = period->getAdaptationSets(type);
std::vector<AdaptationSet *>::const_iterator adaptIt;
std::vector<BaseAdaptationSet *> adaptSets = period->getAdaptationSets(type);
std::vector<BaseAdaptationSet *>::const_iterator adaptIt;
for(adaptIt=adaptSets.begin(); adaptIt!=adaptSets.end(); adaptIt++)
{
std::vector<Representation *> reps = (*adaptIt)->getRepresentations();
std::vector<Representation *>::const_iterator repIt;
std::vector<BaseRepresentation *> reps = (*adaptIt)->getRepresentations();
std::vector<BaseRepresentation *>::const_iterator repIt;
for(repIt=reps.begin(); repIt!=reps.end(); repIt++)
{
if((*repIt)->getWidth() == width && (*repIt)->getHeight() == height)
......@@ -81,11 +84,11 @@ Representation * RepresentationSelector::select(Period *period, dash::Streams::T
return select(resMatchReps, 0, bitrate);
}
Representation * RepresentationSelector::select(std::vector<Representation *>& reps,
BaseRepresentation * RepresentationSelector::select(std::vector<BaseRepresentation *>& reps,
uint64_t minbitrate, uint64_t maxbitrate) const
{
Representation *candidate = NULL, *lowest = NULL;
std::vector<Representation *>::const_iterator repIt;
BaseRepresentation *candidate = NULL, *lowest = NULL;
std::vector<BaseRepresentation *>::const_iterator repIt;
for(repIt=reps.begin(); repIt!=reps.end(); repIt++)
{
if ( !lowest || (*repIt)->getBandwidth() < lowest->getBandwidth())
......
......@@ -19,27 +19,33 @@
*****************************************************************************/
#ifndef REPRESENTATIONSELECTORS_HPP
#define REPRESENTATIONSELECTORS_HPP
#include "mpd/Representation.h"
#include "mpd/Period.h"
using namespace dash::mpd;
#include "../Streams.hpp"
#include <vector>
namespace dash
namespace adaptative
{
namespace playlist
{
class BaseRepresentation;
class BasePeriod;
}
namespace logic
{
using namespace playlist;
class RepresentationSelector
{
public:
RepresentationSelector();
virtual ~RepresentationSelector() {}
virtual Representation * select(Period *period, Streams::Type) const;
virtual Representation * select(Period *period, Streams::Type, uint64_t bitrate) const;
virtual Representation * select(Period *period, Streams::Type, uint64_t bitrate,
virtual BaseRepresentation * select(BasePeriod *period, Streams::Type) const;
virtual BaseRepresentation * select(BasePeriod *period, Streams::Type, uint64_t bitrate) const;
virtual BaseRepresentation * select(BasePeriod *period, Streams::Type, uint64_t bitrate,
int width, int height) const;
protected:
virtual Representation * select(std::vector<Representation *>&reps,
virtual BaseRepresentation * select(std::vector<BaseRepresentation *>&reps,
uint64_t minbitrate, uint64_t maxbitrate) const;
};
......
/*
* AbstractAbstractPlaylist.cpp
*****************************************************************************
* Copyright (C) 2010 - 2011 Klagenfurt University
* Copyright (C) 2015 VideoLAN authors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "AbstractPlaylist.hpp"
#include "../tools/Helper.h"
#include "BasePeriod.h"
#include "SegmentTimeline.h"
#include "BaseUrl.h"
#include <vlc_common.h>
#include <vlc_stream.h>
#include <sstream>
using namespace adaptative::playlist;
AbstractPlaylist::AbstractPlaylist (stream_t *stream_) :
ICanonicalUrl(),
stream(stream_)
{
playbackStart.Set(0);
availabilityStartTime.Set( 0 );
availabilityEndTime.Set( 0 );
duration.Set( 0 );
minUpdatePeriod.Set( 0 );
maxSegmentDuration.Set( 0 );
minBufferTime.Set( 0 );
timeShiftBufferDepth.Set( 0 );
}
AbstractPlaylist::~AbstractPlaylist()
{
for(size_t i = 0; i < this->periods.size(); i++)
delete(this->periods.at(i));
for(size_t i = 0; i < this->baseUrls.size(); i++)
delete(this->baseUrls.at(i));
}
const std::vector<BasePeriod *>& AbstractPlaylist::getPeriods()
{
return periods;
}
void AbstractPlaylist::addBaseUrl(BaseUrl *url)
{
baseUrls.push_back(url);
}
void AbstractPlaylist::addPeriod(BasePeriod *period)
{
periods.push_back(period);
}
void AbstractPlaylist::setType(const std::string &type_)
{
type = type_;
}
Url AbstractPlaylist::getUrlSegment() const
{
if (!baseUrls.empty())
return Url(baseUrls.front()->getUrl());
else
{
std::stringstream ss;
ss << stream->psz_access << "://" << Helper::getDirectoryPath(stream->psz_path) << "/";
return Url(ss.str());
}
}
vlc_object_t * AbstractPlaylist::getVLCObject() const
{
return VLC_OBJECT(stream);
}
BasePeriod* AbstractPlaylist::getFirstPeriod()
{
std::vector<BasePeriod *> periods = getPeriods();
if( !periods.empty() )
return periods.front();
else
return NULL;
}
BasePeriod* AbstractPlaylist::getNextPeriod(BasePeriod *period)
{
std::vector<BasePeriod *> periods = getPeriods();
for(size_t i = 0; i < periods.size(); i++)
{
if(periods.at(i) == period && (i + 1) < periods.size())
return periods.at(i + 1);
}
return NULL;
}
void AbstractPlaylist::getTimeLinesBoundaries(mtime_t *min, mtime_t *max) const
{
*min = *max = 0;
for(size_t i = 0; i < periods.size(); i++)
{
std::vector<SegmentTimeline *> timelines;
periods.at(i)->collectTimelines(&timelines);
for(size_t j = 0; j < timelines.size(); j++)
{
const SegmentTimeline *timeline = timelines.at(j);
if(timeline->start() > *min)
*min = timeline->start();
if(!*max || timeline->end() < *max)
*max = timeline->end();
}
}
}
void AbstractPlaylist::mergeWith(AbstractPlaylist *updatedAbstractPlaylist, mtime_t prunebarrier)
{
availabilityEndTime.Set(updatedAbstractPlaylist->availabilityEndTime.Get());
/* Only merge timelines for now */
for(size_t i = 0; i < periods.size() && i < updatedAbstractPlaylist->periods.size(); i++)
{
std::vector<SegmentTimeline *> timelines;
std::vector<SegmentTimeline *> timelinesUpdate;
periods.at(i)->collectTimelines(&timelines);
updatedAbstractPlaylist->periods.at(i)->collectTimelines(&timelinesUpdate);
for(size_t j = 0; j < timelines.size() && j < timelinesUpdate.size(); j++)
{
timelines.at(j)->mergeWith(*timelinesUpdate.at(j));
if(prunebarrier)
timelines.at(j)->prune(prunebarrier);
}
}
}
/*
* AbstractPlaylist.hpp
*****************************************************************************
* Copyright (C) 2010 - 2011 Klagenfurt University
* Copyright (C) 2015 VideoLAN authors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef ABSTRACTPLAYLIST_HPP_
#define ABSTRACTPLAYLIST_HPP_
#include <vector>
#include <string>
#include "ICanonicalUrl.hpp"
#include "../tools/Properties.hpp"
namespace adaptative
{
namespace playlist
{
class BasePeriod;
class BaseUrl;
class AbstractPlaylist : public ICanonicalUrl
{
public:
AbstractPlaylist(stream_t *);
virtual ~AbstractPlaylist();
virtual bool isLive() const = 0;
void setType(const std::string &);
void addPeriod (BasePeriod *period);
void addBaseUrl (BaseUrl *url);
virtual Url getUrlSegment() const; /* impl */
vlc_object_t * getVLCObject() const;
virtual const std::vector<BasePeriod *>& getPeriods();
virtual BasePeriod* getFirstPeriod();
virtual BasePeriod* getNextPeriod(BasePeriod *period);
void mergeWith(AbstractPlaylist *, mtime_t = 0);
void getTimeLinesBoundaries(mtime_t *, mtime_t *) const;
Property<time_t> duration;
Property<time_t> playbackStart;
Property<time_t> availabilityEndTime;
Property<time_t> availabilityStartTime;
Property<time_t> minUpdatePeriod;
Property<time_t> maxSegmentDuration;
Property<time_t> minBufferTime;
Property<time_t> timeShiftBufferDepth;
protected:
stream_t *stream;
std::vector<BasePeriod *> periods;
std::vector<BaseUrl *> baseUrls;
std::string type;
};
}
}
#endif /* ABSTRACTPLAYLIST_HPP_ */
/*
* BaseAdaptationSet.cpp
*****************************************************************************
* Copyright (C) 2010 - 2011 Klagenfurt University
*
* Created on: Aug 10, 2010
* Authors: Christopher Mueller <christopher.mueller@itec.uni-klu.ac.at>
* Christian Timmerer <christian.timmerer@itec.uni-klu.ac.at>
*
* 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 "BaseAdaptationSet.h"
#include "BaseRepresentation.h"
#include <vlc_common.h>
#include <vlc_arrays.h>
#include "SegmentTemplate.h"
#include "BasePeriod.h"
using namespace adaptative::playlist;
BaseAdaptationSet::BaseAdaptationSet(BasePeriod *period) :
CommonAttributesElements(),
SegmentInformation( period ),
isBitstreamSwitching( false )
{
}
BaseAdaptationSet::~BaseAdaptationSet ()
{
vlc_delete_all( representations );
childs.clear();
}
const std::string& BaseAdaptationSet::getMimeType() const
{
if (mimeType.empty() && !representations.empty())
return representations.front()->getMimeType();
else
return mimeType;
}
std::vector<BaseRepresentation*>& BaseAdaptationSet::getRepresentations()
{
return representations;
}
void BaseAdaptationSet::addRepresentation(BaseRepresentation *rep)
{
representations.push_back(rep);
childs.push_back(rep);
}
void BaseAdaptationSet::setBitstreamSwitching (bool value)
{
this->isBitstreamSwitching = value;
}
bool BaseAdaptationSet::getBitstreamSwitching () const
{
return this->isBitstreamSwitching;
}
Url BaseAdaptationSet::getUrlSegment() const
{
return getParentUrlSegment();
}
std::vector<std::string> BaseAdaptationSet::toString(int indent) const
{
std::vector<std::string> ret;
std::string text(indent, ' ');
text.append("BaseAdaptationSet");
ret.push_back(text);
std::vector<BaseRepresentation *>::const_iterator k;
for(k = representations.begin(); k != representations.end(); k++)
{
std::vector<std::string> debug = (*k)->toString(indent + 1);
ret.insert(ret.end(), debug.begin(), debug.end());
}
return ret;
}
/*
* AdaptationSet.h
*****************************************************************************
* Copyright (C) 2010 - 2011 Klagenfurt University
*
* Created on: Aug 10, 2010
* Authors: Christopher Mueller <christopher.mueller@itec.uni-klu.ac.at>
* Christian Timmerer <christian.timmerer@itec.uni-klu.ac.at>
*
* 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 BASEADAPTATIONSET_H_
#define BASEADAPTATIONSET_H_
#include <vector>
#include <string>
#include "CommonAttributesElements.h"
#include "SegmentInformation.hpp"
namespace adaptative
{
namespace playlist
{
class BaseRepresentation;
class BasePeriod;
class BaseAdaptationSet : public CommonAttributesElements,
public SegmentInformation
{
public:
BaseAdaptationSet(BasePeriod *);
virtual ~BaseAdaptationSet();
virtual const std::string& getMimeType() const; /*reimpl*/
std::vector<BaseRepresentation *>& getRepresentations ();
void setBitstreamSwitching(bool value);
bool getBitstreamSwitching() const;
void addRepresentation( BaseRepresentation *rep );
virtual Url getUrlSegment() const; /* reimpl */
std::vector<std::string> toString(int = 0) const;
protected:
std::vector<BaseRepresentation *> representations;
bool isBitstreamSwitching;
};
}
}
#endif /* BASEADAPTATIONSET_H_ */
/*
* BasePeriod.cpp
*****************************************************************************
* Copyright (C) 2010 - 2011 Klagenfurt University
*
* Created on: Aug 10, 2010
* Authors: Christopher Mueller <christopher.mueller@itec.uni-klu.ac.at>
* Christian Timmerer <christian.timmerer@itec.uni-klu.ac.at>
*
* 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 "BasePeriod.h"
#include "AbstractPlaylist.hpp"
#include "../Streams.hpp"
#include <vlc_common.h>
#include <vlc_arrays.h>
using namespace adaptative::playlist;
BasePeriod::BasePeriod(AbstractPlaylist *playlist) :
SegmentInformation( playlist )
{
duration.Set(0);
startTime.Set(0);
baseUrl.Set(NULL);
}
BasePeriod::~BasePeriod ()
{
vlc_delete_all( adaptationSets );
delete baseUrl.Get();
childs.clear();
}
const std::vector<BaseAdaptationSet*>& BasePeriod::getAdaptationSets() const
{
return adaptationSets;
}
const std::vector<BaseAdaptationSet*> BasePeriod::getAdaptationSets(Streams::Type type) const
{
std::vector<BaseAdaptationSet*> list;
std::vector<BaseAdaptationSet*>::const_iterator it;
for(it = adaptationSets.begin(); it!= adaptationSets.end(); it++)
{
if( Streams::Stream::mimeToType((*it)->getMimeType()) == type )
list.push_back(*it);
}
return list;
}
void BasePeriod::addAdaptationSet(BaseAdaptationSet *adaptationSet)
{
if ( adaptationSet != NULL )
{
adaptationSets.push_back(adaptationSet);
childs.push_back(adaptationSet);
}
}
BaseAdaptationSet * BasePeriod::getAdaptationSet(Streams::Type type) const
{
std::vector<BaseAdaptationSet *>::const_iterator it;
for(it = adaptationSets.begin(); it != adaptationSets.end(); it++)
{
if ( Streams::Stream::mimeToType((*it)->getMimeType()) == type )
return *it;
}
return NULL;
}
Url BasePeriod::getUrlSegment() const
{
if( baseUrl.Get() )
return *(baseUrl.Get());
else
return getParentUrlSegment();
}
std::vector<std::string> BasePeriod::toString(int indent) const
{
std::vector<std::string> ret;
std::string text(indent, ' ');
text.append("Period");
ret.push_back(text);
std::vector<BaseAdaptationSet *>::const_iterator k;
for(k = adaptationSets.begin(); k != adaptationSets.end(); k++)
{
std::vector<std::string> debug = (*k)->toString(indent + 1);
ret.insert(ret.end(), debug.begin(), debug.end());
}
return ret;
}
mtime_t BasePeriod::getPeriodStart() const
{
return startTime.Get();
}
/*
* Period.h
*****************************************************************************
* Copyright (C) 2010 - 2011 Klagenfurt University
*
* Created on: Aug 10, 2010
* Authors: Christopher Mueller <christopher.mueller@itec.uni-klu.ac.at>
* Christian Timmerer <christian.timmerer@itec.uni-klu.ac.at>
*
* 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 BASEPERIOD_H_
#define BASEPERIOD_H_
#include <vector>
#include <string>
#include "BaseAdaptationSet.h"
#include "SegmentInformation.hpp"
#include "../tools/Properties.hpp"
#include "../StreamsType.hpp"
namespace adaptative
{
namespace playlist
{
class BasePeriod : public SegmentInformation
{
public:
BasePeriod(AbstractPlaylist *);
virtual ~BasePeriod ();
const std::vector<BaseAdaptationSet *>& getAdaptationSets () const;
const std::vector<BaseAdaptationSet *> getAdaptationSets (Streams::Type) const;
BaseAdaptationSet * getAdaptationSet (Streams::Type) const;
void addAdaptationSet (BaseAdaptationSet *AdaptationSet);
std::vector<std::string> toString (int = 0) const;
virtual Url getUrlSegment() const; /* reimpl */
virtual mtime_t getPeriodStart() const; /* reimpl */
Property<Url *> baseUrl;
Property<mtime_t> duration;
Property<mtime_t> startTime;
private:
std::vector<BaseAdaptationSet *> adaptationSets;
};
}
}
#endif /* BASEPERIOD_H_ */
/*
* BaseRepresentation.cpp
*****************************************************************************
* Copyright (C) 2010 - 2011 Klagenfurt University
*
* Created on: Aug 10, 2010
* Authors: Christopher Mueller <christopher.mueller@itec.uni-klu.ac.at>
* Christian Timmerer <christian.timmerer@itec.uni-klu.ac.at>
*
* 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 <cstdlib>
#include "BaseRepresentation.h"
#include "BaseAdaptationSet.h"
#include "BaseUrl.h"
#include "SegmentTemplate.h"
using namespace adaptative::playlist;
BaseRepresentation::BaseRepresentation( BaseAdaptationSet *set, AbstractPlaylist *playlist_ ) :
SegmentInformation( set ),
playlist ( playlist_ ),
adaptationSet ( set ),
bandwidth (0),
baseUrl ( NULL )
{
}
BaseRepresentation::~BaseRepresentation ()
{
delete baseUrl;
}
uint64_t BaseRepresentation::getBandwidth () const
{
return bandwidth;
}
void BaseRepresentation::setBandwidth( uint64_t bandwidth )
{
this->bandwidth = bandwidth;
}
void BaseRepresentation::setBaseUrl(BaseUrl *base)
{
baseUrl = base;
}
std::vector<std::string> BaseRepresentation::toString(int indent) const
{
std::vector<std::string> ret;
std::string text(indent, ' ');
text.append("Representation");
ret.push_back(text);
std::vector<ISegment *> list = getSegments();
std::vector<ISegment *>::const_iterator l;
for(l = list.begin(); l < list.end(); l++)
ret.push_back((*l)->toString(indent + 1));
return ret;
}
Url BaseRepresentation::getUrlSegment() const
{
Url ret = getParentUrlSegment();
if (baseUrl)
ret.append(baseUrl->getUrl());
return ret;
}
AbstractPlaylist * BaseRepresentation::getPlaylist() const
{
return playlist;
}
std::string BaseRepresentation::contextualize(size_t, const std::string &component,
const BaseSegmentTemplate *) const
{
return component;
}
/*
* Representation.h
*****************************************************************************
* Copyright (C) 2010 - 2011 Klagenfurt University
*
* Created on: Aug 10, 2010
* Authors: Christopher Mueller <christopher.mueller@itec.uni-klu.ac.at>
* Christian Timmerer <christian.timmerer@itec.uni-klu.ac.at>
*
* 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 BASEREPRESENTATION_H_
#define BASEREPRESENTATION_H_
#include <string>
#include "CommonAttributesElements.h"
#include "SegmentInformation.hpp"
namespace adaptative
{
namespace playlist
{
class BaseAdaptationSet;
class AbstractPlaylist;
class BaseUrl;
class BaseSegmentTemplate;
class BaseRepresentation : public CommonAttributesElements,
public SegmentInformation
{
public:
BaseRepresentation( BaseAdaptationSet *, AbstractPlaylist *playlist );
virtual ~BaseRepresentation ();
/*
* @return The bitrate required for this representation
* in bits per seconds.
* Will be a valid value, as the parser refuses Representation
* without bandwidth.
*/
uint64_t getBandwidth () const;
void setBandwidth ( uint64_t bandwidth );
void setBaseUrl (BaseUrl *baseUrl);
AbstractPlaylist* getPlaylist () const;
std::vector<std::string> toString(int = 0) const;
virtual Url getUrlSegment () const; /* impl */
/* for segment templates */
virtual std::string contextualize(size_t, const std::string &,
const BaseSegmentTemplate *) const;
protected:
AbstractPlaylist *playlist;
BaseAdaptationSet *adaptationSet;
uint64_t bandwidth;
BaseUrl *baseUrl;
};
}
}
#endif /* BASEREPRESENTATION_H_ */
......@@ -27,9 +27,9 @@
#include <string>
namespace dash
namespace adaptative
{
namespace mpd
namespace playlist
{
class BaseUrl
{
......
/*****************************************************************************
* CommonAttributesElements.cpp: Defines the common attributes and elements
* for some Dash elements.
*****************************************************************************
* Copyright © 2011 VideoLAN
*
* Authors: Hugo Beauzée-Luyssen <beauze.h@gmail.com>
*
* 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 "CommonAttributesElements.h"
#include <vlc_common.h>
#include <vlc_arrays.h>
using namespace adaptative::playlist;
CommonAttributesElements::CommonAttributesElements() :
width( -1 ),
height( -1 )
{
}
CommonAttributesElements::~CommonAttributesElements()
{
}
const std::string& CommonAttributesElements::getMimeType() const
{
return mimeType;
}
void CommonAttributesElements::setMimeType( const std::string &mimeType )
{
this->mimeType = mimeType;
}
int CommonAttributesElements::getWidth () const
{
return width;
}
void CommonAttributesElements::setWidth( int width )
{
if ( width > 0 )
this->width = width;
}
int CommonAttributesElements::getHeight () const
{
return height;
}
void CommonAttributesElements::setHeight( int height )
{
if ( height > 0 )
this->height = height;
}
const std::list<std::string>& CommonAttributesElements::getLang() const
{
return lang;
}
void CommonAttributesElements::addLang( const std::string &lang )
{
if ( lang.empty() == false )
this->lang.push_back( lang );
}
/*****************************************************************************
* CommonAttributesElements.h: Defines the common attributes and elements
* for some Dash elements.
*****************************************************************************
* Copyright © 2011 VideoLAN
*
* Authors: Hugo Beauzée-Luyssen <beauze.h@gmail.com>
*
* 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 COMMONATTRIBUTESELEMENTS_H
#define COMMONATTRIBUTESELEMENTS_H
#include <list>
#include <string>
namespace adaptative
{
namespace playlist
{
class CommonAttributesElements
{
public:
CommonAttributesElements();
virtual ~CommonAttributesElements();
virtual const std::string& getMimeType() const;
void setMimeType( const std::string &mimeType );
int getWidth() const;
void setWidth( int width );
int getHeight() const;
void setHeight( int height );
const std::list<std::string>& getLang() const;
void addLang( const std::string &lang );
protected:
std::string mimeType;
int width;
int height;
std::list<std::string> lang;
};
}
}
#endif // COMMONATTRIBUTESELEMENTS_H
......@@ -22,9 +22,9 @@
#include "Url.hpp"
namespace dash
namespace adaptative
{
namespace mpd
namespace playlist
{
class ICanonicalUrl
{
......
......@@ -28,14 +28,10 @@
#endif
#include "Segment.h"
#include "Representation.h"
#include "MPD.h"
#include "mp4/AtomsReader.hpp"
#include "BaseRepresentation.h"
#include <cassert>
using namespace dash::mpd;
using namespace dash::http;
using namespace adaptative::http;
using namespace adaptative::playlist;
ISegment::ISegment(const ICanonicalUrl *parent):
ICanonicalUrl( parent ),
......@@ -48,12 +44,17 @@ ISegment::ISegment(const ICanonicalUrl *parent):
duration.Set(0);
}
dash::http::Chunk * ISegment::getChunk(const std::string &url)
Chunk * ISegment::getChunk(const std::string &url)
{
return new (std::nothrow) SegmentChunk(this, url);
}
dash::http::Chunk* ISegment::toChunk(size_t index, Representation *ctxrep)
void ISegment::onChunkDownload(void *, size_t, Chunk *, BaseRepresentation *)
{
}
Chunk* ISegment::toChunk(size_t index, BaseRepresentation *ctxrep)
{
Chunk *chunk;
try
......@@ -110,14 +111,19 @@ int ISegment::getClassId() const
}
ISegment::SegmentChunk::SegmentChunk(ISegment *segment_, const std::string &url) :
dash::http::Chunk(url)
Chunk(url)
{
segment = segment_;
}
void ISegment::SegmentChunk::onDownload(void *, size_t)
void ISegment::SegmentChunk::setRepresentation(BaseRepresentation *rep_)
{
rep = rep_;
}
void ISegment::SegmentChunk::onDownload(void *data, size_t size)
{
segment->onChunkDownload(data, size, this, rep);
}
Segment::Segment(ICanonicalUrl *parent) :
......@@ -171,7 +177,7 @@ Url Segment::getUrlSegment() const
return ret;
}
dash::http::Chunk* Segment::toChunk(size_t index, Representation *ctxrep)
Chunk* Segment::toChunk(size_t index, BaseRepresentation *ctxrep)
{
Chunk *chunk = ISegment::toChunk(index, ctxrep);
if (chunk && ctxrep)
......@@ -209,38 +215,6 @@ IndexSegment::IndexSegment(ICanonicalUrl *parent) :
classId = CLASSID_INDEXSEGMENT;
}
dash::http::Chunk* IndexSegment::toChunk(size_t index, Representation *ctxrep)
{
IndexSegmentChunk *chunk = dynamic_cast<IndexSegmentChunk *>(Segment::toChunk(index, ctxrep));
chunk->setIndexRepresentation(ctxrep);
return chunk;
}
dash::http::Chunk * IndexSegment::getChunk(const std::string &url)
{
return new IndexSegmentChunk(this, url);
}
IndexSegment::IndexSegmentChunk::IndexSegmentChunk(ISegment *segment, const std::string &url)
: SegmentChunk(segment, url)
{
rep = NULL;
}
void IndexSegment::IndexSegmentChunk::setIndexRepresentation(Representation *rep_)
{
rep = rep_;
}
void IndexSegment::IndexSegmentChunk::onDownload(void *buffer, size_t size)
{
if(!rep)
return;
dash::mp4::AtomsReader br(rep->getMPD()->getVLCObject());
br.parseBlock(buffer, size, rep);
}
SubSegment::SubSegment(Segment *main, size_t start, size_t end) :
ISegment(main), parent(main)
{
......
......@@ -28,18 +28,18 @@
#include <string>
#include <sstream>
#include <vector>
#include "mpd/BaseUrl.h"
#include "mpd/ICanonicalUrl.hpp"
#include "http/Chunk.h"
#include "Properties.hpp"
#include "ICanonicalUrl.hpp"
#include "../http/Chunk.h"
#include "../tools/Properties.hpp"
namespace dash
namespace adaptative
{
namespace mpd
namespace playlist
{
class Representation;
class BaseRepresentation;
class SubSegment;
class SegmentInformation;
using namespace http;
class ISegment : public ICanonicalUrl
{
......@@ -51,7 +51,7 @@ namespace dash
* That is basically true when using an Url, and false
* when using an UrlTemplate
*/
virtual dash::http::Chunk* toChunk (size_t, Representation * = NULL);
virtual Chunk* toChunk (size_t, BaseRepresentation * = NULL);
virtual void setByteRange (size_t start, size_t end);
virtual size_t getOffset () const;
virtual std::vector<ISegment*> subSegments () = 0;
......@@ -69,17 +69,20 @@ namespace dash
std::string debugName;
int classId;
class SegmentChunk : public dash::http::Chunk
class SegmentChunk : public Chunk
{
public:
SegmentChunk(ISegment *segment, const std::string &url);
virtual void onDownload(void *, size_t);
void setRepresentation(BaseRepresentation *);
virtual void onDownload(void *, size_t); // reimpl
protected:
ISegment *segment;
BaseRepresentation *rep;
};
virtual dash::http::Chunk * getChunk(const std::string &);
virtual Chunk * getChunk(const std::string &);
virtual void onChunkDownload(void *, size_t, Chunk *, BaseRepresentation *);
};
class Segment : public ISegment
......@@ -89,7 +92,7 @@ namespace dash
~Segment();
virtual void setSourceUrl( const std::string &url );
virtual Url getUrlSegment() const; /* impl */
virtual dash::http::Chunk* toChunk(size_t, Representation * = NULL);
virtual Chunk* toChunk(size_t, BaseRepresentation * = NULL);
virtual std::vector<ISegment*> subSegments();
virtual std::string toString(int = 0) const;
virtual void addSubSegment(SubSegment *);
......@@ -112,22 +115,7 @@ namespace dash
{
public:
IndexSegment( ICanonicalUrl *parent );
virtual dash::http::Chunk* toChunk(size_t, Representation * = NULL);
static const int CLASSID_INDEXSEGMENT = 3;
protected:
class IndexSegmentChunk : public SegmentChunk
{
public:
IndexSegmentChunk(ISegment *segment, const std::string &);
void setIndexRepresentation(Representation *);
virtual void onDownload(void *, size_t);
private:
Representation *rep;
};
virtual dash::http::Chunk * getChunk(const std::string &);
};
class SubSegment : public ISegment
......
......@@ -22,13 +22,9 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "SegmentBase.h"
using namespace dash::mpd;
using namespace adaptative::playlist;
SegmentBase::SegmentBase () :
Initializable()
......
......@@ -25,12 +25,12 @@
#ifndef SEGMENTBASE_H_
#define SEGMENTBASE_H_
#include "mpd/Segment.h"
#include "mpd/SegmentInfoCommon.h"
#include "Segment.h"
#include "SegmentInfoCommon.h"
namespace dash
namespace adaptative
{
namespace mpd
namespace playlist
{
class SegmentBase : public Initializable<Segment>
{
......
......@@ -31,7 +31,7 @@
#include "Segment.h"
#include "SegmentTimeline.h"
using namespace dash::mpd;
using namespace adaptative::playlist;
Timelineable::Timelineable()
{
......
......@@ -29,13 +29,13 @@
#include <list>
#include <ctime>
#include "ICanonicalUrl.hpp"
#include "Properties.hpp"
#include "Segment.h"
#include "../tools/Properties.hpp"
namespace dash
namespace adaptative
{
namespace mpd
namespace playlist
{
class Segment;
class SegmentTimeline;
template<class T> class Initializable
......
......@@ -24,9 +24,9 @@
#include "SegmentList.h"
#include "SegmentTemplate.h"
#include "SegmentTimeline.h"
#include "MPD.h"
#include "AbstractPlaylist.hpp"
using namespace dash::mpd;
using namespace adaptative::playlist;
using namespace std;
SegmentInformation::SegmentInformation(SegmentInformation *parent_) :
......@@ -37,7 +37,7 @@ SegmentInformation::SegmentInformation(SegmentInformation *parent_) :
init();
}
SegmentInformation::SegmentInformation(MPD * parent_) :
SegmentInformation::SegmentInformation(AbstractPlaylist * parent_) :
ICanonicalUrl(parent_),
TimescaleAble()
{
......
......@@ -20,39 +20,39 @@
#ifndef SEGMENTINFORMATION_HPP
#define SEGMENTINFORMATION_HPP
#define __STDC_CONSTANT_MACROS
#ifndef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS
#endif
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "ICanonicalUrl.hpp"
#include "Properties.hpp"
#include "../tools/Properties.hpp"
#include "SegmentInfoCommon.h"
#include <vlc_common.h>
#include <vector>
namespace dash
namespace adaptative
{
namespace mpd
namespace playlist
{
class ISegment;
class SegmentBase;
class SegmentList;
class SegmentTemplate;
class SegmentTimeline;
class MPD;
class SegmentTemplate;
class AbstractPlaylist;
class ISegment;
/* common segment elements for period/adaptset/rep 5.3.9.1,
* with properties inheritance */
class SegmentInformation : public ICanonicalUrl,
public TimescaleAble
{
friend class IsoffMainParser;
public:
SegmentInformation( SegmentInformation * = 0 );
explicit SegmentInformation( MPD * );
explicit SegmentInformation( AbstractPlaylist * );
virtual ~SegmentInformation();
bool canBitswitch() const;
virtual mtime_t getPeriodStart() const;
......@@ -83,13 +83,14 @@ namespace dash
std::vector<ISegment *> getSegments(SegmentInfoType) const;
std::vector<SegmentInformation *> childs;
private:
void init();
public:
void setSegmentList(SegmentList *);
void setSegmentBase(SegmentBase *);
void setSegmentTemplate(MediaSegmentTemplate *);
void setBitstreamSwitching(bool);
private:
void init();
SegmentBase * inheritSegmentBase() const;
SegmentList * inheritSegmentList() const;
MediaSegmentTemplate * inheritSegmentTemplate() const;
......
......@@ -22,15 +22,11 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "SegmentList.h"
#include "Segment.h"
#include "SegmentInformation.hpp"
using namespace dash::mpd;
using namespace adaptative::playlist;
SegmentList::SegmentList( SegmentInformation *parent ):
SegmentInfoCommon( parent ), TimescaleAble( parent )
......
......@@ -29,17 +29,14 @@
# include "config.h"
#endif
#include "mpd/SegmentInfoCommon.h"
#include "mpd/ICanonicalUrl.hpp"
#include "Properties.hpp"
#include "SegmentInfoCommon.h"
#include <vlc_common.h>
namespace dash
namespace adaptative
{
namespace mpd
namespace playlist
{
class SegmentInformation;
class Segment;
class SegmentList : public SegmentInfoCommon,
public TimescaleAble
......
......@@ -26,10 +26,9 @@
#include "SegmentTemplate.h"
#include "SegmentTimeline.h"
#include "Representation.h"
#include "AdaptationSet.h"
#include "SegmentInformation.hpp"
using namespace dash::mpd;
using namespace adaptative::playlist;
BaseSegmentTemplate::BaseSegmentTemplate( ICanonicalUrl *parent ) :
Segment( parent )
......
......@@ -24,16 +24,17 @@
#ifndef SEGMENTTEMPLATE_H
#define SEGMENTTEMPLATE_H
#include "mpd/Segment.h"
#include "Properties.hpp"
#include "Segment.h"
#include "../tools/Properties.hpp"
#include "SegmentInfoCommon.h"
namespace dash
namespace adaptative
{
namespace mpd
namespace playlist
{
class ICanonicalUrl;
class InitSegmentTemplate;
class SegmentInformation;
class BaseSegmentTemplate : public Segment
{
......
......@@ -22,15 +22,11 @@
*****************************************************************************/
#define __STDC_CONSTANT_MACROS
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "SegmentTimeline.h"
#include <algorithm>
using namespace dash::mpd;
using namespace adaptative::playlist;
SegmentTimeline::SegmentTimeline(TimescaleAble *parent)
:TimescaleAble(parent)
......
......@@ -24,13 +24,17 @@
#ifndef SEGMENTTIMELINE_H
#define SEGMENTTIMELINE_H
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "SegmentInfoCommon.h"
#include <vlc_common.h>
#include <list>
namespace dash
namespace adaptative
{
namespace mpd
namespace playlist
{
class SegmentTimeline : public TimescaleAble
{
......
/*
* Url.cpp
*****************************************************************************
* Copyright (C) 2014 - VideoLAN Authors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "Url.hpp"
#include "BaseRepresentation.h"
#include "SegmentTemplate.h"
using namespace adaptative::playlist;
Url::Url()
{
}
Url::Url(const Component & comp)
{
prepend(comp);
}
Url::Url(const std::string &str)
{
prepend(Component(str));
}
Url & Url::prepend(const Component & comp)
{
components.insert(components.begin(), comp);
return *this;
}
Url & Url::append(const Component & comp)
{
components.push_back(comp);
return *this;
}
Url & Url::prepend(const Url &url)
{
components.insert(components.begin(), url.components.begin(), url.components.end());
return *this;
}
Url & Url::append(const Url &url)
{
components.insert(components.end(), url.components.begin(), url.components.end());
return *this;
}
std::string Url::toString() const
{
return toString(0, NULL);
}
std::string Url::toString(size_t index, const BaseRepresentation *rep) const
{
std::string ret;
std::vector<Component>::const_iterator it;
for(it = components.begin(); it != components.end(); it++)
{
const Component *comp = & (*it);
if(rep)
ret.append(rep->contextualize(index, comp->component, comp->templ));
else
ret.append(comp->component);
}
return ret;
}
Url::Component::Component(const std::string & str, const MediaSegmentTemplate *templ_)
{
component = str;
templ = templ_;
}
......@@ -28,12 +28,12 @@
#include <vector>
#include <vlc_common.h>
namespace dash
namespace adaptative
{
namespace mpd
namespace playlist
{
class Representation;
class MediaSegmentTemplate;
class BaseRepresentation;
class Url
{
......@@ -45,9 +45,6 @@ namespace dash
Component(const std::string &, const MediaSegmentTemplate * = NULL);
protected:
std::string contextualize(size_t, const Representation *) const;
mtime_t getScaledTimeBySegmentNumber(size_t, const Representation *) const;
size_t getSegmentNumber(size_t, const Representation *) const;
std::string component;
const MediaSegmentTemplate *templ;
};
......@@ -59,7 +56,7 @@ namespace dash
Url & append(const Component &);
Url & append(const Url &);
Url & prepend(const Url &);
std::string toString(size_t, const Representation *) const;
std::string toString(size_t, const BaseRepresentation *) const;
std::string toString() const;
private:
......
......@@ -27,7 +27,7 @@
#include "Helper.h"
#include <algorithm>
using namespace dash;
using namespace adaptative;
std::string Helper::combinePaths (const std::string &path1, const std::string &path2)
{
......
......@@ -27,7 +27,7 @@
#include <string>
namespace dash
namespace adaptative
{
class Helper
{
......
......@@ -20,10 +20,8 @@
#ifndef PROPERTIES_HPP
#define PROPERTIES_HPP
namespace dash
template <typename T> class Property
{
template <typename T> class Property
{
public:
Property() {}
......@@ -39,6 +37,6 @@ namespace dash
private:
T value;
};
}
};
#endif // PROPERTIES_HPP
......@@ -36,186 +36,37 @@
#include "DASHManager.h"
#include "mpd/MPDFactory.h"
#include "mpd/SegmentTimeline.h"
#include "xml/DOMParser.h"
#include "adaptationlogic/AdaptationLogicFactory.h"
#include "SegmentTracker.hpp"
#include "../adaptative/logic/RateBasedAdaptationLogic.h"
#include <vlc_stream.h>
#include <algorithm>
using namespace dash;
using namespace dash::http;
using namespace dash::logic;
using namespace dash::mpd;
using namespace adaptative::logic;
DASHManager::DASHManager ( MPD *mpd,
DASHManager::DASHManager(MPD *mpd,
AbstractAdaptationLogic::LogicType type, stream_t *stream) :
conManager ( NULL ),
logicType ( type ),
mpd ( mpd ),
stream ( stream ),
nextMPDupdate ( 0 )
PlaylistManager(mpd, type, stream)
{
for(int i=0; i<Streams::count; i++)
streams[i] = NULL;
}
DASHManager::~DASHManager ()
{
delete conManager;
for(int i=0; i<Streams::count; i++)
delete streams[i];
}
bool DASHManager::start(demux_t *demux)
bool DASHManager::updatePlaylist()
{
const Period *period = mpd->getFirstPeriod();
if(!period)
return false;
for(int i=0; i<Streams::count; i++)
{
Streams::Type type = static_cast<Streams::Type>(i);
const AdaptationSet *set = period->getAdaptationSet(type);
if(set)
{
streams[type] = new (std::nothrow) Streams::Stream(set->getMimeType());
if(!streams[type])
continue;
AbstractAdaptationLogic *logic = AdaptationLogicFactory::create(logicType, mpd);
if(!logic)
{
delete streams[type];
streams[type] = NULL;
continue;
}
SegmentTracker *tracker = new (std::nothrow) SegmentTracker(logic, mpd);
try
{
if(!tracker)
throw VLC_ENOMEM;
streams[type]->create(demux, logic, tracker);
} catch (int) {
delete streams[type];
delete logic;
delete tracker;
streams[type] = NULL;
}
}
}
conManager = new (std::nothrow) HTTPConnectionManager(stream);
if(!conManager)
return false;
mpd->playbackStart.Set(time(NULL));
nextMPDupdate = mpd->playbackStart.Get();
return true;
}
size_t DASHManager::read()
{
size_t i_ret = 0;
for(int type=0; type<Streams::count; type++)
{
if(!streams[type])
continue;
i_ret += streams[type]->read(conManager);
}
return i_ret;
}
mtime_t DASHManager::getPCR() const
{
mtime_t pcr = VLC_TS_INVALID;
for(int type=0; type<Streams::count; type++)
{
if(!streams[type])
continue;
if(pcr == VLC_TS_INVALID || pcr > streams[type]->getPCR())
pcr = streams[type]->getPCR();
}
return pcr;
}
int DASHManager::getGroup() const
{
for(int type=0; type<Streams::count; type++)
{
if(!streams[type])
continue;
return streams[type]->getGroup();
}
return -1;
}
int DASHManager::esCount() const
{
int es = 0;
for(int type=0; type<Streams::count; type++)
{
if(!streams[type])
continue;
es += streams[type]->esCount();
}
return es;
}
mtime_t DASHManager::getDuration() const
{
if (mpd->isLive())
return 0;
else
return CLOCK_FREQ * mpd->duration.Get();
}
bool DASHManager::setPosition(mtime_t time)
{
bool ret = true;
for(int real = 0; real < 2; real++)
{
/* Always probe if we can seek first */
for(int type=0; type<Streams::count; type++)
{
if(!streams[type])
continue;
ret &= streams[type]->setPosition(time, !real);
}
if(!ret)
break;
}
return ret;
}
bool DASHManager::seekAble() const
{
if(mpd->isLive())
return false;
for(int type=0; type<Streams::count; type++)
{
if(!streams[type])
continue;
if(!streams[type]->seekAble())
return false;
}
return true;
}
bool DASHManager::updateMPD()
{
if(!mpd->isLive() || !mpd->minUpdatePeriod.Get())
if(!playlist->isLive() || !playlist->minUpdatePeriod.Get())
return true;
mtime_t now = time(NULL);
if(nextMPDupdate && now < nextMPDupdate)
if(nextPlaylistupdate && now < nextPlaylistupdate)
return true;
/* do update */
if(nextMPDupdate)
if(nextPlaylistupdate)
{
std::string url(stream->psz_access);
url.append("://");
......@@ -245,7 +96,7 @@ bool DASHManager::updateMPD()
MPD *newmpd = MPDFactory::create(parser.getRootNode(), mpdstream, parser.getProfile());
if(newmpd)
{
mpd->mergeWith(newmpd, minsegmentTime);
playlist->mergeWith(newmpd, minsegmentTime);
delete newmpd;
}
stream_Delete(mpdstream);
......@@ -254,20 +105,41 @@ bool DASHManager::updateMPD()
/* Compute new MPD update time */
mtime_t mininterval = 0;
mtime_t maxinterval = 0;
mpd->getTimeLinesBoundaries(&mininterval, &maxinterval);
playlist->getTimeLinesBoundaries(&mininterval, &maxinterval);
if(maxinterval > mininterval)
maxinterval = (maxinterval - mininterval) / CLOCK_FREQ;
else
maxinterval = 60;
maxinterval = std::max(maxinterval, (mtime_t)60);
mininterval = std::max(mpd->minUpdatePeriod.Get(),
mpd->maxSegmentDuration.Get());
mininterval = std::max(playlist->minUpdatePeriod.Get(),
playlist->maxSegmentDuration.Get());
nextMPDupdate = now + (maxinterval - mininterval) / 2;
nextPlaylistupdate = now + (maxinterval - mininterval) / 2;
msg_Dbg(stream, "Updated MPD, next update in %" PRId64 "s (%" PRId64 "..%" PRId64 ")",
nextMPDupdate - now, mininterval, maxinterval );
nextPlaylistupdate - now, mininterval, maxinterval );
return true;
}
AbstractAdaptationLogic *DASHManager::createLogic(AbstractAdaptationLogic::LogicType type)
{
switch(type)
{
case AbstractAdaptationLogic::FixedRate:
{
size_t bps = var_InheritInteger(stream, "dash-prefbw") * 8192;
return new (std::nothrow) FixedRateAdaptationLogic(bps);
}
case AbstractAdaptationLogic::Default:
case AbstractAdaptationLogic::RateBased:
{
int width = var_InheritInteger(stream, "dash-prefwidth");
int height = var_InheritInteger(stream, "dash-prefheight");
return new (std::nothrow) RateBasedAdaptationLogic(width, height);
}
default:
return PlaylistManager::createLogic(type);
}
}
......@@ -25,36 +25,24 @@
#ifndef DASHMANAGER_H_
#define DASHMANAGER_H_
#include "http/HTTPConnectionManager.h"
#include "adaptationlogic/AbstractAdaptationLogic.h"
#include "../adaptative/PlaylistManager.h"
#include "../adaptative/logic/AbstractAdaptationLogic.h"
#include "mpd/MPD.h"
namespace dash
{
class DASHManager
using namespace adaptative;
class DASHManager : public PlaylistManager
{
public:
DASHManager( mpd::MPD *mpd,
logic::AbstractAdaptationLogic::LogicType type, stream_t *stream);
logic::AbstractAdaptationLogic::LogicType type,
stream_t *stream);
virtual ~DASHManager ();
bool start (demux_t *);
size_t read();
mtime_t getDuration() const;
mtime_t getPCR() const;
int getGroup() const;
int esCount() const;
bool setPosition(mtime_t);
bool seekAble() const;
bool updateMPD();
private:
http::HTTPConnectionManager *conManager;
logic::AbstractAdaptationLogic::LogicType logicType;
mpd::MPD *mpd;
stream_t *stream;
Streams::Stream *streams[Streams::count];
mtime_t nextMPDupdate;
virtual bool updatePlaylist(); //reimpl
virtual AbstractAdaptationLogic *createLogic(AbstractAdaptationLogic::LogicType); //reimpl
};
}
......
/*
* AdaptationLogicFactory.cpp
*****************************************************************************
* Copyright (C) 2010 - 2011 Klagenfurt University
*
* Created on: Aug 10, 2010
* Authors: Christopher Mueller <christopher.mueller@itec.uni-klu.ac.at>
* Christian Timmerer <christian.timmerer@itec.uni-klu.ac.at>
*
* 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 "AdaptationLogicFactory.h"
#include "adaptationlogic/AlwaysBestAdaptationLogic.h"
#include "adaptationlogic/RateBasedAdaptationLogic.h"
#include "adaptationlogic/AlwaysLowestAdaptationLogic.hpp"
#include <new>
using namespace dash::logic;
using namespace dash::mpd;
AbstractAdaptationLogic* AdaptationLogicFactory::create (
AbstractAdaptationLogic::LogicType logic, MPD *mpd)
{
switch(logic)
{
case AbstractAdaptationLogic::AlwaysBest:
return new (std::nothrow) AlwaysBestAdaptationLogic(mpd);
case AbstractAdaptationLogic::AlwaysLowest:
return new (std::nothrow) AlwaysLowestAdaptationLogic(mpd);
case AbstractAdaptationLogic::FixedRate:
return new (std::nothrow) FixedRateAdaptationLogic(mpd);
case AbstractAdaptationLogic::Default:
case AbstractAdaptationLogic::RateBased:
return new (std::nothrow) RateBasedAdaptationLogic(mpd);
default:
return NULL;
}
}
......@@ -43,6 +43,14 @@
#include "dash.hpp"
#include "xml/DOMParser.h"
#include "mpd/MPDFactory.h"
#include "mpd/Period.h"
#include "mpd/ProgramInformation.h"
using namespace adaptative::logic;
using namespace adaptative::playlist;
using namespace dash::mpd;
using namespace dash::xml;
using namespace dash;
/*****************************************************************************
* Module descriptor
......@@ -61,10 +69,10 @@ static void Close (vlc_object_t *);
#define DASH_LOGIC_TEXT N_("Adaptation Logic")
static const int pi_logics[] = {dash::logic::AbstractAdaptationLogic::RateBased,
dash::logic::AbstractAdaptationLogic::FixedRate,
dash::logic::AbstractAdaptationLogic::AlwaysLowest,
dash::logic::AbstractAdaptationLogic::AlwaysBest};
static const int pi_logics[] = {AbstractAdaptationLogic::RateBased,
AbstractAdaptationLogic::FixedRate,
AbstractAdaptationLogic::AlwaysLowest,
AbstractAdaptationLogic::AlwaysBest};
static const char *const ppsz_logics[] = { N_("Bandwidth Adaptive"),
N_("Fixed Bandwidth"),
......@@ -108,11 +116,11 @@ static int Open(vlc_object_t *p_obj)
free(psz_mime);
}
if(!b_mimematched && !dash::xml::DOMParser::isDash(p_demux->s))
if(!b_mimematched && !DOMParser::isDash(p_demux->s))
return VLC_EGENERIC;
//Build a XML tree
dash::xml::DOMParser parser(p_demux->s);
DOMParser parser(p_demux->s);
if( !parser.parse() )
{
msg_Err( p_demux, "Could not parse MPD" );
......@@ -120,7 +128,7 @@ static int Open(vlc_object_t *p_obj)
}
//Begin the actual MPD parsing:
dash::mpd::MPD *mpd = dash::mpd::MPDFactory::create(parser.getRootNode(), p_demux->s, parser.getProfile());
MPD *mpd = MPDFactory::create(parser.getRootNode(), p_demux->s, parser.getProfile());
if(mpd == NULL)
{
msg_Err( p_demux, "Cannot create/unknown MPD for profile");
......@@ -133,11 +141,11 @@ static int Open(vlc_object_t *p_obj)
p_sys->p_mpd = mpd;
int logic = var_InheritInteger( p_obj, "dash-logic" );
dash::DASHManager*p_dashManager = new dash::DASHManager(p_sys->p_mpd,
static_cast<dash::logic::AbstractAdaptationLogic::LogicType>(logic),
DASHManager*p_dashManager = new DASHManager(p_sys->p_mpd,
static_cast<AbstractAdaptationLogic::LogicType>(logic),
p_demux->s);
dash::mpd::Period *period = mpd->getFirstPeriod();
BasePeriod *period = mpd->getFirstPeriod();
if(period && !p_dashManager->start(p_demux))
{
delete p_dashManager;
......@@ -160,7 +168,7 @@ static void Close(vlc_object_t *p_obj)
{
demux_t *p_demux = (demux_t*) p_obj;
demux_sys_t *p_sys = (demux_sys_t *) p_demux->p_sys;
dash::DASHManager *p_dashManager = p_sys->p_dashManager;
DASHManager *p_dashManager = p_sys->p_dashManager;
delete p_dashManager;
free(p_sys);
......@@ -183,7 +191,7 @@ static int Demux(demux_t *p_demux)
es_out_Control(p_demux->out, ES_OUT_SET_PCR, pcr);
}
if( !p_sys->p_dashManager->updateMPD() )
if( !p_sys->p_dashManager->updatePlaylist() )
return VLC_DEMUXER_EOF;
return VLC_DEMUXER_SUCCESS;
......
......@@ -41,7 +41,7 @@ AtomsReader::~AtomsReader()
delete rootbox;
}
bool AtomsReader::parseBlock(void *buffer, size_t size, Representation *rep)
bool AtomsReader::parseBlock(void *buffer, size_t size, BaseRepresentation *rep)
{
if(!rep)
return false;
......
......@@ -30,12 +30,16 @@ extern "C" {
#include "../../demux/mp4/libmp4.h"
}
namespace dash
namespace adaptative
{
namespace mpd
namespace playlist
{
class Representation;
class BaseRepresentation;
}
}
namespace dash
{
namespace mp4
{
class AtomsReader
......@@ -43,7 +47,7 @@ namespace dash
public:
AtomsReader(vlc_object_t *);
~AtomsReader();
bool parseBlock(void *, size_t, dash::mpd::Representation *);
bool parseBlock(void *, size_t, adaptative::playlist::BaseRepresentation *);
protected:
vlc_object_t *object;
......
......@@ -22,103 +22,44 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "AdaptationSet.h"
#include <vlc_common.h>
#include <vlc_arrays.h>
#include "SegmentTemplate.h"
#include "Representation.h"
#include "Period.h"
using namespace dash::mpd;
AdaptationSet::AdaptationSet(Period *period) :
SegmentInformation( period ),
subsegmentAlignmentFlag( false ),
isBitstreamSwitching( false )
adaptative::playlist::BaseAdaptationSet( period ),
DASHCommonAttributesElements(),
subsegmentAlignmentFlag( false )
{
}
AdaptationSet::~AdaptationSet ()
AdaptationSet::~AdaptationSet()
{
vlc_delete_all( this->representations );
childs.clear();
}
const std::string& AdaptationSet::getMimeType() const
{
if (mimeType.empty() && !representations.empty())
return representations.front()->getMimeType();
else
return mimeType;
}
bool AdaptationSet::getSubsegmentAlignmentFlag() const
{
return this->subsegmentAlignmentFlag;
return subsegmentAlignmentFlag;
}
void AdaptationSet::setSubsegmentAlignmentFlag(bool alignment)
{
this->subsegmentAlignmentFlag = alignment;
}
std::vector<Representation*>& AdaptationSet::getRepresentations ()
{
return this->representations;
subsegmentAlignmentFlag = alignment;
}
const Representation *AdaptationSet::getRepresentationById(const std::string &id) const
{
std::vector<Representation*>::const_iterator it = this->representations.begin();
std::vector<Representation*>::const_iterator end = this->representations.end();
std::vector<BaseRepresentation*>::const_iterator it = representations.begin();
std::vector<BaseRepresentation*>::const_iterator end = representations.end();
while ( it != end )
{
if ( (*it)->getId() == id )
return *it;
Representation *rep = dynamic_cast<Representation *>(*it);
if ( rep->getId() == id )
return rep;
++it;
}
return NULL;
}
void AdaptationSet::addRepresentation (Representation *rep)
{
this->representations.push_back(rep);
childs.push_back(rep);
}
void AdaptationSet::setBitstreamSwitching (bool value)
{
this->isBitstreamSwitching = value;
}
bool AdaptationSet::getBitstreamSwitching () const
{
return this->isBitstreamSwitching;
}
Url AdaptationSet::getUrlSegment() const
{
return getParentUrlSegment();
}
std::vector<std::string> AdaptationSet::toString(int indent) const
{
std::vector<std::string> ret;
std::string text(indent, ' ');
text.append("AdaptationSet");
ret.push_back(text);
std::vector<Representation *>::const_iterator k;
for(k = representations.begin(); k != representations.end(); k++)
{
std::vector<std::string> debug = (*k)->toString(indent + 1);
ret.insert(ret.end(), debug.begin(), debug.end());
}
return ret;
}
......@@ -29,39 +29,29 @@
#include <string>
#include <map>
#include "mpd/Representation.h"
#include "mpd/CommonAttributesElements.h"
#include "mpd/SegmentInformation.hpp"
#include "../adaptative/playlist/BaseAdaptationSet.h"
#include "DASHCommonAttributesElements.h"
namespace dash
{
namespace mpd
{
class Period;
class SegmentTemplate;
class Representation;
class AdaptationSet : public CommonAttributesElements,
public SegmentInformation
class AdaptationSet : public adaptative::playlist::BaseAdaptationSet,
public DASHCommonAttributesElements
{
public:
AdaptationSet(Period *);
virtual ~AdaptationSet();
virtual const std::string& getMimeType() const; /*reimpl*/
bool getSubsegmentAlignmentFlag() const;
void setSubsegmentAlignmentFlag( bool alignment );
std::vector<Representation *>& getRepresentations ();
const Representation* getRepresentationById ( const std::string &id ) const;
void setBitstreamSwitching(bool value);
bool getBitstreamSwitching() const;
void addRepresentation( Representation *rep );
virtual Url getUrlSegment() const; /* reimpl */
std::vector<std::string> toString(int = 0) const;
private:
bool subsegmentAlignmentFlag;
std::vector<Representation *> representations;
bool isBitstreamSwitching;
};
}
}
......
/*****************************************************************************
* CommonAttributesElements.cpp: Defines the common attributes and elements
* DASHCommonAttributesElements.cpp: Defines the common attributes and elements
* for some Dash elements.
*****************************************************************************
* Copyright © 2011 VideoLAN
......@@ -25,7 +25,7 @@
# include "config.h"
#endif
#include "CommonAttributesElements.h"
#include "DASHCommonAttributesElements.h"
#include "mpd/ContentDescription.h"
......@@ -34,16 +34,14 @@
using namespace dash::mpd;
CommonAttributesElements::CommonAttributesElements() :
width( -1 ),
height( -1 ),
DASHCommonAttributesElements::DASHCommonAttributesElements() :
parX( 1 ),
parY( 1 ),
frameRate( -1 )
{
}
CommonAttributesElements::~CommonAttributesElements()
DASHCommonAttributesElements::~DASHCommonAttributesElements()
{
vlc_delete_all( this->contentProtections );
vlc_delete_all( this->accessibilities );
......@@ -51,143 +49,100 @@ CommonAttributesElements::~CommonAttributesElements()
vlc_delete_all( this->viewpoints );
}
const std::string& CommonAttributesElements::getMimeType() const
{
return this->mimeType;
}
void CommonAttributesElements::setMimeType( const std::string &mimeType )
{
this->mimeType = mimeType;
}
int CommonAttributesElements::getWidth () const
{
return this->width;
}
void CommonAttributesElements::setWidth( int width )
{
if ( width > 0 )
this->width = width;
}
int CommonAttributesElements::getHeight () const
{
return this->height;
}
void CommonAttributesElements::setHeight( int height )
{
if ( height > 0 )
this->height = height;
}
int CommonAttributesElements::getParX () const
int DASHCommonAttributesElements::getParX () const
{
return this->parX;
}
void CommonAttributesElements::setParX( int parX )
void DASHCommonAttributesElements::setParX( int parX )
{
if ( parX > 0 )
this->parX = parX;
}
int CommonAttributesElements::getParY () const
int DASHCommonAttributesElements::getParY () const
{
return this->parY;
}
void CommonAttributesElements::setParY( int parY )
void DASHCommonAttributesElements::setParY( int parY )
{
if ( parY > 0 )
this->setParY( parY );
}
const std::list<std::string>& CommonAttributesElements::getLang() const
{
return this->lang;
}
void CommonAttributesElements::addLang( const std::string &lang )
{
if ( lang.empty() == false )
this->lang.push_back( lang );
}
int CommonAttributesElements::getFrameRate () const
int DASHCommonAttributesElements::getFrameRate () const
{
return this->frameRate;
}
void CommonAttributesElements::setFrameRate( int frameRate )
void DASHCommonAttributesElements::setFrameRate( int frameRate )
{
if ( frameRate > 0 )
this->frameRate = frameRate;
}
const std::list<std::string>& CommonAttributesElements::getNumberOfChannels() const
const std::list<std::string>& DASHCommonAttributesElements::getNumberOfChannels() const
{
return this->channels;
}
void CommonAttributesElements::addChannel( const std::string &channel )
void DASHCommonAttributesElements::addChannel( const std::string &channel )
{
if ( channel.empty() == false )
this->channels.push_back( channel );
}
const std::list<int>& CommonAttributesElements::getSamplingRates() const
const std::list<int>& DASHCommonAttributesElements::getSamplingRates() const
{
return this->sampleRates;
}
void CommonAttributesElements::addSampleRate( int sampleRate )
void DASHCommonAttributesElements::addSampleRate( int sampleRate )
{
if ( sampleRate > 0 )
this->sampleRates.push_back( sampleRate );
}
const std::list<ContentDescription*> &CommonAttributesElements::getContentProtections() const
const std::list<ContentDescription*> &DASHCommonAttributesElements::getContentProtections() const
{
return this->contentProtections;
}
void CommonAttributesElements::addContentProtection(ContentDescription *desc)
void DASHCommonAttributesElements::addContentProtection(ContentDescription *desc)
{
if ( desc != NULL )
this->contentProtections.push_back( desc );
}
const std::list<ContentDescription*> &CommonAttributesElements::getAccessibilities() const
const std::list<ContentDescription*> &DASHCommonAttributesElements::getAccessibilities() const
{
return this->accessibilities;
}
void CommonAttributesElements::addAccessibility(ContentDescription *desc)
void DASHCommonAttributesElements::addAccessibility(ContentDescription *desc)
{
if ( desc )
this->accessibilities.push_back( desc );
}
const std::list<ContentDescription*> &CommonAttributesElements::getRatings() const
const std::list<ContentDescription*> &DASHCommonAttributesElements::getRatings() const
{
return this->ratings;
}
void CommonAttributesElements::addRating(ContentDescription *desc)
void DASHCommonAttributesElements::addRating(ContentDescription *desc)
{
if ( desc )
this->ratings.push_back( desc );
}
const std::list<ContentDescription*> &CommonAttributesElements::getViewpoints() const
const std::list<ContentDescription*> &DASHCommonAttributesElements::getViewpoints() const
{
return this->viewpoints;
}
void CommonAttributesElements::addViewpoint(ContentDescription *desc)
void DASHCommonAttributesElements::addViewpoint(ContentDescription *desc)
{
if ( desc )
this->viewpoints.push_back( desc );
......
......@@ -21,8 +21,8 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef COMMONATTRIBUTESELEMENTS_H
#define COMMONATTRIBUTESELEMENTS_H
#ifndef DASHCOMMONATTRIBUTESELEMENTS_H
#define DASHCOMMONATTRIBUTESELEMENTS_H
#include <list>
#include <string>
......@@ -33,25 +33,17 @@ namespace dash
{
class ContentDescription;
class CommonAttributesElements
class DASHCommonAttributesElements
{
public:
CommonAttributesElements();
virtual ~CommonAttributesElements();
virtual const std::string& getMimeType() const;
void setMimeType( const std::string &mimeType );
int getWidth() const;
void setWidth( int width );
int getHeight() const;
void setHeight( int height );
DASHCommonAttributesElements();
virtual ~DASHCommonAttributesElements();
int getParX() const;
void setParX( int parX );
int getParY() const;
void setParY( int parY );
int getFrameRate() const;
void setFrameRate( int frameRate );
const std::list<std::string>& getLang() const;
void addLang( const std::string &lang );
const std::list<std::string>& getNumberOfChannels() const;
void addChannel( const std::string &channel );
const std::list<int>& getSamplingRates() const;
......@@ -66,13 +58,9 @@ namespace dash
void addViewpoint( ContentDescription *desc );
protected:
std::string mimeType;
int width;
int height;
int parX;
int parY;
int frameRate;
std::list<std::string> lang;
std::list<std::string> channels;
std::list<int> sampleRates;
std::list<ContentDescription*> contentProtections;
......@@ -83,4 +71,4 @@ namespace dash
}
}
#endif // COMMONATTRIBUTESELEMENTS_H
#endif // DASHCOMMONATTRIBUTESELEMENTS_H
/*
* Segment.cpp
*****************************************************************************
* Copyright (C) 2010 - 2011 Klagenfurt University
*
* Created on: Aug 10, 2010
* Authors: Christopher Mueller <christopher.mueller@itec.uni-klu.ac.at>
* Christian Timmerer <christian.timmerer@itec.uni-klu.ac.at>
*
* 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.
*****************************************************************************/
#define __STDC_CONSTANT_MACROS
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "DASHSegment.h"
#include "../adaptative/playlist/BaseRepresentation.h"
#include "../mp4/AtomsReader.hpp"
#include "../adaptative/http/Chunk.h"
#include "../adaptative/playlist/AbstractPlaylist.hpp"
using namespace adaptative::playlist;
using namespace dash::mpd;
using namespace dash::mp4;
DashIndexSegment::DashIndexSegment(ICanonicalUrl *parent) :
IndexSegment(parent)
{
}
Chunk* DashIndexSegment::toChunk(size_t index, BaseRepresentation *ctxrep)
{
SegmentChunk *chunk = dynamic_cast<SegmentChunk *>(Segment::toChunk(index, ctxrep));
chunk->setRepresentation(ctxrep);
return chunk;
}
void DashIndexSegment::onChunkDownload(void *data, size_t size, Chunk *, BaseRepresentation *rep)
{
if(!rep)
return;
AtomsReader br(rep->getPlaylist()->getVLCObject());
br.parseBlock(data, size, rep);
}
/*
* AdaptationLogicFactory.h
* Segment.h
*****************************************************************************
* Copyright (C) 2010 - 2011 Klagenfurt University
*
......@@ -22,29 +22,29 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef ADAPTATIONLOGICFACTORY_H_
#define ADAPTATIONLOGICFACTORY_H_
#ifndef DASHSEGMENT_H_
#define DASHSEGMENT_H_
#include "adaptationlogic/AbstractAdaptationLogic.h"
struct stream_t;
#include "../adaptative/playlist/Segment.h"
namespace dash
{
namespace mpd
{
class MPD;
}
using namespace adaptative::playlist;
using namespace adaptative::http;
namespace logic
{
class AdaptationLogicFactory
class DashIndexSegment : public IndexSegment
{
public:
static AbstractAdaptationLogic* create (
AbstractAdaptationLogic::LogicType logic, mpd::MPD *mpd);
DashIndexSegment( ICanonicalUrl *parent );
virtual Chunk* toChunk(size_t, BaseRepresentation * = NULL); //reimpl
protected:
virtual void onChunkDownload(void *, size_t, Chunk *, BaseRepresentation *); //reimpl
};
}
}
#endif /* ADAPTATIONLOGICFACTORY_H_ */
#endif /* DASHSEGMENT_H_ */
......@@ -19,6 +19,7 @@
*****************************************************************************/
#include "IMPDParser.h"
#include "xml/DOMHelper.h"
#include "../adaptative/playlist/BaseUrl.h"
using namespace dash::mpd;
using namespace dash::xml;
......
......@@ -38,6 +38,9 @@ namespace dash
{
namespace mpd
{
class Representation;
class Period;
class IMPDParser
{
public:
......
......@@ -27,9 +27,17 @@
#endif
#include "IsoffMainParser.h"
#include "SegmentTemplate.h"
#include "SegmentTimeline.h"
#include "../adaptative/playlist/SegmentTemplate.h"
#include "../adaptative/playlist/Segment.h"
#include "../adaptative/playlist/SegmentBase.h"
#include "../adaptative/playlist/SegmentList.h"
#include "../adaptative/playlist/SegmentTimeline.h"
#include "../adaptative/playlist/BaseUrl.h"
#include "Representation.h"
#include "Period.h"
#include "AdaptationSet.h"
#include "ProgramInformation.h"
#include "DASHSegment.h"
#include "xml/DOMHelper.h"
#include <vlc_strings.h>
#include <vlc_stream.h>
......@@ -38,6 +46,7 @@
using namespace dash::mpd;
using namespace dash::xml;
using namespace adaptative::playlist;
IsoffMainParser::IsoffMainParser (Node *root, stream_t *p_stream) :
IMPDParser(root, NULL, p_stream, NULL)
......@@ -255,7 +264,7 @@ void IsoffMainParser::parseSegmentBase(Node * segmentBaseNode, SegmentInformatio
size_t start = 0, end = 0;
if (std::sscanf(segmentBaseNode->getAttributeValue("indexRange").c_str(), "%zu-%zu", &start, &end) == 2)
{
seg = new IndexSegment(info);
seg = new DashIndexSegment(info);
seg->setByteRange(start, end);
list->addSegment(seg);
/* index must be before data, so data starts at index end */
......@@ -427,7 +436,7 @@ void IsoffMainParser::print ()
mpd->minBufferTime.Get());
msg_Dbg(p_stream, "BaseUrl=%s", mpd->getUrlSegment().toString().c_str());
std::vector<Period *>::const_iterator i;
std::vector<BasePeriod *>::const_iterator i;
for(i = mpd->getPeriods().begin(); i != mpd->getPeriods().end(); i++)
{
std::vector<std::string> debug = (*i)->toString();
......
......@@ -25,21 +25,35 @@
#ifndef ISOFFMAINPARSER_H_
#define ISOFFMAINPARSER_H_
#include "xml/Node.h"
#include "mpd/IMPDParser.h"
#include "mpd/AdaptationSet.h"
#include "mpd/BaseUrl.h"
#include "mpd/SegmentBase.h"
#include "mpd/SegmentList.h"
#include "mpd/Segment.h"
#include "IMPDParser.h"
#include "../adaptative/playlist/SegmentInfoCommon.h"
#include <cstdlib>
#include <sstream>
namespace adaptative
{
namespace playlist
{
class SegmentInformation;
class MediaSegmentTemplate;
}
}
namespace dash
{
namespace xml
{
class Node;
}
namespace mpd
{
class Period;
class AdaptationSet;
using namespace adaptative::playlist;
class IsoffMainParser : public IMPDParser
{
public:
......
......@@ -26,55 +26,22 @@
#endif
#include "MPD.h"
#include "Helper.h"
#include "dash.hpp"
#include "SegmentTimeline.h"
#include <vlc_common.h>
#include <vlc_stream.h>
#include "ProgramInformation.h"
using namespace dash::mpd;
MPD::MPD (stream_t *stream_, Profile profile_) :
ICanonicalUrl(),
stream(stream_),
AbstractPlaylist(stream_),
profile( profile_ )
{
playbackStart.Set(0);
availabilityStartTime.Set( 0 );
availabilityEndTime.Set( 0 );
duration.Set( 0 );
minUpdatePeriod.Set( 0 );
maxSegmentDuration.Set( 0 );
minBufferTime.Set( 0 );
timeShiftBufferDepth.Set( 0 );
programInfo.Set( NULL );
}
MPD::~MPD ()
MPD::~MPD()
{
for(size_t i = 0; i < this->periods.size(); i++)
delete(this->periods.at(i));
for(size_t i = 0; i < this->baseUrls.size(); i++)
delete(this->baseUrls.at(i));
delete(programInfo.Get());
}
const std::vector<Period*>& MPD::getPeriods ()
{
return this->periods;
}
void MPD::addBaseUrl (BaseUrl *url)
{
this->baseUrls.push_back(url);
}
void MPD::addPeriod (Period *period)
{
this->periods.push_back(period);
}
bool MPD::isLive() const
{
if(type.empty())
......@@ -86,90 +53,7 @@ bool MPD::isLive() const
return (type != "static");
}
void MPD::setType(const std::string &type_)
{
type = type_;
}
Profile MPD::getProfile() const
{
return profile;
}
Url MPD::getUrlSegment() const
{
if (!baseUrls.empty())
return Url(baseUrls.front()->getUrl());
else
{
std::stringstream ss;
ss << stream->psz_access << "://" << Helper::getDirectoryPath(stream->psz_path) << "/";
return Url(ss.str());
}
}
vlc_object_t * MPD::getVLCObject() const
{
return VLC_OBJECT(stream);
}
Period* MPD::getFirstPeriod()
{
std::vector<Period *> periods = getPeriods();
if( !periods.empty() )
return periods.front();
else
return NULL;
}
Period* MPD::getNextPeriod(Period *period)
{
std::vector<Period *> periods = getPeriods();
for(size_t i = 0; i < periods.size(); i++)
{
if(periods.at(i) == period && (i + 1) < periods.size())
return periods.at(i + 1);
}
return NULL;
}
void MPD::getTimeLinesBoundaries(mtime_t *min, mtime_t *max) const
{
*min = *max = 0;
for(size_t i = 0; i < periods.size(); i++)
{
std::vector<SegmentTimeline *> timelines;
periods.at(i)->collectTimelines(&timelines);
for(size_t j = 0; j < timelines.size(); j++)
{
const SegmentTimeline *timeline = timelines.at(j);
if(timeline->start() > *min)
*min = timeline->start();
if(!*max || timeline->end() < *max)
*max = timeline->end();
}
}
}
void MPD::mergeWith(MPD *updatedMPD, mtime_t prunebarrier)
{
availabilityEndTime.Set(updatedMPD->availabilityEndTime.Get());
/* Only merge timelines for now */
for(size_t i = 0; i < periods.size() && i < updatedMPD->periods.size(); i++)
{
std::vector<SegmentTimeline *> timelines;
std::vector<SegmentTimeline *> timelinesUpdate;
periods.at(i)->collectTimelines(&timelines);
updatedMPD->periods.at(i)->collectTimelines(&timelinesUpdate);
for(size_t j = 0; j < timelines.size() && j < timelinesUpdate.size(); j++)
{
timelines.at(j)->mergeWith(*timelinesUpdate.at(j));
if(prunebarrier)
timelines.at(j)->prune(prunebarrier);
}
}
}
......@@ -25,60 +25,30 @@
#ifndef MPD_H_
#define MPD_H_
#include <vector>
#include <string>
#include <map>
#include "mpd/Period.h"
#include "mpd/BaseUrl.h"
#include "mpd/ICanonicalUrl.hpp"
#include "mpd/ProgramInformation.h"
#include "mpd/Profile.hpp"
#include "Properties.hpp"
#include "../adaptative/playlist/AbstractPlaylist.hpp"
#include "Profile.hpp"
namespace dash
{
namespace mpd
{
class MPD : public ICanonicalUrl
using namespace adaptative::playlist;
class ProgramInformation;
class MPD : public AbstractPlaylist
{
public:
MPD(stream_t *, Profile);
virtual ~MPD();
Profile getProfile() const;
bool isLive() const;
void setType(const std::string &);
void addPeriod (Period *period);
void addBaseUrl (BaseUrl *url);
virtual Url getUrlSegment() const; /* impl */
vlc_object_t * getVLCObject() const;
virtual const std::vector<Period *>& getPeriods();
virtual Period* getFirstPeriod();
virtual Period* getNextPeriod(Period *period);
void mergeWith(MPD *, mtime_t = 0);
void getTimeLinesBoundaries(mtime_t *, mtime_t *) const;
virtual bool isLive() const;
Property<time_t> duration;
Property<time_t> playbackStart;
Property<time_t> availabilityEndTime;
Property<time_t> availabilityStartTime;
Property<time_t> minUpdatePeriod;
Property<time_t> maxSegmentDuration;
Property<time_t> minBufferTime;
Property<time_t> timeShiftBufferDepth;
Property<ProgramInformation *> programInfo;
private:
stream_t *stream;
Profile profile;
std::vector<Period *> periods;
std::vector<BaseUrl *> baseUrls;
std::string type;
};
}
}
......
......@@ -22,94 +22,16 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "Period.h"
#include "MPD.h"
#include <vlc_common.h>
#include <vlc_arrays.h>
using namespace dash::mpd;
Period::Period(MPD *mpd) :
SegmentInformation( mpd )
BasePeriod( mpd )
{
duration.Set(0);
startTime.Set(0);
baseUrl.Set(NULL);
}
Period::~Period ()
{
vlc_delete_all( this->adaptationSets );
delete baseUrl.Get();
childs.clear();
}
const std::vector<AdaptationSet*>& Period::getAdaptationSets() const
{
return this->adaptationSets;
}
const std::vector<AdaptationSet*> Period::getAdaptationSets(dash::Streams::Type type) const
{
std::vector<AdaptationSet*> list;
std::vector<AdaptationSet*>::const_iterator it;
for(it = adaptationSets.begin(); it!= adaptationSets.end(); it++)
{
if( Streams::Stream::mimeToType((*it)->getMimeType()) == type )
list.push_back(*it);
}
return list;
}
void Period::addAdaptationSet(AdaptationSet *adaptationSet)
{
if ( adaptationSet != NULL )
{
this->adaptationSets.push_back(adaptationSet);
childs.push_back(adaptationSet);
}
}
AdaptationSet * Period::getAdaptationSet(dash::Streams::Type type) const
{
std::vector<AdaptationSet *>::const_iterator it;
for(it = adaptationSets.begin(); it != adaptationSets.end(); it++)
{
if ( Streams::Stream::mimeToType((*it)->getMimeType()) == type )
return *it;
}
return NULL;
}
Url Period::getUrlSegment() const
{
if( baseUrl.Get() )
return *(baseUrl.Get());
else
return getParentUrlSegment();
}
std::vector<std::string> Period::toString(int indent) const
{
std::vector<std::string> ret;
std::string text(indent, ' ');
text.append("Period");
ret.push_back(text);
std::vector<AdaptationSet *>::const_iterator k;
for(k = adaptationSets.begin(); k != adaptationSets.end(); k++)
{
std::vector<std::string> debug = (*k)->toString(indent + 1);
ret.insert(ret.end(), debug.begin(), debug.end());
}
return ret;
}
mtime_t Period::getPeriodStart() const
{
return startTime.Get();
}
......@@ -24,43 +24,23 @@
#ifndef PERIOD_H_
#define PERIOD_H_
#include <vector>
#include <string>
#include "mpd/AdaptationSet.h"
#include "mpd/ICanonicalUrl.hpp"
#include "mpd/SegmentInformation.hpp"
#include "Properties.hpp"
#include "Streams.hpp"
#include "../adaptative/playlist/BasePeriod.h"
#include "../adaptative/playlist/SegmentInformation.hpp"
namespace dash
{
namespace mpd
{
class MPD;
using namespace adaptative;
using namespace adaptative::playlist;
class Period : public SegmentInformation,
class Period : public BasePeriod,
public UniqueNess<Period>
{
public:
Period(MPD *);
virtual ~Period ();
const std::vector<AdaptationSet *>& getAdaptationSets () const;
const std::vector<AdaptationSet *> getAdaptationSets (Streams::Type) const;
AdaptationSet * getAdaptationSet (Streams::Type) const;
void addAdaptationSet (AdaptationSet *AdaptationSet);
std::vector<std::string> toString (int = 0) const;
virtual Url getUrlSegment() const; /* reimpl */
virtual mtime_t getPeriodStart() const; /* reimpl */
Property<Url *> baseUrl;
Property<mtime_t> duration;
Property<mtime_t> startTime;
private:
std::vector<AdaptationSet *> adaptationSets;
};
}
}
......
......@@ -28,42 +28,27 @@
#include <cstdlib>
#include "Representation.h"
#include "mpd/AdaptationSet.h"
#include "mpd/MPD.h"
#include "mpd/SegmentTemplate.h"
#include "AdaptationSet.h"
#include "MPD.h"
#include "TrickModeType.h"
#include "../adaptative/playlist/SegmentTemplate.h"
#include "../adaptative/playlist/SegmentTimeline.h"
using namespace dash::mpd;
Representation::Representation ( AdaptationSet *set, MPD *mpd_ ) :
SegmentInformation( set ),
BaseRepresentation( set, mpd_ ),
mpd ( mpd_ ),
adaptationSet ( set ),
bandwidth (0),
qualityRanking ( -1 ),
trickModeType ( NULL ),
baseUrl ( NULL ),
width (0),
height (0)
trickModeType ( NULL )
{
}
Representation::~Representation ()
{
delete(this->trickModeType);
delete baseUrl;
}
uint64_t Representation::getBandwidth () const
{
return this->bandwidth;
}
void Representation::setBandwidth( uint64_t bandwidth )
{
this->bandwidth = bandwidth;
}
TrickModeType* Representation::getTrickModeType () const
{
return this->trickModeType;
......@@ -74,8 +59,6 @@ void Representation::setTrickMode (TrickModeType *trickMod
this->trickModeType = trickModeType;
}
int Representation::getQualityRanking() const
{
return this->qualityRanking;
......@@ -98,52 +81,112 @@ void Representation::addDependency(const Representation *dep)
this->dependencies.push_back( dep );
}
void Representation::setBaseUrl(BaseUrl *base)
{
baseUrl = base;
}
void Representation::setWidth (int width)
{
this->width = width;
}
int Representation::getWidth () const
{
return this->width;
}
void Representation::setHeight (int height)
{
this->height = height;
}
int Representation::getHeight () const
{
return this->height;
}
std::vector<std::string> Representation::toString(int indent) const
{
std::vector<std::string> ret;
std::string text(indent, ' ');
text.append("Representation");
ret.push_back(text);
std::vector<ISegment *> list = getSegments();
std::vector<ISegment *>::const_iterator l;
for(l = list.begin(); l < list.end(); l++)
ret.push_back((*l)->toString(indent + 1));
std::string Representation::contextualize(size_t index, const std::string &component,
const BaseSegmentTemplate *basetempl) const
{
std::string ret(component);
size_t pos;
const MediaSegmentTemplate *templ = dynamic_cast<const MediaSegmentTemplate *>(basetempl);
if(templ)
{
pos = ret.find("$Time$");
if(pos != std::string::npos)
{
std::stringstream ss;
ss << getScaledTimeBySegmentNumber(index, templ);
ret.replace(pos, std::string("$Time$").length(), ss.str());
}
pos = ret.find("$Number$");
if(pos != std::string::npos)
{
std::stringstream ss;
ss << getSegmentNumber(index, templ);
ret.replace(pos, std::string("$Number$").length(), ss.str());
}
else
{
pos = ret.find("$Number%");
size_t tokenlength = std::string("$Number%").length();
size_t fmtstart = pos + tokenlength;
if(pos != std::string::npos && fmtstart < ret.length())
{
size_t fmtend = ret.find('$', fmtstart);
if(fmtend != std::string::npos)
{
std::istringstream iss(ret.substr(fmtstart, fmtend - fmtstart + 1));
try
{
size_t width;
iss >> width;
if (iss.peek() != '$')
throw VLC_EGENERIC;
std::stringstream oss;
oss.width(width); /* set format string length */
oss.fill('0');
oss << getSegmentNumber(index, templ);
ret.replace(pos, fmtend - pos + 1, oss.str());
} catch(int) {}
}
}
}
}
pos = ret.find("$Bandwidth$");
if(pos != std::string::npos)
{
std::stringstream ss;
ss << getBandwidth();
ret.replace(pos, std::string("$Bandwidth$").length(), ss.str());
}
pos = ret.find("$RepresentationID$");
if(pos != std::string::npos)
{
std::stringstream ss;
ss << getId();
ret.replace(pos, std::string("$RepresentationID$").length(), ss.str());
}
return ret;
}
Url Representation::getUrlSegment() const
{
Url ret = getParentUrlSegment();
if (baseUrl)
ret.append(baseUrl->getUrl());
return ret;
}
MPD * Representation::getMPD() const
{
return mpd;
mtime_t Representation::getScaledTimeBySegmentNumber(size_t index, const MediaSegmentTemplate *templ) const
{
mtime_t time = 0;
if(templ->segmentTimeline.Get())
{
time = templ->segmentTimeline.Get()->getScaledPlaybackTimeByElementNumber(index);
}
else if(templ->duration.Get())
{
time = templ->duration.Get() * index;
}
return time;
}
size_t Representation::getSegmentNumber(size_t index, const MediaSegmentTemplate *templ) const
{
index += templ->startNumber.Get();
/* live streams / templated */
if(getPlaylist()->isLive())
{
if(templ->segmentTimeline.Get())
{
// do nothing ?
}
else if(templ->duration.Get())
{
mtime_t playbackstart = getPlaylist()->playbackStart.Get();
mtime_t streamstart = getPlaylist()->availabilityStartTime.Get();
streamstart += getPeriodStart();
mtime_t duration = templ->duration.Get();
uint64_t timescale = templ->inheritTimescale();
if(duration && timescale)
index += (playbackstart - streamstart) * timescale / duration;
}
}
return index;
}
......@@ -22,41 +22,31 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef REPRESENTATION_H_
#define REPRESENTATION_H_
#ifndef DASHREPRESENTATION_H_
#define DASHREPRESENTATION_H_
#include <string>
#include "mpd/CommonAttributesElements.h"
#include "mpd/TrickModeType.h"
#include "mpd/SegmentBase.h"
#include "mpd/SegmentList.h"
#include "mpd/SegmentInformation.hpp"
#include "mpd/BaseUrl.h"
#include "DASHCommonAttributesElements.h"
#include "../adaptative/playlist/SegmentInfoCommon.h"
#include "../adaptative/playlist/BaseRepresentation.h"
namespace dash
{
namespace mpd
{
class AdaptationSet;
class TrickModeType;
class MPD;
class Representation : public CommonAttributesElements,
public SegmentInformation,
using namespace adaptative::playlist;
class Representation : public BaseRepresentation,
public DASHCommonAttributesElements,
public UniqueNess<Representation>
{
public:
Representation( AdaptationSet *, MPD *mpd );
virtual ~Representation ();
/*
* @return The bitrate required for this representation
* in bits per seconds.
* Will be a valid value, as the parser refuses Representation
* without bandwidth.
*/
uint64_t getBandwidth () const;
void setBandwidth ( uint64_t bandwidth );
int getQualityRanking () const;
void setQualityRanking ( int qualityRanking );
const std::list<const Representation*>& getDependencies() const;
......@@ -70,28 +60,21 @@ namespace dash
void setTrickMode( TrickModeType *trickModeType );
void setWidth (int width);
int getWidth () const;
void setHeight (int height);
int getHeight () const;
void setBaseUrl (BaseUrl *baseUrl);
MPD* getMPD () const;
std::vector<std::string> toString(int = 0) const;
virtual Url getUrlSegment () const; /* impl */
/* for segment templates */
virtual std::string contextualize(size_t, const std::string &,
const BaseSegmentTemplate *) const; // reimpl
private:
MPD *mpd;
AdaptationSet *adaptationSet;
uint64_t bandwidth;
int qualityRanking;
std::list<const Representation*> dependencies;
TrickModeType *trickModeType;
BaseUrl *baseUrl;
int width;
int height;
/* for contextualize() */
mtime_t getScaledTimeBySegmentNumber(size_t, const MediaSegmentTemplate *) const;
size_t getSegmentNumber(size_t, const MediaSegmentTemplate *) const;
};
}
}
#endif /* REPRESENTATION_H_ */
#endif /* DASHREPRESENTATION_H_ */
......@@ -25,9 +25,6 @@
#ifndef TRICKMODETYPE_H_
#define TRICKMODETYPE_H_
#include <string>
#include <map>
namespace dash
{
namespace mpd
......
/*
* Url.cpp
*****************************************************************************
* Copyright (C) 2014 - VideoLAN Authors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "Url.hpp"
#include "Representation.h"
#include "SegmentTemplate.h"
#include "SegmentTimeline.h"
#include "MPD.h"
#include <sstream>
using namespace dash::mpd;
Url::Url()
{
}
Url::Url(const Component & comp)
{
prepend(comp);
}
Url::Url(const std::string &str)
{
prepend(Component(str));
}
Url & Url::prepend(const Component & comp)
{
components.insert(components.begin(), comp);
return *this;
}
Url & Url::append(const Component & comp)
{
components.push_back(comp);
return *this;
}
Url & Url::prepend(const Url &url)
{
components.insert(components.begin(), url.components.begin(), url.components.end());
return *this;
}
Url & Url::append(const Url &url)
{
components.insert(components.end(), url.components.begin(), url.components.end());
return *this;
}
std::string Url::toString() const
{
return toString(0, NULL);
}
std::string Url::toString(size_t index, const Representation *rep) const
{
std::string ret;
std::vector<Component>::const_iterator it;
for(it = components.begin(); it != components.end(); it++)
{
ret.append((*it).contextualize(index, rep));
}
return ret;
}
Url::Component::Component(const std::string & str, const MediaSegmentTemplate *templ_)
{
component = str;
templ = templ_;
}
mtime_t Url::Component::getScaledTimeBySegmentNumber(size_t index, const Representation *) const
{
mtime_t time = 0;
if(templ->segmentTimeline.Get())
{
time = templ->segmentTimeline.Get()->getScaledPlaybackTimeByElementNumber(index);
}
else if(templ->duration.Get())
{
time = templ->duration.Get() * index;
}
return time;
}
size_t Url::Component::getSegmentNumber(size_t index, const Representation *rep) const
{
index += templ->startNumber.Get();
/* live streams / templated */
if(rep->getMPD()->isLive())
{
if(templ->segmentTimeline.Get())
{
// do nothing ?
}
else if(templ->duration.Get())
{
mtime_t playbackstart = rep->getMPD()->playbackStart.Get();
mtime_t streamstart = rep->getMPD()->availabilityStartTime.Get();
streamstart += rep->getPeriodStart();
mtime_t duration = templ->duration.Get();
uint64_t timescale = templ->inheritTimescale();
if(duration && timescale)
index += (playbackstart - streamstart) * timescale / duration;
}
}
return index;
}
std::string Url::Component::contextualize(size_t index, const Representation *rep) const
{
std::string ret(component);
size_t pos;
if(!rep)
return ret;
if(templ)
{
pos = ret.find("$Time$");
if(pos != std::string::npos)
{
std::stringstream ss;
ss << getScaledTimeBySegmentNumber(index, rep);
ret.replace(pos, std::string("$Time$").length(), ss.str());
}
pos = ret.find("$Number$");
if(pos != std::string::npos)
{
std::stringstream ss;
ss << getSegmentNumber(index, rep);
ret.replace(pos, std::string("$Number$").length(), ss.str());
}
else
{
pos = ret.find("$Number%");
size_t tokenlength = std::string("$Number%").length();
size_t fmtstart = pos + tokenlength;
if(pos != std::string::npos && fmtstart < ret.length())
{
size_t fmtend = ret.find('$', fmtstart);
if(fmtend != std::string::npos)
{
std::istringstream iss(ret.substr(fmtstart, fmtend - fmtstart + 1));
try
{
size_t width;
iss >> width;
if (iss.peek() != '$')
throw VLC_EGENERIC;
std::stringstream oss;
oss.width(width); /* set format string length */
oss.fill('0');
oss << getSegmentNumber(index, rep);
ret.replace(pos, fmtend - pos + 1, oss.str());
} catch(int) {}
}
}
}
}
pos = ret.find("$Bandwidth$");
if(pos != std::string::npos)
{
std::stringstream ss;
ss << rep->getBandwidth();
ret.replace(pos, std::string("$Bandwidth$").length(), ss.str());
}
pos = ret.find("$RepresentationID$");
if(pos != std::string::npos)
{
std::stringstream ss;
ss << rep->getId();
ret.replace(pos, std::string("$RepresentationID$").length(), ss.str());
}
return ret;
}
......@@ -26,7 +26,7 @@
#endif
#include "DOMParser.h"
#include "../Helper.h"
#include "../adaptative/tools/Helper.h"
#include <vector>
#include <stack>
......@@ -193,7 +193,7 @@ bool DOMParser::isDash (stream_t *stream)
std::string header((const char*)peek, peek_size);
for( size_t i=0; i<ARRAY_SIZE(namespaces); i++ )
{
if ( Helper::ifind(header, namespaces[i]) )
if ( adaptative::Helper::ifind(header, namespaces[i]) )
return true;
}
return false;
......
......@@ -28,7 +28,6 @@
#include <vector>
#include <string>
#include <map>
#include <iostream>
namespace dash
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment