Adding handling for different kind of MPDs (previously the front end could only handl... 69/7069/1
authorjacko <[email protected]>
Thu, 8 Jun 2017 17:54:24 +0000 (19:54 +0200)
committerjacko <[email protected]>
Thu, 8 Jun 2017 17:59:02 +0000 (19:59 +0200)
Now can handle:
MPD with SegmentTemplate in Representation (VOD)
MPD with SegmentTemplate and SegmentTimeline (live)

Change-Id: Ie32e0e1823c94b1412990192595b16d3e2df1cfd
Plus: removed some printf
Signed-off-by: jacko <[email protected]>
Common/ViperBuffer.cpp
Input/DASHReceiver.cpp
Input/ICNConnectionConsumerApi.cpp
MPD/AbstractRepresentationStream.cpp
MPD/AbstractRepresentationStream.h
MPD/IRepresentationStream.h
MPD/SegmentTemplateStream.cpp
MPD/SegmentTemplateStream.h
Managers/MultimediaManager.cpp
UI/DASHPlayer.cpp
UI/DASHPlayer.h

index 90d10d6..27ec8b5 100644 (file)
@@ -85,7 +85,6 @@ qint64 ViperBuffer::writeData(libdash::framework::input::MediaObject* media)
     ret = media->Read(readBuffer,readMax);
     while(ret)
     {
-        printf("ret %d\n", ret);
         total += ret;
         this->writeData((const char *)readBuffer, ret);
         ret = media->Read(readBuffer,readMax);
index df9d019..bbfe3e3 100644 (file)
@@ -55,6 +55,7 @@ DASHReceiver::DASHReceiver          (IMPD *mpd, IDASHReceiverObserver *obs, Buff
     this->adaptationSetStream = new AdaptationSetStream(mpd, period, adaptationSet);
     this->representationStream = adaptationSetStream->getRepresentationStream(this->representation);
     this->segmentOffset = CalculateSegmentOffset();
+    this->representationStream->setSegmentOffset(this->segmentOffset);
 
     this->conn = NULL;
     this->initConn = NULL;
@@ -131,20 +132,23 @@ MediaObject*      DASHReceiver::GetNextSegment    ()
     while(this->isPaused)
         SleepConditionVariableCS(&this->paused, &this->monitorPausedMutex, INFINITE);
 
-    if(this->segmentNumber >= this->representationStream->getSize())
+    if(!strcmp(this->mpd->GetType().c_str(), "static"))
     {
-        qDebug("looping? : %s\n", this->isLooping ? "YES" : "NO");
-        if(this->isLooping)
+        if(this->segmentNumber >= this->representationStream->getSize())
         {
-            this->segmentNumber = 0;
-        }
-        else
-        {
-            LeaveCriticalSection(&this->monitorPausedMutex);
-            return NULL;
+            qDebug("looping? : %s\n", this->isLooping ? "YES" : "NO");
+            if(this->isLooping)
+            {
+                this->segmentNumber = 0;
+            }
+            else
+            {
+                LeaveCriticalSection(&this->monitorPausedMutex);
+                return NULL;
+            }
         }
     }
-    seg = this->representationStream->getMediaSegment(this->segmentNumber + this->segmentOffset);
+    seg = this->representationStream->getMediaSegment(this->segmentNumber);
 
     if (seg != NULL)
     {
@@ -167,7 +171,7 @@ MediaObject*        DASHReceiver::GetSegment                (uint32_t segNum)
     if(segNum >= this->representationStream->getSize())
         return NULL;
 
-    seg = this->representationStream->getMediaSegment(segNum + segmentOffset);
+    seg = this->representationStream->getMediaSegment(segNum);
 
     if (seg != NULL)
     {
index 62e9ecd..8f28e5c 100644 (file)
@@ -112,7 +112,6 @@ void ICNConnectionConsumerApi::InitForMPD(const std::string& url)
 {
     m_first = 1;
     sizeDownloaded = 0;
-    printf("initmpd %s\n", url.c_str());
     m_name = url;
     m_isFinished = false;
 
@@ -120,7 +119,6 @@ void ICNConnectionConsumerApi::InitForMPD(const std::string& url)
     dataPos = 0;
     datSize = 0;
 
-    printf("initiated for mpd\n");
     Debug("ICN_Connection:\tINTIATED_for_mpd %s\n", m_name.c_str());
 }
 
@@ -147,7 +145,6 @@ int ICNConnectionConsumerApi::Read(uint8_t *data, size_t len)
        return len;
     } else
     {
-        printf("minore uguale\n");
         memcpy(data, (char*)response.data() + this->dataPos, response.size() - this->dataPos);
         int length = response.size() - this->dataPos;
        if (length == 0)
index 449c6aa..346938f 100644 (file)
@@ -46,7 +46,8 @@ uint32_t AbstractRepresentationStream::getFirstSegmentNumber()
         uint32_t availStT = TimeResolver::getUTCDateTimeInSec(this->mpd->GetAvailabilityStarttime());
         uint32_t duration = this->getAverageSegmentDuration();
         uint32_t timeshift = TimeResolver::getDurationInSec(this->mpd->GetTimeShiftBufferDepth());
-        return (currTime - duration - availStT - timeshift ) / duration;
+        uint32_t timescale = this->getTimescale();
+        return (double)((double)currTime - (double)availStT - (double)timeshift ) < 0? 0 : (currTime - availStT - timeshift );
     }
     return 0;
 }
@@ -59,7 +60,8 @@ uint32_t AbstractRepresentationStream::getCurrentSegmentNumber()
         uint32_t duration = this->getAverageSegmentDuration();
         uint32_t availStT = TimeResolver::getUTCDateTimeInSec(this->mpd->GetAvailabilityStarttime());
 
-        return (currTime - duration - availStT) / duration;
+        return (double)((double)currTime - (double)availStT) < 0 ? 0 : (currTime - availStT);
+    //    return (currTime - duration - availStT) / duration;
     }
     return 0;
 }
@@ -82,3 +84,11 @@ uint32_t AbstractRepresentationStream::getAverageSegmentDuration()
 {
     return 1;
 }
+uint32_t    AbstractRepresentationStream::getTimescale ()
+{
+    return 1;
+}
+void       AbstractRepresentationStream::setSegmentOffset (uint32_t offset)
+{
+    this->segmentOffset = offset;
+}
index e0f354b..4728e36 100644 (file)
@@ -46,6 +46,9 @@ public:
     virtual uint32_t getLastSegmentNumber();
     virtual uint32_t getAverageSegmentDuration();
 
+    virtual uint32_t getTimescale();
+    virtual void        setSegmentOffset(uint32_t offset);
+
 protected:
     virtual void setBaseUrls(const std::vector<dash::mpd::IBaseUrl *> baseurls);
 
@@ -54,6 +57,7 @@ protected:
     dash::mpd::IPeriod                  *period;
     dash::mpd::IAdaptationSet           *adaptationSet;
     dash::mpd::IRepresentation          *representation;
+    uint32_t                            segmentOffset;
 };
 }
 }
