aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacques Samain <jsamain+fdio@cisco.com>2017-07-25 15:32:54 +0200
committerJacques Samain <jsamain+fdio@cisco.com>2017-07-25 15:32:54 +0200
commit0e275345e28c34f2c6b91a75f44ac93034ae477c (patch)
tree0b94ec17f395fce7ae1015200d45bd61ce0112a8
parentce4d018aa8185da0bbf5445eaf54d88700f1a381 (diff)
Handling live MPDs with variable segments duration
Change-Id: I074d8863a9afb47815e47bf663b87e7f663890b9 Signed-off-by: Jacques Samain <jsamain+fdio@cisco.com>
-rw-r--r--Adaptation/Bola.cpp8
-rw-r--r--Input/DASHReceiver.cpp9
-rw-r--r--Input/DASHReceiver.h6
-rw-r--r--Input/MediaObject.cpp16
-rw-r--r--Input/MediaObject.h15
-rw-r--r--MPD/AbstractRepresentationStream.h2
-rw-r--r--MPD/IRepresentationStream.h2
-rw-r--r--MPD/MPDWrapper.cpp9
-rw-r--r--MPD/SegmentListStream.cpp13
-rw-r--r--MPD/SegmentListStream.h3
-rw-r--r--MPD/SegmentTemplateStream.cpp22
-rw-r--r--MPD/SegmentTemplateStream.h3
-rw-r--r--MPD/SingleMediaSegmentStream.cpp2
-rw-r--r--MPD/SingleMediaSegmentStream.h2
-rw-r--r--Managers/MultimediaManager.cpp1
-rw-r--r--UI/DASHPlayerNoGUI.cpp2
-rw-r--r--UI/ViperGui.cpp4
17 files changed, 78 insertions, 41 deletions
diff --git a/Adaptation/Bola.cpp b/Adaptation/Bola.cpp
index f7acc72e..470d22e8 100644
--- a/Adaptation/Bola.cpp
+++ b/Adaptation/Bola.cpp
@@ -50,7 +50,8 @@ using duration_in_seconds = std::chrono::duration<double, std::ratio<1, 1> >;
BolaAdaptation::BolaAdaptation(viper::managers::StreamType type, MPDWrapper *mpdWrapper, struct AdaptationParameters *params) :
AbstractAdaptationLogic (type, mpdWrapper)
{
- this->bufferMaxSizeSeconds =(double) params->segmentBufferSize * params->segmentDuration;
+ this->segmentDuration = params->segmentDuration;
+ this->bufferMaxSizeSeconds =(double) params->segmentBufferSize * this->segmentDuration;
this->alphaRate = params->Bola_Alpha;
this->bufferTargetSeconds = params->Bola_bufferTargetSeconds;
@@ -86,10 +87,9 @@ BolaAdaptation::BolaAdaptation(viper::managers::StreamType type, MPDWrapper *mpd
// return 0; // Check if exit with a message is necessary
}
- // 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;
+ if(!(this->segmentDuration))
+ this->segmentDuration = 2.0;
Debug("Total Duration - BOLA:\t%f\nSegment Duration - BOLA:\t%f\n",this->totalDuration, this->segmentDuration);
// if not correct --> segmentDuration = 2.0;
diff --git a/Input/DASHReceiver.cpp b/Input/DASHReceiver.cpp
index 59514e57..74415bfa 100644
--- a/Input/DASHReceiver.cpp
+++ b/Input/DASHReceiver.cpp
@@ -141,7 +141,7 @@ MediaObject* DASHReceiver::GetInitSegmentWithoutLock ()
return this->mpdWrapper->getInitSegmentWithoutLock(type);
}
-MediaObject* DASHReceiver::FindInitSegment (int representation)
+MediaObject* DASHReceiver::FindInitSegment (std::string representation)
{
if (!this->InitSegmentExists(representation))
return NULL;
@@ -192,7 +192,7 @@ void DASHReceiver::NotifySegmentDownloaded ()
void DASHReceiver::DownloadInitSegmentWithoutLock ()
{
- int rep = atoi(this->mpdWrapper->getRepresentationIDWithoutLock(type).c_str());
+ std::string rep = this->mpdWrapper->getRepresentationIDWithoutLock(type);
if (this->InitSegmentExists(rep))
return;
@@ -209,7 +209,7 @@ void DASHReceiver::DownloadInitSegmentWithoutLock ()
void DASHReceiver::DownloadInitSegment ()
{
- int rep = atoi(this->mpdWrapper->getRepresentationID(type).c_str());
+ std::string rep = this->mpdWrapper->getRepresentationID(type);
if (this->InitSegmentExists(rep))
return;
@@ -224,7 +224,7 @@ void DASHReceiver::DownloadInitSegment ()
}
}
-bool DASHReceiver::InitSegmentExists (int rep)
+bool DASHReceiver::InitSegmentExists (std::string rep)
{
if (this->initSegments.find(rep) != this->initSegments.end())
return true;
@@ -310,7 +310,6 @@ void* DASHReceiver::DoBuffering (void *recei
}
m_start_time = std::chrono::system_clock::now();
media->StartDownload(dashReceiver->conn);
-
media->WaitFinished();
bool canPush = dashReceiver->CanPush();
if (canPush && !dashReceiver->PushBack(media))
diff --git a/Input/DASHReceiver.h b/Input/DASHReceiver.h
index ee2df388..a6db0382 100644
--- a/Input/DASHReceiver.h
+++ b/Input/DASHReceiver.h
@@ -57,7 +57,7 @@ public:
input::MediaObject* GetSegment(uint32_t segmentNumber);
input::MediaObject* GetInitSegment();
input::MediaObject* GetInitSegmentWithoutLock();
- input::MediaObject* FindInitSegment(int representation);
+ input::MediaObject* FindInitSegment(std::string representation);
uint32_t GetPosition();
void SetPosition(uint32_t segmentNumber);
void SetLooping(bool isLoopinp);
@@ -86,7 +86,7 @@ private:
float drop;
bool withFeedBack;
bool isBufferBased;
- std::map<int, MediaObject*> initSegments;
+ std::map<std::string, MediaObject*> initSegments;
libdash::framework::buffer::Buffer<MediaObject> *buffer;
IDASHReceiverObserver *observer;
libdash::framework::mpd::MPDWrapper *mpdWrapper;
@@ -120,7 +120,7 @@ private:
void NotifySegmentDownloaded();
void DownloadInitSegment();
void DownloadInitSegmentWithoutLock();
- bool InitSegmentExists(int rep);
+ bool InitSegmentExists(std::string rep);
static void* DoBuffering(void *receiver);
};
}
diff --git a/Input/MediaObject.cpp b/Input/MediaObject.cpp
index b2dde357..2f4e0044 100644
--- a/Input/MediaObject.cpp
+++ b/Input/MediaObject.cpp
@@ -28,7 +28,7 @@ MediaObject::MediaObject(ISegment *segment, IRepresentation *rep, bool withFeedB
InitializeCriticalSection (&this->stateLock);
this->representationBandwidth = rep->GetBandwidth();
this->representationHeight = rep->GetHeight();
- this->representationId = atoi(rep->GetId().c_str());
+ this->representationId = rep->GetId();
}
MediaObject::~MediaObject()
@@ -57,12 +57,22 @@ uint32_t MediaObject::GetRepresentationHeight()
return this->representationHeight;
}
-int MediaObject::GetRepresentationID()
+std::string MediaObject::GetRepresentationID()
{
return this->representationId;
}
-void MediaObject::SetFeedBack(bool flag)
+uint64_t MediaObject::GetSegmentDuration()
+{
+ return this->segmentDuration;
+}
+
+void MediaObject::SetSegmentDuration(uint64_t segDuration)
+{
+ this->segmentDuration = segDuration;
+}
+
+void MediaObject::SetFeedBack(bool flag)
{
this->withFeedBack = flag;
}
diff --git a/Input/MediaObject.h b/Input/MediaObject.h
index 1edd69af..24c2995b 100644
--- a/Input/MediaObject.h
+++ b/Input/MediaObject.h
@@ -59,23 +59,26 @@ public:
void SetDASHReceiver(input::DASHReceiver *_dashReceiver);
uint32_t GetRepresentationBandwidth();
uint32_t GetRepresentationHeight();
- int GetRepresentationID();
+ std::string GetRepresentationID();
+ uint64_t GetSegmentDuration();
+ void SetSegmentDuration(uint64_t segmentDuration);
private:
dash::mpd::ISegment *segment;
MediaObject *initSeg;
dash::mpd::IRepresentation *rep;
dash::network::DownloadState state;
- uint64_t bps;
- bool withFeedBack;
+ uint64_t bps;
+ bool withFeedBack;
double dnltime;
input::DASHReceiver *dashReceiver;
adaptation::IAdaptationLogic *adaptationLogic;
mutable CRITICAL_SECTION stateLock;
mutable CONDITION_VARIABLE stateChanged;
- uint32_t representationBandwidth;
- uint32_t representationHeight;
- int representationId;
+ uint32_t representationBandwidth;
+ uint32_t representationHeight;
+ std::string representationId;
+ uint64_t segmentDuration;
};
}
}
diff --git a/MPD/AbstractRepresentationStream.h b/MPD/AbstractRepresentationStream.h
index 113720ed..da847c3c 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) = 0;
+ virtual dash::mpd::ISegment* getMediaSegment(size_t segmentNumber, uint64_t& segmentDuration) = 0;
virtual dash::mpd::ISegment* getBitstreamSwitchingSegment() = 0;
virtual RepresentationStreamType getStreamType() = 0;
diff --git a/MPD/IRepresentationStream.h b/MPD/IRepresentationStream.h
index bf8b08c4..124216ba 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) = 0;
+ virtual dash::mpd::ISegment* getMediaSegment(size_t segmentNumber, uint64_t& segmentDuration) = 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 20d4aa5e..c7bdee9f 100644
--- a/MPD/MPDWrapper.cpp
+++ b/MPD/MPDWrapper.cpp
@@ -645,10 +645,13 @@ MediaObject* MPDWrapper::getNextSegment (viper::managers::StreamType type, bool
representationStream = representations->find(representation)->second;
}
}
- seg = representationStream->getMediaSegment(segmentNumber);
+ uint64_t segDuration = 0;
+ //Returns the segmentDuration in milliseconds
+ seg = representationStream->getMediaSegment(segmentNumber, segDuration);
if(seg != NULL)
{
MediaObject *media = new MediaObject(seg, representation, withFeedBack);
+ media->SetSegmentDuration(segDuration);
segmentNumber++;
switch(type)
{
@@ -696,10 +699,12 @@ MediaObject* MPDWrapper::getSegment (viper::managers::StreamType type, uint32_t
LeaveCriticalSection(&this->monitorMutex);
return NULL;
}
- seg = representationStream->getMediaSegment(segNum);
+ uint64_t segDuration =0;
+ seg = representationStream->getMediaSegment(segNum, segDuration);
if(seg != NULL)
{
MediaObject *media = new MediaObject(seg, representation);
+ media->SetSegmentDuration(segDuration);
LeaveCriticalSection(&this->monitorMutex);
return media;
}
diff --git a/MPD/SegmentListStream.cpp b/MPD/SegmentListStream.cpp
index c3530086..86d36e68 100644
--- a/MPD/SegmentListStream.cpp
+++ b/MPD/SegmentListStream.cpp
@@ -53,11 +53,15 @@ ISegment* SegmentListStream::getIndexSegment(size_t segmentNumber)
return NULL;
}
-ISegment* SegmentListStream::getMediaSegment(size_t segmentNumber)
+ISegment* SegmentListStream::getMediaSegment(size_t segmentNumber, uint64_t& segmentDuration)
{
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;
}
@@ -93,6 +97,11 @@ ISegmentList* SegmentListStream::findSegmentList()
return NULL;
}
+uint32_t SegmentListStream::getTimescale ()
+{
+ return this->segmentList->GetTimescale();
+}
+
uint32_t SegmentListStream::getAverageSegmentDuration()
{
/* TODO calculate average segment durations for SegmentTimeline */
diff --git a/MPD/SegmentListStream.h b/MPD/SegmentListStream.h
index 264ac9cc..589896ff 100644
--- a/MPD/SegmentListStream.h
+++ b/MPD/SegmentListStream.h
@@ -33,11 +33,12 @@ public:
virtual dash::mpd::ISegment* getInitializationSegment();
virtual dash::mpd::ISegment* getIndexSegment(size_t segmentNumber);
- virtual dash::mpd::ISegment* getMediaSegment(size_t segmentNumber);
+ virtual dash::mpd::ISegment* getMediaSegment(size_t segmentNumber, uint64_t& segmentDuration);
virtual dash::mpd::ISegment* getBitstreamSwitchingSegment();
virtual RepresentationStreamType getStreamType();
virtual uint32_t getSize();
virtual uint32_t getAverageSegmentDuration();
+ virtual uint32_t getTimescale();
private:
dash::mpd::ISegmentList *findSegmentList();
diff --git a/MPD/SegmentTemplateStream.cpp b/MPD/SegmentTemplateStream.cpp
index ee51cf07..50801896 100644
--- a/MPD/SegmentTemplateStream.cpp
+++ b/MPD/SegmentTemplateStream.cpp
@@ -64,16 +64,19 @@ ISegment* SegmentTemplateStream::getIndexSegment(size_t segmentNumber)
this->segmentTemplate->GetStartNumber() + segmentNumber);
}
-ISegment* SegmentTemplateStream::getMediaSegment(size_t segmentNumber)
+ISegment* SegmentTemplateStream::getMediaSegment(size_t segmentNumber, uint64_t& segmentDuration)
{
/* 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;
-
+ 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
+ return NULL;
+
//The following is to be used if you wish to start directly from the right time
/* {
if(this->inSync)
@@ -110,6 +113,9 @@ ISegment* SegmentTemplateStream::getMediaSegment(size_t segmentNumber)
}
/* number-based template */
+ uint32_t duration = representation->GetSegmentTemplate()->GetDuration();
+ uint32_t timescale = representation->GetSegmentTemplate()->GetTimescale();
+ segmentDuration = (uint64_t)(((float)duration/(float)timescale) * 1000);
return this->segmentTemplate->GetMediaSegmentFromNumber(baseUrls, representation->GetId(), representation->GetBandwidth(),
this->segmentTemplate->GetStartNumber() + segmentNumber);
@@ -199,6 +205,7 @@ void SegmentTemplateStream::calculateSegmentStartTimes()
if (segStartTime > 0)
{
this->segmentStartTimes.push_back(segStartTime + segDuration * j);
+ this->segmentDurationTimes.push_back(segDuration);
}
else
{
@@ -209,6 +216,7 @@ void SegmentTemplateStream::calculateSegmentStartTimes()
else
{
this->segmentStartTimes.push_back(segStartTime);
+ this->segmentDurationTimes.push_back(segDuration);
}
}
this->averageDuration = totalDuration / numOfTimelines;
@@ -227,7 +235,7 @@ size_t SegmentTemplateStream::getSegmentNumber(uint64_t time)
size_t i;
for(i = 0; i < this->segmentStartTimes.size(); i ++)
{
- if(time <= this->segmentStartTimes.at(i))
+ if(time < this->segmentStartTimes.at(i))
{
break;
}
diff --git a/MPD/SegmentTemplateStream.h b/MPD/SegmentTemplateStream.h
index 0bd0ad13..8485b56b 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);
+ virtual dash::mpd::ISegment* getMediaSegment(size_t segmentNumber, uint64_t& segmentDuration);
virtual dash::mpd::ISegment* getBitstreamSwitchingSegment();
virtual RepresentationStreamType getStreamType();
virtual uint32_t getSize();
@@ -49,6 +49,7 @@ private:
dash::mpd::ISegmentTemplate *segmentTemplate;
std::vector<uint64_t> segmentStartTimes;
+ std::vector<uint64_t> segmentDurationTimes;
uint32_t averageDuration;
bool inSync;
uint32_t currentSegment;
diff --git a/MPD/SingleMediaSegmentStream.cpp b/MPD/SingleMediaSegmentStream.cpp
index 39301928..3eccbefe 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)
+ISegment* SingleMediaSegmentStream::getMediaSegment(size_t segmentNumber, uint64_t& segmentDuration)
{
/* segmentNumber equals the desired BaseUrl */
if (this->representation->GetBaseURLs().size() > segmentNumber)
diff --git a/MPD/SingleMediaSegmentStream.h b/MPD/SingleMediaSegmentStream.h
index e619a7f8..44fead38 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);
+ virtual dash::mpd::ISegment* getMediaSegment(size_t segmentNumber, uint64_t& segmentDuration);
virtual dash::mpd::ISegment* getBitstreamSwitchingSegment();
virtual RepresentationStreamType getStreamType();
diff --git a/Managers/MultimediaManager.cpp b/Managers/MultimediaManager.cpp
index 18061238..997fc6de 100644
--- a/Managers/MultimediaManager.cpp
+++ b/Managers/MultimediaManager.cpp
@@ -659,7 +659,6 @@ void* MultimediaManager::pushVideo(void *data)
{
MultimediaManager *manager = (MultimediaManager*) data;
libdash::framework::input::MediaObject *segment = manager->videoStream->getSegment();
- int segmentDurationInMs = (int)manager->getSegmentDuration();
while(manager->isVideoRendering)
{
if (segment)
diff --git a/UI/DASHPlayerNoGUI.cpp b/UI/DASHPlayerNoGUI.cpp
index d212b556..2195b88a 100644
--- a/UI/DASHPlayerNoGUI.cpp
+++ b/UI/DASHPlayerNoGUI.cpp
@@ -89,6 +89,8 @@ DASHPlayerNoGUI::DASHPlayerNoGUI(int argc, char ** argv, pthread_cond_t *mainCon
webSocketService.start();
this->parameterAdaptation->segmentDuration = this->mpdWrapper->onFirstDownloadMPD(NULL);
this->multimediaManager->setSegmentDuration(this->parameterAdaptation->segmentDuration);
+ //should be in seconds
+ this->parameterAdaptation->segmentDuration = this->parameterAdaptation->segmentDuration / 1000.0;
this->onStartButtonPressed(0,0,0,0,0);
this->multimediaManager->setLooping(this->repeat);
}
diff --git a/UI/ViperGui.cpp b/UI/ViperGui.cpp
index e23bd308..99d2e5a3 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 += this->segmentDuration;
+ this->bufferDuration += media->GetSegmentDuration();
if(this->bufferDuration - this->position > 3000)
{
@@ -206,7 +206,7 @@ void ViperGui::writeData(libdash::framework::input::MediaObject* media)
}
else
{
- this->bufferDuration += (this->durationMilliseconds - (this->segmentDuration * (this->listSegmentSize - 1)));
+ this->bufferDuration += (this->durationMilliseconds - (media->GetSegmentDuration() * (this->listSegmentSize - 1)));
if(this->bufferDuration - this->position >3000)
{