aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacques SAMAIN <jsamain+fdio@cisco.com>2018-06-01 19:56:33 +0200
committerJacques SAMAIN <jsamain+fdio@cisco.com>2018-06-04 12:16:30 +0000
commit872b2e96a111d6da5f821a6dc61b923f9913b3f3 (patch)
tree9dbae9fb4cf3ed4a35a0698e0cf7f4b446ffeedb
parent6120adcbd955c072f560ba3918ed566088374fa0 (diff)
Several corrections:
*effectively take into account live MPD *Fix several bugs Change-Id: I9b925f222653d2d196b09b4e96cb15119ec8af44 Signed-off-by: Jacques SAMAIN <jsamain+fdio@cisco.com>
-rw-r--r--Adaptation/AdapTech.cpp44
-rw-r--r--Adaptation/AdapTech.h1
-rw-r--r--Adaptation/Panda.cpp4
-rw-r--r--Input/DASHManager.cpp4
-rw-r--r--Input/DASHManager.h1
-rw-r--r--Input/DASHReceiver.cpp41
-rw-r--r--Input/DASHReceiver.h2
-rw-r--r--Input/IDASHManagerObserver.h1
-rw-r--r--Input/IDASHReceiverObserver.h1
-rw-r--r--MPD/AbstractRepresentationStream.h2
-rw-r--r--MPD/IRepresentationStream.h2
-rw-r--r--MPD/MPDWrapper.cpp262
-rw-r--r--MPD/MPDWrapper.h9
-rw-r--r--MPD/SegmentListStream.cpp8
-rw-r--r--MPD/SegmentListStream.h2
-rw-r--r--MPD/SegmentTemplateStream.cpp5
-rw-r--r--MPD/SegmentTemplateStream.h2
-rw-r--r--MPD/SingleMediaSegmentStream.cpp2
-rw-r--r--MPD/SingleMediaSegmentStream.h2
-rw-r--r--Managers/IStreamObserver.h1
-rw-r--r--Managers/MultimediaManager.cpp37
-rw-r--r--Managers/MultimediaManager.h2
-rw-r--r--Managers/MultimediaStream.cpp8
-rw-r--r--Managers/MultimediaStream.h1
-rw-r--r--UI/ViperGui.cpp4
25 files changed, 255 insertions, 193 deletions
diff --git a/Adaptation/AdapTech.cpp b/Adaptation/AdapTech.cpp
index dc88fae6..6f248b4d 100644
--- a/Adaptation/AdapTech.cpp
+++ b/Adaptation/AdapTech.cpp
@@ -82,12 +82,6 @@ void AdapTechAdaptation::notifyBitrateChange()
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 AdapTechAdaptation::getBitrate()
@@ -97,6 +91,44 @@ uint64_t AdapTechAdaptation::getBitrate()
void AdapTechAdaptation::setBitrate(uint32_t bufferFill)
{
+ std::vector<IRepresentation *> representations;
+ representations = this->mpdWrapper->getRepresentations(this->type);
+ bool flagIsSet = this->mpdWrapper->getSegmentIsSetFlag(this->type);
+ int mySetQuality = this->mpdWrapper->getSegmentQuality(this->type);
+
+ if(flagIsSet)
+ {
+ Debug("Adaptech:\tFor %s:\tbuffer_level: %f, instantaneousBw: %lu, AverageBW: %lu,already set: %d\n",(this->type == viper::managers::StreamType::VIDEO) ? "video" : "audio", (double)bufferFill/100, this->instantBw, this->averageBw , this->myQuality);
+
+ if(bufferFill < this->reservoirThreshold)
+ {
+ if(mySetQuality == -1)
+ {
+ mySetQuality = this->myQuality;
+ this->myQuality = 0;
+ this->representation = representations.at(this->myQuality);
+ Debug("Adaptech:\tFor %s: buffer level too low, going to panic mode, old quality: %d\n",(this->type == viper::managers::StreamType::VIDEO) ? "video" : "audio", mySetQuality);
+ this->mpdWrapper->setSegmentQuality(this->type, mySetQuality);
+ }
+ }
+ else
+ {
+ if(mySetQuality != -1)
+ {
+ this->myQuality = mySetQuality;
+ Debug("AdaptechNA:\tFor %s: buffer level high enough, restoring old computed quality: %d\n",(this->type == viper::managers::StreamType::VIDEO) ? "video" : "audio", mySetQuality);
+ }
+ this->representation = representations.at(this->myQuality);
+ }
+ }
+ else
+ {
+ this->setBitrateOption1(bufferFill);
+ this->mpdWrapper->setSegmentIsSetFlag(this->type, true);
+ }
+}
+void AdapTechAdaptation::setBitrateOption1(uint32_t bufferFill)
+{
uint32_t phi1, phi2;
std::vector<IRepresentation *> representations;
representations = this->mpdWrapper->getRepresentations(this->type);
diff --git a/Adaptation/AdapTech.h b/Adaptation/AdapTech.h
index c7f4e33c..24ae2231 100644
--- a/Adaptation/AdapTech.h
+++ b/Adaptation/AdapTech.h
@@ -41,6 +41,7 @@ public:
virtual void bufferUpdate(uint32_t bufferFill, int maxC);
virtual void dLTimeUpdate(double time);
void setBitrate(uint32_t bufferFill);
+ void setBitrateOption1(uint32_t bufferFill);
uint64_t getBitrate();
virtual void setMultimediaManager(viper::managers::IMultimediaManagerBase *_mmManager);
void notifyBitrateChange();
diff --git a/Adaptation/Panda.cpp b/Adaptation/Panda.cpp
index e0c19b27..a8c2d887 100644
--- a/Adaptation/Panda.cpp
+++ b/Adaptation/Panda.cpp
@@ -64,7 +64,7 @@ PandaAdaptation::PandaAdaptation(StreamType type, MPDWrapper *mpdWrapper, struct
// Retrieve the available bitrates
this->mpdWrapper->acquireLock();
std::vector<IRepresentation* > representations = this->mpdWrapper->getRepresentations(this->type);
-
+ this->mpdWrapper->releaseLock();
this->availableBitrates.clear();
Debug("PANDA Available Bitrates...\n");
for(size_t i = 0; i < representations.size(); i++)
@@ -76,7 +76,7 @@ PandaAdaptation::PandaAdaptation(StreamType type, MPDWrapper *mpdWrapper, struct
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);
+ Debug("Panda parameters: K= %f, Bmin = %f, alpha = %f, beta = %f, W = %f \n", param_K, param_Bmin, param_Alpha, param_Beta, param_W);
}
PandaAdaptation::~PandaAdaptation() {
diff --git a/Input/DASHManager.cpp b/Input/DASHManager.cpp
index 0c393353..b3ff8305 100644
--- a/Input/DASHManager.cpp
+++ b/Input/DASHManager.cpp
@@ -160,3 +160,7 @@ void DASHManager::onBufferStateChanged(BufferType type, uint32_t fillstateInPerc
if(this->adaptationLogic->isBufferBased())
this->receiver->OnSegmentBufferStateChanged(fillstateInPercent, maxC);
}
+void DASHManager::fetchMPD()
+{
+ this->multimediaStream->fetchMPD();
+}
diff --git a/Input/DASHManager.h b/Input/DASHManager.h
index 3b9bf005..4bd301e7 100644
--- a/Input/DASHManager.h
+++ b/Input/DASHManager.h
@@ -61,6 +61,7 @@ public:
void setTargetDownloadingTime(double);
MediaObject* getSegment();
void onBufferStateChanged(BufferType type, uint32_t fillstateInPercent, int maxC);
+ void fetchMPD();
private:
float beta;
diff --git a/Input/DASHReceiver.cpp b/Input/DASHReceiver.cpp
index 74415bfa..0d77bdf2 100644
--- a/Input/DASHReceiver.cpp
+++ b/Input/DASHReceiver.cpp
@@ -42,7 +42,8 @@ DASHReceiver::DASHReceiver (viper::managers::StreamType type, MPDWrappe
isLooping (false),
beta (beta),
drop (drop),
- bufferingThread (NULL)
+ bufferingThread (NULL),
+ mpdFetcherThread (NULL)
{
readMax = 32768;
readBuffer = (uint8_t*)malloc(sizeof(uint8_t)*readMax);
@@ -95,6 +96,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()
@@ -260,8 +270,8 @@ void DASHReceiver::NotifyCheckedAdaptationLogic()
//Is only called when this->adaptationLogic->IsBufferBased
void DASHReceiver::OnSegmentBufferStateChanged(uint32_t fillstateInPercent, int maxC)
{
- this->adaptationLogic->bufferUpdate(this->observer->getBufferLevel(), maxC);
this->bufferLevelAtUpdate = this->observer->getBufferLevel();
+ this->adaptationLogic->bufferUpdate(this->bufferLevelAtUpdate, maxC);
}
void DASHReceiver::OnEOS(bool value)
{
@@ -274,14 +284,14 @@ bool DASHReceiver::PushBack(MediaObject *mediaObject)
mediaObject->AddInitSegment(init);
//TODO the read should be in a function
- //Grab the infos for the analytics: bitrate, fps
+ //Grab the infos for the analytics: bitrate, bufferLevel
uint32_t bitrate = 0;
- int fps = 0;
+ int bufferLevel = 0;
uint32_t quality = 0;
bitrate = mediaObject->GetRepresentationBandwidth();
quality = mediaObject->GetRepresentationHeight();
- fps = this->bufferLevelAtUpdate;
- this->observer->notifyStatistics((int)this->segmentNumber - 1, bitrate, fps, quality);
+ bufferLevel = this->bufferLevelAtUpdate;
+ this->observer->notifyStatistics((int)this->segmentNumber - 1, bitrate, bufferLevel, quality);
return(this->buffer->pushBack(mediaObject));
}
@@ -335,6 +345,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 ()
{
diff --git a/Input/DASHReceiver.h b/Input/DASHReceiver.h
index a6db0382..e5b48adf 100644
--- a/Input/DASHReceiver.h
+++ b/Input/DASHReceiver.h
@@ -107,6 +107,7 @@ private:
IICNConnection *conn;
IICNConnection *initConn;
THREAD_HANDLE bufferingThread;
+ THREAD_HANDLE mpdFetcherThread;
bool isBuffering;
bool icn;
double icnAlpha;
@@ -122,6 +123,7 @@ private:
void DownloadInitSegmentWithoutLock();
bool InitSegmentExists(std::string rep);
static void* DoBuffering(void *receiver);
+ static void* DoMPDFetching(void * data);
};
}
}
diff --git a/Input/IDASHManagerObserver.h b/Input/IDASHManagerObserver.h
index 0f2d95df..57f15726 100644
--- a/Input/IDASHManagerObserver.h
+++ b/Input/IDASHManagerObserver.h
@@ -33,6 +33,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/MPD/AbstractRepresentationStream.h b/MPD/AbstractRepresentationStream.h
index da847c3c..113720ed 100644
--- a/MPD/AbstractRepresentationStream.h
+++ b/MPD/AbstractRepresentationStream.h
@@ -43,7 +43,7 @@ public:
virtual dash::mpd::ISegment* getInitializationSegment() = 0;
virtual dash::mpd::ISegment* getIndexSegment(size_t segmentNumber) = 0;
- virtual dash::mpd::ISegment* getMediaSegment(size_t segmentNumber, uint64_t& segmentDuration) = 0;
+ virtual dash::mpd::ISegment* getMediaSegment(size_t segmentNumber) = 0;
virtual dash::mpd::ISegment* getBitstreamSwitchingSegment() = 0;
virtual RepresentationStreamType getStreamType() = 0;
diff --git a/MPD/IRepresentationStream.h b/MPD/IRepresentationStream.h
index 124216ba..bf8b08c4 100644
--- a/MPD/IRepresentationStream.h
+++ b/MPD/IRepresentationStream.h
@@ -35,7 +35,7 @@ public:
virtual dash::mpd::ISegment* getInitializationSegment() = 0;
virtual dash::mpd::ISegment* getIndexSegment(size_t segmentNumber) = 0;
- virtual dash::mpd::ISegment* getMediaSegment(size_t segmentNumber, uint64_t& segmentDuration) = 0;
+ virtual dash::mpd::ISegment* getMediaSegment(size_t segmentNumber) = 0;
virtual dash::mpd::ISegment* getBitstreamSwitchingSegment() = 0;
virtual RepresentationStreamType getStreamType() = 0;
virtual uint32_t getSize() = 0;
diff --git a/MPD/MPDWrapper.cpp b/MPD/MPDWrapper.cpp
index 0b1d9596..1dca34fb 100644
--- a/MPD/MPDWrapper.cpp
+++ b/MPD/MPDWrapper.cpp
@@ -28,8 +28,7 @@ MPDWrapper::MPDWrapper(IMPD *mpd):
videoSegmentOffset (0),
audioSegmentOffset (0),
videoSegmentNumber (0),
- audioSegmentNumber (0),
- hasReachedEndOfList (false)
+ audioSegmentNumber (0)
{
InitializeConditionVariable (&this->mpdUpdate);
@@ -52,7 +51,7 @@ void MPDWrapper::updateMPD (IMPD* mpd)
//Assumptions here:
// *only one period in the MPD
// *only triggered if using SegmentTimeline dynamic MPD
- EnterCriticalSection(&this->monitorMutex);
+ this->acquireLock();
this->period = mpd->GetPeriods().at(0);
this->findVideoAdaptationSet(mpd);
this->findAudioAdaptationSet(mpd);
@@ -61,7 +60,7 @@ void MPDWrapper::updateMPD (IMPD* mpd)
delete(this->mpd);
this->mpd = mpd;
WakeAllConditionVariable(&this->mpdUpdate);
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
}
void MPDWrapper::findVideoAdaptationSet (IMPD* mpd)
@@ -186,16 +185,16 @@ void MPDWrapper::findAudioRepresentation (IMPD* mpd)
std::string MPDWrapper::getType ()
{
std::string type;
- EnterCriticalSection(&this->monitorMutex);
+ this->acquireLock();
type = this->mpd->GetType();
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
return type;
}
void MPDWrapper::reInit (viper::managers::StreamType type)
{
- EnterCriticalSection(&this->monitorMutex);
+ this->acquireLock();
switch(type)
{
case viper::managers::StreamType::VIDEO:
@@ -215,30 +214,30 @@ void MPDWrapper::reInit (viper::managers::StreamType type)
default:
break;
}
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
}
bool MPDWrapper::hasVideoAdaptationSetAndVideoRepresentation ()
{
- EnterCriticalSection(&this->monitorMutex);
+ this->acquireLock();
if(this->videoAdaptationSet && this->videoRepresentation)
{
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
return 1;
}
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
return 0;
}
bool MPDWrapper::hasAudioAdaptationSetAndAudioRepresentation ()
{
- EnterCriticalSection(&this->monitorMutex);
+ this->acquireLock();
if(this->audioAdaptationSet && this->audioRepresentation)
{
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
return 1;
}
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
return 0;
}
@@ -281,7 +280,7 @@ void MPDWrapper::initializeAdaptationSetStream (viper::managers::StreamType type
{
IAdaptationSet *adaptationSet = NULL;
std::map<dash::mpd::IRepresentation *, IRepresentationStream *> *representations = NULL;
- EnterCriticalSection(&this->monitorMutex);
+ this->acquireLock();
switch(type)
{
@@ -311,7 +310,7 @@ void MPDWrapper::initializeAdaptationSetStream (viper::managers::StreamType type
RepresentationStreamType typeR = determineRepresentationStreamType(representation, adaptationSet, this->period);
(*representations)[representation] = RepresentationStreamFactory::create(type, typeR, this, period, adaptationSet, representation);
}
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
}
void MPDWrapper::initializeAdaptationSetStreamWithoutLock (viper::managers::StreamType type)
@@ -549,7 +548,7 @@ void MPDWrapper::releaseLock ()
void MPDWrapper::setSegmentOffset(viper::managers::StreamType type, uint32_t segmentOffset)
{
- EnterCriticalSection(&this->monitorMutex);
+ this->acquireLock();
switch(type)
{
case viper::managers::StreamType::AUDIO:
@@ -563,31 +562,28 @@ void MPDWrapper::setSegmentOffset(viper::managers::StreamType type, uint32_t seg
default:
break;
}
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
}
MediaObject* MPDWrapper::getNextSegment (viper::managers::StreamType type, bool isLooping, uint32_t &segmentNumber, bool withFeedBack)
{
IRepresentation* representation;
std::map<dash::mpd::IRepresentation *, IRepresentationStream *> *representations;
- dash::mpd::IAdaptationSet* adaptationSet;
-
- EnterCriticalSection(&this->monitorMutex);
+
+ this->acquireLock();
switch(type)
{
case viper::managers::StreamType::AUDIO:
representation = this->audioRepresentation;
representations = this->audioRepresentations;
- adaptationSet = this->audioAdaptationSet;
break;
case viper::managers::StreamType::VIDEO:
representation = this->videoRepresentation;
representations = this->videoRepresentations;
- adaptationSet = this->videoAdaptationSet;
break;
default:
- LeaveCriticalSection(&this->monitorMutex);
- return NULL;
+ this->releaseLock();
+ return NULL;
}
ISegment* seg = NULL;
@@ -614,7 +610,7 @@ MediaObject* MPDWrapper::getNextSegment (viper::managers::StreamType type, bool
default:
break;
}
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
return NULL;
}
}
@@ -624,105 +620,53 @@ MediaObject* MPDWrapper::getNextSegment (viper::managers::StreamType type, bool
while((this->isStopping == false) && segmentNumber >= representationStream->getSize())
{
SleepConditionVariableCS(&this->mpdUpdate, &this->monitorMutex, INFINITE);
- this->hasReachedEndOfList = true;
+
+ if(this->isStopping)
+ {
+ this->releaseLock();
+ return NULL;
+ }
+ //Need to update representationStream here as it was updated with the mpd (Live only):
switch(type)
{
case viper::managers::StreamType::AUDIO:
representation = this->audioRepresentation;
representations = this->audioRepresentations;
- adaptationSet = this->audioAdaptationSet;
- segmentNumber = this->audioSegmentNumber;
break;
case viper::managers::StreamType::VIDEO:
representation = this->videoRepresentation;
representations = this->videoRepresentations;
- adaptationSet = this->videoAdaptationSet;
- segmentNumber = this->videoSegmentNumber;
break;
default:
break;
}
representationStream = representations->find(representation)->second;
- if(this->hasReachedEndOfList)
- segmentNumber += 1;
- }
- 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:
- segmentNumber = this->audioSegmentNumber;
- break;
- case viper::managers::StreamType::VIDEO:
- segmentNumber = this->videoSegmentNumber;
- break;
- default:
- break;
- }
- if(this->hasReachedEndOfList)
- {
- segmentNumber += 1;
- this->hasReachedEndOfList = false;
}
}
- uint64_t segDuration = 0;
- //Returns the segmentDuration in milliseconds
- seg = representationStream->getMediaSegment(segmentNumber, segDuration);
+ seg = representationStream->getMediaSegment(segmentNumber);
if(seg != NULL)
{
- MediaObject *media = new MediaObject(seg, representation, withFeedBack);
- if(segDuration == 0)
- {
- uint32_t duration = 0;
- uint32_t timescale = 0;
-
- if(representation->GetSegmentTemplate())
- {
- duration = representation->GetSegmentTemplate()->GetDuration();
- timescale = representation->GetSegmentTemplate()->GetTimescale();
- }
- else
- {
- if(adaptationSet->GetSegmentTemplate())
- {
- duration = adaptationSet->GetSegmentTemplate()->GetDuration();
- timescale = adaptationSet->GetSegmentTemplate()->GetTimescale();
- }
- else
- {
- if(this->period->GetSegmentTemplate())
- {
- duration = this->period->GetSegmentTemplate()->GetDuration();
- timescale = this->period->GetSegmentTemplate()->GetTimescale();
- }
- }
- }
- segDuration = 1.0*duration/(1.0*timescale) * 1000;
-
- }
- media->SetSegmentDuration(segDuration);
+ MediaObject *media = new MediaObject(seg, representation, withFeedBack);
segmentNumber++;
-
switch(type)
{
case viper::managers::StreamType::AUDIO:
this->audioSegmentNumber = segmentNumber;
+ this->audioSegmentIsSet = false;
+ this->audioSegmentQuality = -1;
break;
case viper::managers::StreamType::VIDEO:
this->videoSegmentNumber = segmentNumber;
+ this->videoSegmentIsSet = false;
+ this->videoSegmentQuality = -1;
break;
default:
break;
}
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
return media;
}
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
return NULL;
}
@@ -730,7 +674,7 @@ MediaObject* MPDWrapper::getSegment (viper::managers::StreamType type, uint32_t
{
IRepresentation* representation;
std::map<dash::mpd::IRepresentation *, IRepresentationStream *> *representations;
- EnterCriticalSection(&this->monitorMutex);
+ this->acquireLock();
switch(type)
{
@@ -743,7 +687,7 @@ MediaObject* MPDWrapper::getSegment (viper::managers::StreamType type, uint32_t
representations = this->videoRepresentations;
break;
default:
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
return NULL;
}
@@ -751,19 +695,17 @@ MediaObject* MPDWrapper::getSegment (viper::managers::StreamType type, uint32_t
IRepresentationStream* representationStream = representations->find(representation)->second;
if(segNum >= representationStream->getSize())
{
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
return NULL;
}
- uint64_t segDuration =0;
- seg = representationStream->getMediaSegment(segNum, segDuration);
+ seg = representationStream->getMediaSegment(segNum);
if(seg != NULL)
{
MediaObject *media = new MediaObject(seg, representation);
- media->SetSegmentDuration(segDuration);
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
return media;
}
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
return NULL;
}
@@ -771,7 +713,7 @@ MediaObject* MPDWrapper::getInitSegment (viper::managers::StreamType type)
{
IRepresentation* representation;
std::map<dash::mpd::IRepresentation *, IRepresentationStream *> *representations;
- EnterCriticalSection(&this->monitorMutex);
+ this->acquireLock();
switch(type)
{
@@ -784,7 +726,7 @@ MediaObject* MPDWrapper::getInitSegment (viper::managers::StreamType type)
representations = this->videoRepresentations;
break;
default:
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
return NULL;
}
@@ -795,10 +737,10 @@ MediaObject* MPDWrapper::getInitSegment (viper::managers::StreamType type)
if(seg != NULL)
{
MediaObject *media = new MediaObject(seg, representation);
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
return media;
}
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
return NULL;
}
@@ -822,7 +764,7 @@ void MPDWrapper::setAudioQuality (IPeriod *period, IAdaptationSet *adaptationSet
bool periodChanged = false;
if (this->audioRepresentation == representation)
{
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
return;
}
@@ -848,7 +790,7 @@ void MPDWrapper::setVideoQuality (IPeriod *period, IAdaptationSet *adaptationSet
bool periodChanged = false;
if (this->videoRepresentation == representation)
{
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
return;
}
@@ -873,7 +815,7 @@ uint32_t MPDWrapper::calculateSegmentOffset (viper::managers::StreamType type, u
{
IRepresentation* representation;
std::map<dash::mpd::IRepresentation *, IRepresentationStream *> *representations;
- EnterCriticalSection(&this->monitorMutex);
+ this->acquireLock();
switch(type)
{
@@ -886,13 +828,13 @@ uint32_t MPDWrapper::calculateSegmentOffset (viper::managers::StreamType type, u
representations = this->videoRepresentations;
break;
default:
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
return 0;
}
if(!(strcmp(this->mpd->GetType().c_str(), "static")))
{
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
return 0;
}
IRepresentationStream* representationStream = representations->find(representation)->second;
@@ -900,14 +842,14 @@ uint32_t MPDWrapper::calculateSegmentOffset (viper::managers::StreamType type, u
uint32_t currSegNum = representationStream->getCurrentSegmentNumber();
uint32_t startSegNum = currSegNum - 2*bufferSize;
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
return (startSegNum > firstSegNum) ? startSegNum : firstSegNum;
}
std::string MPDWrapper::getRepresentationID (viper::managers::StreamType type)
{
std::string id = "";
- EnterCriticalSection(&this->monitorMutex);
+ this->acquireLock();
switch(type)
{
@@ -920,23 +862,23 @@ std::string MPDWrapper::getRepresentationID (viper::managers::StreamType type)
default:
break;
}
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
return id;
}
std::string MPDWrapper::getPublishTime ()
{
- EnterCriticalSection(&this->monitorMutex);
+ this->acquireLock();
std::string pubTime = this->mpd->GetPublishTime();
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
return pubTime;
}
std::string MPDWrapper::getMinimumUpdatePeriod ()
{
- EnterCriticalSection(&this->monitorMutex);
+ this->acquireLock();
std::string res = this->mpd->GetMinimumUpdatePeriod();
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
return res;
}
@@ -1079,7 +1021,7 @@ uint32_t MPDWrapper::getFetchTime ()
void MPDWrapper::settingsChanged (int period, int videoAdaptationSet, int videoRepresentation, int audioAdaptationSet, int audioRepresentation)
{
- EnterCriticalSection(&this->monitorMutex);
+ this->acquireLock();
this->period = this->mpd->GetPeriods().at(period);
std::vector<IAdaptationSet *> videoAdaptationSets = AdaptationSetHelper::getVideoAdaptationSets(this->period);
std::vector<IAdaptationSet *> audioAdaptationSets = AdaptationSetHelper::getAudioAdaptationSets(this->period);
@@ -1103,14 +1045,14 @@ void MPDWrapper::settingsChanged (int period, int videoAdaptationSet, int videoR
this->audioAdaptationSet = NULL;
this->audioRepresentation = NULL;
}
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
}
//Returns the segmentDuration
float MPDWrapper::onFirstDownloadMPD (viper::IViperGui *gui)
{
float segmentDuration = 0.0;
- EnterCriticalSection(&this->monitorMutex);
+ this->acquireLock();
IRepresentation *representation = this->videoAdaptationSet->GetRepresentation().at(0);
if(!strcmp(this->mpd->GetType().c_str(), "static")) // VOD MPD
{
@@ -1164,8 +1106,26 @@ float MPDWrapper::onFirstDownloadMPD (viper::IViperGui *gui)
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();
+ uint32_t duration = 0;
+ uint32_t timescale = 0;
+ if(representation->GetSegmentTemplate())
+ {
+ duration = representation->GetSegmentTemplate()->GetDuration();
+ timescale = representation->GetSegmentTemplate()->GetTimescale();
+ }
+ else
+ {
+ if(this->videoAdaptationSet->GetSegmentTemplate()) //SegmentTemplate at AdaptationSet level
+ {
+ duration = this->videoAdaptationSet->GetSegmentTemplate()->GetDuration();
+ timescale = this->videoAdaptationSet->GetSegmentTemplate()->GetTimescale();
+ }
+ else
+ { // SegmentTemplate at Period level
+ duration = this->period->GetSegmentTemplate()->GetDuration();
+ timescale = this->period->GetSegmentTemplate()->GetTimescale();
+ }
+ }
segmentDuration = 1.0*duration/(1.0*timescale) * 1000;
if(gui)
{
@@ -1173,7 +1133,7 @@ float MPDWrapper::onFirstDownloadMPD (viper::IViperGui *gui)
gui->setListSegmentSize(0);
}
}
- LeaveCriticalSection(&this->monitorMutex);
+ this->releaseLock();
return segmentDuration;
}
@@ -1182,3 +1142,59 @@ void MPDWrapper::setIsStopping (bool isStopping)
this->isStopping = isStopping;
WakeAllConditionVariable(&this->mpdUpdate);
}
+
+void MPDWrapper::setSegmentIsSetFlag(viper::managers::StreamType type, bool flag)
+{
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ this->audioSegmentIsSet = flag;
+ break;
+ case viper::managers::StreamType::VIDEO:
+ this->videoSegmentIsSet = flag;
+ break;
+ default:
+ break;
+ }
+}
+
+bool MPDWrapper::getSegmentIsSetFlag(viper::managers::StreamType type)
+{
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ return this->audioSegmentIsSet;
+ case viper::managers::StreamType::VIDEO:
+ return this->videoSegmentIsSet;
+ default:
+ return false;
+ }
+}
+
+int MPDWrapper::getSegmentQuality(viper::managers::StreamType type)
+{
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ return this->audioSegmentQuality;
+ case viper::managers::StreamType::VIDEO:
+ return this->videoSegmentQuality;
+ default:
+ return false;
+ }
+}
+
+void MPDWrapper::setSegmentQuality(viper::managers::StreamType type, int segQuality)
+{
+ switch(type)
+ {
+ case viper::managers::StreamType::AUDIO:
+ this->audioSegmentIsSet = segQuality;
+ break;
+ case viper::managers::StreamType::VIDEO:
+ this->videoSegmentIsSet = segQuality;
+ break;
+ default:
+ break;
+ }
+}
diff --git a/MPD/MPDWrapper.h b/MPD/MPDWrapper.h
index cf6275d8..75ade085 100644
--- a/MPD/MPDWrapper.h
+++ b/MPD/MPDWrapper.h
@@ -106,6 +106,10 @@ public:
void settingsChanged(int period, int videoAdaptationSet, int videoRepresentation, int audioAdaptationSet, int audioRepresentation);
float onFirstDownloadMPD(viper::IViperGui *gui);
void setIsStopping(bool isStopping);
+ void setSegmentIsSetFlag(viper::managers::StreamType type, bool flag);
+ bool getSegmentIsSetFlag(viper::managers::StreamType type);
+ int getSegmentQuality(viper::managers::StreamType type);
+ void setSegmentQuality(viper::managers::StreamType type, int segQuality);
private:
RepresentationStreamType determineRepresentationStreamType(dash::mpd::IRepresentation *representation, dash::mpd::IAdaptationSet* adaptationSet, dash::mpd::IPeriod* period);
@@ -124,8 +128,11 @@ private:
uint32_t audioSegmentOffset;
size_t videoSegmentNumber;
size_t audioSegmentNumber;
+ bool videoSegmentIsSet;
+ bool audioSegmentIsSet;
+ int videoSegmentQuality;
+ int audioSegmentQuality;
bool isStopping;
- bool hasReachedEndOfList;
};
}
}
diff --git a/MPD/SegmentListStream.cpp b/MPD/SegmentListStream.cpp
index 86d36e68..0ab67570 100644
--- a/MPD/SegmentListStream.cpp
+++ b/MPD/SegmentListStream.cpp
@@ -53,15 +53,11 @@ ISegment* SegmentListStream::getIndexSegment(size_t segmentNumber)
return NULL;
}
-ISegment* SegmentListStream::getMediaSegment(size_t segmentNumber, uint64_t& segmentDuration)
+ISegment* SegmentListStream::getMediaSegment(size_t segmentNumber)
{
if (this->segmentList->GetSegmentURLs().size() > segmentNumber)
- {
- uint32_t duration = representation->GetSegmentList()->GetDuration();
- uint32_t timescale = representation->GetSegmentList()->GetTimescale();
- segmentDuration = (uint64_t)(((float)duration/(float)timescale) * 1000);
return this->segmentList->GetSegmentURLs().at(segmentNumber)->ToMediaSegment(this->baseUrls);
- }
+
return NULL;
}
diff --git a/MPD/SegmentListStream.h b/MPD/SegmentListStream.h
index 589896ff..a9658748 100644
--- a/MPD/SegmentListStream.h
+++ b/MPD/SegmentListStream.h
@@ -33,7 +33,7 @@ public:
virtual dash::mpd::ISegment* getInitializationSegment();
virtual dash::mpd::ISegment* getIndexSegment(size_t segmentNumber);
- virtual dash::mpd::ISegment* getMediaSegment(size_t segmentNumber, uint64_t& segmentDuration);
+ virtual dash::mpd::ISegment* getMediaSegment(size_t segmentNumber);
virtual dash::mpd::ISegment* getBitstreamSwitchingSegment();
virtual RepresentationStreamType getStreamType();
virtual uint32_t getSize();
diff --git a/MPD/SegmentTemplateStream.cpp b/MPD/SegmentTemplateStream.cpp
index 5a6dd67c..b8f08530 100644
--- a/MPD/SegmentTemplateStream.cpp
+++ b/MPD/SegmentTemplateStream.cpp
@@ -64,14 +64,13 @@ ISegment* SegmentTemplateStream::getIndexSegment(size_t segmentNumber)
this->segmentTemplate->GetStartNumber() + segmentNumber);
}
-ISegment* SegmentTemplateStream::getMediaSegment(size_t segmentNumber, uint64_t& segmentDuration)
+ISegment* SegmentTemplateStream::getMediaSegment(size_t segmentNumber)
{
/* time-based template */
if (this->segmentTemplate->GetSegmentTimeline())
{//Get the one at segmentNumber
if(this->segmentStartTimes.size() > segmentNumber)
{
- segmentDuration = (uint64_t)(((float)this->segmentDurationTimes.at(segmentNumber)/(float)this->getTimescale()) * 1000);
return this->segmentTemplate->GetMediaSegmentFromTime(baseUrls, representation->GetId(), representation->GetBandwidth(), this->segmentStartTimes.at(segmentNumber));
}
else
@@ -228,7 +227,7 @@ uint64_t SegmentTemplateStream::getTime(size_t segmentNumber)
if(segmentNumber < this->segmentStartTimes.size())
return this->segmentStartTimes.at(segmentNumber);
else
- return this->segmentStartTimes.at(this->segmentStartTimes.size()-1);
+ return (this->segmentStartTimes.size() == 0)? 0 : this->segmentStartTimes.at(this->segmentStartTimes.size()-1);
}
size_t SegmentTemplateStream::getSegmentNumber(uint64_t time)
diff --git a/MPD/SegmentTemplateStream.h b/MPD/SegmentTemplateStream.h
index 8485b56b..8325a387 100644
--- a/MPD/SegmentTemplateStream.h
+++ b/MPD/SegmentTemplateStream.h
@@ -34,7 +34,7 @@ public:
virtual dash::mpd::ISegment* getInitializationSegment();
virtual dash::mpd::ISegment* getIndexSegment(size_t segmentNumber);
- virtual dash::mpd::ISegment* getMediaSegment(size_t segmentNumber, uint64_t& segmentDuration);
+ virtual dash::mpd::ISegment* getMediaSegment(size_t segmentNumber);
virtual dash::mpd::ISegment* getBitstreamSwitchingSegment();
virtual RepresentationStreamType getStreamType();
virtual uint32_t getSize();
diff --git a/MPD/SingleMediaSegmentStream.cpp b/MPD/SingleMediaSegmentStream.cpp
index 3eccbefe..39301928 100644
--- a/MPD/SingleMediaSegmentStream.cpp
+++ b/MPD/SingleMediaSegmentStream.cpp
@@ -51,7 +51,7 @@ ISegment* SingleMediaSegmentStream::getIndexSegment(size_t segmentNumber)
return NULL;
}
-ISegment* SingleMediaSegmentStream::getMediaSegment(size_t segmentNumber, uint64_t& segmentDuration)
+ISegment* SingleMediaSegmentStream::getMediaSegment(size_t segmentNumber)
{
/* segmentNumber equals the desired BaseUrl */
if (this->representation->GetBaseURLs().size() > segmentNumber)
diff --git a/MPD/SingleMediaSegmentStream.h b/MPD/SingleMediaSegmentStream.h
index 44fead38..e619a7f8 100644
--- a/MPD/SingleMediaSegmentStream.h
+++ b/MPD/SingleMediaSegmentStream.h
@@ -31,7 +31,7 @@ public:
virtual dash::mpd::ISegment* getInitializationSegment();
virtual dash::mpd::ISegment* getIndexSegment(size_t segmentNumber);
- virtual dash::mpd::ISegment* getMediaSegment(size_t segmentNumber, uint64_t& segmentDuration);
+ virtual dash::mpd::ISegment* getMediaSegment(size_t segmentNumber);
virtual dash::mpd::ISegment* getBitstreamSwitchingSegment();
virtual RepresentationStreamType getStreamType();
diff --git a/Managers/IStreamObserver.h b/Managers/IStreamObserver.h
index 31baca68..1d628d51 100644
--- a/Managers/IStreamObserver.h
+++ b/Managers/IStreamObserver.h
@@ -38,6 +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 1b759f4b..30f8427a 100644
--- a/Managers/MultimediaManager.cpp
+++ b/Managers/MultimediaManager.cpp
@@ -41,8 +41,7 @@ MultimediaManager::MultimediaManager(ViperGui *viperGui, int segBufSize, std::st
eos (false),
playing (false),
noDecoding (nodecoding),
- mpdWrapper (NULL),
- mpdFetcherThread (NULL)
+ mpdWrapper (NULL)
{
InitializeCriticalSection (&this->monitorMutex);
InitializeCriticalSection (&this->monitorBufferMutex);
@@ -239,14 +238,6 @@ void MultimediaManager::start(bool icnEnabled, double icnAlpha, uint32_t nextOff
this->started = true;
this->playing = true;
- 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;
- }
- }
LeaveCriticalSection(&this->monitorMutex);
}
@@ -265,11 +256,6 @@ void MultimediaManager::stop()
Debug("VIDEO STOPPED\n");
this->mpdWrapper->reInit(viper::managers::StreamType::VIDEO);
this->mpdWrapper->reInit(viper::managers::StreamType::AUDIO);
- if(this->mpdFetcherThread != NULL)
- {
- JoinThread(this->mpdFetcherThread);
- destroyThreadPortable(this->mpdFetcherThread);
- }
}
void MultimediaManager::stopVideo()
@@ -706,24 +692,3 @@ float MultimediaManager::getSegmentDuration()
return this->segmentDuration;
}
-void* MultimediaManager::DoMPDFetching (void* data)
-{
- MultimediaManager *manager = (MultimediaManager*) data;
- uint32_t currTime = TimeResolver::getCurrentTimeInSec();
- uint32_t publishedTime = manager->mpdWrapper->getFetchTime();
-// To avoid clock synchronisation issues: using fetching time instead of publish time
-// uint32_t publishedTime = TimeResolver::getUTCDateTimeInSec(dashReceiver->mpdWrapper->getPublishTime());
- uint32_t periodUpdate = TimeResolver::getDurationInSec(manager->mpdWrapper->getMinimumUpdatePeriod());
- while(manager->isStarted())
- {
- while(manager->isStarted() && currTime < publishedTime + periodUpdate)
- {
- usleep(((publishedTime + periodUpdate) - currTime) * 1000000);
- currTime = TimeResolver::getCurrentTimeInSec();
- }
- manager->fetchMPD();
- publishedTime = manager->mpdWrapper->getFetchTime();
-// publishedTime = TimeResolver::getUTCDateTimeInSec(dashReceiver->mpdWrapper->getPublishTime());
- periodUpdate = TimeResolver::getDurationInSec(manager->mpdWrapper->getMinimumUpdatePeriod());
- }
-}
diff --git a/Managers/MultimediaManager.h b/Managers/MultimediaManager.h
index c00ff866..ade2b767 100644
--- a/Managers/MultimediaManager.h
+++ b/Managers/MultimediaManager.h
@@ -106,7 +106,6 @@ private:
double frameRate;
THREAD_HANDLE videoRendererHandle;
THREAD_HANDLE audioRendererHandle;
- THREAD_HANDLE mpdFetcherThread;
bool isVideoRendering;
bool isAudioRendering;
bool eos;
@@ -137,7 +136,6 @@ private:
void notifyAudioSegmentBufferObservers (uint32_t fillstateInPercent);
void updateMPD ();
void updateMPDICN ();
- static void* DoMPDFetching (void* manager);
};
}
}
diff --git a/Managers/MultimediaStream.cpp b/Managers/MultimediaStream.cpp
index f70eabfb..86cde35d 100644
--- a/Managers/MultimediaStream.cpp
+++ b/Managers/MultimediaStream.cpp
@@ -198,3 +198,11 @@ void MultimediaStream::notifyBufferChange(uint32_t bufferfill, int maxC)
{
this->dashManager->onBufferStateChanged(libdash::framework::buffer::VIDEO, bufferfill, maxC);
}
+
+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 52a7ac9d..454cca23 100644
--- a/Managers/MultimediaStream.h
+++ b/Managers/MultimediaStream.h
@@ -75,6 +75,7 @@ public:
bool isICN();
void shouldAbort();
void setTargetDownloadingTime(double);
+ void fetchMPD();
private:
float beta;
diff --git a/UI/ViperGui.cpp b/UI/ViperGui.cpp
index 99d2e5a3..e23bd308 100644
--- a/UI/ViperGui.cpp
+++ b/UI/ViperGui.cpp
@@ -192,7 +192,7 @@ void ViperGui::writeData(libdash::framework::input::MediaObject* media)
this->segment = this->segment + 1;
if( this->segment > 0)
{
- this->bufferDuration += media->GetSegmentDuration();
+ this->bufferDuration += this->segmentDuration;
if(this->bufferDuration - this->position > 3000)
{
@@ -206,7 +206,7 @@ void ViperGui::writeData(libdash::framework::input::MediaObject* media)
}
else
{
- this->bufferDuration += (this->durationMilliseconds - (media->GetSegmentDuration() * (this->listSegmentSize - 1)));
+ this->bufferDuration += (this->durationMilliseconds - (this->segmentDuration * (this->listSegmentSize - 1)));
if(this->bufferDuration - this->position >3000)
{