index 370c84e..31f83d5 100644 (file)
@@ -43,6 +43,8 @@ public:
     virtual uint32_t getCurrentSegmentNumber() = 0;
     virtual uint32_t getLastSegmentNumber() = 0;
     virtual uint32_t getAverageSegmentDuration() = 0;
+    virtual void     setSegmentOffset(uint32_t offset) = 0;
+
 };
 }
 }
index f0f475e..6600429 100644 (file)
@@ -19,6 +19,8 @@ SegmentTemplateStream::SegmentTemplateStream(IMPD *mpd, IPeriod *period, IAdapta
 {
     this->baseUrls          = BaseUrlResolver::resolveBaseUrl(mpd, period, adaptationSet, 0, 0, 0);
     this->segmentTemplate   = findSegmentTemplate();
+    this->inSync = false;
+    this->currentSegment = 0;
     calculateSegmentStartTimes();
 }
 SegmentTemplateStream::~SegmentTemplateStream()
@@ -54,9 +56,36 @@ ISegment* SegmentTemplateStream::getMediaSegment(size_t segmentNumber)
     /* time-based template */
     if (this->segmentTemplate->GetSegmentTimeline())
     {
-        if (this->segmentStartTimes.size() > segmentNumber)
-            return this->segmentTemplate->GetMediaSegmentFromTime(baseUrls, representation->GetId(), representation->GetBandwidth(), this->segmentStartTimes.at(segmentNumber));
+        if(this->inSync)
+        {
+            this->currentSegment++;
+            if(this->currentSegment < this->segmentStartTimes.size())
+                return this->segmentTemplate->GetMediaSegmentFromTime(baseUrls, representation->GetId(), representation->GetBandwidth(), this->segmentStartTimes.at(this->currentSegment));
+            else
+                return NULL;
+        }
+
+        //Look for the start point of segment, ie: the closest lowest to segmentNumber
+        //adding segment offset
+        segmentNumber = segmentNumber + this->segmentOffset;
 
+        size_t prevSegNumber = 0;
+        size_t segNumber = 0;
+        for(segNumber = 0; segNumber < this->segmentStartTimes.size(); segNumber++)
+        {
+            if(this->segmentStartTimes.at(segNumber)/this->getTimescale() > segmentNumber)
+            {
+                segNumber = prevSegNumber;
+                break;
+            }
+            prevSegNumber = segNumber;
+        }
+        if(segNumber != this->segmentStartTimes.size())
+        {
+            this->inSync = true;
+            this->currentSegment = segNumber;
+            return this->segmentTemplate->GetMediaSegmentFromTime(baseUrls, representation->GetId(), representation->GetBandwidth(), this->segmentStartTimes.at(this->currentSegment));
+        }
         return NULL;
     }
 
@@ -98,10 +127,16 @@ uint32_t SegmentTemplateStream::getSize()
     return numberOfSegments;
 }
 
