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);
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;
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)
{
if(segNum >= this->representationStream->getSize())
return NULL;
- seg = this->representationStream->getMediaSegment(segNum + segmentOffset);
+ seg = this->representationStream->getMediaSegment(segNum);
if (seg != NULL)
{
{
m_first = 1;
sizeDownloaded = 0;
- printf("initmpd %s\n", url.c_str());
m_name = url;
m_isFinished = false;
dataPos = 0;
datSize = 0;
- printf("initiated for mpd\n");
Debug("ICN_Connection:\tINTIATED_for_mpd %s\n", m_name.c_str());
}
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)
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;
}
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;
}
{
return 1;
}
+uint32_t AbstractRepresentationStream::getTimescale ()
+{
+ return 1;
+}
+void AbstractRepresentationStream::setSegmentOffset (uint32_t offset)
+{
+ this->segmentOffset = offset;
+}
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);
dash::mpd::IPeriod *period;
dash::mpd::IAdaptationSet *adaptationSet;
dash::mpd::IRepresentation *representation;
+ uint32_t segmentOffset;
};
}
}
virtual uint32_t getCurrentSegmentNumber() = 0;
virtual uint32_t getLastSegmentNumber() = 0;
virtual uint32_t getAverageSegmentDuration() = 0;
+ virtual void setSegmentOffset(uint32_t offset) = 0;
+
};
}
}
{
this->baseUrls = BaseUrlResolver::resolveBaseUrl(mpd, period, adaptationSet, 0, 0, 0);
this->segmentTemplate = findSegmentTemplate();
+ this->inSync = false;
+ this->currentSegment = 0;
calculateSegmentStartTimes();
}
SegmentTemplateStream::~SegmentTemplateStream()
/* 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;
}
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()
uint32_t segStartTime = 0;
uint32_t segDuration = 0;
size_t repeatCount = 0;
+ uint32_t totalDuration = 0;
numOfTimelines = this->segmentTemplate->GetSegmentTimeline()->GetTimelines().size();
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)
{
this->segmentStartTimes.push_back(segStartTime);
}
}
+ this->averageDuration = totalDuration / numOfTimelines;
}
virtual RepresentationStreamType getStreamType();
virtual uint32_t getSize();
virtual uint32_t getAverageSegmentDuration();
+ virtual uint32_t getTimescale();
private:
dash::mpd::ISegmentTemplate* findSegmentTemplate();
dash::mpd::ISegmentTemplate *segmentTemplate;
std::vector<uint32_t> segmentStartTimes;
+ uint32_t averageDuration;
+ bool inSync;
+ uint32_t currentSegment;
};
}
}
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);
free(data);
delete icnConn;
LeaveCriticalSection(&this->monitorMutex);
- printf("return true\n");
return true;
}
{
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());
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();
float beta;
float drop;
bool seek;
+ bool isLive;
Config *config;
bool repeat;
float segmentDuration;