aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuca Muscariello <lumuscar+fdio@cisco.com>2017-06-23 14:51:19 +0000
committerGerrit Code Review <gerrit@fd.io>2017-06-23 14:51:19 +0000
commitea99c36cadfab26fe4bf523931f87132c01a54a2 (patch)
tree13fc8ff2f6072add96f987a1a68a15c22d68d911
parente207b82a2b7e70e2700cf1c4237a2e819c655809 (diff)
parenta644414fd2c3a3f7f41e716b6875a78981e4cfe1 (diff)
Merge "adding mpd live handling + automatic mpd fetching" into viper/master
-rw-r--r--Adaptation/AbstractAdaptationLogic.cpp29
-rw-r--r--Adaptation/AbstractAdaptationLogic.h38
-rw-r--r--Adaptation/AdaptationLogicFactory.cpp20
-rw-r--r--Adaptation/AdaptationLogicFactory.h4
-rw-r--r--Adaptation/AlwaysLowestLogic.cpp6
-rw-r--r--Adaptation/AlwaysLowestLogic.h3
-rw-r--r--Adaptation/Bola.cpp46
-rw-r--r--Adaptation/Bola.h73
-rw-r--r--Adaptation/BufferBasedAdaptation.cpp33
-rw-r--r--Adaptation/BufferBasedAdaptation.h17
-rw-r--r--Adaptation/BufferBasedAdaptationWithRateBased.cpp34
-rw-r--r--Adaptation/BufferBasedAdaptationWithRateBased.h25
-rw-r--r--Adaptation/BufferBasedThreeThresholdAdaptation.cpp151
-rw-r--r--Adaptation/BufferBasedThreeThresholdAdaptation.h27
-rw-r--r--Adaptation/IAdaptationLogic.h7
-rw-r--r--Adaptation/Panda.cpp35
-rw-r--r--Adaptation/Panda.h53
-rw-r--r--Adaptation/RateBasedAdaptation.cpp22
-rw-r--r--Adaptation/RateBasedAdaptation.h11
-rw-r--r--Common/ViperBuffer.cpp5
-rw-r--r--Input/DASHManager.cpp21
-rw-r--r--Input/DASHManager.h25
-rw-r--r--Input/DASHReceiver.cpp291
-rw-r--r--Input/DASHReceiver.h44
-rw-r--r--Input/ICNConnectionConsumerApi.cpp8
-rw-r--r--Input/IDASHManagerObserver.h1
-rw-r--r--Input/IDASHReceiverObserver.h1
-rw-r--r--Input/MediaObject.cpp22
-rw-r--r--Input/MediaObject.h6
-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
-rw-r--r--Managers/IMultimediaManagerBase.h8
-rw-r--r--Managers/IMultimediaManagerObserver.h1
-rw-r--r--Managers/IStreamObserver.h2
-rw-r--r--Managers/MultimediaManager.cpp176
-rw-r--r--Managers/MultimediaManager.h129
-rw-r--r--Managers/MultimediaStream.cpp33
-rw-r--r--Managers/MultimediaStream.h32
-rw-r--r--UI/DASHPlayer.cpp82
-rw-r--r--UI/DASHPlayer.h57
-rw-r--r--UI/DASHPlayerNoGUI.cpp101
-rw-r--r--UI/DASHPlayerNoGUI.h47
-rw-r--r--UI/IViperGui.h30
-rw-r--r--UI/ViperGui.cpp43
-rw-r--r--UI/ViperGui.h3
-rw-r--r--libdash/include/IMPD.h9
-rw-r--r--libdash/source/mpd/MPD.cpp8
-rw-r--r--libdash/source/mpd/MPD.h3
-rw-r--r--libdash/source/xml/Node.cpp4
-rw-r--r--viper.pro4
66 files changed, 2529 insertions, 925 deletions
diff --git a/Adaptation/AbstractAdaptationLogic.cpp b/Adaptation/AbstractAdaptationLogic.cpp
index 4f578958..ada388b7 100644
--- a/Adaptation/AbstractAdaptationLogic.cpp
+++ b/Adaptation/AbstractAdaptationLogic.cpp
@@ -14,17 +14,16 @@
using namespace libdash::framework::adaptation;
using namespace dash::mpd;
-AbstractAdaptationLogic::AbstractAdaptationLogic(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, bool isVid) :
- mpd (mpd),
- period (period),
- adaptationSet (adaptationSet),
- representation (NULL),
- isVideo (isVid)
+AbstractAdaptationLogic::AbstractAdaptationLogic(viper::managers::StreamType type, libdash::framework::mpd::MPDWrapper *mpdWrapper) :
+ mpdWrapper (mpdWrapper),
+ type (type)
{
+ InitializeCriticalSection (&this->monitorLock);
}
AbstractAdaptationLogic::~AbstractAdaptationLogic()
{
+ DeleteCriticalSection (&this->monitorLock);
}
uint32_t AbstractAdaptationLogic::getPosition()
@@ -39,15 +38,19 @@ void AbstractAdaptationLogic::setPosition(uint32_t segmentNumber)
IRepresentation* AbstractAdaptationLogic::getRepresentation()
{
- return this->representation;
+// return this->representation;
}
-void AbstractAdaptationLogic::setRepresentation(IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation)
-{
- this->period = period;
- this->adaptationSet = adaptationSet;
- this->representation = representation;
-}
+//void AbstractAdaptationLogic::setRepresentation(IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation)
+//{
+// this->period = period;
+// this->adaptationSet = adaptationSet;
+// this->representation = representation;
+//}
+
+//void AbstractAdaptationLogic::updateMPD(IMPD* mpd)
+//{
+//}
void AbstractAdaptationLogic::dLTimeUpdate(double time)
{
diff --git a/Adaptation/AbstractAdaptationLogic.h b/Adaptation/AbstractAdaptationLogic.h
index 24fab91d..c407f01b 100644
--- a/Adaptation/AbstractAdaptationLogic.h
+++ b/Adaptation/AbstractAdaptationLogic.h
@@ -24,33 +24,37 @@ namespace adaptation
class AbstractAdaptationLogic : public IAdaptationLogic
{
public:
- AbstractAdaptationLogic(dash::mpd::IMPD *mpd, dash::mpd::IPeriod* period, dash::mpd::IAdaptationSet *adaptationSet, bool isVideo);
+// AbstractAdaptationLogic(dash::mpd::IMPD *mpd, dash::mpd::IPeriod* period, dash::mpd::IAdaptationSet *adaptationSet, bool isVideo);
+ AbstractAdaptationLogic(viper::managers::StreamType type, libdash::framework::mpd::MPDWrapper *mpdWrapper);
virtual ~AbstractAdaptationLogic();
virtual uint32_t getPosition();
virtual void setPosition(uint32_t segmentNumber);
virtual dash::mpd::IRepresentation* getRepresentation ();
- virtual void setRepresentation(dash::mpd::IPeriod *period,
- dash::mpd::IAdaptationSet *adaptationSet,
- dash::mpd::IRepresentation *representation);
+// virtual void setRepresentation(dash::mpd::IPeriod *period,
+// dash::mpd::IAdaptationSet *adaptationSet,
+// dash::mpd::IRepresentation *representation);
+// virtual void updateMPD(dash::mpd::IMPD* mpd);
- virtual LogicType getType() = 0;
- virtual bool isUserDependent() = 0;
- virtual bool isRateBased() = 0;
- virtual bool isBufferBased() = 0;
+ virtual LogicType getType() = 0;
+ virtual bool isUserDependent() = 0;
+ virtual bool isRateBased() = 0;
+ virtual bool isBufferBased() = 0;
virtual void bitrateUpdate(uint64_t, uint32_t) = 0;
- virtual void bufferUpdate(uint32_t, int) = 0;
- virtual void onEOS(bool value)= 0;
- virtual void dLTimeUpdate(double) = 0;
+ virtual void bufferUpdate(uint32_t, int) = 0;
+ virtual void onEOS(bool value) = 0;
+ virtual void dLTimeUpdate(double) = 0;
+ virtual void checkedByDASHReceiver() = 0;
- virtual void checkedByDASHReceiver() = 0;
protected:
- dash::mpd::IMPD *mpd;
- dash::mpd::IPeriod *period;
- dash::mpd::IAdaptationSet *adaptationSet;
- dash::mpd::IRepresentation *representation;
+ libdash::framework::mpd::MPDWrapper *mpdWrapper;
+// dash::mpd::IPeriod *period;
+// dash::mpd::IAdaptationSet *adaptationSet;
+// dash::mpd::IRepresentation *representation;
uint32_t segmentNumber;
- bool isVideo;
+// bool isVideo;
+ viper::managers::StreamType type;
+ mutable CRITICAL_SECTION monitorLock;
};
}
}
diff --git a/Adaptation/AdaptationLogicFactory.cpp b/Adaptation/AdaptationLogicFactory.cpp
index 6901a597..b2cae9c1 100644
--- a/Adaptation/AdaptationLogicFactory.cpp
+++ b/Adaptation/AdaptationLogicFactory.cpp
@@ -13,36 +13,36 @@
#include<stdio.h>
using namespace libdash::framework::adaptation;
+using namespace libdash::framework::mpd;
using namespace dash::mpd;
-IAdaptationLogic* AdaptationLogicFactory::create(LogicType logic, IMPD *mpd, IPeriod *period, IAdaptationSet *adaptationSet,bool isVid, struct AdaptationParameters* paramsForAdaptation)
+IAdaptationLogic* AdaptationLogicFactory::create(LogicType logic, viper::managers::StreamType type, MPDWrapper *mpdWrapper, struct AdaptationParameters* paramsForAdaptation)
{
- Debug("Adaptation Logic for %s: ", isVid ? "video" : "audio");
switch(logic)
{
case AlwaysLowest:
Debug("Always lowest\n");
- return new AlwaysLowestLogic(mpd, period, adaptationSet, isVid, paramsForAdaptation);
+ return new AlwaysLowestLogic(type, mpdWrapper, paramsForAdaptation);
case RateBased:
Debug("Rate based\n");
- return new RateBasedAdaptation(mpd,period,adaptationSet, isVid, paramsForAdaptation);
+ return new RateBasedAdaptation(type, mpdWrapper, paramsForAdaptation);
case BufferBased:
Debug("Buffer based\n");
- return new BufferBasedAdaptation(mpd,period,adaptationSet, isVid, paramsForAdaptation);
+ return new BufferBasedAdaptation(type, mpdWrapper, paramsForAdaptation);
case BufferRateBased:
Debug("Buffer Rate based\n");
- return new BufferBasedAdaptationWithRateBased(mpd,period,adaptationSet, isVid, paramsForAdaptation);
+ return new BufferBasedAdaptationWithRateBased(type, mpdWrapper, paramsForAdaptation);
case BufferBasedThreeThreshold:
Debug("Buffer based 3 threshold\n");
- return new BufferBasedThreeThresholdAdaptation(mpd,period,adaptationSet, isVid, paramsForAdaptation);
+ return new BufferBasedThreeThresholdAdaptation(type, mpdWrapper, paramsForAdaptation);
case Panda:
Debug("Panda\n");
- return new PandaAdaptation(mpd, period, adaptationSet, isVid, paramsForAdaptation);
+ return new PandaAdaptation(type, mpdWrapper, paramsForAdaptation);
case Bola:
Debug("Bola\n");
- return new BolaAdaptation(mpd, period, adaptationSet, isVid, paramsForAdaptation);
+ return new BolaAdaptation(type, mpdWrapper, paramsForAdaptation);
default:
Debug("default => return Always Lowest\n");
- return new AlwaysLowestLogic(mpd, period, adaptationSet, isVid, paramsForAdaptation);
+ return new AlwaysLowestLogic(type, mpdWrapper, paramsForAdaptation);
}
}
diff --git a/Adaptation/AdaptationLogicFactory.h b/Adaptation/AdaptationLogicFactory.h
index 0f1616a7..e78d2865 100644
--- a/Adaptation/AdaptationLogicFactory.h
+++ b/Adaptation/AdaptationLogicFactory.h
@@ -30,8 +30,8 @@ namespace adaptation
class AdaptationLogicFactory
{
public:
- static IAdaptationLogic* create(libdash::framework::adaptation::LogicType logic,
- dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, bool isVid, struct AdaptationParameters *params);
+ static IAdaptationLogic* create(libdash::framework::adaptation::LogicType logic, viper::managers::StreamType type, libdash::framework::mpd::MPDWrapper *mpdWrapper, struct AdaptationParameters *params);
+// static IAdaptationLogic* create(libdash::framework::adaptation::LogicType logic, dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, bool isVid, struct AdaptationParameters *params);
};
}
}
diff --git a/Adaptation/AlwaysLowestLogic.cpp b/Adaptation/AlwaysLowestLogic.cpp
index 54409bfd..1f318867 100644
--- a/Adaptation/AlwaysLowestLogic.cpp
+++ b/Adaptation/AlwaysLowestLogic.cpp
@@ -14,12 +14,12 @@
using namespace libdash::framework::adaptation;
using namespace libdash::framework::input;
+using namespace libdash::framework::mpd;
using namespace dash::mpd;
-AlwaysLowestLogic::AlwaysLowestLogic(IMPD *mpd, IPeriod *period, IAdaptationSet *adaptationSet, bool isVid, struct AdaptationParameters *params) :
- AbstractAdaptationLogic(mpd, period, adaptationSet, isVid)
+AlwaysLowestLogic::AlwaysLowestLogic(viper::managers::StreamType type, MPDWrapper *mpdWrapper, struct AdaptationParameters *params) :
+ AbstractAdaptationLogic(type, mpdWrapper)
{
- this->representation = this->adaptationSet->GetRepresentation().at(0);
}
AlwaysLowestLogic::~AlwaysLowestLogic()
diff --git a/Adaptation/AlwaysLowestLogic.h b/Adaptation/AlwaysLowestLogic.h
index 782a8b29..f8b50e37 100644
--- a/Adaptation/AlwaysLowestLogic.h
+++ b/Adaptation/AlwaysLowestLogic.h
@@ -24,7 +24,8 @@ namespace adaptation
class AlwaysLowestLogic : public AbstractAdaptationLogic
{
public:
- AlwaysLowestLogic(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, bool isVid, struct AdaptationParameters *params);
+// AlwaysLowestLogic(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, bool isVid, struct AdaptationParameters *params);
+ AlwaysLowestLogic(viper::managers::StreamType type, libdash::framework::mpd::MPDWrapper *mpdWrapper, struct AdaptationParameters *params);
virtual ~AlwaysLowestLogic();
virtual LogicType getType();
diff --git a/Adaptation/Bola.cpp b/Adaptation/Bola.cpp
index 6477e0f5..f7acc72e 100644
--- a/Adaptation/Bola.cpp
+++ b/Adaptation/Bola.cpp
@@ -47,8 +47,8 @@ using std::placeholders::_2;
using duration_in_seconds = std::chrono::duration<double, std::ratio<1, 1> >;
-BolaAdaptation::BolaAdaptation(IMPD *mpd, IPeriod *period, IAdaptationSet *adaptationSet, bool isVid, struct AdaptationParameters *params) :
- AbstractAdaptationLogic (mpd, period, adaptationSet, isVid)
+BolaAdaptation::BolaAdaptation(viper::managers::StreamType type, MPDWrapper *mpdWrapper, struct AdaptationParameters *params) :
+ AbstractAdaptationLogic (type, mpdWrapper)
{
this->bufferMaxSizeSeconds =(double) params->segmentBufferSize * params->segmentDuration;
this->alphaRate = params->Bola_Alpha;
@@ -62,11 +62,12 @@ BolaAdaptation::BolaAdaptation(IMPD *mpd, IPeriod *period, IAdaptationSet *adapt
this->currentDownloadTimeInstant = 0.0;
//this->lastSegmentDownloadTime = 0.0;
this->currentQuality = 0;
-
+ this->representation = NULL;
this->bufferTargetPerc = (uint32_t) ( round(this->bufferTargetSeconds / this->bufferMaxSizeSeconds)*100 );
+ this->mpdWrapper->acquireLock();
/// Retrieve available bitrates
- std::vector<IRepresentation* > representations = this->adaptationSet->GetRepresentation();
+ std::vector<IRepresentation* > representations = this->mpdWrapper->getRepresentations(this->type);
this->availableBitrates.clear();
Debug("BOLA Available Bitrates...\n");
@@ -85,8 +86,8 @@ BolaAdaptation::BolaAdaptation(IMPD *mpd, IPeriod *period, IAdaptationSet *adapt
// return 0; // Check if exit with a message is necessary
}
- // Check if the following is correct
- this->totalDuration = TimeResolver::getDurationInSec(this->mpd->GetMediaPresentationDuration());
+ // Check if the following is correct XXX Maybe useless
+ this->totalDuration = TimeResolver::getDurationInSec(this->mpdWrapper->getMediaPresentationDuration());
// this->segmentDuration = (double) (representations.at(0)->GetSegmentTemplate()->GetDuration() / representations.at(0)->GetSegmentTemplate()->GetTimescale() );
this->segmentDuration = 2.0;
Debug("Total Duration - BOLA:\t%f\nSegment Duration - BOLA:\t%f\n",this->totalDuration, this->segmentDuration);
@@ -169,6 +170,7 @@ BolaAdaptation::BolaAdaptation(IMPD *mpd, IPeriod *period, IAdaptationSet *adapt
this->representation = representations.at(0);
this->currentBitrate = (uint64_t) this->representation->GetBandwidth();
+ this->mpdWrapper->releaseLock();
Debug("BOLA Init Params - \tAlpha: %f \t BufferTarget: %f\n",this->alphaRate, this->bufferTargetSeconds);
Debug("BOLA Init Current BitRate - %I64u\n",this->currentBitrate);
Debug("Buffer Adaptation BOLA: STARTED\n");
@@ -204,16 +206,20 @@ void BolaAdaptation::setMultimediaManager(viper::managers::IMultimediaManagerBas
void BolaAdaptation::notifyBitrateChange()
{
+ this->mpdWrapper->setRepresentation(this->type, this->representation);
if(this->multimediaManager)
if(this->multimediaManager->isStarted() && !this->multimediaManager->isStopping())
- if(this->isVideo)
- this->multimediaManager->setVideoQuality(this->period, this->adaptationSet, this->representation);
+ if(type==viper::managers::VIDEO)
+ this->multimediaManager->setVideoQuality();
+// this->multimediaManager->setVideoQuality(this->period, this->adaptationSet, this->representation);
else
- this->multimediaManager->setAudioQuality(this->period, this->adaptationSet, this->representation);
+ this->multimediaManager->setAudioQuality();
+// this->multimediaManager->setAudioQuality(this->period, this->adaptationSet, this->representation);
//Should Abort is done here to avoid race condition with DASHReceiver::DoBuffering()
if(this->shouldAbort)
{
- this->multimediaManager->shouldAbort(this->isVideo);
+ this->multimediaManager->shouldAbort(1);
+// this->multimediaManager->shouldAbort((this->type == viper::managers::StreamType::VIDEO));
}
this->shouldAbort = false;
}
@@ -263,10 +269,10 @@ void BolaAdaptation::setBitrate(uint32_t bufferFill)
}
//this->representation = this->availableBitrates[this->currentQuality];
//this->currentBitrate = (uint64_t) this->representation->GetBandwidth();
- this->representation = this->adaptationSet->GetRepresentation().at(this->currentQuality);
+ this->representation = this->mpdWrapper->getRepresentationAt(this->type, this->currentQuality);
this->currentBitrate = (uint64_t) this->availableBitrates[this->currentQuality];
Debug("INIT - Current Bitrate:\t%I64u\n", this->currentBitrate);
- Debug("ADAPTATION_LOGIC:\tFor %s:\tlast_buffer: %f\tbuffer_level: %f, instantaneousBw: %lu, AverageBW: %lu, choice: %d\n",isVideo ? "video" : "audio",(double)lastBufferFill/100 , (double)bufferFill/100, this->instantBw, this->averageBw , this->currentQuality);
+ Debug("ADAPTATION_LOGIC:\tFor %s:\tlast_buffer: %f\tbuffer_level: %f, instantaneousBw: %lu, AverageBW: %lu, choice: %d\n",(this->type == viper::managers::VIDEO) ? "video" : "audio",(double)lastBufferFill/100 , (double)bufferFill/100, this->instantBw, this->averageBw , this->currentQuality);
this->lastBufferFill = bufferFill;
return;
}
@@ -275,10 +281,10 @@ void BolaAdaptation::setBitrate(uint32_t bufferFill)
this->currentQuality = 0;
//this->representation = this->availableBitrates[this->currentQuality];
//this->currentBitrate = (uint64_t) this->representation->GetBandwidth();
- this->representation = this->adaptationSet->GetRepresentation().at(this->currentQuality);
+ this->representation = this->mpdWrapper->getRepresentationAt(this->type,this->currentQuality);
this->currentBitrate = (uint64_t) this->availableBitrates[this->currentQuality];
Debug("ONE BITRATE - Current Bitrate:\t%I64u\n", this->currentBitrate);
- Debug("ADAPTATION_LOGIC:\tFor %s:\tlast_buffer: %f\tbuffer_level: %f, instantaneousBw: %lu, AverageBW: %lu, choice: %d\n",isVideo ? "video" : "audio",(double)lastBufferFill/100 , (double)bufferFill/100, this->instantBw, this->averageBw , this->currentQuality);
+ Debug("ADAPTATION_LOGIC:\tFor %s:\tlast_buffer: %f\tbuffer_level: %f, instantaneousBw: %lu, AverageBW: %lu, choice: %d\n",(this->type == viper::managers::VIDEO) ? "video" : "audio",(double)lastBufferFill/100 , (double)bufferFill/100, this->instantBw, this->averageBw , this->currentQuality);
this->lastBufferFill = bufferFill;
return;
}
@@ -384,10 +390,10 @@ void BolaAdaptation::setBitrate(uint32_t bufferFill)
this->currentQuality = quality;
//this->representation = this->availableBitrates[this->currentQuality];
//this->currentBitrate = (uint64_t) this->representation->GetBandwidth();
- this->representation = this->adaptationSet->GetRepresentation().at(this->currentQuality);
+ this->representation = this->mpdWrapper->getRepresentationAt(this->type, this->currentQuality);
this->currentBitrate = (uint64_t) this->availableBitrates[this->currentQuality];
Debug("STILL IN STARTUP - Current Bitrate:\t%I64u\n", this->currentBitrate);
- Debug("ADAPTATION_LOGIC:\tFor %s:\tlast_buffer: %f\tbuffer_level: %f, instantaneousBw: %lu, AverageBW: %lu, choice: %d\n",isVideo ? "video" : "audio",(double)lastBufferFill/100 , (double)bufferFill/100, this->instantBw, this->averageBw , this->currentQuality);
+ Debug("ADAPTATION_LOGIC:\tFor %s:\tlast_buffer: %f\tbuffer_level: %f, instantaneousBw: %lu, AverageBW: %lu, choice: %d\n",(this->type == viper::managers::VIDEO) ? "video" : "audio",(double)lastBufferFill/100 , (double)bufferFill/100, this->instantBw, this->averageBw , this->currentQuality);
this->lastBufferFill = bufferFill;
return;
}
@@ -434,15 +440,15 @@ void BolaAdaptation::setBitrate(uint32_t bufferFill)
// streamProcessor.getScheduleController().setTimeToLoadDelay(1000.0 * delaySeconds);
// NEED TO CHECK THIS
Debug("STEADY -- DELAY DOWNLOAD OF:\t%f\n", delaySeconds);
- this->multimediaManager->setTargetDownloadingTime(this->isVideo, delaySeconds);
+ this->multimediaManager->setTargetDownloadingTime((this->type == viper::managers::StreamType::VIDEO), delaySeconds);
}
this->currentQuality = bolaQuality;
//this->representation = this->availableBitrates[this->currentQuality];
- this->representation = this->adaptationSet->GetRepresentation().at(this->currentQuality);
+ this->representation = this->mpdWrapper->getRepresentationAt(this->type, this->currentQuality);
this->currentBitrate = (uint64_t) this->availableBitrates[this->currentQuality];
Debug("STEADY - Current Bitrate:\t%I64u\n", this->currentBitrate);
- Debug("ADAPTATION_LOGIC:\tFor %s:\tlast_buffer: %f\tbuffer_level: %f, instantaneousBw: %lu, AverageBW: %lu, choice: %d\n",isVideo ? "video" : "audio",(double)lastBufferFill/100 , (double)bufferFill/100, this->instantBw, this->averageBw , this->currentQuality);
+ Debug("ADAPTATION_LOGIC:\tFor %s:\tlast_buffer: %f\tbuffer_level: %f, instantaneousBw: %lu, AverageBW: %lu, choice: %d\n",(this->type == viper::managers::VIDEO) ? "video" : "audio",(double)lastBufferFill/100 , (double)bufferFill/100, this->instantBw, this->averageBw , this->currentQuality);
this->lastBufferFill = bufferFill;
}
@@ -501,6 +507,8 @@ void BolaAdaptation::checkedByDASHReceiver()
}
void BolaAdaptation::bufferUpdate(uint32_t bufferFill, int maxC)
{
+ this->mpdWrapper->acquireLock();
this->setBitrate(bufferFill);
this->notifyBitrateChange();
+ this->mpdWrapper->releaseLock();
}
diff --git a/Adaptation/Bola.h b/Adaptation/Bola.h
index 29011664..404e9968 100644
--- a/Adaptation/Bola.h
+++ b/Adaptation/Bola.h
@@ -29,7 +29,8 @@ namespace adaptation
class BolaAdaptation : public AbstractAdaptationLogic
{
public:
- BolaAdaptation (dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, bool isVid, struct AdaptationParameters *params);
+// BolaAdaptation (dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, bool isVid, struct AdaptationParameters *params);
+ BolaAdaptation (viper::managers::StreamType type, libdash::framework::mpd::MPDWrapper *mpdWrapper, struct AdaptationParameters *params);
virtual ~BolaAdaptation();
virtual LogicType getType();
@@ -58,58 +59,54 @@ private:
STEADY // The buffer is primed (should be above bufferTarget)
};
- bool initState;
- double bufferMaxSizeSeconds; // Usually set to 30s
- double bufferTargetSeconds; // It is passed as an init parameter.
+ bool initState;
+ double bufferMaxSizeSeconds; // Usually set to 30s
+ double bufferTargetSeconds; // It is passed as an init parameter.
// It states the difference between STARTUP and STEADY
// 12s following dash.js implementation
- double bolaBufferTargetSeconds; // BOLA introduces a virtual buffer level in order to make quality decisions
+ double bolaBufferTargetSeconds; // BOLA introduces a virtual buffer level in order to make quality decisions
// as it was filled (instead of the actual bufferTargetSeconds)
- double bolaBufferMaxSeconds; // When using the virtual buffer, it must be capped.
-
- uint32_t bufferTargetPerc; // Computed considering a bufferSize = 30s
- double totalDuration; // Total video duration in seconds (taken from MPD)
- double segmentDuration; // Segment duration in seconds
+ double bolaBufferMaxSeconds; // When using the virtual buffer, it must be capped.
+ uint32_t bufferTargetPerc; // Computed considering a bufferSize = 30s
+ double totalDuration; // Total video duration in seconds (taken from MPD)
+ double segmentDuration; // Segment duration in seconds
std::vector<uint64_t> availableBitrates;
std::vector<double> utilityVector;
- uint32_t bitrateCount; // Number of available bitrates
- BolaState bolaState; // Keeps track of Bola state
+ uint32_t bitrateCount; // Number of available bitrates
+ BolaState bolaState; // Keeps track of Bola state
// Bola Vp and gp (multiplied by the segment duration 'p')
// They are dimensioned such that log utility would always prefer
// - the lowest bitrate when bufferLevel = segmentDuration
// - the highest bitrate when bufferLevel = bufferTarget
- double Vp;
- double gp;
-
- bool safetyGuarantee;
- double maxRtt;
-
- double virtualBuffer;
-
- uint64_t currentBitrate;
- int currentQuality;
- uint64_t batchBw;
- int batchBwCount;
+ double Vp;
+ double gp;
+ bool safetyGuarantee;
+ double maxRtt;
+ double virtualBuffer;
+
+ uint64_t currentBitrate;
+ int currentQuality;
+ uint64_t batchBw;
+ int batchBwCount;
std::vector<uint64_t> batchBwSamples;
- uint64_t instantBw;
- uint64_t averageBw;
-
- double lastDownloadTimeInstant;
- double currentDownloadTimeInstant;
- double lastSegmentDownloadTime;
-
- uint32_t lastBufferFill;
- bool bufferEOS;
- bool shouldAbort;
- double alphaRate;
- bool isCheckedForReceiver;
-
+ uint64_t instantBw;
+ uint64_t averageBw;
+
+ double lastDownloadTimeInstant;
+ double currentDownloadTimeInstant;
+ double lastSegmentDownloadTime;
+
+ uint32_t lastBufferFill;
+ bool bufferEOS;
+ bool shouldAbort;
+ double alphaRate;
+ bool isCheckedForReceiver;
viper::managers::IMultimediaManagerBase *multimediaManager;
- dash::mpd::IRepresentation *representation;
+ dash::mpd::IRepresentation *representation;
};
}
}
diff --git a/Adaptation/BufferBasedAdaptation.cpp b/Adaptation/BufferBasedAdaptation.cpp
index 18d4a592..eea7ef36 100644
--- a/Adaptation/BufferBasedAdaptation.cpp
+++ b/Adaptation/BufferBasedAdaptation.cpp
@@ -22,15 +22,13 @@ using namespace libdash::framework::adaptation;
using namespace libdash::framework::input;
using namespace libdash::framework::mpd;
-BufferBasedAdaptation::BufferBasedAdaptation (IMPD *mpd, IPeriod *period, IAdaptationSet *adaptationSet, bool isVid, struct AdaptationParameters *params) :
- AbstractAdaptationLogic (mpd, period, adaptationSet, isVid)
+BufferBasedAdaptation::BufferBasedAdaptation (viper::managers::StreamType type, MPDWrapper *mpd, struct AdaptationParameters *params) :
+ AbstractAdaptationLogic (type, mpdWrapper)
{
this->reservoirThreshold = params->BufferBased_reservoirThreshold;
this->maxThreshold = params->BufferBased_maxThreshold;
- std::vector<IRepresentation* > representations = this->adaptationSet->GetRepresentation();
-
- this->representation = this->adaptationSet->GetRepresentation().at(0);
+// this->representation = this->adaptationSet->GetRepresentation().at(0);
this->multimediaManager = NULL;
this->lastBufferFill = 0;
this->bufferEOS = false;
@@ -69,18 +67,19 @@ void BufferBasedAdaptation::setMultimediaManager (viper::managers::IMultimediaMa
void BufferBasedAdaptation::notifyBitrateChange()
{
+ this->mpdWrapper->setRepresentation(this->type, this->representation);
if(this->multimediaManager)
if(this->multimediaManager->isStarted() && !this->multimediaManager->isStopping())
- if(this->isVideo)
- this->multimediaManager->setVideoQuality(this->period, this->adaptationSet, this->representation);
+ if(this->type == viper::managers::StreamType::VIDEO)
+ this->multimediaManager->setVideoQuality();
else
- this->multimediaManager->setAudioQuality(this->period, this->adaptationSet, this->representation);
+ this->multimediaManager->setAudioQuality();
- if(this->shouldAbort)
- {
- this->multimediaManager->shouldAbort(this->isVideo);
- }
- this->shouldAbort = false;
+// if(this->shouldAbort)
+// {
+// this->multimediaManager->shouldAbort((this->type == viper::managers::StreamType::VIDEO));
+// }
+// this->shouldAbort = false;
}
uint64_t BufferBasedAdaptation::getBitrate()
@@ -90,8 +89,8 @@ uint64_t BufferBasedAdaptation::getBitrate()
void BufferBasedAdaptation::setBitrate(uint32_t bufferFill)
{
- std::vector<IRepresentation *> representations;
- representations = this->adaptationSet->GetRepresentation();
+ std::vector<IRepresentation *> representations = this->mpdWrapper->getRepresentations(this->type);
+ this->representation = representations.at(0);
size_t i = 0;
if(representations.size() == 1)
@@ -112,7 +111,7 @@ void BufferBasedAdaptation::setBitrate(uint32_t bufferFill)
{
this->shouldAbort = true;
}
- Debug("ADAPTATION_LOGIC:\tFor %s:\tlast_buffer: %f\tbuffer_level: %f, choice: %lu, should_trigger_abort: %s\n",isVideo ? "video" : "audio",(double)lastBufferFill/100 , (double)bufferFill/100, i, this->shouldAbort ? "YES" : "NO");
+ Debug("ADAPTATION_LOGIC:\tFor %s:\tlast_buffer: %f\tbuffer_level: %f, choice: %lu, should_trigger_abort: %s\n", (this->type == viper::managers::StreamType::VIDEO) ? "video" : "audio",(double)lastBufferFill/100 , (double)bufferFill/100, i, this->shouldAbort ? "YES" : "NO");
this->lastBufferFill = bufferFill;
}
@@ -136,6 +135,8 @@ void BufferBasedAdaptation::checkedByDASHReceiver()
void BufferBasedAdaptation::bufferUpdate(uint32_t bufferFill, int maxC)
{
+ this->mpdWrapper->acquireLock();
this->setBitrate(bufferFill);
this->notifyBitrateChange();
+ this->mpdWrapper->releaseLock();
}
diff --git a/Adaptation/BufferBasedAdaptation.h b/Adaptation/BufferBasedAdaptation.h
index 32ad8045..f610064f 100644
--- a/Adaptation/BufferBasedAdaptation.h
+++ b/Adaptation/BufferBasedAdaptation.h
@@ -29,7 +29,8 @@ namespace adaptation
class BufferBasedAdaptation : public AbstractAdaptationLogic
{
public:
- BufferBasedAdaptation(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, bool isVid, struct AdaptationParameters *params);
+// BufferBasedAdaptation(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, bool isVid, struct AdaptationParameters *params);
+ BufferBasedAdaptation(viper::managers::StreamType type, libdash::framework::mpd::MPDWrapper *mpdWrapper, struct AdaptationParameters *params);
virtual ~BufferBasedAdaptation();
virtual LogicType getType();
@@ -47,15 +48,15 @@ public:
void checkedByDASHReceiver();
private:
- uint64_t currentBitrate;
+ uint64_t currentBitrate;
std::vector<uint64_t> availableBitrates;
viper::managers::IMultimediaManagerBase *multimediaManager;
- dash::mpd::IRepresentation *representation;
- uint32_t reservoirThreshold;
- uint32_t maxThreshold;
- uint32_t lastBufferFill;
- bool bufferEOS;
- bool shouldAbort;
+ dash::mpd::IRepresentation *representation;
+ uint32_t reservoirThreshold;
+ uint32_t maxThreshold;
+ uint32_t lastBufferFill;
+ bool bufferEOS;
+ bool shouldAbort;
};
}
}
diff --git a/Adaptation/BufferBasedAdaptationWithRateBased.cpp b/Adaptation/BufferBasedAdaptationWithRateBased.cpp
index 3a1895c0..3df1cf84 100644
--- a/Adaptation/BufferBasedAdaptationWithRateBased.cpp
+++ b/Adaptation/BufferBasedAdaptationWithRateBased.cpp
@@ -21,8 +21,8 @@ using namespace libdash::framework::adaptation;
using namespace libdash::framework::input;
using namespace libdash::framework::mpd;
-BufferBasedAdaptationWithRateBased::BufferBasedAdaptationWithRateBased(IMPD *mpd, IPeriod *period, IAdaptationSet *adaptationSet, bool isVid, struct AdaptationParameters *params) :
- AbstractAdaptationLogic(mpd, period, adaptationSet, isVid)
+BufferBasedAdaptationWithRateBased::BufferBasedAdaptationWithRateBased(viper::managers::StreamType type, MPDWrapper *mpdWrapper, struct AdaptationParameters *params) :
+ AbstractAdaptationLogic(type, mpdWrapper)
{
this->alphaRate = params->Adaptech_Alpha;
this->reservoirThreshold = params->Adaptech_FirstThreshold;
@@ -30,18 +30,18 @@ BufferBasedAdaptationWithRateBased::BufferBasedAdaptationWithRateBased(IMPD *mpd
this->switchUpThreshold = params->Adaptech_SwitchUpThreshold;
this->slackParam = params->Adaptech_SlackParameter;
- std::vector<IRepresentation* > representations = this->adaptationSet->GetRepresentation();
-
this->m_count = 0;
this->instantBw = 0;
this->averageBw = 0;
- this->representation = this->adaptationSet->GetRepresentation().at(0);
+// this->representation = this->adaptationSet->GetRepresentation().at(0);
+
this->multimediaManager = NULL;
this->lastBufferFill = 0;
this->bufferEOS = false;
this->shouldAbort = false;
this->isCheckedForReceiver = false;
this->myQuality = 0;
+ this->currentBitrate = 0;
Debug("BufferRateBasedParams:\talpha:%f\tfirst threshold: %f\tsecond threshold: %f\tswitch-up margin: %d\tSlack: %f\n",this->alphaRate, (double)reservoirThreshold/100, (double)maxThreshold/100, this->switchUpThreshold, this->slackParam);
Debug("Buffer Adaptation: STARTED\n");
}
@@ -75,18 +75,19 @@ void BufferBasedAdaptationWithRateBased::setMultimediaManager(viper::managers::I
void BufferBasedAdaptationWithRateBased::notifyBitrateChange()
{
+ this->mpdWrapper->setRepresentation(this->type, this->representation);
if(this->multimediaManager)
if(this->multimediaManager->isStarted() && !this->multimediaManager->isStopping())
- if(this->isVideo)
- this->multimediaManager->setVideoQuality(this->period, this->adaptationSet, this->representation);
+ if(this->type==viper::managers::StreamType::VIDEO)
+ this->multimediaManager->setVideoQuality();
else
- this->multimediaManager->setAudioQuality(this->period, this->adaptationSet, this->representation);
+ this->multimediaManager->setAudioQuality();
//Should Abort is done here to avoid race condition with DASHReceiver::DoBuffering()
- if(this->shouldAbort)
- {
- this->multimediaManager->shouldAbort(this->isVideo);
- }
- this->shouldAbort = false;
+// if(this->shouldAbort)
+// {
+// this->multimediaManager->shouldAbort((this->type == viper::managers::StreamType::VIDEO));
+// }
+// this->shouldAbort = false;
}
uint64_t BufferBasedAdaptationWithRateBased::getBitrate()
@@ -98,7 +99,7 @@ void BufferBasedAdaptationWithRateBased::setBitrate(uint32_t bufferFill)
{
uint32_t phi1, phi2;
std::vector<IRepresentation *> representations;
- representations = this->adaptationSet->GetRepresentation();
+ representations = this->mpdWrapper->getRepresentations(this->type);
size_t i = 0;
Debug("bufferlevel: %u, instant rate %lu, average rate %lu\n", bufferFill, this->instantBw, this->averageBw);
@@ -167,7 +168,7 @@ void BufferBasedAdaptationWithRateBased::setBitrate(uint32_t bufferFill)
}
this->representation = representations.at(this->myQuality);
this->currentBitrate = (uint64_t) this->representation->GetBandwidth();
- Debug("ADAPTATION_LOGIC:\tFor %s:\tlast_buffer: %f\tbuffer_level: %f, instantaneousBw: %lu, AverageBW: %lu, choice: %d\n",isVideo ? "video" : "audio",(double)lastBufferFill/100 , (double)bufferFill/100, this->instantBw, this->averageBw , this->myQuality);
+ Debug("ADAPTATION_LOGIC:\tFor %s:\tlast_buffer: %f\tbuffer_level: %f, instantaneousBw: %lu, AverageBW: %lu, choice: %d\n",(this->type == viper::managers::StreamType::VIDEO) ? "video" : "audio",(double)lastBufferFill/100 , (double)bufferFill/100, this->instantBw, this->averageBw , this->myQuality);
}
void BufferBasedAdaptationWithRateBased::bitrateUpdate(uint64_t bps, uint32_t segNum)
@@ -196,11 +197,14 @@ void BufferBasedAdaptationWithRateBased::checkedByDASHReceiver()
void BufferBasedAdaptationWithRateBased::bufferUpdate(uint32_t bufferFill, int maxC)
{
Debug("buffer update: %u\n", bufferFill);
+ EnterCriticalSection(&this->monitorLock);
this->setBitrate(bufferFill);
this->notifyBitrateChange();
+ LeaveCriticalSection(&this->monitorLock);
}
void BufferBasedAdaptationWithRateBased::dLTimeUpdate(double time)
{
}
+
diff --git a/Adaptation/BufferBasedAdaptationWithRateBased.h b/Adaptation/BufferBasedAdaptationWithRateBased.h
index 5c787d30..45147ed2 100644
--- a/Adaptation/BufferBasedAdaptationWithRateBased.h
+++ b/Adaptation/BufferBasedAdaptationWithRateBased.h
@@ -29,7 +29,8 @@ namespace adaptation
class BufferBasedAdaptationWithRateBased : public AbstractAdaptationLogic
{
public:
- BufferBasedAdaptationWithRateBased(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, bool isVid, struct AdaptationParameters *params);
+// BufferBasedAdaptationWithRateBased(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, bool isVid, struct AdaptationParameters *params);
+ BufferBasedAdaptationWithRateBased(viper::managers::StreamType type, libdash::framework::mpd::MPDWrapper *mpdWrapper, struct AdaptationParameters *params);
virtual ~BufferBasedAdaptationWithRateBased();
virtual LogicType getType();
@@ -48,22 +49,22 @@ public:
private:
uint64_t currentBitrate;
- std::vector<uint64_t> availableBitrates;
- viper::managers::IMultimediaManagerBase *multimediaManager;
- dash::mpd::IRepresentation *representation;
+ std::vector<uint64_t> availableBitrates;
+ viper::managers::IMultimediaManagerBase *multimediaManager;
+ dash::mpd::IRepresentation *representation;
uint32_t reservoirThreshold;
uint32_t maxThreshold;
uint32_t lastBufferFill;
- int m_count;
- int switchUpThreshold;
- bool bufferEOS;
- bool shouldAbort;
- double alphaRate;
+ int m_count;
+ int switchUpThreshold;
+ bool bufferEOS;
+ bool shouldAbort;
+ double alphaRate;
uint64_t averageBw;
uint64_t instantBw;
- int myQuality;
- double slackParam;
- bool isCheckedForReceiver;
+ int myQuality;
+ double slackParam;
+ bool isCheckedForReceiver;
};
}
}
diff --git a/Adaptation/BufferBasedThreeThresholdAdaptation.cpp b/Adaptation/BufferBasedThreeThresholdAdaptation.cpp
index 021e7b7c..7efab53a 100644
--- a/Adaptation/BufferBasedThreeThresholdAdaptation.cpp
+++ b/Adaptation/BufferBasedThreeThresholdAdaptation.cpp
@@ -20,23 +20,24 @@ using namespace dash::mpd;
using namespace libdash::framework::adaptation;
using namespace libdash::framework::input;
using namespace libdash::framework::mpd;
+using namespace viper::managers;
-BufferBasedThreeThresholdAdaptation::BufferBasedThreeThresholdAdaptation(IMPD *mpd, IPeriod *period, IAdaptationSet *adaptationSet, bool isVid, struct AdaptationParameters *params) :
- AbstractAdaptationLogic(mpd, period, adaptationSet, isVid)
+BufferBasedThreeThresholdAdaptation::BufferBasedThreeThresholdAdaptation(viper::managers::StreamType type, MPDWrapper *mpdWrapper, struct AdaptationParameters *params) :
+ AbstractAdaptationLogic(type, mpdWrapper)
{
- this->firstThreshold = params->BufferThreeThreshold_FirstThreshold;
- this->secondThreshold = params->BufferThreeThreshold_SecondThreshold;
- this->thirdThreshold = params->BufferThreeThreshold_ThirdThreshold;
- this->slackParam = params->BufferThreeThreshold_slackParameter;
- std::vector<IRepresentation* > representations = this->adaptationSet->GetRepresentation();
- this->representation = this->adaptationSet->GetRepresentation().at(0);
- this->multimediaManager = NULL;
- this->lastBufferFill = 0;
- this->bufferEOS = false;
- this->shouldAbort = false;
- this->isCheckedForReceiver = false;
- Debug("BufferRateBasedParams:\t%f\t%f\t%f\n",(double)this->firstThreshold/100, (double)secondThreshold/100, (double)thirdThreshold/100);
- Debug("Buffer Adaptation: STARTED\n");
+ this->firstThreshold = params->BufferThreeThreshold_FirstThreshold;
+ this->secondThreshold = params->BufferThreeThreshold_SecondThreshold;
+ this->thirdThreshold = params->BufferThreeThreshold_ThirdThreshold;
+ this->slackParam = params->BufferThreeThreshold_slackParameter;
+// this->representation = this->adaptationSet->GetRepresentation().at(0);
+ this->multimediaManager = NULL;
+ this->lastBufferFill = 0;
+ this->bufferEOS = false;
+ this->shouldAbort = false;
+ this->isCheckedForReceiver = false;
+ this->currentBitrate = 0;
+ Debug("BufferRateBasedParams:\t%f\t%f\t%f\n",(double)this->firstThreshold/100, (double)secondThreshold/100, (double)thirdThreshold/100);
+ Debug("Buffer Adaptation: STARTED\n");
}
BufferBasedThreeThresholdAdaptation::~BufferBasedThreeThresholdAdaptation()
@@ -70,18 +71,19 @@ void BufferBasedThreeThresholdAdaptation::setMultimediaManager(viper::managers::
void BufferBasedThreeThresholdAdaptation::notifyBitrateChange()
{
- if(this->multimediaManager)
- if(this->multimediaManager->isStarted() && !this->multimediaManager->isStopping())
- if(this->isVideo)
- this->multimediaManager->setVideoQuality(this->period, this->adaptationSet, this->representation);
- else
- this->multimediaManager->setAudioQuality(this->period, this->adaptationSet, this->representation);
- //Should Abort is done here to avoid race condition with DASHReceiver::DoBuffering()
- if(this->shouldAbort)
- {
- this->multimediaManager->shouldAbort(this->isVideo);
- }
- this->shouldAbort = false;
+ this->mpdWrapper->setRepresentation(this->type, this->representation);
+ if(this->multimediaManager)
+ if(this->multimediaManager->isStarted() && !this->multimediaManager->isStopping())
+ if(this->type == viper::managers::StreamType::VIDEO)
+ this->multimediaManager->setVideoQuality();
+ else
+ this->multimediaManager->setAudioQuality();
+ //Should Abort is done here to avoid race condition with DASHReceiver::DoBuffering()
+// if(this->shouldAbort)
+// {
+// this->multimediaManager->shouldAbort((this->type == viper::managers::StreamType::VIDEO));
+// }
+// this->shouldAbort = false;
}
uint64_t BufferBasedThreeThresholdAdaptation::getBitrate()
@@ -91,52 +93,53 @@ uint64_t BufferBasedThreeThresholdAdaptation::getBitrate()
void BufferBasedThreeThresholdAdaptation::setBitrate(uint32_t bufferFill)
{
- uint32_t phi1, phi2;
- std::vector<IRepresentation *> representations;
- representations = this->adaptationSet->GetRepresentation();
- size_t i = 0;
-
- if(this->isCheckedForReceiver)
- {
- return;
- }
- this->isCheckedForReceiver = true;
-
-
- if(bufferFill < this->firstThreshold)
- {
- this->myQuality = 0;
- }
- else
- {
- if(bufferFill < this->secondThreshold)
- {
- if(this->currentBitrate >= this->instantBw)
- {
- if(this->myQuality > 0)
- {
- this->myQuality--;
- }
- }
- }
- else
- {
- if(bufferFill < this->thirdThreshold)
- {
- }
- else
- {// bufferLevel > thirdThreshold
- if(this->currentBitrate <= this->instantBw)
- {
- if(this->myQuality < representations.size() - 1)
- this->myQuality++;
- }
- }
- }
- }
- this->representation = representations.at(this->myQuality);
- this->currentBitrate = (uint64_t) this->representation->GetBandwidth();
- Debug("ADAPTATION_LOGIC:\tFor %s:\tlast_buffer: %f\tbuffer_level: %f, instantaneousBw: %lu, choice: %d\n",isVideo ? "video" : "audio",(double)lastBufferFill/100 , (double)bufferFill/100, this->instantBw, this->myQuality);
+ uint32_t phi1, phi2;
+ std::vector<IRepresentation *> representations;
+ representations = this->mpdWrapper->getRepresentations(this->type);
+ this->representation = representations.at(0);
+ size_t i = 0;
+
+ if(this->isCheckedForReceiver)
+ {
+ return;
+ }
+ this->isCheckedForReceiver = true;
+
+
+ if(bufferFill < this->firstThreshold)
+ {
+ this->myQuality = 0;
+ }
+ else
+ {
+ if(bufferFill < this->secondThreshold)
+ {
+ if(this->currentBitrate >= this->instantBw)
+ {
+ if(this->myQuality > 0)
+ {
+ this->myQuality--;
+ }
+ }
+ }
+ else
+ {
+ if(bufferFill < this->thirdThreshold)
+ {
+ }
+ else
+ {// bufferLevel > thirdThreshold
+ if(this->currentBitrate <= this->instantBw)
+ {
+ if(this->myQuality < representations.size() - 1)
+ this->myQuality++;
+ }
+ }
+ }
+ }
+ this->representation = representations.at(this->myQuality);
+ this->currentBitrate = (uint64_t) this->representation->GetBandwidth();
+ Debug("ADAPTATION_LOGIC:\tFor %s:\tlast_buffer: %f\tbuffer_level: %f, instantaneousBw: %lu, choice: %d\n",(this->type == viper::managers::StreamType::VIDEO) ? "video" : "audio",(double)lastBufferFill/100 , (double)bufferFill/100, this->instantBw, this->myQuality);
}
void BufferBasedThreeThresholdAdaptation::bitrateUpdate(uint64_t bps, uint32_t segNum)
@@ -155,8 +158,10 @@ void BufferBasedThreeThresholdAdaptation::checkedByDASHReceiver()
}
void BufferBasedThreeThresholdAdaptation::bufferUpdate(uint32_t bufferFill, int maxC)
{
+ this->mpdWrapper->acquireLock();
this->setBitrate(bufferFill);
this->notifyBitrateChange();
+ this->mpdWrapper->releaseLock();
}
void BufferBasedThreeThresholdAdaptation::dLTimeUpdate(double time)
diff --git a/Adaptation/BufferBasedThreeThresholdAdaptation.h b/Adaptation/BufferBasedThreeThresholdAdaptation.h
index 62160bc3..1448bae2 100644
--- a/Adaptation/BufferBasedThreeThresholdAdaptation.h
+++ b/Adaptation/BufferBasedThreeThresholdAdaptation.h
@@ -29,7 +29,8 @@ namespace adaptation
class BufferBasedThreeThresholdAdaptation : public AbstractAdaptationLogic
{
public:
- BufferBasedThreeThresholdAdaptation(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, bool isVid, struct AdaptationParameters *params);
+// BufferBasedThreeThresholdAdaptation(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, bool isVid, struct AdaptationParameters *params);
+ BufferBasedThreeThresholdAdaptation(viper::managers::StreamType type, libdash::framework::mpd::MPDWrapper *mpdWrapper, struct AdaptationParameters *params);
virtual ~BufferBasedThreeThresholdAdaptation();
virtual LogicType getType();
@@ -47,20 +48,20 @@ public:
void checkedByDASHReceiver();
private:
- uint64_t currentBitrate;
+ uint64_t currentBitrate;
std::vector<uint64_t> availableBitrates;
viper::managers::IMultimediaManagerBase *multimediaManager;
- dash::mpd::IRepresentation *representation;
- uint32_t secondThreshold;
- uint32_t thirdThreshold;
- uint32_t lastBufferFill;
- bool bufferEOS;
- bool shouldAbort;
- uint32_t firstThreshold;
- uint64_t instantBw;
- int myQuality;
- double slackParam;
- bool isCheckedForReceiver;
+ dash::mpd::IRepresentation *representation;
+ uint32_t secondThreshold;
+ uint32_t thirdThreshold;
+ uint32_t lastBufferFill;
+ bool bufferEOS;
+ bool shouldAbort;
+ uint32_t firstThreshold;
+ uint64_t instantBw;
+ int myQuality;
+ double slackParam;
+ bool isCheckedForReceiver;
};
}
}
diff --git a/Adaptation/IAdaptationLogic.h b/Adaptation/IAdaptationLogic.h
index bfe980c7..081366dd 100644
--- a/Adaptation/IAdaptationLogic.h
+++ b/Adaptation/IAdaptationLogic.h
@@ -58,9 +58,9 @@ public:
virtual uint32_t getPosition() = 0;
virtual void setPosition(uint32_t segmentNumber) = 0;
virtual dash::mpd::IRepresentation* getRepresentation() = 0;
- virtual void setRepresentation(dash::mpd::IPeriod *period,
- dash::mpd::IAdaptationSet *adaptationSet,
- dash::mpd::IRepresentation *representation)= 0;
+// virtual void setRepresentation(dash::mpd::IPeriod *period,
+// dash::mpd::IAdaptationSet *adaptationSet,
+// dash::mpd::IRepresentation *representation)= 0;
virtual LogicType getType() = 0;
virtual bool isUserDependent()= 0;
virtual void bitrateUpdate(uint64_t bps, uint32_t segNum) = 0;
@@ -71,6 +71,7 @@ public:
virtual void setMultimediaManager(viper::managers::IMultimediaManagerBase *mmManager)= 0;
virtual void onEOS(bool value) = 0;
virtual void checkedByDASHReceiver() = 0;
+// virtual void updateMPD(dash::mpd::IMPD* mpd) = 0;
};
struct AdaptationParameters
diff --git a/Adaptation/Panda.cpp b/Adaptation/Panda.cpp
index cb2ec660..e0c19b27 100644
--- a/Adaptation/Panda.cpp
+++ b/Adaptation/Panda.cpp
@@ -21,9 +21,10 @@ using namespace dash::mpd;
using namespace libdash::framework::adaptation;
using namespace libdash::framework::input;
using namespace libdash::framework::mpd;
+using namespace viper::managers;
-PandaAdaptation::PandaAdaptation(IMPD *mpd, IPeriod *period, IAdaptationSet *adaptationSet, bool isVid, struct AdaptationParameters *params) :
- AbstractAdaptationLogic (mpd, period, adaptationSet, isVid)
+PandaAdaptation::PandaAdaptation(StreamType type, MPDWrapper *mpdWrapper, struct AdaptationParameters *params) :
+ AbstractAdaptationLogic (type, mpdWrapper)
{
this->param_Alpha = params->Panda_Alpha;
this->param_Beta = params->Panda_Beta;
@@ -52,17 +53,17 @@ PandaAdaptation::PandaAdaptation(IMPD *mpd, IPeriod *period, IAdaptationSet *ada
this->downloadTime = 0.0;
- this->isVideo = isVid;
- this->mpd = mpd;
- this->adaptationSet = adaptationSet;
- this->period = period;
+// this->mpd = mpd;
+// this->adaptationSet = adaptationSet;
+// this->period = period;
this->multimediaManager = NULL;
this->representation = NULL;
this->currentBitrate = 0;
this->current = 0;
// Retrieve the available bitrates
- std::vector<IRepresentation* > representations = this->adaptationSet->GetRepresentation();
+ this->mpdWrapper->acquireLock();
+ std::vector<IRepresentation* > representations = this->mpdWrapper->getRepresentations(this->type);
this->availableBitrates.clear();
Debug("PANDA Available Bitrates...\n");
@@ -72,7 +73,7 @@ PandaAdaptation::PandaAdaptation(IMPD *mpd, IPeriod *period, IAdaptationSet *ada
Debug("%d - %I64u bps\n", i+1, this->availableBitrates[i]);
}
- this->representation = this->adaptationSet->GetRepresentation().at(0);
+ this->representation = representations.at(0);
this->currentBitrate = (uint64_t) this->representation->GetBandwidth();
Debug("Panda parameters: K= %f, Bmin = %f, alpha = %f, beta = %f, W = %f\n", param_K, param_Bmin, param_Alpha, param_Beta, param_W);
@@ -108,11 +109,12 @@ void PandaAdaptation::setMultimediaManager (viper::managers::IMultimediaManagerB
void PandaAdaptation::notifyBitrateChange()
{
+ this->mpdWrapper->setRepresentation(this->type, this->representation);
if(this->multimediaManager->isStarted() && !this->multimediaManager->isStopping())
- if(this->isVideo)
- this->multimediaManager->setVideoQuality(this->period, this->adaptationSet, this->representation);
+ if(this->type == viper::managers::StreamType::VIDEO)
+ this->multimediaManager->setVideoQuality();
else
- this->multimediaManager->setAudioQuality(this->period, this->adaptationSet, this->representation);
+ this->multimediaManager->setAudioQuality();
}
uint64_t PandaAdaptation::getBitrate()
@@ -133,7 +135,7 @@ void PandaAdaptation::quantizer()
Debug("** Smooth-BW UP:\t%d\t Smooth-BW DOWN:\t%d\n", smoothBw_UP, smoothBw_DOWN);
std::vector<IRepresentation *> representations;
- representations = this->adaptationSet->GetRepresentation();
+ representations = this->mpdWrapper->getRepresentations(this->type);
uint32_t numQualLevels = representations.size();
// We have to find bitrateMin and bitrateMax
@@ -188,7 +190,7 @@ void PandaAdaptation::quantizer()
this->currentBitrate = bitrateDown;
this->current = iDown;
}
- this->representation = this->adaptationSet->GetRepresentation().at(this->current);
+ this->representation = representations.at(this->current);
}
void PandaAdaptation::setBitrate(uint64_t bps)
@@ -220,7 +222,7 @@ void PandaAdaptation::setBitrate(uint64_t bps)
// 3. Quantization
this->quantizer();
- Debug("ADAPTATION_LOGIC:\tFor %s:\tlast_buffer: %f\tbuffer_level: %f, instantaneousBw: %lu, AverageBW: %lu, choice: %d\n",isVideo ? "video" : "audio",(double)lastBufferLevel/100 , (double)bufferLevel/100, this->instantBw, this->averageBw , this->current);
+ Debug("ADAPTATION_LOGIC:\tFor %s:\tlast_buffer: %f\tbuffer_level: %f, instantaneousBw: %lu, AverageBW: %lu, choice: %d\n",(this->type == viper::managers::StreamType::VIDEO) ? "video" : "audio",(double)lastBufferLevel/100 , (double)bufferLevel/100, this->instantBw, this->averageBw , this->current);
this->lastBufferLevel = this->bufferLevel;
// 4. Computing the "actual inter time"
@@ -233,7 +235,7 @@ void PandaAdaptation::setBitrate(uint64_t bps)
this->interTime = this->interTime > 3 ? 3 : this->interTime;
Debug("** ACTUAL INTER TIME:\t%f\n", this->interTime);
- this->multimediaManager->setTargetDownloadingTime(this->isVideo, interTime);
+ this->multimediaManager->setTargetDownloadingTime((this->type == viper::managers::StreamType::VIDEO), interTime);
}
void PandaAdaptation::bitrateUpdate(uint64_t bps, uint32_t segNum)
@@ -249,9 +251,10 @@ void PandaAdaptation::bitrateUpdate(uint64_t bps, uint32_t segNum)
{
this->averageBw = this->alpha_ewma*this->averageBw + (1 - this->alpha_ewma)*bps;
}
-
+ this->mpdWrapper->acquireLock();
this->setBitrate(bps);
this->notifyBitrateChange();
+ this->mpdWrapper->releaseLock();
}
void PandaAdaptation::dLTimeUpdate(double time)
diff --git a/Adaptation/Panda.h b/Adaptation/Panda.h
index 000131a1..37b397fe 100644
--- a/Adaptation/Panda.h
+++ b/Adaptation/Panda.h
@@ -29,7 +29,8 @@ namespace adaptation
class PandaAdaptation : public AbstractAdaptationLogic
{
public:
- PandaAdaptation(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, bool isVid, struct AdaptationParameters *params);
+// PandaAdaptation(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, bool isVid, struct AdaptationParameters *params);
+ PandaAdaptation(viper::managers::StreamType type, libdash::framework::mpd::MPDWrapper *mpdWrapper, struct AdaptationParameters *params);
virtual ~PandaAdaptation();
virtual LogicType getType();
@@ -48,38 +49,36 @@ public:
void quantizer();
private:
- uint64_t currentBitrate;
+ uint64_t currentBitrate;
std::vector<uint64_t> availableBitrates;
viper::managers::IMultimediaManagerBase *multimediaManager;
- dash::mpd::IRepresentation *representation;
+ dash::mpd::IRepresentation *representation;
- uint64_t averageBw; // Classic EWMA
- uint64_t instantBw;
- uint64_t smoothBw; // Panda paper smoothed y[n]
- uint64_t targetBw; // Panda paper x[n] bw estimation
+ uint64_t averageBw; // Classic EWMA
+ uint64_t instantBw;
+ uint64_t smoothBw; // Panda paper smoothed y[n]
+ uint64_t targetBw; // Panda paper x[n] bw estimation
+ double param_Alpha;
+ double alpha_ewma;
+ double param_Epsilon;
+ double param_K;
+ double param_W;
+ double param_Beta;
+ double param_Bmin;
+ double interTime; // Actual inter time
+ double targetInterTime; // Target inter time
+ double downloadTime;
- double param_Alpha;
- double alpha_ewma;
- double param_Epsilon;
- double param_K;
- double param_W;
- double param_Beta;
- double param_Bmin;
+ uint32_t bufferLevel;
+ uint32_t lastBufferLevel;
+ double bufferMaxSizeSeconds; // Usually set to 60s
+ double bufferLevelSeconds; // Current buffer level [s]
- double interTime; // Actual inter time
- double targetInterTime; // Target inter time
- double downloadTime;
-
- uint32_t bufferLevel;
- uint32_t lastBufferLevel;
- double bufferMaxSizeSeconds; // Usually set to 60s
- double bufferLevelSeconds; // Current buffer level [s]
-
- double segmentDuration;
- double deltaUp;
- double deltaDown;
- size_t current;
+ double segmentDuration;
+ double deltaUp;
+ double deltaDown;
+ size_t current;
};
} /* namespace adaptation */
diff --git a/Adaptation/RateBasedAdaptation.cpp b/Adaptation/RateBasedAdaptation.cpp
index 73d4ee9b..14b3f3d6 100644
--- a/Adaptation/RateBasedAdaptation.cpp
+++ b/Adaptation/RateBasedAdaptation.cpp
@@ -19,11 +19,13 @@ using namespace dash::mpd;
using namespace libdash::framework::adaptation;
using namespace libdash::framework::input;
using namespace libdash::framework::mpd;
+using namespace viper::managers;
-RateBasedAdaptation::RateBasedAdaptation(IMPD *mpd, IPeriod *period, IAdaptationSet *adaptationSet, bool isVid, struct AdaptationParameters *params) :
- AbstractAdaptationLogic(mpd, period, adaptationSet, isVid)
+RateBasedAdaptation::RateBasedAdaptation(StreamType type, MPDWrapper *mpdWrapper, struct AdaptationParameters *params) :
+ AbstractAdaptationLogic(type, mpdWrapper)
{
- std::vector<IRepresentation* > representations = this->adaptationSet->GetRepresentation();
+ this->mpdWrapper->acquireLock();
+ std::vector<IRepresentation* > representations = this->mpdWrapper->getRepresentations(type);
this->availableBitrates.clear();
for(size_t i = 0; i < representations.size(); i++)
@@ -32,6 +34,7 @@ RateBasedAdaptation::RateBasedAdaptation(IMPD *mpd, IPeriod *period, IAdaptation
}
this->currentBitrate = this->availableBitrates.at(0);
this->representation = representations.at(0);
+ this->mpdWrapper->releaseLock();
this->multimediaManager = NULL;
this->alpha = params->Rate_Alpha;
Debug("RateBasedParams:\t%f\n",alpha);
@@ -69,11 +72,12 @@ void RateBasedAdaptation::setMultimediaManager(viper::managers::IMultimediaManag
void RateBasedAdaptation::notifyBitrateChange()
{
+ this->mpdWrapper->setRepresentation(this->type, this->representation);
if(this->multimediaManager->isStarted() && !this->multimediaManager->isStopping())
- if(this->isVideo)
- this->multimediaManager->setVideoQuality(this->period, this->adaptationSet, this->representation);
+ if(this->type == viper::managers::StreamType::VIDEO)
+ this->multimediaManager->setVideoQuality();
else
- this->multimediaManager->setAudioQuality(this->period, this->adaptationSet, this->representation);
+ this->multimediaManager->setAudioQuality();
}
uint64_t RateBasedAdaptation::getBitrate()
@@ -84,7 +88,7 @@ uint64_t RateBasedAdaptation::getBitrate()
void RateBasedAdaptation::setBitrate(uint64_t bps)
{
std::vector<IRepresentation *> representations;
- representations = this->adaptationSet->GetRepresentation();
+ representations = this->mpdWrapper->getRepresentations(this->type);
size_t i = 0;
this->ewma(bps);
for(i = 0;i < representations.size();i++)
@@ -99,7 +103,7 @@ void RateBasedAdaptation::setBitrate(uint64_t bps)
if((size_t)i == (size_t)(representations.size()))
i = i-1;
- Debug("ADAPTATION_LOGIC:\tFor %s:\tBW_estimation(ewma): %lu, choice: %lu\n", (this->isVideo ? "video" : "audio"), this->averageBw, i);
+ Debug("ADAPTATION_LOGIC:\tFor %s:\tBW_estimation(ewma): %lu, choice: %lu\n", ((this->type == viper::managers::StreamType::VIDEO) ? "video" : "audio"), this->averageBw, i);
this->representation = representations.at(i);
this->currentBitrate = this->representation->GetBandwidth();
}
@@ -107,8 +111,10 @@ void RateBasedAdaptation::setBitrate(uint64_t bps)
void RateBasedAdaptation::bitrateUpdate(uint64_t bps, uint32_t segNum)
{
Debug("Rate Based adaptation: speed received: %lu\n", bps);
+ this->mpdWrapper->acquireLock();
this->setBitrate(bps);
this->notifyBitrateChange();
+ this->mpdWrapper->releaseLock();
}
void RateBasedAdaptation::ewma(uint64_t bps)
diff --git a/Adaptation/RateBasedAdaptation.h b/Adaptation/RateBasedAdaptation.h
index cbf7471c..670bc031 100644
--- a/Adaptation/RateBasedAdaptation.h
+++ b/Adaptation/RateBasedAdaptation.h
@@ -29,7 +29,8 @@ namespace adaptation
class RateBasedAdaptation : public AbstractAdaptationLogic
{
public:
- RateBasedAdaptation(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, bool isVid, struct AdaptationParameters *params);
+// RateBasedAdaptation(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, bool isVid, struct AdaptationParameters *params);
+ RateBasedAdaptation(viper::managers::StreamType type, libdash::framework::mpd::MPDWrapper *mpdWrapper, struct AdaptationParameters *params);
virtual ~RateBasedAdaptation();
virtual LogicType getType();
@@ -47,12 +48,12 @@ public:
void ewma(uint64_t bps);
void checkedByDASHReceiver();
private:
- uint64_t currentBitrate;
+ uint64_t currentBitrate;
std::vector<uint64_t> availableBitrates;
viper::managers::IMultimediaManagerBase *multimediaManager;
- dash::mpd::IRepresentation *representation;
- double alpha;
- uint64_t averageBw;
+ dash::mpd::IRepresentation *representation;
+ double alpha;
+ uint64_t averageBw;
};
}
}
diff --git a/Common/ViperBuffer.cpp b/Common/ViperBuffer.cpp
index 27ec8b5e..c59cec04 100644
--- a/Common/ViperBuffer.cpp
+++ b/Common/ViperBuffer.cpp
@@ -12,7 +12,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
+#include <stdio.h>
#include "ViperBuffer.h"
ViperBuffer::ViperBuffer(QObject* parent) :
QIODevice(parent)
@@ -76,17 +76,18 @@ qint64 ViperBuffer::readData(char* data, qint64 maxSize)
qint64 ViperBuffer::writeData(libdash::framework::input::MediaObject* media)
{
pthread_mutex_lock(&(this->monitorMutex));
+
int ret = 0;
int total = 0;
ret = media->ReadInitSegment(readBuffer,readMax);
total += ret;
this->writeData((const char *)readBuffer, ret);
-
ret = media->Read(readBuffer,readMax);
while(ret)
{
total += ret;
this->writeData((const char *)readBuffer, ret);
+
ret = media->Read(readBuffer,readMax);
}
pthread_mutex_unlock(&(this->monitorMutex));
diff --git a/Input/DASHManager.cpp b/Input/DASHManager.cpp
index a86263dc..4d52a638 100644
--- a/Input/DASHManager.cpp
+++ b/Input/DASHManager.cpp
@@ -17,8 +17,9 @@ using namespace libdash::framework::buffer;
using namespace dash;
using namespace dash::network;
using namespace dash::mpd;
+using namespace libdash::framework::mpd;
-DASHManager::DASHManager(viper::managers::StreamType type, uint32_t maxCapacity, IDASHManagerObserver* stream, IMPD* mpd, bool icnEnabled, double icnAlpha, bool nodecoding, float beta, float drop) :
+DASHManager::DASHManager(viper::managers::StreamType type, uint32_t maxCapacity, IDASHManagerObserver* stream, MPDWrapper* mpdWrapper, bool icnEnabled, double icnAlpha, bool nodecoding, float beta, float drop) :
readSegmentCount (0),
receiver (NULL),
multimediaStream (stream),
@@ -33,7 +34,7 @@ DASHManager::DASHManager(viper::managers::StreamType type, uint32_t maxCapacity,
this->buffer = new Buffer<MediaObject>(maxCapacity,libdash::framework::buffer::VIDEO);
this->buffer->attachObserver(this);
- this->receiver = new DASHReceiver(mpd, this, this->buffer, maxCapacity, this->isICN(), this->icnAlpha, this->beta, this->drop);
+ this->receiver = new DASHReceiver(type, mpdWrapper, this, this->buffer, maxCapacity, this->isICN(), this->icnAlpha, this->beta, this->drop);
}
DASHManager::~DASHManager()
{
@@ -107,14 +108,14 @@ void DASHManager::clear()
this->buffer->clear();
}
-void DASHManager::setRepresentation(IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation)
+void DASHManager::setRepresentation()
{
- this->receiver->SetRepresentation(period, adaptationSet, representation);
+ this->receiver->SetRepresentation();
}
void DASHManager::enqueueRepresentation(IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation)
{
- this->receiver->SetRepresentation(period, adaptationSet, representation);
+// this->receiver->SetRepresentation(period, adaptationSet, representation);
}
void DASHManager::onSegmentDownloaded()
@@ -159,3 +160,13 @@ void DASHManager::onBufferStateChanged(BufferType type, uint32_t fillstateInPerc
if(this->adaptationLogic->isBufferBased())
this->receiver->OnSegmentBufferStateChanged(fillstateInPercent, maxC);
}
+
+void DASHManager::updateMPD(IMPD* mpd)
+{
+// this->receiver->updateMPD(mpd);
+}
+
+void DASHManager::fetchMPD()
+{
+ this->multimediaStream->fetchMPD();
+}
diff --git a/Input/DASHManager.h b/Input/DASHManager.h
index 2b723426..6bd54da9 100644
--- a/Input/DASHManager.h
+++ b/Input/DASHManager.h
@@ -22,18 +22,21 @@
#include "../Managers/IStreamObserver.h"
#include "../Buffer/IBufferObserver.h"
-
namespace libdash
{
namespace framework
{
+namespace mpd
+{
+class MPDWrapper;
+}
namespace input
{
class DASHManager : public IDASHReceiverObserver, public IBufferObserver
{
public:
- DASHManager (viper::managers::StreamType type, uint32_t maxCapacity, IDASHManagerObserver *multimediaStream, dash::mpd::IMPD *mpd, bool icnEnabled, double icnAlpha, bool nodecoding, float beta, float drop);
+ DASHManager (viper::managers::StreamType type, uint32_t maxCapacity, IDASHManagerObserver *multimediaStream, libdash::framework::mpd::MPDWrapper *mpdWrapper, bool icnEnabled, double icnAlpha, bool nodecoding, float beta, float drop);
virtual ~DASHManager ();
bool start();
@@ -43,7 +46,8 @@ public:
void setLooping(bool looping);
void setPositionInMsec(uint32_t millisec);
void clear();
- void setRepresentation(dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation);
+// void setRepresentation(dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation);
+ void setRepresentation();
void enqueueRepresentation(dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation);
void onSegmentDownloaded();
@@ -58,19 +62,20 @@ public:
void setTargetDownloadingTime(double);
MediaObject* getSegment();
void onBufferStateChanged(BufferType type, uint32_t fillstateInPercent, int maxC);
+ void updateMPD(dash::mpd::IMPD* mpd);
+ void fetchMPD();
private:
- float beta;
- float drop;
- buffer::Buffer<MediaObject> *buffer;
- DASHReceiver *receiver;
- uint32_t readSegmentCount;
- IDASHManagerObserver *multimediaStream;
+ float beta;
+ float drop;
+ buffer::Buffer<MediaObject> *buffer;
+ DASHReceiver *receiver;
+ uint32_t readSegmentCount;
+ IDASHManagerObserver *multimediaStream;
bool isRunning;
bool icn;
double icnAlpha;
bool noDecoding;
-
libdash::framework::adaptation::IAdaptationLogic *adaptationLogic;
};
}
diff --git a/Input/DASHReceiver.cpp b/Input/DASHReceiver.cpp
index bbfe3e35..aaa75205 100644
--- a/Input/DASHReceiver.cpp
+++ b/Input/DASHReceiver.cpp
@@ -19,44 +19,47 @@ using namespace dash::mpd;
using duration_in_seconds = std::chrono::duration<double, std::ratio<1, 1> >;
-DASHReceiver::DASHReceiver (IMPD *mpd, IDASHReceiverObserver *obs, Buffer<MediaObject> *buffer, uint32_t bufferSize, bool icnEnabled, double icnAlpha, float beta, float drop) :
- mpd (mpd),
- period (NULL),
- adaptationSet (NULL),
- representation (NULL),
- adaptationSetStream (NULL),
- representationStream (NULL),
- segmentNumber (0),
- observer (obs),
- buffer (buffer),
- bufferSize (bufferSize),
- isBuffering (false),
- withFeedBack (false),
- icn (icnEnabled),
- icnAlpha (icnAlpha),
- previousQuality (0),
- isPaused (false),
- threadComplete (false),
- isScheduledPaced (false),
- targetDownload (0.0),
- downloadingTime (0.0),
- bufferLevelAtUpdate (0),
- isBufferBased (false),
- isLooping (false),
- beta (beta),
- drop (drop)
+DASHReceiver::DASHReceiver (viper::managers::StreamType type, MPDWrapper *mpdWrapper, IDASHReceiverObserver *obs, Buffer<MediaObject> *buffer, uint32_t bufferSize, bool icnEnabled, double icnAlpha, float beta, float drop) :
+ type (type),
+ mpdWrapper (mpdWrapper),
+// period (NULL),
+// adaptationSet (NULL),
+// representation (NULL),
+ adaptationSetStream (NULL),
+// representationStream (NULL),
+ segmentNumber (0),
+ observer (obs),
+ buffer (buffer),
+ bufferSize (bufferSize),
+ isBuffering (false),
+ withFeedBack (false),
+ icn (icnEnabled),
+ icnAlpha (icnAlpha),
+ previousQuality (0),
+ isPaused (false),
+ threadComplete (false),
+ isScheduledPaced (false),
+ targetDownload (0.0),
+ downloadingTime (0.0),
+ bufferLevelAtUpdate (0),
+ isBufferBased (false),
+ isLooping (false),
+ beta (beta),
+ drop (drop),
+ bufferingThread (NULL),
+ mpdFetcherThread (NULL)
{
readMax = 32768;
readBuffer = (uint8_t*)malloc(sizeof(uint8_t)*readMax);
- this->period = this->mpd->GetPeriods().at(0);
- this->adaptationSet = this->period->GetAdaptationSets().at(0);
- this->representation = this->adaptationSet->GetRepresentation().at(0);
+// this->period = this->mpd->GetPeriods().at(0);
+// this->adaptationSet = this->period->GetAdaptationSets().at(0);
+// this->representation = this->adaptationSet->GetRepresentation().at(0);
- this->adaptationSetStream = new AdaptationSetStream(mpd, period, adaptationSet);
- this->representationStream = adaptationSetStream->getRepresentationStream(this->representation);
+ this->adaptationSetStream = new AdaptationSetStream(type, mpdWrapper);
+// this->representationStream = adaptationSetStream->getRepresentationStream(this->representation);
this->segmentOffset = CalculateSegmentOffset();
- this->representationStream->setSegmentOffset(this->segmentOffset);
-
+// this->representationStream->setSegmentOffset(this->segmentOffset);
+ this->mpdWrapper->setSegmentOffset(type, this->segmentOffset);
this->conn = NULL;
this->initConn = NULL;
readMax = 32768;
@@ -103,7 +106,15 @@ bool DASHReceiver::Start ()
this->isBuffering = false;
return false;
}
-
+ //if dynamic, set up the fetching loop
+ if(!strcmp(this->mpdWrapper->getType().c_str(), "dynamic"))
+ {
+ this->mpdFetcherThread = createThreadPortable(DoMPDFetching, this);
+ if(this->mpdFetcherThread == NULL)
+ {
+ std::cout << "mpd Fetcher thread is NULL. Need to think of how to handle this?" << std::endl;
+ }
+ }
return true;
}
void DASHReceiver::Stop()
@@ -119,83 +130,43 @@ void DASHReceiver::Stop()
JoinThread(this->bufferingThread);
destroyThreadPortable(this->bufferingThread);
}
- this->period = this->mpd->GetPeriods().at(0);
- this->adaptationSet = this->period->GetAdaptationSets().at(0);
- this->representation = this->adaptationSet->GetRepresentation().at(0);
+ if(this->mpdFetcherThread != NULL)
+ {
+ JoinThread(this->mpdFetcherThread);
+ destroyThreadPortable(this->mpdFetcherThread);
+ }
}
MediaObject* DASHReceiver::GetNextSegment ()
{
- ISegment *seg = NULL;
EnterCriticalSection(&this->monitorPausedMutex);
while(this->isPaused)
SleepConditionVariableCS(&this->paused, &this->monitorPausedMutex, INFINITE);
- if(!strcmp(this->mpd->GetType().c_str(), "static"))
- {
- if(this->segmentNumber >= this->representationStream->getSize())
- {
- qDebug("looping? : %s\n", this->isLooping ? "YES" : "NO");
- if(this->isLooping)
- {
- this->segmentNumber = 0;
- }
- else
- {
- LeaveCriticalSection(&this->monitorPausedMutex);
- return NULL;
- }
- }
- }
- seg = this->representationStream->getMediaSegment(this->segmentNumber);
-
- if (seg != NULL)
- {
- std::vector<IRepresentation *> rep = this->adaptationSet->GetRepresentation();
-
- this->NotifyQualityDownloading(this->representation->GetBandwidth());
+ MediaObject *media = this->mpdWrapper->getNextSegment(type, isLooping, this->segmentNumber, withFeedBack);
- MediaObject *media = new MediaObject(seg, this->representation,this->withFeedBack);
- this->segmentNumber++;
- LeaveCriticalSection(&this->monitorPausedMutex);
- return media;
- }
+ if(media)
+ this->NotifyQualityDownloading(media->GetRepresentationBandwidth());
LeaveCriticalSection(&this->monitorPausedMutex);
- return NULL;
+ return media;
}
MediaObject* DASHReceiver::GetSegment (uint32_t segNum)
{
- ISegment *seg = NULL;
-
- if(segNum >= this->representationStream->getSize())
- return NULL;
-
- seg = this->representationStream->getMediaSegment(segNum);
-
- if (seg != NULL)
- {
- MediaObject *media = new MediaObject(seg, this->representation);
- return media;
- }
-
- return NULL;
+ return this->mpdWrapper->getSegment(type, segNum);
}
+
MediaObject* DASHReceiver::GetInitSegment ()
{
- ISegment *seg = NULL;
-
- seg = this->representationStream->getInitializationSegment();
-
- if (seg != NULL)
- {
- MediaObject *media = new MediaObject(seg, this->representation);
- return media;
- }
+ return this->mpdWrapper->getInitSegment(type);
+}
- return NULL;
+MediaObject* DASHReceiver::GetInitSegmentWithoutLock ()
+{
+ return this->mpdWrapper->getInitSegmentWithoutLock(type);
}
-MediaObject* DASHReceiver::FindInitSegment (dash::mpd::IRepresentation *representation)
+
+MediaObject* DASHReceiver::FindInitSegment (int representation)
{
if (!this->InitSegmentExists(representation))
return NULL;
@@ -224,45 +195,9 @@ void DASHReceiver::NotifyQualityDownloading (uint32_t quality)
this->observer->notifyQualityDownloading(quality);
}
-void DASHReceiver::SetRepresentation (IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation)
+void DASHReceiver::SetRepresentation ()
{
- EnterCriticalSection(&this->monitorMutex);
-
- bool periodChanged = false;
-
- if (this->representation == representation)
- {
- LeaveCriticalSection(&this->monitorMutex);
- return;
- }
-
- this->representation = representation;
-
- if (this->adaptationSet != adaptationSet)
- {
- this->adaptationSet = adaptationSet;
-
- if (this->period != period)
- {
- this->period = period;
- periodChanged = true;
- }
-
- delete this->adaptationSetStream;
- this->adaptationSetStream = NULL;
-
- this->adaptationSetStream = new AdaptationSetStream(this->mpd, this->period, this->adaptationSet);
- }
-
- this->representationStream = this->adaptationSetStream->getRepresentationStream(this->representation);
- this->DownloadInitSegment(this->representation);
-
- if (periodChanged)
- {
- this->segmentNumber = 0;
- this->CalculateSegmentOffset();
- }
- LeaveCriticalSection(&this->monitorMutex);
+ this->DownloadInitSegmentWithoutLock();
}
libdash::framework::adaptation::IAdaptationLogic* DASHReceiver::GetAdaptationLogic ()
@@ -271,19 +206,13 @@ libdash::framework::adaptation::IAdaptationLogic* DASHReceiver::GetAdaptationLog
}
dash::mpd::IRepresentation* DASHReceiver::GetRepresentation ()
{
- return this->representation;
+ return NULL;
}
uint32_t DASHReceiver::CalculateSegmentOffset ()
{
- if (mpd->GetType() == "static")
- return 0;
-
- uint32_t firstSegNum = this->representationStream->getFirstSegmentNumber();
- uint32_t currSegNum = this->representationStream->getCurrentSegmentNumber();
- uint32_t startSegNum = currSegNum - 2*bufferSize;
-
- return (startSegNum > firstSegNum) ? startSegNum : firstSegNum;
+ return this->mpdWrapper->calculateSegmentOffset(type, bufferSize);
}
+
void DASHReceiver::NotifySegmentDownloaded ()
{
this->observer->onSegmentDownloaded();
@@ -291,14 +220,32 @@ void DASHReceiver::NotifySegmentDownloaded ()
void DASHReceiver::NotifyBitrateChange(dash::mpd::IRepresentation *representation)
{
- if(this->representation != representation)
+// if(this->representation != representation)
+// {
+// this->representation = representation;
+// this->SetRepresentation(this->period,this->adaptationSet,this->representation);
+// }
+}
+void DASHReceiver::DownloadInitSegmentWithoutLock ()
+{
+ int rep = std::stoi(this->mpdWrapper->getRepresentationIDWithoutLock(type).c_str());
+ if (this->InitSegmentExists(rep))
+ return;
+
+ MediaObject *initSeg = NULL;
+ initSeg = this->GetInitSegmentWithoutLock();
+
+ if (initSeg)
{
- this->representation = representation;
- this->SetRepresentation(this->period,this->adaptationSet,this->representation);
+ initSeg->StartDownload(this->initConn);
+ this->initSegments[rep] = initSeg;
+ initSeg->WaitFinished();
}
}
-void DASHReceiver::DownloadInitSegment (IRepresentation* rep)
+
+void DASHReceiver::DownloadInitSegment ()
{
+ int rep = std::stoi(this->mpdWrapper->getRepresentationID(type).c_str());
if (this->InitSegmentExists(rep))
return;
@@ -312,7 +259,8 @@ void DASHReceiver::DownloadInitSegment (IRepresentatio
initSeg->WaitFinished();
}
}
-bool DASHReceiver::InitSegmentExists (IRepresentation* rep)
+
+bool DASHReceiver::InitSegmentExists (int rep)
{
if (this->initSegments.find(rep) != this->initSegments.end())
return true;
@@ -358,20 +306,18 @@ void DASHReceiver::OnEOS(bool value)
bool DASHReceiver::PushBack(MediaObject *mediaObject)
{
- MediaObject *init = this->FindInitSegment(mediaObject->GetRepresentation());
+ MediaObject *init = this->FindInitSegment(mediaObject->GetRepresentationID());
mediaObject->AddInitSegment(init);
//TODO the read should be in a function
//Grab the infos for the analytics: bitrate, fps
- dash::mpd::IRepresentation* datRep = mediaObject->GetRepresentation();
uint32_t bitrate = 0;
int fps = 0;
uint32_t quality = 0;
- bitrate = datRep->GetBandwidth();
- quality = datRep->GetHeight();
+ bitrate = mediaObject->GetRepresentationBandwidth();
+ quality = mediaObject->GetRepresentationHeight();
fps = this->bufferLevelAtUpdate;
this->observer->notifyStatistics((int)this->segmentNumber - 1, bitrate, fps, quality);
-
return(this->buffer->pushBack(mediaObject));
}
@@ -380,7 +326,7 @@ void* DASHReceiver::DoBuffering (void *recei
{
DASHReceiver *dashReceiver = (DASHReceiver *) receiver;
- dashReceiver->DownloadInitSegment(dashReceiver->GetRepresentation());
+ dashReceiver->DownloadInitSegment();
MediaObject *media = dashReceiver->GetNextSegment();
dashReceiver->NotifyCheckedAdaptationLogic();
@@ -426,6 +372,25 @@ void* DASHReceiver::DoBuffering (void *recei
return NULL;
}
+void* DASHReceiver::DoMPDFetching (void* receiver)
+{
+ DASHReceiver* dashReceiver = (DASHReceiver*) receiver;
+ uint32_t currTime = TimeResolver::getCurrentTimeInSec();
+ uint32_t publishedTime = TimeResolver::getUTCDateTimeInSec(dashReceiver->mpdWrapper->getPublishTime());
+ uint32_t period = TimeResolver::getDurationInSec(dashReceiver->mpdWrapper->getMinimumUpdatePeriod());
+ while(dashReceiver->isBuffering)
+ {
+ while(dashReceiver->isBuffering && currTime < publishedTime + period)
+ {
+ usleep(((publishedTime + period) - currTime) * 1000000);
+ currTime = TimeResolver::getCurrentTimeInSec();
+ }
+ dashReceiver->observer->fetchMPD();
+ publishedTime = TimeResolver::getUTCDateTimeInSec(dashReceiver->mpdWrapper->getPublishTime());
+ period = TimeResolver::getDurationInSec(dashReceiver->mpdWrapper->getMinimumUpdatePeriod());
+ }
+}
+
//can Push video to buffer in the renderer
bool DASHReceiver::CanPush ()
{
@@ -454,4 +419,30 @@ void DASHReceiver::SetDrop (float drop)
this->drop = drop;
}
+void DASHReceiver::updateMPD(IMPD* mpd)
+{
+// EnterCriticalSection(&this->monitorMutex);
+ //First we need to find the new segmentNumber -> what is the segment time now?
+// uint32_t time = this->representationStream->getTime(this->segmentNumber);
+// printf("old segmentNumber!: %d\n", this->segmentNumber);
+// printf("time: %u\n", time);
+ //Second, replace the MPD with the new one
+// delete(this->mpd);
+// this->mpd = mpd;
+//
+ //Third, Update all the structures associated to the mpd
+// this->period = this->mpd->GetPeriods().at(0);
+// this->adaptationSet = this->period->GetAdaptationSets().at(0);
+// this->representation = this->adaptationSet->GetRepresentation().at(0);
+// delete(this->adaptationSetStream);
+// this->adaptationSetStream = new AdaptationSetStream(mpd, period, adaptationSet);
+// this->representationStream = adaptationSetStream->getRepresentationStream(this->representation);
+// this->segmentOffset = CalculateSegmentOffset();
+// this->representationStream->setSegmentOffset(this->segmentOffset);
+//
+ //Fourth, Set the new segmentNumber by finding the index of the segment associated to 'uint32_t time' in the new mpd
+// this->segmentNumber = this->representationStream->getSegmentNumber(time);
+// printf("new segmentNumber!: %d\n", this->segmentNumber);
+// LeaveCriticalSection(&this->monitorMutex);
+}
diff --git a/Input/DASHReceiver.h b/Input/DASHReceiver.h
index a2893b4d..cf56166b 100644
--- a/Input/DASHReceiver.h
+++ b/Input/DASHReceiver.h
@@ -14,7 +14,7 @@
#include "libdash.h"
#include "IMPD.h"
-
+#include "../MPD/MPDWrapper.h"
#include "../Input/MediaObject.h"
#include "IDASHReceiverObserver.h"
#include "../MPD/AdaptationSetStream.h"
@@ -28,6 +28,10 @@ namespace libdash
{
namespace framework
{
+namespace mpd
+{
+class AdaptationSetStream;
+}
namespace adaptation
{
class IAdaptationLogic;
@@ -44,7 +48,7 @@ class MediaObject;
class DASHReceiver
{
public:
- DASHReceiver(dash::mpd::IMPD *mpd, IDASHReceiverObserver *obs, buffer::Buffer<MediaObject> *buffer, uint32_t bufferSize, bool icnEnabled, double icnAlpha, float beta, float drop);
+ DASHReceiver(viper::managers::StreamType type, libdash::framework::mpd::MPDWrapper *mpdWrapper, IDASHReceiverObserver *obs, buffer::Buffer<MediaObject> *buffer, uint32_t bufferSize, bool icnEnabled, double icnAlpha, float beta, float drop);
virtual ~DASHReceiver();
bool Start();
@@ -52,15 +56,18 @@ public:
input::MediaObject* GetNextSegment();
input::MediaObject* GetSegment(uint32_t segmentNumber);
input::MediaObject* GetInitSegment();
- input::MediaObject* FindInitSegment(dash::mpd::IRepresentation *representation);
+ input::MediaObject* GetInitSegmentWithoutLock();
+// input::MediaObject* FindInitSegment(dash::mpd::IRepresentation *representation);
+ input::MediaObject* FindInitSegment(int representation);
uint32_t GetPosition();
void SetPosition(uint32_t segmentNumber);
void SetLooping(bool isLoopinp);
void SetPositionInMsecs(uint32_t milliSecs);
dash::mpd::IRepresentation* GetRepresentation();
- void SetRepresentation(dash::mpd::IPeriod *period,
- dash::mpd::IAdaptationSet *adaptationSet,
- dash::mpd::IRepresentation *representation);
+// void SetRepresentation(dash::mpd::IPeriod *period,
+// dash::mpd::IAdaptationSet *adaptationSet,
+// dash::mpd::IRepresentation *representation);
+ void SetRepresentation();
void SetAdaptationLogic(adaptation::IAdaptationLogic *_adaptationLogic);
libdash::framework::adaptation::IAdaptationLogic* GetAdaptationLogic();
void NotifyQualityDownloading(uint32_t quality);
@@ -78,21 +85,24 @@ public:
bool CanPush();
void SetBeta(float beta);
void SetDrop(float drop);
+ void updateMPD(dash::mpd::IMPD* mpd);
private:
float beta;
float drop;
bool withFeedBack;
bool isBufferBased;
- std::map<dash::mpd::IRepresentation*, MediaObject*> initSegments;
+// std::map<dash::mpd::IRepresentation*, MediaObject*> initSegments;
+ std::map<int, MediaObject*> initSegments;
libdash::framework::buffer::Buffer<MediaObject> *buffer;
IDASHReceiverObserver *observer;
- dash::mpd::IMPD *mpd;
- dash::mpd::IPeriod *period;
- dash::mpd::IAdaptationSet *adaptationSet;
- dash::mpd::IRepresentation *representation;
+ libdash::framework::mpd::MPDWrapper *mpdWrapper;
+// dash::mpd::IMPD *mpd;
+// dash::mpd::IPeriod *period;
+// dash::mpd::IAdaptationSet *adaptationSet;
+// dash::mpd::IRepresentation *representation;
mpd::AdaptationSetStream *adaptationSetStream;
- mpd::IRepresentationStream *representationStream;
+// mpd::IRepresentationStream *representationStream;
uint32_t segmentNumber;
uint32_t positionInMsecs;
uint32_t segmentOffset;
@@ -109,6 +119,7 @@ private:
IICNConnection *conn;
IICNConnection *initConn;
THREAD_HANDLE bufferingThread;
+ THREAD_HANDLE mpdFetcherThread;
bool isBuffering;
bool icn;
double icnAlpha;
@@ -116,11 +127,16 @@ private:
int bufferLevelAtUpdate;
int readMax;
uint8_t *readBuffer;
+ viper::managers::StreamType type;
uint32_t CalculateSegmentOffset();
void NotifySegmentDownloaded();
- void DownloadInitSegment(dash::mpd::IRepresentation* rep);
- bool InitSegmentExists(dash::mpd::IRepresentation* rep);
+// void DownloadInitSegment(dash::mpd::IRepresentation* rep);
+ void DownloadInitSegment();
+ void DownloadInitSegmentWithoutLock();
+// bool InitSegmentExists(dash::mpd::IRepresentation* rep);
+ bool InitSegmentExists(int rep);
static void* DoBuffering(void *receiver);
+ static void* DoMPDFetching(void * data);
};
}
}
diff --git a/Input/ICNConnectionConsumerApi.cpp b/Input/ICNConnectionConsumerApi.cpp
index 8f28e5ce..04b378df 100644
--- a/Input/ICNConnectionConsumerApi.cpp
+++ b/Input/ICNConnectionConsumerApi.cpp
@@ -68,7 +68,7 @@ ICNConnectionConsumerApi::ICNConnectionConsumerApi(double alpha, float beta, flo
}
if(!configFile)
{
- qDebug("beta %f, drop %f", this->beta, this->drop);
+// qDebug("beta %f, drop %f", this->beta, this->drop);
// this->myConsumer->setSocketOption(RaaqmTransportOptions::BETA_VALUE, this->beta);
// this->myConsumer->setSocketOption(RaaqmTransportOptions::DROP_FACTOR, this->drop);
}
@@ -104,8 +104,8 @@ void ICNConnectionConsumerApi::Init(IChunk *chunk) {
m_isFinished = false;
res = false;
- qDebug("ICN_Connection:\tINTIATED_to_name %s\n", m_name.c_str());
- qDebug("ICN_Connection:\tSTARTING DOWNLOAD %s\n", m_name.c_str());
+ Debug("ICN_Connection:\tINTIATED_to_name %s\n", m_name.c_str());
+ Debug("ICN_Connection:\tSTARTING DOWNLOAD %s\n", m_name.c_str());
}
void ICNConnectionConsumerApi::InitForMPD(const std::string& url)
@@ -118,7 +118,6 @@ void ICNConnectionConsumerApi::InitForMPD(const std::string& url)
res = false;
dataPos = 0;
datSize = 0;
-
Debug("ICN_Connection:\tINTIATED_for_mpd %s\n", m_name.c_str());
}
@@ -134,7 +133,6 @@ int ICNConnectionConsumerApi::Read(uint8_t *data, size_t len)
std::string s(m_name.c_str());
hTTPClientConnection->get(s);
response = hTTPClientConnection->response();
- std::cout << m_name.c_str()<< " SIZE:" << response.size() << std::endl;
this->res = true;
this->dataPos = 0;
}
diff --git a/Input/IDASHManagerObserver.h b/Input/IDASHManagerObserver.h
index c5df8fe9..1003d8a1 100644
--- a/Input/IDASHManagerObserver.h
+++ b/Input/IDASHManagerObserver.h
@@ -34,6 +34,7 @@ public:
virtual void notifyQualityDownloading (uint32_t quality) = 0;
virtual bool canPush() = 0;
virtual int getBufferLevel() = 0;
+ virtual void fetchMPD() = 0;
};
}
}
diff --git a/Input/IDASHReceiverObserver.h b/Input/IDASHReceiverObserver.h
index 0a334aa2..f6a2baa1 100644
--- a/Input/IDASHReceiverObserver.h
+++ b/Input/IDASHReceiverObserver.h
@@ -28,6 +28,7 @@ public:
virtual void notifyQualityDownloading(uint32_t quality) = 0;
virtual bool canPush() = 0;
virtual int getBufferLevel() = 0;
+ virtual void fetchMPD() = 0;
};
}
}
diff --git a/Input/MediaObject.cpp b/Input/MediaObject.cpp
index ae6b9f6b..f479a886 100644
--- a/Input/MediaObject.cpp
+++ b/Input/MediaObject.cpp
@@ -26,6 +26,9 @@ MediaObject::MediaObject(ISegment *segment, IRepresentation *rep, bool withFeedB
this->initSeg = NULL;
InitializeConditionVariable (&this->stateChanged);
InitializeCriticalSection (&this->stateLock);
+ this->representationBandwidth = rep->GetBandwidth();
+ this->representationHeight = rep->GetHeight();
+ this->representationId = std::stoi(rep->GetId());
}
MediaObject::~MediaObject()
@@ -44,6 +47,21 @@ MediaObject::~MediaObject()
this->segment = NULL;
}
+uint32_t MediaObject::GetRepresentationBandwidth()
+{
+ return this->representationBandwidth;
+}
+
+uint32_t MediaObject::GetRepresentationHeight()
+{
+ return this->representationHeight;
+}
+
+int MediaObject::GetRepresentationID()
+{
+ return this->representationId;
+}
+
void MediaObject::SetFeedBack(bool flag)
{
this->withFeedBack = flag;
@@ -57,9 +75,13 @@ void MediaObject::AddInitSegment(MediaObject* initSeg)
int MediaObject::ReadInitSegment(uint8_t* data, size_t len)
{
if(this->initSeg)
+ {
return this->initSeg->Peek(data,len);
+ }
else
+ {
return 0;
+ }
}
bool MediaObject::StartDownload()
diff --git a/Input/MediaObject.h b/Input/MediaObject.h
index 9d5c7826..1edd69af 100644
--- a/Input/MediaObject.h
+++ b/Input/MediaObject.h
@@ -57,6 +57,9 @@ public:
const std::vector<dash::metrics::IHTTPTransaction *>& GetHTTPTransactionList() const;
void SetAdaptationLogic(framework::adaptation::IAdaptationLogic *_adaptationLogic);
void SetDASHReceiver(input::DASHReceiver *_dashReceiver);
+ uint32_t GetRepresentationBandwidth();
+ uint32_t GetRepresentationHeight();
+ int GetRepresentationID();
private:
dash::mpd::ISegment *segment;
@@ -70,6 +73,9 @@ private:
adaptation::IAdaptationLogic *adaptationLogic;
mutable CRITICAL_SECTION stateLock;
mutable CONDITION_VARIABLE stateChanged;
+ uint32_t representationBandwidth;
+ uint32_t representationHeight;
+ int representationId;
};
}
}
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();
diff --git a/Managers/IMultimediaManagerBase.h b/Managers/IMultimediaManagerBase.h
index f08803ba..1ef0b101 100644
--- a/Managers/IMultimediaManagerBase.h
+++ b/Managers/IMultimediaManagerBase.h
@@ -16,7 +16,7 @@
#ifndef VIPER_MANAGERS_IMULTIMEDIAMANAGERBASE_H_
#define VIPER_MANAGERS_IMULTIMEDIAMANAGERBASE_H_
-#include "IMPD.h"
+#include "MPD/MPDWrapper.h"
namespace viper
{
@@ -25,8 +25,10 @@ namespace managers
class IMultimediaManagerBase
{
public:
- virtual bool setVideoQuality(dash::mpd::IPeriod* period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation) = 0;
- virtual bool setAudioQuality(dash::mpd::IPeriod* period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation) = 0;
+// virtual bool setVideoQuality(dash::mpd::IPeriod* period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation) = 0;
+// virtual bool setAudioQuality(dash::mpd::IPeriod* period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation) = 0;
+ virtual bool setVideoQuality() = 0;
+ virtual bool setAudioQuality() = 0;
virtual bool isStarted() = 0;
virtual bool isStopping() = 0;
virtual void shouldAbort(bool isVideo) = 0;
diff --git a/Managers/IMultimediaManagerObserver.h b/Managers/IMultimediaManagerObserver.h
index eea0bfb1..24ce8d08 100644
--- a/Managers/IMultimediaManagerObserver.h
+++ b/Managers/IMultimediaManagerObserver.h
@@ -29,6 +29,7 @@ public:
virtual void onEOS() = 0;
virtual void notifyStatistics(int, uint32_t, int, uint32_t) = 0;
virtual void notifyQualityDownloading(uint32_t) = 0;
+ virtual void setMPDWrapper(libdash::framework::mpd::MPDWrapper*) = 0;
};
}
}
diff --git a/Managers/IStreamObserver.h b/Managers/IStreamObserver.h
index d6e8a19c..1d628d51 100644
--- a/Managers/IStreamObserver.h
+++ b/Managers/IStreamObserver.h
@@ -38,7 +38,7 @@ public:
virtual void notifyQualityDownloading(uint32_t quality) = 0;
virtual bool canPush() = 0;
virtual int getBufferLevel() = 0;
-
+ virtual void fetchMPD() = 0;
};
}
}
diff --git a/Managers/MultimediaManager.cpp b/Managers/MultimediaManager.cpp
index faab66cf..23118464 100644
--- a/Managers/MultimediaManager.cpp
+++ b/Managers/MultimediaManager.cpp
@@ -14,6 +14,7 @@
#include <fstream>
using namespace libdash::framework::adaptation;
+using namespace libdash::framework::mpd;
using namespace libdash::framework::buffer;
using namespace viper::managers;
using namespace dash::mpd;
@@ -25,17 +26,11 @@ MultimediaManager::MultimediaManager(ViperGui *viperGui, int segBufSize, std::st
segmentBufferSize (segBufSize),
downloadPath (downloadPath),
offset (offset),
- mpd (NULL),
- period (NULL),
- videoAdaptationSet (NULL),
- videoRepresentation (NULL),
videoLogic (NULL),
videoStream (NULL),
- audioAdaptationSet (NULL),
- audioRepresentation (NULL),
audioLogic (NULL),
- videoRendererHandle (NULL),
- audioRendererHandle (NULL),
+ videoRendererHandle (NULL),
+ audioRendererHandle (NULL),
audioStream (NULL),
started (false),
stopping (false),
@@ -45,7 +40,8 @@ MultimediaManager::MultimediaManager(ViperGui *viperGui, int segBufSize, std::st
isAudioRendering (false),
eos (false),
playing (false),
- noDecoding (nodecoding)
+ noDecoding (nodecoding),
+ mpdWrapper (NULL)
{
InitializeCriticalSection (&this->monitorMutex);
InitializeCriticalSection (&this->monitorBufferMutex);
@@ -71,28 +67,39 @@ MultimediaManager::~MultimediaManager ()
IMPD* MultimediaManager::getMPD()
{
- return this->mpd;
+ return this->mpdWrapper->getMPD();
+}
+
+MPDWrapper* MultimediaManager::getMPDWrapper()
+{
+ return this->mpdWrapper;
}
bool MultimediaManager::init(const std::string& url)
{
+ this->url = url;
EnterCriticalSection(&this->monitorMutex);
- this->mpd = this->manager->Open((char *)url.c_str());
+ IMPD* mpd = this->manager->Open((char *)url.c_str());
Debug("url : %s\n", url.c_str());
- if(this->mpd == NULL)
+ if(mpd == NULL)
{
LeaveCriticalSection(&this->monitorMutex);
return false;
}
Debug("Done DL the mpd\n");
+ this->mpdWrapper->setIsStopping(false);
+ this->mpdWrapper->updateMPD(mpd);
+ for (size_t i = 0; i < this->managerObservers.size(); i++)
+ this->managerObservers.at(i)->setMPDWrapper(this->mpdWrapper);
LeaveCriticalSection(&this->monitorMutex);
return true;
}
bool MultimediaManager::initICN(const std::string& url)
{
+ this->url = url;
EnterCriticalSection(&this->monitorMutex);
- libdash::framework::input::IICNConnection* icnConn = new libdash::framework::input::ICNConnectionConsumerApi(20.0, this->beta, this->drop);
+ this->icnConn = new libdash::framework::input::ICNConnectionConsumerApi(20.0, this->beta, this->drop);
icnConn->InitForMPD(url);
int ret = 0;
char * data = (char *)malloc(4096);
@@ -123,22 +130,69 @@ bool MultimediaManager::initICN(const std::string& url)
ret = icnConn->Read((uint8_t*)data,4096);
}
fclose(fp);
- this->mpd = this->manager->Open(const_cast<char*>(downloadFile.c_str()), url);
- if(this->mpd == NULL)
+ IMPD* mpd = this->manager->Open(const_cast<char*>(downloadFile.c_str()), url);
+ remove(downloadFile.c_str());
+ free(data);
+ if(mpd == NULL)
{
- remove(downloadFile.c_str());
- free(data);
delete icnConn;
LeaveCriticalSection(&this->monitorMutex);
return false;
}
- remove(downloadFile.c_str());
- free(data);
- delete icnConn;
+ this->mpdWrapper->setIsStopping(false);
+ this->mpdWrapper->updateMPD(mpd);
+ for (size_t i = 0; i < this->managerObservers.size(); i++)
+ this->managerObservers.at(i)->setMPDWrapper(this->mpdWrapper);
+ if( !strcmp(this->mpdWrapper->getType().c_str(), "static") )
+ {
+ delete icnConn;
+ }
+
LeaveCriticalSection(&this->monitorMutex);
return true;
}
+void MultimediaManager::updateMPD()
+{
+ this->mpdWrapper->updateMPD(this->manager->Open((char *)url.c_str()));
+}
+
+void MultimediaManager::updateMPDICN()
+{
+ this->icnConn->InitForMPD(this->url);
+ int ret = 0;
+ char * data = (char *)malloc(4096);
+ int pos = this->url.find_last_of("/");
+ if(pos == std::string::npos)
+ {
+ pos = strlen(this->url.c_str());
+ }
+ else
+ {
+ pos = pos + 1;
+ }
+
+ std::string downloadFile(this->downloadPath + this->url.substr(pos).c_str());
+ FILE *fp;
+ fp = fopen(downloadFile.c_str(), "w");
+ if(fp == NULL)
+ {
+ free(data);
+ return;
+ }
+ ret = icnConn->Read((uint8_t*)data, 4096);
+ while(ret)
+ {
+ fwrite(data, sizeof(char), ret, fp);
+ ret = icnConn->Read((uint8_t*)data,4096);
+ }
+ fclose(fp);
+ this->mpdWrapper->updateMPD(this->manager->Open(const_cast<char*>(downloadFile.c_str()), this->url));
+
+ remove(downloadFile.c_str());
+ free(data);
+}
+
bool MultimediaManager::isStarted()
{
return this->started;
@@ -154,6 +208,11 @@ bool MultimediaManager::isICN()
return this->icn;
}
+void MultimediaManager::setMPDWrapper(MPDWrapper* mpdWrapper)
+{
+ this->mpdWrapper = mpdWrapper;
+}
+
void MultimediaManager::start(bool icnEnabled, double icnAlpha, uint32_t nextOffset)
{
this->icn = icnEnabled;
@@ -168,7 +227,7 @@ void MultimediaManager::start(bool icnEnabled, double icnAlpha, uint32_t nextOff
qDebug("normal rate estimation\n");
}
EnterCriticalSection(&this->monitorMutex);
- if (this->videoAdaptationSet && this->videoRepresentation)
+ if(this->mpdWrapper->hasVideoAdaptationSetAndVideoRepresentation())
{
this->initVideoRendering(nextOffset);
this->videoStream->setAdaptationLogic(this->videoLogic);
@@ -185,6 +244,8 @@ void MultimediaManager::stop()
{
if (!this->started)
return;
+
+ this->mpdWrapper->setIsStopping(true);
this->stopping = true;
EnterCriticalSection(&this->monitorMutex);
this->stopVideo();
@@ -192,10 +253,8 @@ void MultimediaManager::stop()
this->started = false;
LeaveCriticalSection(&this->monitorMutex);
Debug("VIDEO STOPPED\n");
- this->period = this->mpd->GetPeriods().at(0);
- this->videoAdaptationSet = this->period->GetAdaptationSets().at(0);
- this->videoRepresentation = this->videoAdaptationSet->GetRepresentation().at(0);
-
+ this->mpdWrapper->reInit(viper::managers::StreamType::VIDEO);
+ this->mpdWrapper->reInit(viper::managers::StreamType::AUDIO);
}
void MultimediaManager::stopVideo()
@@ -219,30 +278,18 @@ void MultimediaManager::stopAudio()
}
}
-bool MultimediaManager::setVideoQuality(IPeriod* period, IAdaptationSet *adaptationSet, IRepresentation *representation)
+bool MultimediaManager::setVideoQuality()
{
- EnterCriticalSection(&this->monitorMutex);
- this->period = period;
- this->videoAdaptationSet = adaptationSet;
- this->videoRepresentation = representation;
if (this->videoStream)
- this->videoStream->setRepresentation(this->period, this->videoAdaptationSet, this->videoRepresentation);
-
- LeaveCriticalSection(&this->monitorMutex);
+ this->videoStream->setRepresentation();
return true;
}
-bool MultimediaManager::setAudioQuality(IPeriod* period, IAdaptationSet *adaptationSet, IRepresentation *representation)
+bool MultimediaManager::setAudioQuality()
{
- EnterCriticalSection(&this->monitorMutex);
-
- this->period = period;
- this->audioAdaptationSet = adaptationSet;
- this->audioRepresentation = representation;
if (this->audioStream)
- this->audioStream->setRepresentation(this->period, this->audioAdaptationSet, this->audioRepresentation);
- LeaveCriticalSection(&this->monitorMutex);
+ this->audioStream->setRepresentation();
return true;
}
@@ -256,11 +303,11 @@ bool MultimediaManager::isUserDependent()
bool MultimediaManager::setVideoAdaptationLogic(libdash::framework::adaptation::LogicType type, struct libdash::framework::adaptation::AdaptationParameters *params)
{
- if(this->videoAdaptationSet)
+ if(this->mpdWrapper->hasVideoAdaptationSetAndVideoRepresentation())
{
if(this->videoLogic)
delete(this->videoLogic);
- this->videoLogic = AdaptationLogicFactory::create(type, this->mpd, this->period, this->videoAdaptationSet, 1, params);
+ this->videoLogic = AdaptationLogicFactory::create(type, viper::managers::StreamType::VIDEO, this->mpdWrapper, params);
this->logicName = LogicType_string[type];
}
else
@@ -297,9 +344,11 @@ void MultimediaManager::setTargetDownloadingTime(bool isVideo, double target)
bool MultimediaManager::setAudioAdaptationLogic(libdash::framework::adaptation::LogicType type, struct libdash::framework::adaptation::AdaptationParameters *params)
{
- if(this->audioAdaptationSet)
+ if(this->mpdWrapper->hasAudioAdaptationSetAndAudioRepresentation())
{
- this->audioLogic = AdaptationLogicFactory::create(type, this->mpd, this->period, this->audioAdaptationSet, 0, params);
+ if(this->audioLogic)
+ delete(this->audioLogic);
+ this->audioLogic = AdaptationLogicFactory::create(type, viper::managers::StreamType::AUDIO, this->mpdWrapper, params);
this->logicName = LogicType_string[type];
}
else
@@ -344,17 +393,15 @@ void MultimediaManager::notifyAudioBufferObservers(uint32_t fillstateInPercent)
void MultimediaManager::initVideoRendering(uint32_t offset)
{
- this->videoStream = new MultimediaStream(viper::managers::VIDEO, this->mpd, this->segmentBufferSize, this->isICN(), this->icnAlpha, this->noDecoding, this->beta, this->drop);
+ this->videoStream = new MultimediaStream(viper::managers::VIDEO, this->mpdWrapper, this->segmentBufferSize, this->isICN(), this->icnAlpha, this->noDecoding, this->beta, this->drop);
this->videoStream->attachStreamObserver(this);
- this->videoStream->setRepresentation(this->period, this->videoAdaptationSet, this->videoRepresentation);
this->videoStream->setPosition(offset);
}
void MultimediaManager::initAudioPlayback(uint32_t offset)
{
- this->audioStream = new MultimediaStream(viper::managers::AUDIO, this->mpd, this->segmentBufferSize, this->isICN(), this->icnAlpha, this->noDecoding, this->beta, this->drop);
+ this->audioStream = new MultimediaStream(viper::managers::AUDIO, this->mpdWrapper, this->segmentBufferSize, this->isICN(), this->icnAlpha, this->noDecoding, this->beta, this->drop);
this->audioStream->attachStreamObserver(this);
- this->audioStream->setRepresentation(this->period, this->audioAdaptationSet, this->audioRepresentation);
this->audioStream->setPosition(offset);
}
@@ -506,14 +553,12 @@ void* MultimediaManager::pushVideoNoOut(void *data)
{
Debug("MANAGER:\tRebuffered %d ms\n", actualPosition *(-1));
manager->lastPointInTime = timeOfInsertion;
- //TODO Replace the 2 by a variable with segmentDuration
- manager->bufferingLimit = manager->lastPointInTime + std::chrono::seconds(2);
+ manager->bufferingLimit = manager->lastPointInTime + std::chrono::seconds(((int)manager->getSegmentDuration() / 1000));
}
else
{
- //TODO Replace the 2 by a variable with segmentDuration
Debug("MANAGER: INSERT TO BUFFER old_fillness: %f, new_fillness: %f\n", (double)((double)actualPosition/1000.0) / (double) this->segmentBufferSize, (double)((double)(actualPosition + 2000)/1000.0) / (double) manager->segmentBufferSize);
- manager->bufferingLimit = manager->bufferingLimit + std::chrono::seconds(2);
+ manager->bufferingLimit = manager->bufferingLimit + std::chrono::seconds(((int)manager->getSegmentDuration() /1000));
manager->lastPointInTime = timeOfInsertion;
}
delete segment;
@@ -566,7 +611,7 @@ int MultimediaManager::getBufferLevel()
uint32_t MultimediaManager::getUBufferLevel()
{
int mBufferLevel = 0;
- int segmentDurationInMs = 2000;
+ int segmentDurationInMs = (int) this->segmentDuration;
if(noDecoding)
{
@@ -587,7 +632,7 @@ uint32_t MultimediaManager::getUBufferLevel()
bool MultimediaManager::canPush()
{
- int segmentDurationInMs = 2000;
+ int segmentDurationInMs = (int)this->segmentDuration;
while(this->getUBufferLevel() >= 100 && !this->stopping)
{
sleep(segmentDurationInMs / 1000);
@@ -599,7 +644,7 @@ void* MultimediaManager::pushVideo(void *data)
{
MultimediaManager *manager = (MultimediaManager*) data;
libdash::framework::input::MediaObject *segment = manager->videoStream->getSegment();
- long int segmentDurationInMs = 2000;
+ int segmentDurationInMs = (int)manager->getSegmentDuration();
while(manager->isVideoRendering)
{
if (segment)
@@ -627,3 +672,22 @@ void MultimediaManager::setDrop(float drop)
{
this->drop = drop;
}
+
+void MultimediaManager::fetchMPD()
+{
+ if(this->icn)
+ this->updateMPDICN();
+ else
+ this->updateMPD();
+}
+
+//SegmentDuration is in ms
+void MultimediaManager::setSegmentDuration(float segDuration)
+{
+ this->segmentDuration = segDuration;
+}
+
+float MultimediaManager::getSegmentDuration()
+{
+ return this->segmentDuration;
+}
diff --git a/Managers/MultimediaManager.h b/Managers/MultimediaManager.h
index b4187486..ade2b767 100644
--- a/Managers/MultimediaManager.h
+++ b/Managers/MultimediaManager.h
@@ -35,50 +35,52 @@ public:
MultimediaManager(ViperGui *viperGui, int segmentBufferSize, std::string downloadPath, bool noDecoding = false);
virtual ~MultimediaManager();
- bool init (const std::string& url);
- bool initICN (const std::string& url);
- void start (bool icnEnabled, double icnAlpha, uint32_t nextOffset);
- void stop ();
- dash::mpd::IMPD* getMPD ();
-
- bool setVideoQuality (dash::mpd::IPeriod* period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation);
- bool setAudioQuality (dash::mpd::IPeriod* period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation);
-
- bool setVideoAdaptationLogic (libdash::framework::adaptation::LogicType type, struct libdash::framework::adaptation::AdaptationParameters *params);
- bool setAudioAdaptationLogic (libdash::framework::adaptation::LogicType type, struct libdash::framework::adaptation::AdaptationParameters *params);
-
- void attachManagerObserver (IMultimediaManagerObserver *observer);
-
- void setFrameRate (double frameRate);
+ bool init (const std::string& url);
+ bool initICN (const std::string& url);
+ void start (bool icnEnabled, double icnAlpha, uint32_t nextOffset);
+ void stop ();
+ dash::mpd::IMPD* getMPD ();
+ bool setVideoQuality ();
+ bool setAudioQuality ();
+ bool setVideoAdaptationLogic (libdash::framework::adaptation::LogicType type, struct libdash::framework::adaptation::AdaptationParameters *params);
+ bool setAudioAdaptationLogic (libdash::framework::adaptation::LogicType type, struct libdash::framework::adaptation::AdaptationParameters *params);
+ void attachManagerObserver (IMultimediaManagerObserver *observer);
+ void setFrameRate (double frameRate);
+ void setSegmentDuration (float segDuration);
+ float getSegmentDuration ();
/* IStreamObserver */
- void onSegmentDownloaded ();
- void onSegmentBufferStateChanged (StreamType type, uint32_t fillstateInPercent, int maxC);
- void onVideoBufferStateChanged (uint32_t fillstateInPercent);
- void onAudioBufferStateChanged (uint32_t fillstateInPercent);
- bool isUserDependent ();
- bool isStarted ();
- bool isStopping ();
- bool isICN ();
- void setEOS (bool value);
- void shouldAbort (bool isVideo);
- void setTargetDownloadingTime (bool isVid, double time);
- bool isPlaying ();
- void onPausePressed ();
- void notifyStatistics (int segNum, uint32_t bitrate, int fps, uint32_t quality);
- void notifyQualityDownloading (uint32_t quality);
- uint32_t getUBufferLevel ();
- int getBufferLevel ();
- void setLooping (bool looping);
- void setOffset(int offset);
- void setBeta(float beta);
- void setDrop(float drop);
- bool canPush ();
- CRITICAL_SECTION monitorBufferMutex;
+ void onSegmentDownloaded ();
+ void onSegmentBufferStateChanged (StreamType type, uint32_t fillstateInPercent, int maxC);
+ void onVideoBufferStateChanged (uint32_t fillstateInPercent);
+ void onAudioBufferStateChanged (uint32_t fillstateInPercent);
+ bool isUserDependent ();
+ bool isStarted ();
+ bool isStopping ();
+ bool isICN ();
+ void setEOS (bool value);
+ void shouldAbort (bool isVideo);
+ void setTargetDownloadingTime (bool isVid, double time);
+ bool isPlaying ();
+ void onPausePressed ();
+ void notifyStatistics (int segNum, uint32_t bitrate, int fps, uint32_t quality);
+ void notifyQualityDownloading (uint32_t quality);
+ uint32_t getUBufferLevel ();
+ int getBufferLevel ();
+ void setLooping (bool looping);
+ libdash::framework::mpd::MPDWrapper* getMPDWrapper ();
+ void setMPDWrapper (libdash::framework::mpd::MPDWrapper* mpdWrapper);
+ void setOffset (int offset);
+ void setBeta (float beta);
+ void setDrop (float drop);
+ bool canPush ();
+ void fetchMPD ();
+
- int offset;
- std::chrono::time_point<std::chrono::system_clock> lastPointInTime;
- std::chrono::time_point<std::chrono::system_clock> bufferingLimit;
+ CRITICAL_SECTION monitorBufferMutex;
+ int offset;
+ std::chrono::time_point<std::chrono::system_clock> lastPointInTime;
+ std::chrono::time_point<std::chrono::system_clock> bufferingLimit;
private:
float beta;
@@ -87,14 +89,9 @@ private:
int segmentBufferSize;
ViperGui *viperGui;
dash::IDASHManager *manager;
- dash::mpd::IMPD *mpd;
- dash::mpd::IPeriod *period;
- dash::mpd::IAdaptationSet *videoAdaptationSet;
- dash::mpd::IRepresentation *videoRepresentation;
+ libdash::framework::mpd::MPDWrapper *mpdWrapper;
libdash::framework::adaptation::IAdaptationLogic *videoLogic;
MultimediaStream *videoStream;
- dash::mpd::IAdaptationSet *audioAdaptationSet;
- dash::mpd::IRepresentation *audioRepresentation;
libdash::framework::adaptation::IAdaptationLogic *audioLogic;
MultimediaStream *audioStream;
std::vector<IMultimediaManagerObserver *> managerObservers;
@@ -102,6 +99,7 @@ private:
bool stopping;
bool icn;
double icnAlpha;
+ libdash::framework::input::IICNConnection *icnConn;
uint64_t framesDisplayed;
uint64_t segmentsDownloaded;
CRITICAL_SECTION monitorMutex;
@@ -117,22 +115,27 @@ private:
mutable CRITICAL_SECTION monitor_playing_audio_mutex;
mutable CONDITION_VARIABLE playingAudioStatusChanged;
const char *logicName;
- bool noDecoding;
- void notifyBufferChange ();
- bool startVideoRenderingThread ();
- void stopVideoRenderingThread ();
- static void* pushVideo (void *data);
- static void* pushVideoNoOut (void *data);
- bool startAudioRenderingThread ();
- void stopAudioRenderingThread ();
- void initVideoRendering (uint32_t offset);
- void initAudioPlayback (uint32_t offset);
- void stopVideo ();
- void stopAudio ();
- void notifyVideoBufferObservers (uint32_t fillstateInPercent);
- void notifyVideoSegmentBufferObservers (uint32_t fillstateInPercent);
- void notifyAudioBufferObservers (uint32_t fillstateInPercent);
- void notifyAudioSegmentBufferObservers (uint32_t fillstateInPercent);
+ bool noDecoding;
+ std::string url;
+ float segmentDuration;
+
+ void notifyBufferChange ();
+ bool startVideoRenderingThread ();
+ void stopVideoRenderingThread ();
+ static void* pushVideo (void *data);
+ static void* pushVideoNoOut (void *data);
+ bool startAudioRenderingThread ();
+ void stopAudioRenderingThread ();
+ void initVideoRendering (uint32_t offset);
+ void initAudioPlayback (uint32_t offset);
+ void stopVideo ();
+ void stopAudio ();
+ void notifyVideoBufferObservers (uint32_t fillstateInPercent);
+ void notifyVideoSegmentBufferObservers (uint32_t fillstateInPercent);
+ void notifyAudioBufferObservers (uint32_t fillstateInPercent);
+ void notifyAudioSegmentBufferObservers (uint32_t fillstateInPercent);
+ void updateMPD ();
+ void updateMPDICN ();
};
}
}
diff --git a/Managers/MultimediaStream.cpp b/Managers/MultimediaStream.cpp
index ed0d967c..4b5b66fe 100644
--- a/Managers/MultimediaStream.cpp
+++ b/Managers/MultimediaStream.cpp
@@ -15,23 +15,26 @@ using namespace viper::managers;
using namespace libdash::framework::adaptation;
using namespace libdash::framework::input;
using namespace libdash::framework::buffer;
+using namespace libdash::framework::mpd;
using namespace dash::mpd;
-MultimediaStream::MultimediaStream(StreamType type, IMPD *mpd, uint32_t bufferSize, bool icnEnabled, double icnAlpha, bool nodecoding, float beta, float drop) :
+MultimediaStream::MultimediaStream(StreamType type, MPDWrapper *mpdWrapper, uint32_t bufferSize, bool icnEnabled, double icnAlpha, bool nodecoding, float beta, float drop) :
type (type),
segmentBufferSize (bufferSize),
dashManager (NULL),
- mpd (mpd),
- icn (icnEnabled),
+ mpdWrapper (mpdWrapper),
+ icn (icnEnabled),
icnAlpha (icnAlpha),
noDecoding (nodecoding),
- beta (beta),
- drop (drop)
+ beta (beta),
+ drop (drop)
{
+// InitializeCriticalSection (&this->monitorMutex);
this->init();
}
MultimediaStream::~MultimediaStream ()
{
+// DestroyCriticalSection (&this->monitorMutex);
this->stop();
delete this->dashManager;
}
@@ -68,7 +71,7 @@ void MultimediaStream::setPositionInMsec(uint32_t milliSecs)
void MultimediaStream::init()
{
- this->dashManager = new DASHManager(this->type, this->segmentBufferSize, this, this->mpd, this->isICN(), this->icnAlpha, this->noDecoding, this->beta, this->drop);
+ this->dashManager = new DASHManager(this->type, this->segmentBufferSize, this, this->mpdWrapper, this->isICN(), this->icnAlpha, this->noDecoding, this->beta, this->drop);
}
bool MultimediaStream::start()
@@ -117,9 +120,9 @@ void MultimediaStream::attachStreamObserver(IStreamObserver *observer)
this->observers.push_back(observer);
}
-void MultimediaStream::setRepresentation(IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation)
+void MultimediaStream::setRepresentation()
{
- this->dashManager->setRepresentation(period, adaptationSet, representation);
+ this->dashManager->setRepresentation();
}
void MultimediaStream::enqueueRepresentation(IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation)
@@ -206,3 +209,17 @@ void MultimediaStream::notifyBufferChange(uint32_t bufferfill, int maxC)
{
this->dashManager->onBufferStateChanged(libdash::framework::buffer::VIDEO, bufferfill, maxC);
}
+
+void MultimediaStream::updateMPD (IMPD* mpd)
+{
+// this->mpd = mpd;
+// this->dashManager->updateMPD(mpd);
+}
+
+void MultimediaStream::fetchMPD()
+{
+ for(size_t i=0; i < this->observers.size(); i++)
+ {
+ this->observers.at(i)->fetchMPD();
+ }
+}
diff --git a/Managers/MultimediaStream.h b/Managers/MultimediaStream.h
index 6918f639..d9db5f66 100644
--- a/Managers/MultimediaStream.h
+++ b/Managers/MultimediaStream.h
@@ -14,6 +14,7 @@
#include "IMPD.h"
#include "IStreamObserver.h"
+#include "../MPD/MPDWrapper.h"
#include "../Input/DASHManager.h"
#include "../Buffer/IBufferObserver.h"
#include "../Adaptation/IAdaptationLogic.h"
@@ -22,6 +23,20 @@
#include "../Buffer/Buffer.h"
#include <QImage>
+namespace libdash
+{
+namespace framework
+{
+namespace mpd
+{
+class MPDWrapper;
+}
+namespace input
+{
+class DASHManager;
+}
+}
+}
namespace viper
{
namespace managers
@@ -29,7 +44,7 @@ namespace managers
class MultimediaStream : public libdash::framework::input::IDASHManagerObserver, public libdash::framework::buffer::IBufferObserver
{
public:
- MultimediaStream(StreamType type, dash::mpd::IMPD *mpd, uint32_t segmentBufferSize, bool icnEnabled, double icnAlpha, bool nodecoding, float beta, float drop);
+ MultimediaStream(StreamType type, libdash::framework::mpd::MPDWrapper *mpdWrapper, uint32_t segmentBufferSize, bool icnEnabled, double icnAlpha, bool nodecoding, float beta, float drop);
virtual ~MultimediaStream();
bool start();
@@ -50,7 +65,8 @@ public:
void notifyBufferChange(uint32_t bufferfill, int maxC);
- void setRepresentation(dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation);
+// void setRepresentation(dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation);
+ void setRepresentation();
void enqueueRepresentation(dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation);
void setAdaptationLogic(libdash::framework::adaptation::IAdaptationLogic *logic);
@@ -65,20 +81,22 @@ public:
int getBufferLevel();
bool isICN();
void shouldAbort();
-
void setTargetDownloadingTime(double);
+ void updateMPD(dash::mpd::IMPD* mpd);
+ void fetchMPD();
private:
float beta;
float drop;
std::vector<IStreamObserver *> observers;
- dash::mpd::IMPD *mpd;
- libdash::framework::adaptation::IAdaptationLogic *logic;
+ libdash::framework::mpd::MPDWrapper *mpdWrapper;
+ libdash::framework::adaptation::IAdaptationLogic *logic;
libdash::framework::input::DASHManager *dashManager;
- uint32_t segmentBufferSize;
- StreamType type;
+ uint32_t segmentBufferSize;
+ StreamType type;
bool icn;
double icnAlpha;
+ mutable CRITICAL_SECTION monitorMutex;
bool noDecoding;
void init ();
diff --git a/UI/DASHPlayer.cpp b/UI/DASHPlayer.cpp
index 0f1db8cc..cdad7d5a 100644
--- a/UI/DASHPlayer.cpp
+++ b/UI/DASHPlayer.cpp
@@ -30,7 +30,6 @@ DASHPlayer::DASHPlayer(ViperGui &gui, Config *config) :
this->icn = false;
this->adaptLogic = LogicType::RateBased;
this->seek = false;
- this->isLive = false;
this->reloadParameters();
this->setSettings(0, 0, 0, 0, 0);
this->multimediaManager = new MultimediaManager(this->gui, this->parametersAdaptation->segmentBufferSize, config->getConfigPath().toStdString() + QString::fromLatin1("/").toStdString());
@@ -40,15 +39,24 @@ DASHPlayer::DASHPlayer(ViperGui &gui, Config *config) :
connect(this->gui->getVideoPlayer(), SIGNAL(stateChanged(QtAV::AVPlayer::State)), SLOT(manageGraph(QtAV::AVPlayer::State)));
connect(this->gui->getVideoPlayer(), SIGNAL(error(QtAV::AVError)), this, SLOT(error(QtAV::AVError)));
this->multimediaManager->attachManagerObserver(this);
+ this->mpdWrapper = new MPDWrapper(NULL);
+ this->multimediaManager->setMPDWrapper(this->mpdWrapper);
}
DASHPlayer::~DASHPlayer()
{
this->multimediaManager->stop();
delete(this->multimediaManager);
+ if(this->mpdWrapper)
+ delete(this->mpdWrapper);
DeleteCriticalSection(&this->monitorMutex);
}
+void DASHPlayer::setMPDWrapper(MPDWrapper* mpdWrapper)
+{
+ this->mpdWrapper = mpdWrapper;
+}
+
void DASHPlayer::onStartButtonPressed(int period, int videoAdaptationSet, int videoRepresentation, int audioAdaptationSet, int audioRepresentation, int adaptationLogic)
{
bool setOk = false;
@@ -85,25 +93,27 @@ void DASHPlayer::onPauseButtonPressed()
void DASHPlayer::onSettingsChanged(int period, int videoAdaptationSet, int videoRepresentation, int audioAdaptationSet, int audioRepresentation)
{
- if(this->multimediaManager->getMPD() == NULL)
+ if(this->mpdWrapper->getMPD() == NULL)
return;
if (!this->settingsChanged(period, videoAdaptationSet, videoRepresentation, audioAdaptationSet, audioRepresentation))
return;
- IPeriod *currentPeriod = this->multimediaManager->getMPD()->GetPeriods().at(period);
- std::vector<IAdaptationSet *> videoAdaptationSets = AdaptationSetHelper::getVideoAdaptationSets(currentPeriod);
- std::vector<IAdaptationSet *> audioAdaptationSets = AdaptationSetHelper::getAudioAdaptationSets(currentPeriod);
- if (videoAdaptationSet >= 0 && videoRepresentation >= 0)
- {
- this->multimediaManager->setVideoQuality(currentPeriod,
- videoAdaptationSets.at(videoAdaptationSet),
- videoAdaptationSets.at(videoAdaptationSet)->GetRepresentation().at(videoRepresentation));
- }
- else
- {
- this->multimediaManager->setVideoQuality(currentPeriod, NULL, NULL);
- }
+// IPeriod *currentPeriod = this->multimediaManager->getMPD()->GetPeriods().at(period);
+// std::vector<IAdaptationSet *> videoAdaptationSets = AdaptationSetHelper::getVideoAdaptationSets(currentPeriod);
+// std::vector<IAdaptationSet *> audioAdaptationSets = AdaptationSetHelper::getAudioAdaptationSets(currentPeriod);
+// if (videoAdaptationSet >= 0 && videoRepresentation >= 0)
+// {
+// this->multimediaManager->setVideoQuality(currentPeriod,
+// videoAdaptationSets.at(videoAdaptationSet),
+// videoAdaptationSets.at(videoAdaptationSet)->GetRepresentation().at(videoRepresentation));
+// }
+// else
+// {
+// this->multimediaManager->setVideoQuality(currentPeriod, NULL, NULL);
+// }
+ this->mpdWrapper->settingsChanged(period, videoAdaptationSet, videoRepresentation, audioAdaptationSet, audioRepresentation);
+ this->multimediaManager->setVideoQuality();
}
void DASHPlayer::onVideoBufferStateChanged(uint32_t fillstateInPercent)
@@ -149,7 +159,7 @@ bool DASHPlayer::onDownloadMPDPressed (const std::string &url)
}
}
this->setSettings(-1, -1, -1, -1, -1);
- this->gui->setGuiFields(this->multimediaManager->getMPD());
+ this->gui->setGuiFields(this->mpdWrapper->getMPD());
return true;
}
@@ -205,42 +215,10 @@ bool DASHPlayer::downloadMPD(const QString &url, const QString &adaptationLogic,
}
if (!this->onDownloadMPDPressed(mUrl))
return false;
- IPeriod *period = this->multimediaManager->getMPD()->GetPeriods().at(0);
- IAdaptationSet *adaptation = period->GetAdaptationSets().at(0);
- IRepresentation *representation = adaptation->GetRepresentation().at(0);
- if(!strcmp(this->multimediaManager->getMPD()->GetType().c_str(), "static")) // VOD MPD
- {
- if(representation->GetSegmentList())
- {
- uint32_t duration = representation->GetSegmentList()->GetDuration();
- uint32_t timescale = representation->GetSegmentList()->GetTimescale();
- this->gui->setListSegmentSize(representation->GetSegmentList()->GetSegmentURLs().size());
- this->segmentDuration = 1.0*duration/(1.0*timescale) * 1000;
- this->gui->setSegmentDuration(this->segmentDuration);
- this->parametersAdaptation->segmentDuration = this->segmentDuration;
- }
- else //SegmentTemplate
- {
- uint32_t duration = representation->GetSegmentTemplate()->GetDuration();
- uint32_t timescale = representation->GetSegmentTemplate()->GetTimescale();
- this->segmentDuration = 1.0*duration/(1.0*timescale) * 1000;
- this->gui->setSegmentDuration(this->segmentDuration);
- this->gui->setListSegmentSize(TimeResolver::getDurationInSec(period->GetDuration())*1000/this->segmentDuration + 1);
- this->parametersAdaptation->segmentDuration = this->segmentDuration;
- }
- }
- else //Live MPD
- {
- //SegmentTemplate->SegmentTimeline
- this->isLive = true;
- //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();
- this->segmentDuration = 1.0*duration/(1.0*timescale) * 1000;
- this->gui->setSegmentDuration(this->segmentDuration);
- this->gui->setListSegmentSize(1);
- this->parametersAdaptation->segmentDuration = this->segmentDuration;
- }
+
+ this->segmentDuration = this->mpdWrapper->onFirstDownloadMPD(this->gui);
+ this->multimediaManager->setSegmentDuration(this->segmentDuration);
+ this->parametersAdaptation->segmentDuration = this->segmentDuration / 1000.0; //to have it in seconds
this->onSettingsChanged(0,0,0,0,0);
int j =0;
std::string temp = adaptationLogic.toStdString();
diff --git a/UI/DASHPlayer.h b/UI/DASHPlayer.h
index fad28710..6204f46a 100644
--- a/UI/DASHPlayer.h
+++ b/UI/DASHPlayer.h
@@ -60,6 +60,7 @@ public:
virtual void notifyStatistics(int, uint32_t, int, uint32_t);
virtual void notifyQualityDownloading(uint32_t);
virtual bool onDownloadMPDPressed(const std::string &url);
+ void setMPDWrapper(libdash::framework::mpd::MPDWrapper* mpdWrapper);
void setConfig(Config *config);
Q_INVOKABLE bool downloadMPD(const QString &url, const QString &adaptationLogic, bool icn);
Q_INVOKABLE void pause();
@@ -160,34 +161,36 @@ public:
Q_INVOKABLE int getRateEstimator();
private:
- float gamma;
- float beta;
- float drop;
- bool seek;
- bool isLive;
- Config *config;
- bool repeat;
- float segmentDuration;
- uint64_t offset;
- uint64_t position;
- int segment;
- int adaptationLogic;
- dash::mpd::IMPD *mpd;
- ViperGui *gui = NULL;
- viper::managers::MultimediaManager *multimediaManager;
- settings_t currentSettings;
- CRITICAL_SECTION monitorMutex;
- const char *url;
- bool icn;
- std::string icnPrefix;
- std::string httpPrefix;
- std::string icnSuffix;
- std::string httpSuffix;
- double alpha;
+ float gamma;
+ float beta;
+ float drop;
+ bool seek;
+ bool isLive;
+ Config *config;
+ bool repeat;
+ float segmentDuration;
+ uint64_t offset;
+ uint64_t position;
+ int segment;
+ int adaptationLogic;
+ dash::mpd::IMPD *mpd;
+ libdash::framework::mpd::MPDWrapper *mpdWrapper;
+ ViperGui *gui = NULL;
+ viper::managers::MultimediaManager *multimediaManager;
+ settings_t currentSettings;
+ CRITICAL_SECTION monitorMutex;
+ const char *url;
+ bool icn;
+ std::string icnPrefix;
+ std::string httpPrefix;
+ std::string icnSuffix;
+ std::string httpSuffix;
+ double alpha;
struct libdash::framework::adaptation::AdaptationParameters *parametersAdaptation;
- libdash::framework::adaptation::LogicType adaptLogic;
- std::map<int,std::tuple<uint32_t, int, uint32_t>> mStats;
- int qualityDownloading;
+ libdash::framework::adaptation::LogicType adaptLogic;
+ std::map<int,std::tuple<uint32_t, int, uint32_t>> mStats;
+ int qualityDownloading;
+
bool settingsChanged(int period, int videoAdaptationSet, int videoRepresentation, int audioAdaptationSet, int audioRepresentation);
void setSettings(int period, int videoAdaptationSet, int videoRepresentation, int audioAdaptationSet, int audioRepresentation);
std::string msec2string(uint64_t milliseconds);
diff --git a/UI/DASHPlayerNoGUI.cpp b/UI/DASHPlayerNoGUI.cpp
index 729621ef..d212b556 100644
--- a/UI/DASHPlayerNoGUI.cpp
+++ b/UI/DASHPlayerNoGUI.cpp
@@ -30,11 +30,9 @@ DASHPlayerNoGUI::DASHPlayerNoGUI(int argc, char ** argv, pthread_cond_t *mainCon
noDecoding (nodecoding)
{
InitializeCriticalSection(&this->monitorMutex);
-
- this->mpd = NULL;
- this->url = NULL;
- this->adaptLogic = LogicType::RateBased;
- this->isICN = false;
+ this->url = NULL;
+ this->adaptLogic = LogicType::RateBased;
+ this->isICN = false;
this->alpha = -1;
this->graphData = NULL;
this->parameterAdaptation = (struct libdash::framework::adaptation::AdaptationParameters *)malloc(sizeof(struct libdash::framework::adaptation::AdaptationParameters));
@@ -71,6 +69,8 @@ DASHPlayerNoGUI::DASHPlayerNoGUI(int argc, char ** argv, pthread_cond_t *mainCon
this->parseArgs(argc, argv);
this->multimediaManager = new MultimediaManager(NULL, this->parameterAdaptation->segmentBufferSize, "/tmp/", noDecoding);
+ this->mpdWrapper = new MPDWrapper(NULL);
+ this->multimediaManager->setMPDWrapper(this->mpdWrapper);
this->multimediaManager->attachManagerObserver(this);
if(this->url == NULL)
@@ -87,6 +87,8 @@ DASHPlayerNoGUI::DASHPlayerNoGUI(int argc, char ** argv, pthread_cond_t *mainCon
WebSocketService webSocketService;
webSocketService.setGraphDataSource(this->graphData);
webSocketService.start();
+ this->parameterAdaptation->segmentDuration = this->mpdWrapper->onFirstDownloadMPD(NULL);
+ this->multimediaManager->setSegmentDuration(this->parameterAdaptation->segmentDuration);
this->onStartButtonPressed(0,0,0,0,0);
this->multimediaManager->setLooping(this->repeat);
}
@@ -102,40 +104,23 @@ DASHPlayerNoGUI::~DASHPlayerNoGUI()
{
this->multimediaManager->stop();
delete(this->multimediaManager);
+ if(this->mpdWrapper)
+ delete(this->mpdWrapper);
if(this->graphData)
delete(this->graphData);
DeleteCriticalSection(&this->monitorMutex);
}
+void DASHPlayerNoGUI::setMPDWrapper(MPDWrapper *mpdWrapper)
+{
+ this->mpdWrapper = mpdWrapper;
+}
+
void DASHPlayerNoGUI::onStartButtonPressed(int period, int videoAdaptationSet, int videoRepresentation, int audioAdaptationSet, int audioRepresentation)
{
this->onSettingsChanged(period,videoAdaptationSet,videoRepresentation, audioAdaptationSet, audioRepresentation);
bool setOk = false;
-
- switch(adaptLogic)
- {
- case RateBased:
- setOk = this->multimediaManager->setVideoAdaptationLogic((LogicType)adaptLogic, this->parameterAdaptation);
- break;
- case BufferBased:
- setOk = this->multimediaManager->setVideoAdaptationLogic((LogicType)adaptLogic, this->parameterAdaptation);
- break;
- case BufferRateBased:
- setOk = this->multimediaManager->setVideoAdaptationLogic((LogicType)adaptLogic, this->parameterAdaptation);
- break;
- case BufferBasedThreeThreshold:
- setOk = this->multimediaManager->setVideoAdaptationLogic((LogicType)adaptLogic, this->parameterAdaptation);
- break;
- case Panda:
- setOk = this->multimediaManager->setVideoAdaptationLogic((LogicType)adaptLogic, this->parameterAdaptation);
- break;
- case Bola:
- setOk = this->multimediaManager->setVideoAdaptationLogic((LogicType)adaptLogic, this->parameterAdaptation);
- break;
- default:
- setOk = this->multimediaManager->setVideoAdaptationLogic((LogicType)adaptLogic, this->parameterAdaptation);
- break;
- }
+ setOk = this->multimediaManager->setVideoAdaptationLogic((LogicType)adaptLogic, this->parameterAdaptation);
if(!setOk)
{
@@ -302,37 +287,39 @@ void DASHPlayerNoGUI::helpMessage(char * name)
void DASHPlayerNoGUI::onSettingsChanged(int period, int videoAdaptationSet, int videoRepresentation, int audioAdaptationSet, int audioRepresentation)
{
- if(this->multimediaManager->getMPD() == NULL)
- return; // TODO dialog or symbol that indicates that error
+ if(this->mpdWrapper->getMPD() == NULL)
+ return;
if (!this->settingsChanged(period, videoAdaptationSet, videoRepresentation, audioAdaptationSet, audioRepresentation))
return;
- IPeriod *currentPeriod = this->multimediaManager->getMPD()->GetPeriods().at(period);
- std::vector<IAdaptationSet *> videoAdaptationSets = AdaptationSetHelper::getVideoAdaptationSets(currentPeriod);
- std::vector<IAdaptationSet *> audioAdaptationSets = AdaptationSetHelper::getAudioAdaptationSets(currentPeriod);
-
- if (videoAdaptationSet >= 0 && videoRepresentation >= 0 && !videoAdaptationSets.empty())
- {
- this->multimediaManager->setVideoQuality(currentPeriod,
- videoAdaptationSets.at(videoAdaptationSet),
- videoAdaptationSets.at(videoAdaptationSet)->GetRepresentation().at(videoRepresentation));
- }
- else
- {
- this->multimediaManager->setVideoQuality(currentPeriod, NULL, NULL);
- }
-
- if (audioAdaptationSet >= 0 && audioRepresentation >= 0 && !audioAdaptationSets.empty())
- {
- this->multimediaManager->setAudioQuality(currentPeriod,
- audioAdaptationSets.at(audioAdaptationSet),
- audioAdaptationSets.at(audioAdaptationSet)->GetRepresentation().at(audioRepresentation));
- }
- else
- {
- this->multimediaManager->setAudioQuality(currentPeriod, NULL, NULL);
- }
+// IPeriod *currentPeriod = this->multimediaManager->getMPD()->GetPeriods().at(period);
+// std::vector<IAdaptationSet *> videoAdaptationSets = AdaptationSetHelper::getVideoAdaptationSets(currentPeriod);
+// std::vector<IAdaptationSet *> audioAdaptationSets = AdaptationSetHelper::getAudioAdaptationSets(currentPeriod);
+//
+// if (videoAdaptationSet >= 0 && videoRepresentation >= 0 && !videoAdaptationSets.empty())
+// {
+// this->multimediaManager->setVideoQuality(currentPeriod,
+// videoAdaptationSets.at(videoAdaptationSet),
+// videoAdaptationSets.at(videoAdaptationSet)->GetRepresentation().at(videoRepresentation));
+// }
+// else
+// {
+// this->multimediaManager->setVideoQuality(currentPeriod, NULL, NULL);
+// }
+//
+// if (audioAdaptationSet >= 0 && audioRepresentation >= 0 && !audioAdaptationSets.empty())
+// {
+// this->multimediaManager->setAudioQuality(currentPeriod,
+// audioAdaptationSets.at(audioAdaptationSet),
+// audioAdaptationSets.at(audioAdaptationSet)->GetRepresentation().at(audioRepresentation));
+// }
+// else
+// {
+// this->multimediaManager->setAudioQuality(currentPeriod, NULL, NULL);
+// }
+ this->mpdWrapper->settingsChanged(period, videoAdaptationSet, videoRepresentation, audioAdaptationSet, audioRepresentation);
+ this->multimediaManager->setVideoQuality();
}
void DASHPlayerNoGUI::onEOS()
diff --git a/UI/DASHPlayerNoGUI.h b/UI/DASHPlayerNoGUI.h
index 58ba52c4..4b070de8 100644
--- a/UI/DASHPlayerNoGUI.h
+++ b/UI/DASHPlayerNoGUI.h
@@ -50,42 +50,25 @@ public:
virtual void notifyStatistics(int, uint32_t, int, uint32_t);
virtual void notifyQualityDownloading(uint32_t);
virtual bool onDownloadMPDPressed(const std::string &url);
+ virtual void setMPDWrapper(libdash::framework::mpd::MPDWrapper* mpdWrapper);
bool isRunning();
private:
- dash::mpd::IMPD *mpd;
- viper::managers::MultimediaManager *multimediaManager;
- CRITICAL_SECTION monitorMutex;
- char *url;
- bool isICN;
- libdash::framework::adaptation::LogicType adaptLogic;
- pthread_cond_t *mainCond;
- bool running;
+// dash::mpd::IMPD *mpd;
+ libdash::framework::mpd::MPDWrapper *mpdWrapper;
+ viper::managers::MultimediaManager *multimediaManager;
+ CRITICAL_SECTION monitorMutex;
+ char *url;
+ bool isICN;
+ libdash::framework::adaptation::LogicType adaptLogic;
+ pthread_cond_t *mainCond;
+ bool running;
struct libdash::framework::adaptation::AdaptationParameters *parameterAdaptation;
- float segmentDuration;
- int segmentBufferSize;
- double alpha;
- double rateAlpha;
- double bolaAlpha;
- double bolaBufferTargetSeconds;
- int bufferBasedReservoirThreshold;
- int bufferBasedMaxThreshold;
- double adaptechAlpha;
- int adaptechFirstThreshold;
- int adaptechSecondThreshold;
- int adaptechSwitchUpThreshold;
- int bufferThreeThreshold_FirstThreshold;
- int bufferThreeThreshold_SecondThreshold;
- int bufferThreeThreshold_ThirdThreshold;
- double pandaAlpha;
- double pandaParam_Beta;
- double pandaParam_Bmin;
- double pandaParam_K;
- double pandaParam_W;
- double pandaParamEpsilon;
- bool repeat;
- GraphDataSource *graphData;
- bool noDecoding;
+ double alpha;
+ bool repeat;
+ GraphDataSource *graphData;
+ bool noDecoding;
+
bool settingsChanged(int period, int videoAdaptationSet, int videoRepresentation, int audioAdaptationSet, int audioRepresentation);
};
diff --git a/UI/IViperGui.h b/UI/IViperGui.h
new file mode 100644
index 00000000..bf3cb5c3
--- /dev/null
+++ b/UI/IViperGui.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INTERFACE_VIPER_H
+#define INTERFACE_VIPER_H
+
+namespace viper
+{
+
+class IViperGui
+{
+public:
+ virtual void setListSegmentSize(int listSegmentSize) = 0;
+ virtual void setSegmentDuration(long long int segmentDuration) = 0;
+};
+}
+
+#endif // INTERFACE_VIPER_H
diff --git a/UI/ViperGui.cpp b/UI/ViperGui.cpp
index 11ba2e8e..24dcfad2 100644
--- a/UI/ViperGui.cpp
+++ b/UI/ViperGui.cpp
@@ -41,6 +41,7 @@ ViperGui::ViperGui(QObject *parent) :
this->position = 0;
this->videoPlayer = qvariant_cast<QtAV::AVPlayer *>(parent->property("mediaObject"));
this->streamBuffer = new ViperBuffer();
+ this->listSegmentSize = 0;
pthread_mutex_init(&(this->monitorMutex), NULL);
if (streamBuffer->open(QIODevice::ReadWrite)) {
this->videoPlayer->setIODevice(streamBuffer);
@@ -55,25 +56,28 @@ ViperGui::~ViperGui()
void ViperGui::setGuiFields(dash::mpd::IMPD* mpd)
{
- this->setPeriodComboBox(mpd);
- if (mpd->GetPeriods().size() > 0)
+//USELESS CALLS
+// this->setPeriodComboBox(mpd);
+// if (mpd->GetPeriods().size() > 0)
+// {
+// IPeriod *period = mpd->GetPeriods().at(0);
+// this->setVideoAdaptationSetComboBox(period);
+// if (!AdaptationSetHelper::getVideoAdaptationSets(period).empty())
+// {
+// IAdaptationSet *adaptationSet = AdaptationSetHelper::getVideoAdaptationSets(period).at(0);
+// this->setRepresentationComoboBox(adaptationSet);
+// }
+// if (!AdaptationSetHelper::getAudioAdaptationSets(period).empty())
+// {
+// IAdaptationSet *adaptationSet = AdaptationSetHelper::getAudioAdaptationSets(period).at(0);
+// this->setRepresentationComoboBox(adaptationSet);
+// }
+// }
+ if(!strcmp(mpd->GetType().c_str(),"static"))
{
- IPeriod *period = mpd->GetPeriods().at(0);
- this->setVideoAdaptationSetComboBox(period);
- if (!AdaptationSetHelper::getVideoAdaptationSets(period).empty())
- {
- IAdaptationSet *adaptationSet = AdaptationSetHelper::getVideoAdaptationSets(period).at(0);
- this->setRepresentationComoboBox(adaptationSet);
- }
- if (!AdaptationSetHelper::getAudioAdaptationSets(period).empty())
- {
- IAdaptationSet *adaptationSet = AdaptationSetHelper::getAudioAdaptationSets(period).at(0);
- this->setRepresentationComoboBox(adaptationSet);
- }
+ parse8601(mpd->GetMediaPresentationDuration());
+ this->lifeLabel->setProperty("text", QVariant(this->durationString.c_str()));
}
- parse8601(mpd->GetMediaPresentationDuration());
- this->mpd = mpd;
- this->lifeLabel->setProperty("text", QVariant(this->durationString.c_str()));
}
void ViperGui::parse8601(std::string durationISO8601)
@@ -242,7 +246,10 @@ void ViperGui::writeData(libdash::framework::input::MediaObject* media)
{
this->streamBuffer->writeData(media);
pthread_mutex_lock(&(this->monitorMutex));
- this->segment = (this->segment + 1) % this->listSegmentSize;
+ if(this->listSegmentSize)
+ this->segment = (this->segment + 1) % this->listSegmentSize;
+ else
+ this->segment = this->segment + 1;
if( this->segment > 0)
{
this->bufferDuration += this->segmentDuration;
diff --git a/UI/ViperGui.h b/UI/ViperGui.h
index f4586753..1ce8e574 100644
--- a/UI/ViperGui.h
+++ b/UI/ViperGui.h
@@ -28,6 +28,7 @@
#include "../Common/QtQuick2ApplicationViewer.h"
#include "../Managers/MultimediaStream.h"
#include "GraphDataSource.h"
+#include "IViperGui.h"
#include <QLabel>
@@ -35,7 +36,7 @@ namespace viper
{
class IDASHPlayerGuiObserver;
-class ViperGui : public QObject
+class ViperGui : public QObject,public IViperGui
{
Q_OBJECT
diff --git a/libdash/include/IMPD.h b/libdash/include/IMPD.h
index 7e69eecf..7ac82755 100644
--- a/libdash/include/IMPD.h
+++ b/libdash/include/IMPD.h
@@ -111,6 +111,13 @@ namespace dash
/**
* Returns a reference to a string that specifies
+ * the publishTime
+ * @return a reference to a string
+ */
+ virtual const std::string& GetPublishTime () const = 0;
+
+ /**
+ * Returns a reference to a string that specifies
* <ul>
* <li>the anchor for the computation of the earliest availability time (in UTC) for any Segment in the Media Presentation if <tt>\@type=\"dynamic\"</tt>.
* <li>the Segment availability start time for all Segments referred to in this MPD if <tt>\@type=\"static\"</tt>.
@@ -204,4 +211,4 @@ namespace dash
}
}
-#endif /* IMPD_H_ */ \ No newline at end of file
+#endif /* IMPD_H_ */
diff --git a/libdash/source/mpd/MPD.cpp b/libdash/source/mpd/MPD.cpp
index 84e0e614..0c4f2f3a 100644
--- a/libdash/source/mpd/MPD.cpp
+++ b/libdash/source/mpd/MPD.cpp
@@ -104,6 +104,10 @@ void MPD::SetType
{
this->type = type;
}
+const std::string& MPD::GetPublishTime () const
+{
+ return this->publishTime;
+}
const std::string& MPD::GetAvailabilityStarttime () const
{
return this->availabilityStarttime;
@@ -112,6 +116,10 @@ void MPD::SetAvailabilityStarttime
{
this->availabilityStarttime = availabilityStarttime;
}
+void MPD::SetPublishTime (const std::string& publishTime)
+{
+ this->publishTime = publishTime;
+}
const std::string& MPD::GetAvailabilityEndtime () const
{
return this->availabilityEndtime;
diff --git a/libdash/source/mpd/MPD.h b/libdash/source/mpd/MPD.h
index 9bcb38af..fec0266e 100644
--- a/libdash/source/mpd/MPD.h
+++ b/libdash/source/mpd/MPD.h
@@ -41,6 +41,7 @@ namespace dash
const std::string& GetId () const;
const std::vector<std::string>& GetProfiles () const;
const std::string& GetType () const;
+ const std::string& GetPublishTime () const;
const std::string& GetAvailabilityStarttime () const;
const std::string& GetAvailabilityEndtime () const;
const std::string& GetMediaPresentationDuration () const;
@@ -66,6 +67,7 @@ namespace dash
void SetId (const std::string& id);
void SetProfiles (const std::string& profiles);
void SetType (const std::string& type);
+ void SetPublishTime (const std::string& publishTime);
void SetAvailabilityStarttime (const std::string& availabilityStarttime);
void SetAvailabilityEndtime (const std::string& availabilityEndtime);
void SetMediaPresentationDuration (const std::string& mediaPresentationDuration);
@@ -87,6 +89,7 @@ namespace dash
std::string id;
std::vector<std::string> profiles;
std::string type;
+ std::string publishTime;
std::string availabilityStarttime;
std::string availabilityEndtime;
std::string mediaPresentationDuration;
diff --git a/libdash/source/xml/Node.cpp b/libdash/source/xml/Node.cpp
index d04558b6..53193207 100644
--- a/libdash/source/xml/Node.cpp
+++ b/libdash/source/xml/Node.cpp
@@ -715,6 +715,10 @@ dash::mpd::MPD* Node::ToMPD () cons
{
mpd->SetType(this->GetAttributeValue("type"));
}
+ if (this->HasAttribute("publishTime"))
+ {
+ mpd->SetPublishTime(this->GetAttributeValue("publishTime"));
+ }
if (this->HasAttribute("availabilityStartTime"))
{
mpd->SetAvailabilityStarttime(this->GetAttributeValue("availabilityStartTime"));
diff --git a/viper.pro b/viper.pro
index 9b12da0f..836eab92 100644
--- a/viper.pro
+++ b/viper.pro
@@ -55,6 +55,7 @@ SOURCES += \
MPD/SegmentTemplateStream.cpp \
MPD/SingleMediaSegmentStream.cpp \
MPD/TimeResolver.cpp \
+ MPD/MPDWrapper.cpp \
Portable/MultiThreading.cpp \
Managers/MultimediaManager.cpp \
Managers/MultimediaStream.cpp \
@@ -142,6 +143,8 @@ HEADERS *= \
MPD/SegmentTemplateStream.h \
MPD/SingleMediaSegmentStream.h \
MPD/TimeResolver.h \
+ MPD/IMPDWrapper.h \
+ MPD/MPDWrapper.h \
Portable/MultiThreading.h \
Portable/Networking.h \
Managers/IMultimediaManagerBase.h \
@@ -257,6 +260,7 @@ HEADERS *= \
websocketpp/utf8_validator.hpp \
websocketpp/utilities.hpp \
websocketpp/version.hpp \
+ UI/IViperGui.h \
UI/ViperGui.h \
Common/ViperBuffer.h \
Common/QtQuick2ApplicationViewer.h