+uint32_t                   SegmentTemplateStream::getTimescale                 ()
+{
+    return this->segmentTemplate->GetTimescale();
+}
+
 uint32_t SegmentTemplateStream::getAverageSegmentDuration()
 {
     /* TODO calculate average segment durations for SegmentTimeline */
-    return this->segmentTemplate->GetDuration();
+    return this->averageDuration;
+//    return this->segmentTemplate->GetDuration();
 }
 
 ISegmentTemplate* SegmentTemplateStream::findSegmentTemplate()
@@ -127,6 +162,7 @@ void SegmentTemplateStream::calculateSegmentStartTimes()
     uint32_t segStartTime   = 0;
     uint32_t segDuration    = 0;
     size_t   repeatCount    = 0;
+    uint32_t totalDuration  = 0;
 
     numOfTimelines      = this->segmentTemplate->GetSegmentTimeline()->GetTimelines().size();
 
@@ -135,6 +171,7 @@ void SegmentTemplateStream::calculateSegmentStartTimes()
         repeatCount     = this->segmentTemplate->GetSegmentTimeline()->GetTimelines().at(i)->GetRepeatCount();
         segStartTime    = this->segmentTemplate->GetSegmentTimeline()->GetTimelines().at(i)->GetStartTime();
         segDuration     = this->segmentTemplate->GetSegmentTimeline()->GetTimelines().at(i)->GetDuration();
+        totalDuration   = totalDuration + segDuration;
 
         if (repeatCount > 0)
         {
@@ -155,4 +192,5 @@ void SegmentTemplateStream::calculateSegmentStartTimes()
             this->segmentStartTimes.push_back(segStartTime);
         }
     }
+    this->averageDuration = totalDuration / numOfTimelines;
 }
index ea85ab1..f27b77f 100644 (file)
@@ -38,6 +38,7 @@ public:
     virtual RepresentationStreamType getStreamType();
     virtual uint32_t getSize();
     virtual uint32_t getAverageSegmentDuration();
+    virtual uint32_t getTimescale();
 
 private:
     dash::mpd::ISegmentTemplate* findSegmentTemplate();
@@ -45,6 +46,9 @@ private:
 
     dash::mpd::ISegmentTemplate *segmentTemplate;
     std::vector<uint32_t>       segmentStartTimes;
+    uint32_t                    averageDuration;
+    bool                        inSync;
+    uint32_t                    currentSegment;
 };
 }
 }
index 52dbd6a..faab66c 100644 (file)
@@ -117,12 +117,10 @@ bool    MultimediaManager::initICN(const std::string& url)
         return false;
     }
     ret = icnConn->Read((uint8_t*)data, 4096);
-    printf("downloaded %d\n", ret);
     while(ret)
     {
         fwrite(data, sizeof(char), ret, fp);
         ret = icnConn->Read((uint8_t*)data,4096);
-        printf("downloaded %d\n", ret);
     }
     fclose(fp);
     this->mpd = this->manager->Open(const_cast<char*>(downloadFile.c_str()), url);
