Several corrections: 58/12858/2
authorJacques SAMAIN <[email protected]>
Fri, 1 Jun 2018 17:56:33 +0000 (19:56 +0200)
committerJacques SAMAIN <[email protected]>
Mon, 4 Jun 2018 12:16:30 +0000 (12:16 +0000)
*effectively take into account live MPD
*Fix several bugs

Change-Id: I9b925f222653d2d196b09b4e96cb15119ec8af44
Signed-off-by: Jacques SAMAIN <[email protected]>
25 files changed:
Adaptation/AdapTech.cpp
Adaptation/AdapTech.h
Adaptation/Panda.cpp
Input/DASHManager.cpp
Input/DASHManager.h
Input/DASHReceiver.cpp
Input/DASHReceiver.h
Input/IDASHManagerObserver.h
Input/IDASHReceiverObserver.h
MPD/AbstractRepresentationStream.h
MPD/IRepresentationStream.h
MPD/MPDWrapper.cpp
MPD/MPDWrapper.h
MPD/SegmentListStream.cpp
MPD/SegmentListStream.h
MPD/SegmentTemplateStream.cpp
MPD/SegmentTemplateStream.h
MPD/SingleMediaSegmentStream.cpp
MPD/SingleMediaSegmentStream.h
Managers/IStreamObserver.h
Managers/MultimediaManager.cpp
Managers/MultimediaManager.h
Managers/MultimediaStream.cpp
Managers/MultimediaStream.h
UI/ViperGui.cpp

index dc88fae..6f248b4 100644 (file)
@@ -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()
@@ -96,6 +90,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;
index c7f4e33..24ae223 100644 (file)
@@ -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();
index e0c19b2..a8c2d88 100644 (file)
@@ -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() {
index 0c39335..b3ff830 100644 (file)
@@ -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();
+}
index 3b9bf00..4bd301e 100644 (file)
@@ -61,6 +61,7 @@ public:
     void setTargetDownloadingTime(double);
     MediaObject* getSegment();
     void onBufferStateChanged(BufferType type, uint32_t fillstateInPercent, int maxC);
+    void fetchMPD();
 
 private:
     float                                               beta;
index 74415bf..0d77bdf 100644 (file)
@@ -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                                   ()
 {
index a6db038..e5b48ad 100644 (file)
@@ -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);
 };
 }
 }
index 0f2d95d..57f1572 100644 (file)
@@ -33,6 +33,7 @@ public:
     virtual void notifyQualityDownloading (uint32_t quality) = 0;
     virtual bool canPush() = 0;
     virtual int         getBufferLevel() = 0;
+    virtual void fetchMPD() = 0;
 };
 }
 }
index 0a334aa..f6a2baa 100644 (file)
@@ -28,6 +28,7 @@ public:
     virtual void notifyQualityDownloading(uint32_t quality) = 0;
     virtual bool canPush() = 0;
     virtual int getBufferLevel() = 0;
+    virtual void fetchMPD() = 0;
 };
 }
 }
index da847c3..113720e 100644 (file)
@@ -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;
 
index 124216b..bf8b08c 100644 (file)
@@ -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;
index 0b1d959..1dca34f 100644 (file)
@@ -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;
+    }
+}
index cf6275d..75ade08 100644 (file)
@@ -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;
 };
 }
 }
index 86d36e6..0ab6757 100644 (file)
@@ -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;
 }
 
index 589896f..a965874 100644 (file)
@@ -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();
index 5a6dd67..b8f0853 100644 (file)
@@ -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)
index 8485b56..8325a38 100644 (file)
@@ -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();
index 3eccbef..3930192 100644 (file)
@@ -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)
index 44fead3..e619a7f 100644 (file)
@@ -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();
 
index 31baca6..1d628d5 100644 (file)
@@ -38,6 +38,7 @@ public:
     virtual void notifyQualityDownloading(uint32_t quality) = 0;
     virtual bool canPush() = 0;
     virtual int  getBufferLevel() = 0;
+    virtual void fetchMPD() = 0;
 };
 }
 }
index 1b759f4..30f8427 100644 (file)
@@ -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());
-    }
-}
index c00ff86..ade2b76 100644 (file)
@@ -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);
 };
 }
 }
index f70eabf..86cde35 100644 (file)
@@ -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();
+    }
+}
index 52a7ac9..454cca2 100644 (file)
@@ -75,6 +75,7 @@ public:
     bool isICN();
     void shouldAbort();
     void setTargetDownloadingTime(double);
+    void fetchMPD();
 
 private:
     float                                               beta;
index 99d2e5a..e23bd30 100644 (file)
@@ -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)
         {