aboutsummaryrefslogtreecommitdiffstats
path: root/MPD
diff options
context:
space:
mode:
authorjacko <jsamain+fdio@cisco.com>2017-06-23 16:12:18 +0200
committerjacko <jsamain+fdio@cisco.com>2017-06-23 16:12:18 +0200
commita644414fd2c3a3f7f41e716b6875a78981e4cfe1 (patch)
tree13fc8ff2f6072add96f987a1a68a15c22d68d911 /MPD
parentf8907f0a7a84928800adbbfd8e66e500794aa5d5 (diff)
adding mpd live handling + automatic mpd fetching
Change-Id: I2c05bdf6a4d940ad22bb8632268f4b63a08a80a8 Signed-off-by: jacko <jsamain+fdio@cisco.com>
Diffstat (limited to 'MPD')
-rw-r--r--MPD/AbstractRepresentationStream.cpp32
-rw-r--r--MPD/AbstractRepresentationStream.h18
-rw-r--r--MPD/AdaptationSetStream.cpp111
-rw-r--r--MPD/AdaptationSetStream.h18
-rw-r--r--MPD/BaseUrlResolver.cpp13
-rw-r--r--MPD/BaseUrlResolver.h6
-rw-r--r--MPD/IMPDWrapper.h46
-rw-r--r--MPD/IRepresentationStream.h3
-rw-r--r--MPD/MPDWrapper.cpp1098
-rw-r--r--MPD/MPDWrapper.h134
-rw-r--r--MPD/RepresentationStreamFactory.cpp26
-rw-r--r--MPD/RepresentationStreamFactory.h7
-rw-r--r--MPD/SegmentListStream.cpp22
-rw-r--r--MPD/SegmentListStream.h11
-rw-r--r--MPD/SegmentTemplateStream.cpp55
-rw-r--r--MPD/SegmentTemplateStream.h7
-rw-r--r--MPD/SingleMediaSegmentStream.cpp12
-rw-r--r--MPD/SingleMediaSegmentStream.h5
18 files changed, 1510 insertions, 114 deletions
diff --git a/MPD/AbstractRepresentationStream.cpp b/MPD/AbstractRepresentationStream.cpp
index 346938f4..e02f65cb 100644
--- a/MPD/AbstractRepresentationStream.cpp
+++ b/MPD/AbstractRepresentationStream.cpp
@@ -14,8 +14,9 @@
using namespace libdash::framework::mpd;
using namespace dash::mpd;
-AbstractRepresentationStream::AbstractRepresentationStream(IMPD *mpd, IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation) :
- mpd (mpd),
+AbstractRepresentationStream::AbstractRepresentationStream(viper::managers::StreamType type, IMPDWrapper *mpdWrapper, IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation) :
+ type (type),
+ mpdWrapper (mpdWrapper),
period (period),
adaptationSet (adaptationSet),
representation (representation)
@@ -40,12 +41,12 @@ uint32_t AbstractRepresentationStream::getSize()
uint32_t AbstractRepresentationStream::getFirstSegmentNumber()
{
- if (this->mpd->GetType() == "dynamic")
+ if (this->mpdWrapper->getTypeWithoutLock() == "dynamic")
{
uint32_t currTime = TimeResolver::getCurrentTimeInSec();
- uint32_t availStT = TimeResolver::getUTCDateTimeInSec(this->mpd->GetAvailabilityStarttime());
+ uint32_t availStT = TimeResolver::getUTCDateTimeInSec(this->mpdWrapper->getAvailabilityStarttime());
uint32_t duration = this->getAverageSegmentDuration();
- uint32_t timeshift = TimeResolver::getDurationInSec(this->mpd->GetTimeShiftBufferDepth());
+ uint32_t timeshift = TimeResolver::getDurationInSec(this->mpdWrapper->getTimeShiftBufferDepth());
uint32_t timescale = this->getTimescale();
return (double)((double)currTime - (double)availStT - (double)timeshift ) < 0? 0 : (currTime - availStT - timeshift );
}
@@ -54,11 +55,11 @@ uint32_t AbstractRepresentationStream::getFirstSegmentNumber()
uint32_t AbstractRepresentationStream::getCurrentSegmentNumber()
{
- if (this->mpd->GetType() == "dynamic")
+ if (this->mpdWrapper->getTypeWithoutLock() == "dynamic")
{
uint32_t currTime = TimeResolver::getCurrentTimeInSec();
uint32_t duration = this->getAverageSegmentDuration();
- uint32_t availStT = TimeResolver::getUTCDateTimeInSec(this->mpd->GetAvailabilityStarttime());
+ uint32_t availStT = TimeResolver::getUTCDateTimeInSec(this->mpdWrapper->getAvailabilityStarttime());
return (double)((double)currTime - (double)availStT) < 0 ? 0 : (currTime - availStT);
// return (currTime - duration - availStT) / duration;
@@ -68,13 +69,13 @@ uint32_t AbstractRepresentationStream::getCurrentSegmentNumber()
uint32_t AbstractRepresentationStream::getLastSegmentNumber ()
{
- if (this->mpd->GetType() == "dynamic")
+ if (this->mpdWrapper->getTypeWithoutLock() == "dynamic")
{
uint32_t currTime = TimeResolver::getCurrentTimeInSec();
uint32_t duration = this->getAverageSegmentDuration();
- uint32_t availStT = TimeResolver::getUTCDateTimeInSec(this->mpd->GetAvailabilityStarttime());
- uint32_t checkTime = mpd->GetFetchTime() +
- TimeResolver::getDurationInSec(this->mpd->GetMinimumUpdatePeriod());
+ uint32_t availStT = TimeResolver::getUTCDateTimeInSec(this->mpdWrapper->getAvailabilityStarttime());
+ uint32_t checkTime = mpdWrapper->getFetchTime() +
+ TimeResolver::getDurationInSec(this->mpdWrapper->getMinimumUpdatePeriodWithoutLock());
return ( ((checkTime > currTime) ? currTime : checkTime) - duration - availStT) / duration;
}
return 0;
@@ -92,3 +93,12 @@ void AbstractRepresentationStream::setSegmentOffset (uint32_t offset)
{
this->segmentOffset = offset;
}
+
+uint32_t AbstractRepresentationStream::getTime(size_t segmentNumber)
+{
+ return 0;
+}
+size_t AbstractRepresentationStream::getSegmentNumber(uint32_t time)
+{
+ return 0;
+}
diff --git a/MPD/AbstractRepresentationStream.h b/MPD/AbstractRepresentationStream.h
index 4728e366..87400c0c 100644
--- a/MPD/AbstractRepresentationStream.h
+++ b/MPD/AbstractRepresentationStream.h
@@ -12,15 +12,22 @@
#ifndef LIBDASH_FRAMEWORK_MPD_ABSTRACTREPRESENTATIONSTREAM_H_
#define LIBDASH_FRAMEWORK_MPD_ABSTRACTREPRESENTATIONSTREAM_H_
+#include "../MPD/IMPDWrapper.h"
#include "IRepresentationStream.h"
#include "IBaseUrl.h"
#include "IRepresentation.h"
#include "IAdaptationSet.h"
-#include "IMPD.h"
#include "IPeriod.h"
#include "BaseUrlResolver.h"
#include "TimeResolver.h"
+namespace viper
+{
+namespace managers
+{
+enum StreamType;
+}
+}
namespace libdash
{
namespace framework
@@ -30,7 +37,7 @@ namespace mpd
class AbstractRepresentationStream : public IRepresentationStream
{
public:
- AbstractRepresentationStream(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet,
+ AbstractRepresentationStream(viper::managers::StreamType type, libdash::framework::mpd::IMPDWrapper *mpdWrapper, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet,
dash::mpd::IRepresentation *representation);
virtual ~AbstractRepresentationStream();
@@ -47,17 +54,20 @@ public:
virtual uint32_t getAverageSegmentDuration();
virtual uint32_t getTimescale();
- virtual void setSegmentOffset(uint32_t offset);
+ virtual void setSegmentOffset(uint32_t offset);
+ virtual uint32_t getTime(size_t segmentNumber);
+ virtual size_t getSegmentNumber(uint32_t time);
protected:
virtual void setBaseUrls(const std::vector<dash::mpd::IBaseUrl *> baseurls);
std::vector<dash::mpd::IBaseUrl *> baseUrls;
- dash::mpd::IMPD *mpd;
+ libdash::framework::mpd::IMPDWrapper *mpdWrapper;
dash::mpd::IPeriod *period;
dash::mpd::IAdaptationSet *adaptationSet;
dash::mpd::IRepresentation *representation;
uint32_t segmentOffset;
+ viper::managers::StreamType type;
};
}
}
diff --git a/MPD/AdaptationSetStream.cpp b/MPD/AdaptationSetStream.cpp
index 62bc1912..94f97df9 100644
--- a/MPD/AdaptationSetStream.cpp
+++ b/MPD/AdaptationSetStream.cpp
@@ -14,69 +14,72 @@
using namespace libdash::framework::mpd;
using namespace dash::mpd;
-AdaptationSetStream::AdaptationSetStream(IMPD *mpd, IPeriod *period, IAdaptationSet *adaptationSet) :
- mpd (mpd),
- period (period),
- adaptationSet (adaptationSet)
+AdaptationSetStream::AdaptationSetStream(viper::managers::StreamType type, MPDWrapper *mpdWrapper) :
+ mpdWrapper (mpdWrapper),
+ type (type)
+// period (period),
+// adaptationSet (adaptationSet)
{
initialize();
}
AdaptationSetStream::~AdaptationSetStream()
{
- std::map<IRepresentation *, IRepresentationStream *>::iterator iter;
- for (iter = representations.begin(); iter != representations.end(); ++iter)
- {
- delete(iter->second);
- }
+ this->mpdWrapper->destroyAdaptationSetStream(type);
+// std::map<IRepresentation *, IRepresentationStream *>::iterator iter;
+// for (iter = representations.begin(); iter != representations.end(); ++iter)
+// {
+// delete(iter->second);
+// }
}
-IRepresentationStream* AdaptationSetStream::getRepresentationStream(IRepresentation *representation)
-{
- return this->representations.find(representation)->second;
-}
-
-RepresentationStreamType AdaptationSetStream::determineRepresentationStreamType (IRepresentation *representation)
-{
- /* check on Representation Level */
- if (representation->GetSegmentList())
- return libdash::framework::mpd::SegmentList;
-
- if (representation->GetSegmentTemplate())
- return libdash::framework::mpd::SegmentTemplate;
-
- if (representation->GetSegmentBase() || representation->GetBaseURLs().size() > 0)
- return libdash::framework::mpd::SingleMediaSegment;
-
- /* check on AdaptationSet Level */
- if (this->adaptationSet->GetSegmentList())
- return libdash::framework::mpd::SegmentList;
-
- if (this->adaptationSet->GetSegmentTemplate())
- return libdash::framework::mpd::SegmentTemplate;
-
- if (this->adaptationSet->GetSegmentBase())
- return libdash::framework::mpd::SingleMediaSegment;
-
- /* check on Period Level */
- if (this->period->GetSegmentList())
- return libdash::framework::mpd::SegmentList;
-
- if (this->period->GetSegmentTemplate())
- return libdash::framework::mpd::SegmentTemplate;
-
- if (this->period->GetSegmentBase())
- return libdash::framework::mpd::SingleMediaSegment;
-
- return libdash::framework::mpd::UNDEFINED;
-}
+//IRepresentationStream* AdaptationSetStream::getRepresentationStream(IRepresentation *representation)
+//{
+// return this->representations.find(representation)->second;
+//}
+
+//RepresentationStreamType AdaptationSetStream::determineRepresentationStreamType (IRepresentation *representation)
+//{
+// /* check on Representation Level */
+// if (representation->GetSegmentList())
+// return libdash::framework::mpd::SegmentList;
+//
+// if (representation->GetSegmentTemplate())
+// return libdash::framework::mpd::SegmentTemplate;
+//
+// if (representation->GetSegmentBase() || representation->GetBaseURLs().size() > 0)
+// return libdash::framework::mpd::SingleMediaSegment;
+//
+// /* check on AdaptationSet Level */
+// if (this->adaptationSet->GetSegmentList())
+// return libdash::framework::mpd::SegmentList;
+//
+// if (this->adaptationSet->GetSegmentTemplate())
+// return libdash::framework::mpd::SegmentTemplate;
+//
+// if (this->adaptationSet->GetSegmentBase())
+// return libdash::framework::mpd::SingleMediaSegment;
+//
+// /* check on Period Level */
+// if (this->period->GetSegmentList())
+// return libdash::framework::mpd::SegmentList;
+//
+// if (this->period->GetSegmentTemplate())
+// return libdash::framework::mpd::SegmentTemplate;
+//
+// if (this->period->GetSegmentBase())
+// return libdash::framework::mpd::SingleMediaSegment;
+//
+// return libdash::framework::mpd::UNDEFINED;
+//}
void AdaptationSetStream::initialize()
{
- for (size_t i = 0; i < adaptationSet->GetRepresentation().size(); i++)
- {
- IRepresentation *representation = adaptationSet->GetRepresentation().at(i);
- RepresentationStreamType type = determineRepresentationStreamType(representation);
- representations[representation] = RepresentationStreamFactory::create(type, mpd, period, adaptationSet, representation);
- }
+ this->mpdWrapper->initializeAdaptationSetStream(type);
+// for (size_t i = 0; i < adaptationSet->GetRepresentation().size(); i++)
+// {
+// IRepresentation *representation = adaptationSet->GetRepresentation().at(i);
+// RepresentationStreamType type = determineRepresentationStreamType(representation);
+// representations[representation] = RepresentationStreamFactory::create(type, mpd, period, adaptationSet, representation);
+// }
}
diff --git a/MPD/AdaptationSetStream.h b/MPD/AdaptationSetStream.h
index 3ad9788f..d38c1388 100644
--- a/MPD/AdaptationSetStream.h
+++ b/MPD/AdaptationSetStream.h
@@ -14,7 +14,7 @@
#include "IRepresentationStream.h"
#include "IRepresentation.h"
-#include "IMPD.h"
+#include "MPDWrapper.h"
#include "IPeriod.h"
#include "IAdaptationSet.h"
#include "RepresentationStreamFactory.h"
@@ -29,19 +29,21 @@ namespace mpd
class AdaptationSetStream
{
public:
- AdaptationSetStream(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet);
+// AdaptationSetStream(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet);
+ AdaptationSetStream(viper::managers::StreamType type, libdash::framework::mpd::MPDWrapper *mpdWrapper);
virtual ~AdaptationSetStream();
- IRepresentationStream* getRepresentationStream(dash::mpd::IRepresentation *representation);
+// IRepresentationStream* getRepresentationStream(dash::mpd::IRepresentation *representation);
private:
- RepresentationStreamType determineRepresentationStreamType(dash::mpd::IRepresentation *representation);
+// RepresentationStreamType determineRepresentationStreamType(dash::mpd::IRepresentation *representation);
void initialize();
- std::map<dash::mpd::IRepresentation *, IRepresentationStream *> representations;
- dash::mpd::IMPD *mpd;
- dash::mpd::IPeriod *period;
- dash::mpd::IAdaptationSet *adaptationSet;
+// std::map<dash::mpd::IRepresentation *, IRepresentationStream *> representations;
+ libdash::framework::mpd::MPDWrapper *mpdWrapper;
+ viper::managers::StreamType type;
+// dash::mpd::IPeriod *period;
+// dash::mpd::IAdaptationSet *adaptationSet;
};
}
diff --git a/MPD/BaseUrlResolver.cpp b/MPD/BaseUrlResolver.cpp
index 54b586cd..4340840d 100644
--- a/MPD/BaseUrlResolver.cpp
+++ b/MPD/BaseUrlResolver.cpp
@@ -14,10 +14,10 @@
using namespace dash::mpd;
using namespace libdash::framework::mpd;
-std::vector<dash::mpd::IBaseUrl *> BaseUrlResolver::resolveBaseUrl(IMPD *mpd, IPeriod *period, IAdaptationSet *adaptationSet,
- size_t mpdBaseUrl, size_t periodBaseUrl, size_t adaptationSetBaseUrl)
+std::vector<dash::mpd::IBaseUrl *> BaseUrlResolver::resolveBaseUrl(viper::managers::StreamType type, IMPDWrapper *mpdWrapper, size_t mpdBaseUrl, size_t periodBaseUrl, size_t adaptationSetBaseUrl)
{
- std::vector<dash::mpd::IBaseUrl *> urls;
+ return mpdWrapper->resolveBaseUrl(type, mpdBaseUrl, periodBaseUrl, adaptationSetBaseUrl);
+/* std::vector<dash::mpd::IBaseUrl *> urls;
if (mpd->GetBaseUrls().size() > 0)
{
@@ -60,5 +60,10 @@ std::vector<dash::mpd::IBaseUrl *> BaseUrlResolver::resolveBaseUrl(IMPD *mpd, IP
urls.push_back(mpd->GetMPDPathBaseUrl());
}
- return urls;
+ return urls; */
+}
+
+std::vector<dash::mpd::IBaseUrl *> BaseUrlResolver::resolveBaseUrl(viper::managers::StreamType type, IMPDWrapper *mpdWrapper, size_t mpdBaseUrl, size_t periodBaseUrl, size_t adaptationSetBaseUrl, IMPD* mpd)
+{
+ return mpdWrapper->resolveBaseUrl(type, mpdBaseUrl, periodBaseUrl, adaptationSetBaseUrl, mpd);
}
diff --git a/MPD/BaseUrlResolver.h b/MPD/BaseUrlResolver.h
index 6956a00e..b2513f05 100644
--- a/MPD/BaseUrlResolver.h
+++ b/MPD/BaseUrlResolver.h
@@ -12,7 +12,7 @@
#ifndef LIBDASH_FRAMEWORK_MPD_BASEURLRESOLVER_H_
#define LIBDASH_FRAMEWORK_MPD_BASEURLRESOLVER_H_
-#include "IMPD.h"
+#include "IMPDWrapper.h"
namespace libdash
{
@@ -23,8 +23,10 @@ namespace mpd
class BaseUrlResolver
{
public:
- static std::vector<dash::mpd::IBaseUrl *> resolveBaseUrl(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet,
+ static std::vector<dash::mpd::IBaseUrl *> resolveBaseUrl(viper::managers::StreamType type, libdash::framework::mpd::IMPDWrapper *mpdWrapper,
size_t mpdBaseUrl, size_t periodBaseUrl, size_t adaptationSetBaseUrl);
+ static std::vector<dash::mpd::IBaseUrl *> resolveBaseUrl(viper::managers::StreamType type, libdash::framework::mpd::IMPDWrapper *mpdWrapper,
+ size_t mpdBaseUrl, size_t periodBaseUrl, size_t adaptationSetBaseUrl, dash::mpd::IMPD* mpd);
};
}
}
diff --git a/MPD/IMPDWrapper.h b/MPD/IMPDWrapper.h
new file mode 100644
index 00000000..7390494e
--- /dev/null
+++ b/MPD/IMPDWrapper.h
@@ -0,0 +1,46 @@
+/*
+ * MPDWrapper.h
+ *****************************************************************************
+ * Copyright (C) 2017, Cisco Systems France
+ *
+ * Email: cicn-dev@lists.fd.io
+ *
+ * This source code and its use and distribution, is subject to the terms
+ * and conditions of the applicable license agreement.
+ *****************************************************************************/
+
+
+#ifndef LIBDASH_FRAMEWORK_MPD_IMPDWRAPPER_H_
+#define LIBDASH_FRAMEWORK_MPD_IMPDWRAPPER_H_
+
+#include "../Managers/IStreamObserver.h"
+//#include <string>
+//#include <vector>
+#include "IMPD.h"
+#include "../Managers/IStreamObserver.h"
+
+namespace libdash
+{
+namespace framework
+{
+namespace mpd
+{
+class IMPDWrapper
+{
+public:
+ virtual std::string getAvailabilityStarttime() = 0;
+ virtual std::string getTimeShiftBufferDepth() = 0;
+ virtual std::string getTypeWithoutLock() = 0;
+ virtual uint32_t getFetchTime() = 0;
+ virtual std::string getMinimumUpdatePeriodWithoutLock() = 0;
+ virtual std::vector<dash::mpd::IBaseUrl *> resolveBaseUrl(viper::managers::StreamType type, size_t mpdBaseUrl, size_t periodBaseUrl, size_t adaptationSetBaseUrl) = 0;
+ virtual std::vector<dash::mpd::IBaseUrl *> resolveBaseUrl(viper::managers::StreamType type, size_t mpdBaseUrl, size_t periodBaseUrl, size_t adaptationSetBaseUrl, dash::mpd::IMPD* mpd) = 0;
+ virtual void releaseLock() = 0;
+ virtual std::string getMediaPresentationDuration() = 0;
+};
+}
+}
+}
+
+#endif /* LIBDASH_FRAMEWORK_MPD_IMPDWRAPPER_H_ */
+
diff --git a/MPD/IRepresentationStream.h b/MPD/IRepresentationStream.h
index 31f83d54..5734c4cf 100644
--- a/MPD/IRepresentationStream.h
+++ b/MPD/IRepresentationStream.h
@@ -44,6 +44,9 @@ public:
virtual uint32_t getLastSegmentNumber() = 0;
virtual uint32_t getAverageSegmentDuration() = 0;
virtual void setSegmentOffset(uint32_t offset) = 0;
+ virtual uint32_t getTime(size_t segmentNumber) = 0;
+ virtual size_t getSegmentNumber(uint32_t time) = 0;
+
};
}
diff --git a/MPD/MPDWrapper.cpp b/MPD/MPDWrapper.cpp
new file mode 100644
index 00000000..4c8baa6b
--- /dev/null
+++ b/MPD/MPDWrapper.cpp
@@ -0,0 +1,1098 @@
+/*
+ * MPDWrapper.cpp
+ *****************************************************************************
+ * Copyright (C) 2017, Cisco Systems France
+ *
+ * Email: libdash-dev@vicky.bitmovin.net
+ *
+ * This source code and its use and distribution, is subject to the terms
+ * and conditions of the applicable license agreement.
+ *****************************************************************************/
+
+#include "MPDWrapper.h"
+
+using namespace dash::mpd;
+using namespace libdash::framework::mpd;
+using namespace libdash::framework::input;
+using namespace viper::managers;
+
+MPDWrapper::MPDWrapper(IMPD *mpd):
+ mpd (mpd),
+ period (NULL),
+ videoAdaptationSet (NULL),
+ videoRepresentation (NULL),
+ audioAdaptationSet (NULL),
+ audioRepresentation (NULL),
+ videoRepresentations(NULL),
+ audioRepresentations(NULL),
+ videoSegmentOffset (0),
+ audioSegmentOffset (0),
+ videoSegmentNumber (0),
+ audioSegmentNumber (0)
+{
+ InitializeConditionVariable (&this->mpdUpdate);
+ InitializeCriticalSection(&this->monitorMutex);
+}
+
+MPDWrapper::~MPDWrapper()
+{
+ DeleteCriticalSection(&this->monitorMutex);
+ DeleteConditionVariable(&this->mpdUpdate);
+}
+
+IMPD* MPDWrapper::getMPD ()
+{
+ return this->mpd;
+}
+
+void MPDWrapper::updateMPD (IMPD* mpd)
+{
+//Assumptions here:
+// *only one period in the MPD
+// *only triggered if using SegmentTimeline dynamic MPD
+ EnterCriticalSection(&this->monitorMutex);
+ this->period = mpd->GetPeriods().at(0);
+ this->findVideoAdaptationSet(mpd);
+ this->findAudioAdaptationSet(mpd);
+ this->findVideoRepresentation(mpd);
+ this->findAudioRepresentation(mpd);
+ delete(this->mpd);
+ this->mpd = mpd;
+ WakeAllConditionVariable(&this->mpdUpdate);
+ LeaveCriticalSection(&this->monitorMutex);
+}
+
+void MPDWrapper::findVideoAdaptationSet (IMPD* mpd)
+{
+ std::vector<IAdaptationSet *> adaptationSets = AdaptationSetHelper::getVideoAdaptationSets(mpd->GetPeriods().at(0));
+ if(!(adaptationSets.empty()) && this->videoAdaptationSet)
+ {
+ for(size_t i = 0; i < adaptationSets.size(); i++)
+ {
+ if(adaptationSets.at(i)->GetId() == this->videoAdaptationSet->GetId())
+ {
+ this->videoAdaptationSet = adaptationSets.at(i);
+ return;
+ }
+ }
+ //Not found in the new set of adaptation logc => select the first one
+ this->videoAdaptationSet = adaptationSets.at(0);
+ }
+ else
+ {
+ if(!adaptationSets.empty())
+ {
+ this->videoAdaptationSet = adaptationSets.at(0);
+ return;
+ }
+ this->videoAdaptationSet = NULL;
+ }
+}
+
+void MPDWrapper::findAudioAdaptationSet (IMPD* mpd)
+{
+ std::vector<IAdaptationSet *> adaptationSets = AdaptationSetHelper::getAudioAdaptationSets(mpd->GetPeriods().at(0));
+ if(!(adaptationSets.empty()) && this->audioAdaptationSet)
+ {
+ for(size_t i = 0; i < adaptationSets.size(); i++)
+ {
+ if(adaptationSets.at(i)->GetId() == this->audioAdaptationSet->GetId())
+ {
+ this->audioAdaptationSet = adaptationSets.at(i);
+ return;
+ }
+ }
+ //Not found in the new set of adaptation logc => select the first one
+ this->audioAdaptationSet = adaptationSets.at(0);
+
+ }
+ else
+ {
+ if(!adaptationSets.empty())
+ {
+ this->audioAdaptationSet = adaptationSets.at(0);
+ return;
+ }
+ this->audioAdaptationSet = NULL;
+ }
+}
+
+void MPDWrapper::findVideoRepresentation (IMPD* mpd)
+{
+ if(this->videoAdaptationSet)
+ {
+ std::vector<IRepresentation *> representations = this->videoAdaptationSet->GetRepresentation();
+ if(this->videoRepresentation)
+ {
+ uint32_t time = this->videoRepresentations->find(this->videoRepresentation)->second->getTime(this->videoSegmentNumber);
+ uint32_t id = std::stoi(this->videoRepresentation->GetId());
+ for(size_t i = 0; i < representations.size(); i++)
+ {
+ if(id == std::stoi(representations.at(i)->GetId()))
+ {
+ this->videoRepresentation = representations.at(i);
+ this->destroyAdaptationSetStream(viper::managers::StreamType::VIDEO);
+ this->initializeAdaptationSetStreamWithoutLock(viper::managers::StreamType::VIDEO, mpd);
+ this->videoSegmentNumber = this->videoRepresentations->find(this->videoRepresentation)->second->getSegmentNumber(time);
+ return;
+ }
+ }
+ this->destroyAdaptationSetStream(viper::managers::StreamType::VIDEO);
+ }
+ this->videoRepresentation = representations.at(0);
+ this->initializeAdaptationSetStreamWithoutLock(viper::managers::StreamType::VIDEO, mpd);
+ this->videoSegmentNumber = this->videoRepresentations->find(this->videoRepresentation)->second->getSegmentNumber(time);
+ }
+ else
+ {
+ this->videoRepresentation = NULL;
+ }
+}
+
+void MPDWrapper::findAudioRepresentation (IMPD* mpd)
+{
+ if(this->audioAdaptationSet)
+ {
+ std::vector<IRepresentation *> representations = this->audioAdaptationSet->GetRepresentation();
+ if(this->audioRepresentation)
+ {
+ uint32_t time = this->audioRepresentations->find(this->audioRepresentation)->second->getTime(this->audioSegmentNumber);
+ uint32_t id = std::stoi(this->audioRepresentation->GetId());
+ for(size_t i = 0; i < representations.size(); i++)
+ {
+ if(id == std::stoi(representations.at(i)->GetId()))
+ {
+ this->videoRepresentation = representations.at(i);
+ this->destroyAdaptationSetStream(viper::managers::StreamType::AUDIO);
+ this->initializeAdaptationSetStreamWithoutLock(viper::managers::StreamType::AUDIO, mpd);
+ this->audioSegmentNumber = this->audioRepresentations->find(this->audioRepresentation)->second->getSegmentNumber(time);
+ return;
+ }
+ }
+ this->destroyAdaptationSetStream(viper::managers::StreamType::AUDIO);
+ }
+ this->audioRepresentation = representations.at(0);
+ this->initializeAdaptationSetStreamWithoutLock(viper::managers::StreamType::AUDIO,mpd);
+ this->audioSegmentNumber = this->audioRepresentations->find(this->audioRepresentation)->second->getSegmentNumber(time);
+ }
+ else
+ {
+ this->audioRepresentation = NULL;
+ }
+}
+
+std::string MPDWrapper::getType ()
+{
+ std::string type;
+ EnterCriticalSection(&this->monitorMutex);
+ type = this->mpd->GetType();
+ LeaveCriticalSection(&this->monitorMutex);
+ return type;
+}
+
+
+void MPDWrapper::reInit (viper::managers::StreamType type)
+{
+ EnterCriticalSection(&this->monitorMutex);
+ switch(type)
+ {
+ case viper::managers::StreamType::VIDEO:
+ {
+ this->period = NULL;
+ this->videoAdaptationSet = NULL;
+ this->videoRepresentation = NULL;
+ break;
+ }
+ case viper::managers::StreamType::AUDIO:
+ {
+ this->period = NULL;
+ this->audioAdaptationSet = NULL;
+ this->audioRepresentation = NULL;
+ break;
+ }
+ default:
+ break;
+ }
+ LeaveCriticalSection(&this->monitorMutex);
+}
+
+bool MPDWrapper::hasVideoAdaptationSetAndVideoRepresentation ()
+{
+ EnterCriticalSection(&this->monitorMutex);
+ if(this->videoAdaptationSet && this->videoRepresentation)
+ {
+ LeaveCriticalSection(&this->monitorMutex);
+ return 1;
+ }
+ LeaveCriticalSection(&this->monitorMutex);
+ return 0;
+}
+
+bool MPDWrapper::hasAudioAdaptationSetAndAudioRepresentation ()
+{
+ EnterCriticalSection(&this->monitorMutex);
+ if(this->audioAdaptationSet && this->audioRepresentation)
+ {
+ LeaveCriticalSection(&this->monitorMutex);
+ return 1;
+ }
+ LeaveCriticalSection(&this->monitorMutex);
+ return 0;
+}
+
+RepresentationStreamType MPDWrapper::determineRepresentationStreamType (IRepresentation *representation, IAdaptationSet *adaptationSet, IPeriod* period)
+{
+ /* check on Representation Level */
+ if (representation->GetSegmentList())
+ return libdash::framework::mpd::SegmentList;
+
+ if (representation->GetSegmentTemplate())
+ return libdash::framework::mpd::SegmentTemplate;
+
+ if (representation->GetSegmentBase() || representation->GetBaseURLs().size() > 0)
+ return libdash::framework::mpd::SingleMediaSegment;
+
+ /* check on AdaptationSet Level */
+ if (adaptationSet->GetSegmentList())
+ return libdash::framework::mpd::SegmentList;
+
+ if (adaptationSet->GetSegmentTemplate())
+ return libdash::framework::mpd::SegmentTemplate;
+
+ if (adaptationSet->GetSegmentBase())
+ return libdash::framework::mpd::SingleMediaSegment;
+
+ /* check on Period Level */
+ if (period->GetSegmentList())
+ return libdash::framework::mpd::SegmentList;
+
+ if (period->GetSegmentTemplate())
+ return libdash::framework::mpd::SegmentTemplate;
+
+ if (period->GetSegmentBase())
+ return libdash::framework::mpd::SingleMediaSegment;
+
+ return libdash::framework::mpd::UNDEFINED;
+}
+
+void MPDWrapper::initializeAdaptationSetStream (viper::managers::StreamType type)
+{
+ IAdaptationSet *adaptationSet = NULL;
+ std::map<dash::mpd::IRepresentation *, IRepresentationStream *> *representations = NULL;
+ EnterCriticalSection(&this->monitorMutex);
+
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ if(this->audioRepresentations == NULL)
+ this->audioRepresentations = new std::map<dash::mpd::IRepresentation *, IRepresentationStream *>();
+ if(this->audioAdaptationSet == NULL)
+ return;
+ adaptationSet = this->audioAdaptationSet;
+ representations = this->audioRepresentations;
+ break;
+ case viper::managers::StreamType::VIDEO:
+ if(this->videoRepresentations == NULL)
+ this->videoRepresentations = new std::map<dash::mpd::IRepresentation *, IRepresentationStream *>();
+ if(this->videoAdaptationSet == NULL)
+ return;
+ adaptationSet = this->videoAdaptationSet;
+ representations = this->videoRepresentations;
+ break;
+ default:
+ return;
+ }
+
+ for (size_t i = 0; i < adaptationSet->GetRepresentation().size(); i++)
+ {
+ IRepresentation *representation = adaptationSet->GetRepresentation().at(i);
+ RepresentationStreamType typeR = determineRepresentationStreamType(representation, adaptationSet, this->period);
+ (*representations)[representation] = RepresentationStreamFactory::create(type, typeR, this, period, adaptationSet, representation);
+ }
+ LeaveCriticalSection(&this->monitorMutex);
+}
+
+void MPDWrapper::initializeAdaptationSetStreamWithoutLock (viper::managers::StreamType type)
+{
+ IAdaptationSet *adaptationSet = NULL;
+ std::map<dash::mpd::IRepresentation *, IRepresentationStream *> *representations = NULL;
+
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ if(this->audioRepresentations == NULL)
+ this->audioRepresentations = new std::map<dash::mpd::IRepresentation *, IRepresentationStream *>();
+ if(this->audioAdaptationSet == NULL)
+ return;
+ adaptationSet = this->audioAdaptationSet;
+ representations = this->audioRepresentations;
+ break;
+ case viper::managers::StreamType::VIDEO:
+ if(this->videoRepresentations == NULL)
+ this->videoRepresentations = new std::map<dash::mpd::IRepresentation *, IRepresentationStream *>();
+ if(this->videoAdaptationSet == NULL)
+ return;
+ adaptationSet = this->videoAdaptationSet;
+ representations = this->videoRepresentations;
+ break;
+ default:
+ return;
+ }
+ for (size_t i = 0; i < adaptationSet->GetRepresentation().size(); i++)
+ {
+ IRepresentation *representation = adaptationSet->GetRepresentation().at(i);
+ RepresentationStreamType typeR = determineRepresentationStreamType(representation, adaptationSet, this->period);
+ (*representations)[representation] = RepresentationStreamFactory::create(type, typeR, this, period, adaptationSet, representation);
+ }
+}
+
+void MPDWrapper::initializeAdaptationSetStreamWithoutLock (viper::managers::StreamType type, IMPD* mpd)
+{
+ IAdaptationSet *adaptationSet = NULL;
+ std::map<dash::mpd::IRepresentation *, IRepresentationStream *> *representations = NULL;
+
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ if(this->audioRepresentations == NULL)
+ this->audioRepresentations = new std::map<dash::mpd::IRepresentation *, IRepresentationStream *>();
+ if(this->audioAdaptationSet == NULL)
+ return;
+ adaptationSet = this->audioAdaptationSet;
+ representations = this->audioRepresentations;
+ break;
+ case viper::managers::StreamType::VIDEO:
+ if(this->videoRepresentations == NULL)
+ this->videoRepresentations = new std::map<dash::mpd::IRepresentation *, IRepresentationStream *>();
+ if(this->videoAdaptationSet == NULL)
+ return;
+ adaptationSet = this->videoAdaptationSet;
+ representations = this->videoRepresentations;
+ break;
+ default:
+ return;
+ }
+ for (size_t i = 0; i < adaptationSet->GetRepresentation().size(); i++)
+ {
+ IRepresentation *representation = adaptationSet->GetRepresentation().at(i);
+ RepresentationStreamType typeR = determineRepresentationStreamType(representation, adaptationSet, this->period);
+ (*representations)[representation] = RepresentationStreamFactory::create(type, typeR, this, period, adaptationSet, representation, mpd);
+ }
+}
+
+void MPDWrapper::destroyAdaptationSetStream (viper::managers::StreamType type)
+{
+ std::map<dash::mpd::IRepresentation *, IRepresentationStream *> *representations = NULL;
+
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ representations = this->audioRepresentations;
+ break;
+ case viper::managers::StreamType::VIDEO:
+ representations = this->videoRepresentations;
+ break;
+ default:
+ return;
+ }
+
+ std::map<IRepresentation *, IRepresentationStream *>::iterator iter;
+ for (iter = representations->begin(); iter != representations->end(); ++iter)
+ {
+ delete(iter->second);
+ }
+ representations->clear();
+}
+
+std::vector<dash::mpd::IBaseUrl *> MPDWrapper::resolveBaseUrl (viper::managers::StreamType type, size_t mpdBaseUrl, size_t periodBaseUrl, size_t adaptationSetBaseUrl)
+{
+
+ IAdaptationSet *adaptationSet = NULL;
+ std::vector<dash::mpd::IBaseUrl *> urls;
+
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ adaptationSet = this->audioAdaptationSet;
+ break;
+ case viper::managers::StreamType::VIDEO:
+ adaptationSet = this->videoAdaptationSet;
+ break;
+ default:
+ return urls;
+ }
+
+ if(adaptationSet == NULL)
+ return urls;
+
+ if (mpd->GetBaseUrls().size() > 0)
+ {
+ if (mpd->GetBaseUrls().size() > mpdBaseUrl)
+ urls.push_back(mpd->GetBaseUrls().at(mpdBaseUrl));
+ else
+ urls.push_back(mpd->GetBaseUrls().at(0));
+ }
+ if (period->GetBaseURLs().size() > 0)
+ {
+ if (period->GetBaseURLs().size() > periodBaseUrl)
+ urls.push_back(period->GetBaseURLs().at(periodBaseUrl));
+ else
+ urls.push_back(period->GetBaseURLs().at(0));
+ }
+ if (adaptationSet->GetBaseURLs().size() > 0)
+ {
+ if (adaptationSet->GetBaseURLs().size() > adaptationSetBaseUrl)
+ urls.push_back(adaptationSet->GetBaseURLs().at(adaptationSetBaseUrl));
+ else
+ urls.push_back(adaptationSet->GetBaseURLs().at(0));
+ }
+
+ if (urls.size() > 0)
+ {
+ if (urls.at(0)->GetUrl().substr(0,7) != "http://" && urls.at(0)->GetUrl().substr(0,8) != "https://")
+ {
+ urls.push_back(mpd->GetMPDPathBaseUrl());
+ size_t lastPos = urls.size() - 1;
+ IBaseUrl *absoluteUrl = urls.at(lastPos);
+ for (size_t i = lastPos; i > 0; i--)
+ {
+ urls[i] = urls[i-1];
+ }
+ urls[0] = absoluteUrl;
+ }
+ }
+ else
+ {
+ urls.push_back(mpd->GetMPDPathBaseUrl());
+ }
+
+ return urls;
+}
+
+std::vector<dash::mpd::IBaseUrl *> MPDWrapper::resolveBaseUrl (viper::managers::StreamType type, size_t mpdBaseUrl, size_t periodBaseUrl, size_t adaptationSetBaseUrl, IMPD* mpd)
+{
+
+ IAdaptationSet *adaptationSet = NULL;
+ std::vector<dash::mpd::IBaseUrl *> urls;
+
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ adaptationSet = this->audioAdaptationSet;
+ break;
+ case viper::managers::StreamType::VIDEO:
+ adaptationSet = this->videoAdaptationSet;
+ break;
+ default:
+ return urls;
+ }
+
+ if(adaptationSet == NULL)
+ return urls;
+
+ if (mpd->GetBaseUrls().size() > 0)
+ {
+ if (mpd->GetBaseUrls().size() > mpdBaseUrl)
+ urls.push_back(mpd->GetBaseUrls().at(mpdBaseUrl));
+ else
+ urls.push_back(mpd->GetBaseUrls().at(0));
+ }
+ if (period->GetBaseURLs().size() > 0)
+ {
+ if (period->GetBaseURLs().size() > periodBaseUrl)
+ urls.push_back(period->GetBaseURLs().at(periodBaseUrl));
+ else
+ urls.push_back(period->GetBaseURLs().at(0));
+ }
+ if (adaptationSet->GetBaseURLs().size() > 0)
+ {
+ if (adaptationSet->GetBaseURLs().size() > adaptationSetBaseUrl)
+ urls.push_back(adaptationSet->GetBaseURLs().at(adaptationSetBaseUrl));
+ else
+ urls.push_back(adaptationSet->GetBaseURLs().at(0));
+ }
+
+ if (urls.size() > 0)
+ {
+ if (urls.at(0)->GetUrl().substr(0,7) != "http://" && urls.at(0)->GetUrl().substr(0,8) != "https://")
+ {
+ urls.push_back(mpd->GetMPDPathBaseUrl());
+ size_t lastPos = urls.size() - 1;
+ IBaseUrl *absoluteUrl = urls.at(lastPos);
+ for (size_t i = lastPos; i > 0; i--)
+ {
+ urls[i] = urls[i-1];
+ }
+ urls[0] = absoluteUrl;
+ }
+ }
+ else
+ {
+ urls.push_back(mpd->GetMPDPathBaseUrl());
+ }
+
+ return urls;
+}
+
+void MPDWrapper::acquireLock ()
+{
+ EnterCriticalSection(&this->monitorMutex);
+}
+
+
+void MPDWrapper::releaseLock ()
+{
+ LeaveCriticalSection(&this->monitorMutex);
+}
+
+void MPDWrapper::setSegmentOffset(viper::managers::StreamType type, uint32_t segmentOffset)
+{
+ EnterCriticalSection(&this->monitorMutex);
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ this->audioSegmentOffset = segmentOffset;
+ this->audioRepresentations->find(this->audioRepresentation)->second->setSegmentOffset(segmentOffset);
+ break;
+ case viper::managers::StreamType::VIDEO:
+ this->videoSegmentOffset = segmentOffset;
+ this->videoRepresentations->find(this->videoRepresentation)->second->setSegmentOffset(segmentOffset);
+ break;
+ default:
+ break;
+ }
+ LeaveCriticalSection(&this->monitorMutex);
+}
+
+MediaObject* MPDWrapper::getNextSegment (viper::managers::StreamType type, bool isLooping, uint32_t &segmentNumber, bool withFeedBack)
+{
+ IRepresentation* representation;
+ std::map<dash::mpd::IRepresentation *, IRepresentationStream *> *representations;
+
+ EnterCriticalSection(&this->monitorMutex);
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ representation = this->audioRepresentation;
+ representations = this->audioRepresentations;
+ break;
+ case viper::managers::StreamType::VIDEO:
+ representation = this->videoRepresentation;
+ representations = this->videoRepresentations;
+ break;
+ default:
+ LeaveCriticalSection(&this->monitorMutex);
+ return NULL;
+ }
+
+ ISegment* seg = NULL;
+ IRepresentationStream* representationStream = representations->find(representation)->second;
+
+ if(!strcmp(this->mpd->GetType().c_str(), "static"))
+ {
+ if(segmentNumber >= representationStream->getSize())
+ {
+ if(isLooping)
+ {
+ segmentNumber = 0;
+ }
+ else
+ {
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ this->audioSegmentNumber = segmentNumber;
+ break;
+ case viper::managers::StreamType::VIDEO:
+ this->videoSegmentNumber = segmentNumber;
+ break;
+ default:
+ break;
+ }
+ LeaveCriticalSection(&this->monitorMutex);
+ return NULL;
+ }
+ }
+ }
+ else
+ {
+ while((this->isStopping == false) && segmentNumber >= representationStream->getSize())
+ {
+ SleepConditionVariableCS(&this->mpdUpdate, &this->monitorMutex, INFINITE);
+
+ if(this->isStopping)
+ {
+ LeaveCriticalSection(&this->monitorMutex);
+ return NULL;
+ }
+
+ //Need to update representationStream here as it was updated with the mpd:
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ representation = this->audioRepresentation;
+ representations = this->audioRepresentations;
+ break;
+ case viper::managers::StreamType::VIDEO:
+ representation = this->videoRepresentation;
+ representations = this->videoRepresentations;
+ break;
+ default:
+ break;
+ }
+ representationStream = representations->find(representation)->second;
+ }
+ }
+ seg = representationStream->getMediaSegment(segmentNumber);
+ if(seg != NULL)
+ {
+ MediaObject *media = new MediaObject(seg, representation, withFeedBack);
+ segmentNumber++;
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ this->audioSegmentNumber = segmentNumber;
+ break;
+ case viper::managers::StreamType::VIDEO:
+ this->videoSegmentNumber = segmentNumber;
+ break;
+ default:
+ break;
+ }
+ LeaveCriticalSection(&this->monitorMutex);
+ return media;
+ }
+ LeaveCriticalSection(&this->monitorMutex);
+ return NULL;
+}
+
+MediaObject* MPDWrapper::getSegment (viper::managers::StreamType type, uint32_t segNum)
+{
+ IRepresentation* representation;
+ std::map<dash::mpd::IRepresentation *, IRepresentationStream *> *representations;
+ EnterCriticalSection(&this->monitorMutex);
+
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ representation = this->audioRepresentation;
+ representations = this->audioRepresentations;
+ break;
+ case viper::managers::StreamType::VIDEO:
+ representation = this->videoRepresentation;
+ representations = this->videoRepresentations;
+ break;
+ default:
+ LeaveCriticalSection(&this->monitorMutex);
+ return NULL;
+ }
+
+ ISegment* seg = NULL;
+ IRepresentationStream* representationStream = representations->find(representation)->second;
+ if(segNum >= representationStream->getSize())
+ {
+ LeaveCriticalSection(&this->monitorMutex);
+ return NULL;
+ }
+ seg = representationStream->getMediaSegment(segNum);
+ if(seg != NULL)
+ {
+ MediaObject *media = new MediaObject(seg, representation);
+ LeaveCriticalSection(&this->monitorMutex);
+ return media;
+ }
+ LeaveCriticalSection(&this->monitorMutex);
+ return NULL;
+}
+
+MediaObject* MPDWrapper::getInitSegment (viper::managers::StreamType type)
+{
+ IRepresentation* representation;
+ std::map<dash::mpd::IRepresentation *, IRepresentationStream *> *representations;
+ EnterCriticalSection(&this->monitorMutex);
+
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ representation = this->audioRepresentation;
+ representations = this->audioRepresentations;
+ break;
+ case viper::managers::StreamType::VIDEO:
+ representation = this->videoRepresentation;
+ representations = this->videoRepresentations;
+ break;
+ default:
+ LeaveCriticalSection(&this->monitorMutex);
+ return NULL;
+ }
+
+ ISegment* seg = NULL;
+ IRepresentationStream* representationStream = representations->find(representation)->second;
+ seg = representationStream->getInitializationSegment();
+
+ if(seg != NULL)
+ {
+ MediaObject *media = new MediaObject(seg, representation);
+ LeaveCriticalSection(&this->monitorMutex);
+ return media;
+ }
+ LeaveCriticalSection(&this->monitorMutex);
+ return NULL;
+}
+
+void MPDWrapper::setQuality(viper::managers::StreamType type, IPeriod* period, IAdaptationSet *adaptationSet, IRepresentation *representation)
+{
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ this->setAudioQuality(period, adaptationSet, representation);
+ break;
+ case viper::managers::StreamType::VIDEO:
+ this->setVideoQuality(period, adaptationSet, representation);
+ break;
+ default:
+ return;
+ }
+}
+
+void MPDWrapper::setAudioQuality (IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation)
+{
+ bool periodChanged = false;
+ if (this->audioRepresentation == representation)
+ {
+ LeaveCriticalSection(&this->monitorMutex);
+ return;
+ }
+
+ this->audioRepresentation = representation;
+
+ if (this->audioAdaptationSet != adaptationSet)
+ {
+ this->audioAdaptationSet = adaptationSet;
+
+ if (this->period != period)
+ {
+ this->period = period;
+ periodChanged = true;
+ }
+
+ this->destroyAdaptationSetStream(viper::managers::StreamType::AUDIO);
+ this->initializeAdaptationSetStreamWithoutLock(viper::managers::StreamType::AUDIO);
+ }
+}
+
+void MPDWrapper::setVideoQuality (IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation)
+{
+ bool periodChanged = false;
+ if (this->videoRepresentation == representation)
+ {
+ LeaveCriticalSection(&this->monitorMutex);
+ return;
+ }
+
+ this->videoRepresentation = representation;
+
+ if (this->videoAdaptationSet != adaptationSet)
+ {
+ this->videoAdaptationSet = adaptationSet;
+
+ if (this->period != period)
+ {
+ this->period = period;
+ periodChanged = true;
+ }
+
+ this->destroyAdaptationSetStream(viper::managers::StreamType::VIDEO);
+ this->initializeAdaptationSetStreamWithoutLock(viper::managers::StreamType::VIDEO);
+ }
+}
+
+uint32_t MPDWrapper::calculateSegmentOffset (viper::managers::StreamType type, uint32_t bufferSize)
+{
+ IRepresentation* representation;
+ std::map<dash::mpd::IRepresentation *, IRepresentationStream *> *representations;
+ EnterCriticalSection(&this->monitorMutex);
+
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ representation = this->audioRepresentation;
+ representations = this->audioRepresentations;
+ break;
+ case viper::managers::StreamType::VIDEO:
+ representation = this->videoRepresentation;
+ representations = this->videoRepresentations;
+ break;
+ default:
+ LeaveCriticalSection(&this->monitorMutex);
+ return 0;
+ }
+
+ if(!(strcmp(this->mpd->GetType().c_str(), "static")))
+ {
+ LeaveCriticalSection(&this->monitorMutex);
+ return 0;
+ }
+ IRepresentationStream* representationStream = representations->find(representation)->second;
+ uint32_t firstSegNum = representationStream->getFirstSegmentNumber();
+ uint32_t currSegNum = representationStream->getCurrentSegmentNumber();
+ uint32_t startSegNum = currSegNum - 2*bufferSize;
+
+ LeaveCriticalSection(&this->monitorMutex);
+ return (startSegNum > firstSegNum) ? startSegNum : firstSegNum;
+}
+
+std::string MPDWrapper::getRepresentationID (viper::managers::StreamType type)
+{
+ std::string id = "";
+ EnterCriticalSection(&this->monitorMutex);
+
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ id = this->audioRepresentation->GetId();
+ break;
+ case viper::managers::StreamType::VIDEO:
+ id = this->videoRepresentation->GetId();
+ break;
+ default:
+ break;
+ }
+ LeaveCriticalSection(&this->monitorMutex);
+ return id;
+}
+
+std::string MPDWrapper::getPublishTime ()
+{
+ EnterCriticalSection(&this->monitorMutex);
+ std::string pubTime = this->mpd->GetPublishTime();
+ LeaveCriticalSection(&this->monitorMutex);
+ return pubTime;
+}
+
+std::string MPDWrapper::getMinimumUpdatePeriod ()
+{
+ EnterCriticalSection(&this->monitorMutex);
+ std::string res = this->mpd->GetMinimumUpdatePeriod();
+ LeaveCriticalSection(&this->monitorMutex);
+ return res;
+}
+
+
+/*******************************************
+********************************************
+***** CAREFUL *****
+***** These functions should be called *****
+***** only if the lock was acquired!!! *****
+***** *****
+********************************************
+*******************************************/
+
+std::vector<IRepresentation *> MPDWrapper::getRepresentations (viper::managers::StreamType type)
+{
+ std::vector<IRepresentation *> rep;
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ if(this->audioAdaptationSet)
+ return this->audioAdaptationSet->GetRepresentation();
+ return rep;
+ case viper::managers::StreamType::VIDEO:
+ if(this->videoAdaptationSet)
+ return this->videoAdaptationSet->GetRepresentation();
+ return rep;
+ default:
+ return rep;
+ }
+}
+
+std::string MPDWrapper::getMediaPresentationDuration ()
+{
+ return this->mpd->GetMediaPresentationDuration();
+}
+
+IRepresentation* MPDWrapper::getRepresentationAt (viper::managers::StreamType type, int index)
+{
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ if(this->audioAdaptationSet)
+ return this->audioAdaptationSet->GetRepresentation().at(index);
+ return NULL;
+ case viper::managers::StreamType::VIDEO:
+ if(this->videoAdaptationSet)
+ return this->videoAdaptationSet->GetRepresentation().at(index);
+ return NULL;
+ default:
+ return NULL;
+ }
+}
+
+void MPDWrapper::setRepresentation (viper::managers::StreamType type, IRepresentation* rep)
+{
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ this->audioRepresentation = rep;
+ return;
+ case viper::managers::StreamType::VIDEO:
+ this->videoRepresentation = rep;
+ return;
+ default:
+ break;
+ }
+}
+
+std::string MPDWrapper::getRepresentationIDWithoutLock (viper::managers::StreamType type)
+{
+ std::string id = "";
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ id = this->audioRepresentation->GetId();
+ break;
+ case viper::managers::StreamType::VIDEO:
+ id = this->videoRepresentation->GetId();
+ break;
+ default:
+ break;
+ }
+ return id;
+}
+
+MediaObject* MPDWrapper::getInitSegmentWithoutLock (viper::managers::StreamType type)
+{
+ IRepresentation* representation;
+ std::map<dash::mpd::IRepresentation *, IRepresentationStream *> *representations;
+
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ representation = this->audioRepresentation;
+ representations = this->audioRepresentations;
+ break;
+ case viper::managers::StreamType::VIDEO:
+ representation = this->videoRepresentation;
+ representations = this->videoRepresentations;
+ break;
+ default:
+ return NULL;
+ }
+ ISegment* seg = NULL;
+ IRepresentationStream* representationStream = representations->find(representation)->second;
+ seg = representationStream->getInitializationSegment();
+
+ if(seg != NULL)
+ {
+ MediaObject *media = new MediaObject(seg, representation);
+ return media;
+ }
+ return NULL;
+}
+
+std::string MPDWrapper::getAvailabilityStarttime ()
+{
+ return this->mpd->GetAvailabilityStarttime();
+}
+
+std::string MPDWrapper::getTimeShiftBufferDepth ()
+{
+ return this->mpd->GetTimeShiftBufferDepth();
+}
+
+std::string MPDWrapper::getTypeWithoutLock ()
+{
+ return this->mpd->GetType();
+}
+
+std::string MPDWrapper::getMinimumUpdatePeriodWithoutLock ()
+{
+ return this->mpd->GetMinimumUpdatePeriod();
+}
+
+uint32_t MPDWrapper::getFetchTime ()
+{
+ return this->mpd->GetFetchTime();
+}
+
+void MPDWrapper::settingsChanged (int period, int videoAdaptationSet, int videoRepresentation, int audioAdaptationSet, int audioRepresentation)
+{
+ EnterCriticalSection(&this->monitorMutex);
+ this->period = this->mpd->GetPeriods().at(period);
+ std::vector<IAdaptationSet *> videoAdaptationSets = AdaptationSetHelper::getVideoAdaptationSets(this->period);
+ std::vector<IAdaptationSet *> audioAdaptationSets = AdaptationSetHelper::getAudioAdaptationSets(this->period);
+ if (videoAdaptationSet >= 0 && videoRepresentation >= 0 && !videoAdaptationSets.empty())
+ {
+ this->videoAdaptationSet = videoAdaptationSets.at(videoAdaptationSet);
+ this->videoRepresentation = this->videoAdaptationSet->GetRepresentation().at(videoRepresentation);
+ }
+ else
+ {
+ this->videoAdaptationSet = NULL;
+ this->videoRepresentation = NULL;
+ }
+ if (audioAdaptationSet >= 0 && audioRepresentation >= 0 && !audioAdaptationSets.empty())
+ {
+ this->audioAdaptationSet = audioAdaptationSets.at(audioAdaptationSet);
+ this->audioRepresentation = this->audioAdaptationSet->GetRepresentation().at(audioRepresentation);
+ }
+ else
+ {
+ this->audioAdaptationSet = NULL;
+ this->audioRepresentation = NULL;
+ }
+ LeaveCriticalSection(&this->monitorMutex);
+}
+
+//Returns the segmentDuration
+float MPDWrapper::onFirstDownloadMPD (viper::IViperGui *gui)
+{
+ float segmentDuration = 0.0;
+ EnterCriticalSection(&this->monitorMutex);
+ IRepresentation *representation = this->videoAdaptationSet->GetRepresentation().at(0);
+ if(!strcmp(this->mpd->GetType().c_str(), "static")) // VOD MPD
+ {
+ if(representation->GetSegmentList())
+ {
+ uint32_t duration = representation->GetSegmentList()->GetDuration();
+ uint32_t timescale = representation->GetSegmentList()->GetTimescale();
+ segmentDuration = 1.0*duration/(1.0*timescale) * 1000;
+ if(gui)
+ {
+ gui->setListSegmentSize(representation->GetSegmentList()->GetSegmentURLs().size());
+ gui->setSegmentDuration(segmentDuration);
+ }
+ }
+ else //SegmentTemplate
+ {
+ uint32_t duration = representation->GetSegmentTemplate()->GetDuration();
+ uint32_t timescale = representation->GetSegmentTemplate()->GetTimescale();
+ segmentDuration = 1.0*duration/(1.0*timescale) * 1000;
+ if(gui)
+ {
+ gui->setSegmentDuration(segmentDuration);
+ gui->setListSegmentSize(TimeResolver::getDurationInSec(period->GetDuration())*1000/segmentDuration + 1);
+ }
+ }
+ }
+ else //Live MPD
+ {
+ //Assuming here that the segment duration doesn't change. If so, need to do an average over all segments.
+ uint32_t duration = representation->GetSegmentTemplate()->GetSegmentTimeline()->GetTimelines().at(0)->GetDuration();
+ uint32_t timescale = representation->GetSegmentTemplate()->GetTimescale();
+ segmentDuration = 1.0*duration/(1.0*timescale) * 1000;
+ if(gui)
+ {
+ gui->setSegmentDuration(segmentDuration);
+ gui->setListSegmentSize(0);
+ }
+ }
+ LeaveCriticalSection(&this->monitorMutex);
+ return segmentDuration;
+}
+
+void MPDWrapper::setIsStopping (bool isStopping)
+{
+ this->isStopping = isStopping;
+ WakeAllConditionVariable(&this->mpdUpdate);
+}
diff --git a/MPD/MPDWrapper.h b/MPD/MPDWrapper.h
new file mode 100644
index 00000000..902fa3dc
--- /dev/null
+++ b/MPD/MPDWrapper.h
@@ -0,0 +1,134 @@
+/*
+ * MPDWrapper.h
+ *****************************************************************************
+ * Copyright (C) 2017, Cisco Systems France
+ *
+ * Email: cicn-dev@lists.fd.io
+ *
+ * This source code and its use and distribution, is subject to the terms
+ * and conditions of the applicable license agreement.
+ *****************************************************************************/
+
+
+#ifndef LIBDASH_FRAMEWORK_MPD_MPDWRAPPER_H_
+#define LIBDASH_FRAMEWORK_MPD_MPDWRAPPER_H_
+//TODO: fix the circular includes
+namespace viper
+{
+class ViperGui;
+}
+namespace libdash
+{
+namespace framework
+{
+namespace mpd
+{
+class MPDWrapper;
+}
+namespace input
+{
+class MediaObject;
+class DASHReceiver;
+}
+namespace adaptation
+{
+class IAdaptationLogic;
+}
+}
+}
+#include "IMPD.h"
+#include "IMPDWrapper.h"
+#include "../Portable/MultiThreading.h"
+#include "../Managers/IStreamObserver.h"
+#include "../UI/IViperGui.h"
+#include "IRepresentationStream.h"
+#include "IRepresentation.h"
+#include "IPeriod.h"
+#include "IAdaptationSet.h"
+#include "RepresentationStreamFactory.h"
+#include "../Input/MediaObject.h"
+#include "AdaptationSetHelper.h"
+
+
+namespace libdash
+{
+namespace framework
+{
+namespace mpd
+{
+class MPDWrapper : public IMPDWrapper
+{
+public:
+ MPDWrapper(dash::mpd::IMPD *mpd);
+ ~MPDWrapper();
+
+ dash::mpd::IMPD* getMPD();
+ void updateMPD(dash::mpd::IMPD* mpd);
+ std::string getType();
+ void reInit(viper::managers::StreamType type);
+ void setVideoQuality(dash::mpd::IPeriod* period, dash::mpd::IAdaptationSet* adaptationSet, dash::mpd::IRepresentation* representation);
+ void setAudioQuality(dash::mpd::IPeriod* period, dash::mpd::IAdaptationSet* adaptationSet, dash::mpd::IRepresentation* representation);
+ bool hasAudioAdaptationSetAndAudioRepresentation();
+ bool hasVideoAdaptationSetAndVideoRepresentation();
+ void initializeAdaptationSetStream(viper::managers::StreamType type);
+// void initializeAdaptationSetStream(viper::managers::StreamType type, dash::mpd::IMPD* mpd);
+ void destroyAdaptationSetStream(viper::managers::StreamType type);
+ void acquireLock();
+ void releaseLock();
+ void setSegmentOffset(viper::managers::StreamType type, uint32_t segmentOffset);
+ void findVideoAdaptationSet(dash::mpd::IMPD* mpd);
+ void findAudioAdaptationSet(dash::mpd::IMPD* mpd);
+ void findVideoRepresentation(dash::mpd::IMPD* mpd);
+ void findAudioRepresentation(dash::mpd::IMPD* mpd);
+ void initializeAdaptationSetStreamWithoutLock(viper::managers::StreamType type);
+ void initializeAdaptationSetStreamWithoutLock(viper::managers::StreamType type, dash::mpd::IMPD* mpd);
+ std::vector<dash::mpd::IBaseUrl *> resolveBaseUrl(viper::managers::StreamType type, size_t mpdBaseUrl, size_t periodBaseUrl, size_t adaptationSetBaseUrl);
+ std::vector<dash::mpd::IBaseUrl *> resolveBaseUrl(viper::managers::StreamType type, size_t mpdBaseUrl, size_t periodBaseUrl, size_t adaptationSetBaseUrl, dash::mpd::IMPD* mpd);
+ libdash::framework::input::MediaObject* getNextSegment(viper::managers::StreamType type, bool isLooping, uint32_t &segmentNumber, bool withFeedBack);
+ libdash::framework::input::MediaObject* getSegment(viper::managers::StreamType type, uint32_t segNum);
+ libdash::framework::input::MediaObject* getInitSegment(viper::managers::StreamType type);
+ void setQuality(viper::managers::StreamType type, dash::mpd::IPeriod* period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation);
+ uint32_t calculateSegmentOffset(viper::managers::StreamType type, uint32_t bufferSize);
+ std::string getRepresentationID(viper::managers::StreamType type);
+ std::string getPublishTime();
+ std::string getMinimumUpdatePeriod();
+ std::vector<dash::mpd::IRepresentation *> getRepresentations(viper::managers::StreamType type);
+ std::string getMediaPresentationDuration();
+ dash::mpd::IRepresentation* getRepresentationAt(viper::managers::StreamType type, int index);
+ void setRepresentation(viper::managers::StreamType type, dash::mpd::IRepresentation* rep);
+ std::string getRepresentationIDWithoutLock(viper::managers::StreamType type);
+ libdash::framework::input::MediaObject* getInitSegmentWithoutLock(viper::managers::StreamType type);
+ std::string getAvailabilityStarttime();
+ std::string getTimeShiftBufferDepth();
+ std::string getTypeWithoutLock();
+ std::string getMinimumUpdatePeriodWithoutLock();
+ uint32_t getFetchTime();
+ void settingsChanged(int period, int videoAdaptationSet, int videoRepresentation, int audioAdaptationSet, int audioRepresentation);
+ float onFirstDownloadMPD(viper::IViperGui *gui);
+ void setIsStopping(bool isStopping);
+
+private:
+ RepresentationStreamType determineRepresentationStreamType(dash::mpd::IRepresentation *representation, dash::mpd::IAdaptationSet* adaptationSet, dash::mpd::IPeriod* period);
+
+ dash::mpd::IMPD *mpd;
+ mutable CRITICAL_SECTION monitorMutex;
+ mutable CONDITION_VARIABLE mpdUpdate;
+ dash::mpd::IPeriod *period;
+ dash::mpd::IAdaptationSet *videoAdaptationSet;
+ dash::mpd::IRepresentation *videoRepresentation;
+ dash::mpd::IAdaptationSet *audioAdaptationSet;
+ dash::mpd::IRepresentation *audioRepresentation;
+ std::map<dash::mpd::IRepresentation *, IRepresentationStream *> *videoRepresentations;
+ std::map<dash::mpd::IRepresentation *, IRepresentationStream *> *audioRepresentations;
+ uint32_t videoSegmentOffset;
+ uint32_t audioSegmentOffset;
+ size_t videoSegmentNumber;
+ size_t audioSegmentNumber;
+ bool isStopping;
+};
+}
+}
+}
+
+#endif /* LIBDASH_FRAMEWORK_MPD_MPDWRAPPER_H_ */
+
diff --git a/MPD/RepresentationStreamFactory.cpp b/MPD/RepresentationStreamFactory.cpp
index b84bf558..e5c57ddd 100644
--- a/MPD/RepresentationStreamFactory.cpp
+++ b/MPD/RepresentationStreamFactory.cpp
@@ -14,14 +14,28 @@
using namespace libdash::framework::mpd;
using namespace dash::mpd;
-IRepresentationStream* RepresentationStreamFactory::create(RepresentationStreamType type, IMPD *mpd, IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation)
+IRepresentationStream* RepresentationStreamFactory::create(viper::managers::StreamType streamType, libdash::framework::mpd::RepresentationStreamType type, libdash::framework::mpd::MPDWrapper *mpdWrapper, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation, dash::mpd::IMPD* mpd)
{
- switch(type)
+ if(mpd)
{
- case SingleMediaSegment: return new SingleMediaSegmentStream(mpd, period, adaptationSet, representation);
- case SegmentList: return new SegmentListStream (mpd, period, adaptationSet, representation);
- case SegmentTemplate: return new SegmentTemplateStream (mpd, period, adaptationSet, representation);
+ switch(type)
+ {
+ case SingleMediaSegment: return new SingleMediaSegmentStream(streamType, mpdWrapper, period, adaptationSet, representation,mpd);
+ case SegmentList: return new SegmentListStream (streamType, mpdWrapper, period, adaptationSet, representation,mpd);
+ case SegmentTemplate: return new SegmentTemplateStream (streamType, mpdWrapper, period, adaptationSet, representation,mpd);
- default: return NULL;
+ default: return NULL;
+ }
+ }
+ else
+ {
+ switch(type)
+ {
+ case SingleMediaSegment: return new SingleMediaSegmentStream(streamType, mpdWrapper, period, adaptationSet, representation);
+ case SegmentList: return new SegmentListStream (streamType, mpdWrapper, period, adaptationSet, representation);
+ case SegmentTemplate: return new SegmentTemplateStream (streamType, mpdWrapper, period, adaptationSet, representation);
+
+ default: return NULL;
+ }
}
}
diff --git a/MPD/RepresentationStreamFactory.h b/MPD/RepresentationStreamFactory.h
index 22c70b96..e3eb137c 100644
--- a/MPD/RepresentationStreamFactory.h
+++ b/MPD/RepresentationStreamFactory.h
@@ -12,6 +12,8 @@
#ifndef LIBDASH_FRAMEWORK_MPD_RERPRESENTATIONSTREAMFACTORY_H_
#define LIBDASH_FRAMEWORK_MPD_RERPRESENTATIONSTREAMFACTORY_H_
+
+#include "../MPD/MPDWrapper.h"
#include "IRepresentationStream.h"
#include "SingleMediaSegmentStream.h"
#include "SegmentListStream.h"
@@ -27,8 +29,9 @@ namespace mpd
class RepresentationStreamFactory
{
public:
- static IRepresentationStream* create(libdash::framework::mpd::RepresentationStreamType type, dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period,
- dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation);
+ static IRepresentationStream* create(viper::managers::StreamType streamType, libdash::framework::mpd::RepresentationStreamType type, libdash::framework::mpd::MPDWrapper *mpdWrapper, dash::mpd::IPeriod *period,
+ dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation, dash::mpd::IMPD* mpd = NULL);
+// static IRepresentationStream* create(viper::managers::StreamType streamType, libdash::framework::mpd::RepresentationStreamType type, dash::mpd::MPDWrapper *mpdWrapper);
};
}
diff --git a/MPD/SegmentListStream.cpp b/MPD/SegmentListStream.cpp
index 3a475e71..c3530086 100644
--- a/MPD/SegmentListStream.cpp
+++ b/MPD/SegmentListStream.cpp
@@ -14,10 +14,19 @@
using namespace dash::mpd;
using namespace libdash::framework::mpd;
-SegmentListStream::SegmentListStream(IMPD *mpd, IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation) :
- AbstractRepresentationStream (mpd, period, adaptationSet, representation)
+SegmentListStream::SegmentListStream(viper::managers::StreamType type, MPDWrapper *mpdWrapper, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation) :
+ AbstractRepresentationStream (type, mpdWrapper, period, adaptationSet, representation)
{
- this->baseUrls = BaseUrlResolver::resolveBaseUrl(mpd, period, adaptationSet, 0, 0, 0);
+ this->baseUrls = BaseUrlResolver::resolveBaseUrl(type, mpdWrapper, 0, 0, 0);
+// this->baseUrls = mpdWrapper->resolveBaseUrl(type, mpdWrapper, 0, 0, 0);
+ this->segmentList = findSegmentList();
+}
+
+SegmentListStream::SegmentListStream(viper::managers::StreamType type, MPDWrapper *mpdWrapper, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation, dash::mpd::IMPD* mpd) :
+ AbstractRepresentationStream (type, mpdWrapper, period, adaptationSet, representation)
+{
+ this->baseUrls = BaseUrlResolver::resolveBaseUrl(type, mpdWrapper, 0, 0, 0, mpd);
+// this->baseUrls = mpdWrapper->resolveBaseUrl(type, mpdWrapper, 0, 0, 0);
this->segmentList = findSegmentList();
}
@@ -28,16 +37,19 @@ SegmentListStream::~SegmentListStream()
ISegment* SegmentListStream::getInitializationSegment()
{
if (this->segmentList->GetInitialization())
+ {
return this->segmentList->GetInitialization()->ToSegment(this->baseUrls);
-
+ }
return NULL;
}
ISegment* SegmentListStream::getIndexSegment(size_t segmentNumber)
{
if (this->segmentList->GetSegmentURLs().size() > segmentNumber)
+ {
+ this->mpdWrapper->releaseLock();
return this->segmentList->GetSegmentURLs().at(segmentNumber)->ToIndexSegment(this->baseUrls);
-
+ }
return NULL;
}
diff --git a/MPD/SegmentListStream.h b/MPD/SegmentListStream.h
index 323852f0..264ac9cc 100644
--- a/MPD/SegmentListStream.h
+++ b/MPD/SegmentListStream.h
@@ -12,7 +12,7 @@
#ifndef LIBDASH_FRAMEWORK_MPD_SEGMENTLISTSTREAM_H_
#define LIBDASH_FRAMEWORK_MPD_SEGMENTLISTSTREAM_H_
-#include "IMPD.h"
+#include "MPDWrapper.h"
#include "AbstractRepresentationStream.h"
#include "ISegment.h"
#include "ISegmentList.h"
@@ -26,7 +26,9 @@ namespace mpd
class SegmentListStream: public AbstractRepresentationStream
{
public:
- SegmentListStream(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation);
+ SegmentListStream(viper::managers::StreamType type, MPDWrapper *mpdWrapper, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation);
+ SegmentListStream(viper::managers::StreamType type, MPDWrapper *mpdWrapper, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation, dash::mpd::IMPD* mpd);
+// SegmentListStream(viper::managers::StreamType type, dash::mpd::MPDWrapper *mpdWrapper);
virtual ~SegmentListStream();
virtual dash::mpd::ISegment* getInitializationSegment();
@@ -38,8 +40,9 @@ public:
virtual uint32_t getAverageSegmentDuration();
private:
- dash::mpd::ISegmentList* findSegmentList();
- dash::mpd::ISegmentList *segmentList;
+ dash::mpd::ISegmentList *findSegmentList();
+
+ dash::mpd::ISegmentList *segmentList;
};
}
diff --git a/MPD/SegmentTemplateStream.cpp b/MPD/SegmentTemplateStream.cpp
index 66004294..a62a9bab 100644
--- a/MPD/SegmentTemplateStream.cpp
+++ b/MPD/SegmentTemplateStream.cpp
@@ -14,15 +14,28 @@
using namespace dash::mpd;
using namespace libdash::framework::mpd;
-SegmentTemplateStream::SegmentTemplateStream(IMPD *mpd, IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation) :
- AbstractRepresentationStream (mpd, period, adaptationSet, representation)
+SegmentTemplateStream::SegmentTemplateStream(viper::managers::StreamType type, MPDWrapper *mpdWrapper, IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation) :
+ AbstractRepresentationStream (type, mpdWrapper, period, adaptationSet, representation)
{
- this->baseUrls = BaseUrlResolver::resolveBaseUrl(mpd, period, adaptationSet, 0, 0, 0);
+// this->baseUrls = BaseUrlResolver::resolveBaseUrl(mpd, period, adaptationSet, 0, 0, 0);
+ this->baseUrls = BaseUrlResolver::resolveBaseUrl(type, mpdWrapper, 0, 0, 0);
this->segmentTemplate = findSegmentTemplate();
this->inSync = false;
this->currentSegment = 0;
calculateSegmentStartTimes();
}
+
+SegmentTemplateStream::SegmentTemplateStream(viper::managers::StreamType type, MPDWrapper *mpdWrapper, IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation, IMPD* mpd) :
+ AbstractRepresentationStream (type, mpdWrapper, period, adaptationSet, representation)
+{
+// this->baseUrls = BaseUrlResolver::resolveBaseUrl(mpd, period, adaptationSet, 0, 0, 0);
+ this->baseUrls = BaseUrlResolver::resolveBaseUrl(type, mpdWrapper, 0, 0, 0, mpd);
+ this->segmentTemplate = findSegmentTemplate();
+ this->inSync = false;
+ this->currentSegment = 0;
+ calculateSegmentStartTimes();
+}
+
SegmentTemplateStream::~SegmentTemplateStream()
{
}
@@ -55,7 +68,14 @@ ISegment* SegmentTemplateStream::getMediaSegment(size_t segmentNumber)
{
/* time-based template */
if (this->segmentTemplate->GetSegmentTimeline())
- {
+ {//Get the one at segmentNumber
+ if(this->segmentStartTimes.size() > segmentNumber)
+ return this->segmentTemplate->GetMediaSegmentFromTime(baseUrls, representation->GetId(), representation->GetBandwidth(), this->segmentStartTimes.at(segmentNumber));
+ else
+ return NULL;
+
+//The following is to be used if you wish to start directly from the right time
+/* {
if(this->inSync)
{
this->currentSegment++;
@@ -86,7 +106,7 @@ ISegment* SegmentTemplateStream::getMediaSegment(size_t segmentNumber)
this->currentSegment = segNumber;
return this->segmentTemplate->GetMediaSegmentFromTime(baseUrls, representation->GetId(), representation->GetBandwidth(), this->segmentStartTimes.at(this->currentSegment));
}
- return NULL;
+ return NULL; */
}
/* number-based template */
@@ -115,9 +135,9 @@ uint32_t SegmentTemplateStream::getSize()
uint32_t numberOfSegments = 0;
double mediaPresentationDuration = 0;
- if (this->mpd->GetType() == "static")
+ if (this->mpdWrapper->getTypeWithoutLock() == "static")
{
- mediaPresentationDuration = TimeResolver::getDurationInSec(this->mpd->GetMediaPresentationDuration());
+ mediaPresentationDuration = TimeResolver::getDurationInSec(this->mpdWrapper->getMediaPresentationDuration());
numberOfSegments = (uint32_t) ceil(mediaPresentationDuration / (this->segmentTemplate->GetDuration() / this->segmentTemplate->GetTimescale()));
}
else
@@ -194,3 +214,24 @@ void SegmentTemplateStream::calculateSegmentStartTimes()
}
this->averageDuration = totalDuration / numOfTimelines;
}
+
+uint32_t SegmentTemplateStream::getTime(size_t segmentNumber)
+{
+ if(segmentNumber < this->segmentStartTimes.size())
+ return this->segmentStartTimes.at(segmentNumber);
+ else
+ return 0;
+}
+
+size_t SegmentTemplateStream::getSegmentNumber(uint32_t time)
+{
+ size_t i;
+ for(i = 0; i < this->segmentStartTimes.size(); i ++)
+ {
+ if(time <= this->segmentStartTimes.at(i))
+ {
+ break;
+ }
+ }
+ return i;
+}
diff --git a/MPD/SegmentTemplateStream.h b/MPD/SegmentTemplateStream.h
index f27b77fb..68d4f848 100644
--- a/MPD/SegmentTemplateStream.h
+++ b/MPD/SegmentTemplateStream.h
@@ -14,7 +14,7 @@
#include <math.h>
-#include "IMPD.h"
+#include "MPDWrapper.h"
#include "AbstractRepresentationStream.h"
#include "ISegment.h"
#include "ISegmentTemplate.h"
@@ -28,7 +28,8 @@ namespace mpd
class SegmentTemplateStream: public AbstractRepresentationStream
{
public:
- SegmentTemplateStream(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation);
+ SegmentTemplateStream(viper::managers::StreamType type, libdash::framework::mpd::MPDWrapper *mpdWrapper, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation);
+ SegmentTemplateStream(viper::managers::StreamType type, libdash::framework::mpd::MPDWrapper *mpdWrapper, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation, dash::mpd::IMPD* mpd);
virtual ~SegmentTemplateStream();
virtual dash::mpd::ISegment* getInitializationSegment();
@@ -39,6 +40,8 @@ public:
virtual uint32_t getSize();
virtual uint32_t getAverageSegmentDuration();
virtual uint32_t getTimescale();
+ virtual uint32_t getTime(size_t segmentNumber);
+ virtual size_t getSegmentNumber(uint32_t time);
private:
dash::mpd::ISegmentTemplate* findSegmentTemplate();
diff --git a/MPD/SingleMediaSegmentStream.cpp b/MPD/SingleMediaSegmentStream.cpp
index ff4540e2..39301928 100644
--- a/MPD/SingleMediaSegmentStream.cpp
+++ b/MPD/SingleMediaSegmentStream.cpp
@@ -14,10 +14,16 @@
using namespace dash::mpd;
using namespace libdash::framework::mpd;
-SingleMediaSegmentStream::SingleMediaSegmentStream(IMPD *mpd, IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation) :
- AbstractRepresentationStream (mpd, period, adaptationSet, representation)
+SingleMediaSegmentStream::SingleMediaSegmentStream(viper::managers::StreamType type, MPDWrapper *mpdWrapper, IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation) :
+ AbstractRepresentationStream (type, mpdWrapper, period, adaptationSet, representation)
{
- this->baseUrls = BaseUrlResolver::resolveBaseUrl(mpd, period, adaptationSet, 0, 0, 0);
+ this->baseUrls = BaseUrlResolver::resolveBaseUrl(type, mpdWrapper, 0, 0, 0);
+}
+
+SingleMediaSegmentStream::SingleMediaSegmentStream(viper::managers::StreamType type, MPDWrapper *mpdWrapper, IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation, IMPD* mpd) :
+ AbstractRepresentationStream (type, mpdWrapper, period, adaptationSet, representation)
+{
+ this->baseUrls = BaseUrlResolver::resolveBaseUrl(type, mpdWrapper, 0, 0, 0, mpd);
}
SingleMediaSegmentStream::~SingleMediaSegmentStream()
{
diff --git a/MPD/SingleMediaSegmentStream.h b/MPD/SingleMediaSegmentStream.h
index afc919ee..e619a7f8 100644
--- a/MPD/SingleMediaSegmentStream.h
+++ b/MPD/SingleMediaSegmentStream.h
@@ -12,7 +12,7 @@
#ifndef LIBDASH_FRAMEWORK_MPD_SINGLEMEDIASEGMENTSTREAM_H_
#define LIBDASH_FRAMEWORK_MPD_SINGLEMEDIASEGMENTSTREAM_H_
-#include "IMPD.h"
+#include "MPDWrapper.h"
#include "AbstractRepresentationStream.h"
#include "ISegment.h"
@@ -25,7 +25,8 @@ namespace mpd
class SingleMediaSegmentStream: public AbstractRepresentationStream
{
public:
- SingleMediaSegmentStream(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation);
+ SingleMediaSegmentStream(viper::managers::StreamType type, libdash::framework::mpd::MPDWrapper *mpdWrapper, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation);
+ SingleMediaSegmentStream(viper::managers::StreamType type, libdash::framework::mpd::MPDWrapper *mpdWrapper, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation, dash::mpd::IMPD* mpd);
virtual ~SingleMediaSegmentStream();
virtual dash::mpd::ISegment* getInitializationSegment();