@@ -138,7 +136,6 @@ bool    MultimediaManager::initICN(const std::string& url)
     free(data);
     delete icnConn;
     LeaveCriticalSection(&this->monitorMutex);
-    printf("return true\n");
     return true;
 }
 
index b87dde7..0f1db8c 100644 (file)
@@ -26,10 +26,11 @@ DASHPlayer::DASHPlayer(ViperGui &gui, Config *config) :
 {
     InitializeCriticalSection(&this->monitorMutex);
     this->offset = 0;
-    this->url                          = NULL;
-    this->icn                          = false;
+    this->url = NULL;
+    this->icn = false;
     this->adaptLogic = LogicType::RateBased;
-    this->seek              = false;
+    this->seek = false;
+    this->isLive = false;
     this->reloadParameters();
     this->setSettings(0, 0, 0, 0, 0);
     this->multimediaManager = new MultimediaManager(this->gui, this->parametersAdaptation->segmentBufferSize, config->getConfigPath().toStdString() + QString::fromLatin1("/").toStdString());
@@ -207,13 +208,39 @@ bool DASHPlayer::downloadMPD(const QString &url, const QString &adaptationLogic,
         IPeriod *period = this->multimediaManager->getMPD()->GetPeriods().at(0);
         IAdaptationSet *adaptation = period->GetAdaptationSets().at(0);
         IRepresentation *representation = adaptation->GetRepresentation().at(0);
-        uint32_t duration = representation->GetSegmentList()->GetDuration();
-        uint32_t timescale = representation->GetSegmentList()->GetTimescale();
-        this->gui->setListSegmentSize(representation->GetSegmentList()->GetSegmentURLs().size());
-        this->segmentDuration = 1.0*duration/(1.0*timescale) * 1000;
-        this->gui->setSegmentDuration(this->segmentDuration);
-        this->parametersAdaptation->segmentDuration = this->segmentDuration;
-        this->parametersAdaptation->segmentDuration = 1.0*duration/(1.0*timescale) * 1000;
+        if(!strcmp(this->multimediaManager->getMPD()->GetType().c_str(), "static")) // VOD MPD
+        {
+            if(representation->GetSegmentList())
+            {
+                uint32_t duration = representation->GetSegmentList()->GetDuration();
+                uint32_t timescale = representation->GetSegmentList()->GetTimescale();
+                this->gui->setListSegmentSize(representation->GetSegmentList()->GetSegmentURLs().size());
+                this->segmentDuration = 1.0*duration/(1.0*timescale) * 1000;
+                this->gui->setSegmentDuration(this->segmentDuration);
+                this->parametersAdaptation->segmentDuration = this->segmentDuration;
+           }
+            else //SegmentTemplate
+            {
+                uint32_t duration = representation->GetSegmentTemplate()->GetDuration();
+                uint32_t timescale = representation->GetSegmentTemplate()->GetTimescale();
+                this->segmentDuration = 1.0*duration/(1.0*timescale) * 1000;
+                this->gui->setSegmentDuration(this->segmentDuration);
+                this->gui->setListSegmentSize(TimeResolver::getDurationInSec(period->GetDuration())*1000/this->segmentDuration + 1);
+                this->parametersAdaptation->segmentDuration = this->segmentDuration;
+            }
+        }
+        else   //Live MPD
+        {
+            //SegmentTemplate->SegmentTimeline
+            this->isLive = true;
+            //Assuming here that the segment duration doesn't change. If so, need to do an average over all segments.
+            uint32_t duration = representation->GetSegmentTemplate()->GetSegmentTimeline()->GetTimelines().at(0)->GetDuration();
+            uint32_t timescale = representation->GetSegmentTemplate()->GetTimescale();
+            this->segmentDuration = 1.0*duration/(1.0*timescale) * 1000;
+            this->gui->setSegmentDuration(this->segmentDuration);
+            this->gui->setListSegmentSize(1);
+            this->parametersAdaptation->segmentDuration = this->segmentDuration;
+        }
         this->onSettingsChanged(0,0,0,0,0);
         int j =0;
         std::string temp = adaptationLogic.toStdString();
index 8913a84..fad2871 100644 (file)
@@ -164,6 +164,7 @@ private:
     float                                       beta;
     float                                       drop;
     bool                                        seek;
+    bool                                        isLive;
     Config                                      *config;
     bool                                        repeat;
     float                                       segmentDuration;