diff options
Diffstat (limited to 'MPD')
-rw-r--r-- | MPD/AbstractRepresentationStream.cpp | 84 | ||||
-rw-r--r-- | MPD/AbstractRepresentationStream.h | 61 | ||||
-rw-r--r-- | MPD/AdaptationSetHelper.cpp | 58 | ||||
-rw-r--r-- | MPD/AdaptationSetHelper.h | 36 | ||||
-rw-r--r-- | MPD/AdaptationSetStream.cpp | 82 | ||||
-rw-r--r-- | MPD/AdaptationSetStream.h | 50 | ||||
-rw-r--r-- | MPD/BaseUrlResolver.cpp | 64 | ||||
-rw-r--r-- | MPD/BaseUrlResolver.h | 33 | ||||
-rw-r--r-- | MPD/IRepresentationStream.h | 50 | ||||
-rw-r--r-- | MPD/RepresentationStreamFactory.cpp | 27 | ||||
-rw-r--r-- | MPD/RepresentationStreamFactory.h | 38 | ||||
-rw-r--r-- | MPD/SegmentListStream.cpp | 88 | ||||
-rw-r--r-- | MPD/SegmentListStream.h | 49 | ||||
-rw-r--r-- | MPD/SegmentTemplateStream.cpp | 158 | ||||
-rw-r--r-- | MPD/SegmentTemplateStream.h | 53 | ||||
-rw-r--r-- | MPD/SingleMediaSegmentStream.cpp | 76 | ||||
-rw-r--r-- | MPD/SingleMediaSegmentStream.h | 46 | ||||
-rw-r--r-- | MPD/TimeResolver.cpp | 148 | ||||
-rw-r--r-- | MPD/TimeResolver.h | 43 |
19 files changed, 1244 insertions, 0 deletions
diff --git a/MPD/AbstractRepresentationStream.cpp b/MPD/AbstractRepresentationStream.cpp new file mode 100644 index 00000000..449c6aa8 --- /dev/null +++ b/MPD/AbstractRepresentationStream.cpp @@ -0,0 +1,84 @@ +/* + * AbstractRepresentationStream.cpp + ***************************************************************************** + * Copyright (C) 2012, bitmovin Softwareentwicklung OG, All Rights Reserved + * + * Email: libdash-dev@vicky.bitmovin.net + * + * This source code and its use and distribution, is subject to the terms + * and conditions of the applicable license agreement. + *****************************************************************************/ + +#include "AbstractRepresentationStream.h" + +using namespace libdash::framework::mpd; +using namespace dash::mpd; + +AbstractRepresentationStream::AbstractRepresentationStream(IMPD *mpd, IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation) : + mpd (mpd), + period (period), + adaptationSet (adaptationSet), + representation (representation) +{ +} +AbstractRepresentationStream::~AbstractRepresentationStream() +{ +} + +void AbstractRepresentationStream::setBaseUrls(const std::vector<dash::mpd::IBaseUrl *> baseurls) +{ + this->baseUrls.clear(); + + for (size_t i = 0; i < baseurls.size(); i++) + this->baseUrls.push_back(baseurls.at(i)); +} + +uint32_t AbstractRepresentationStream::getSize() +{ + return UINT32_MAX - 1; +} + +uint32_t AbstractRepresentationStream::getFirstSegmentNumber() +{ + if (this->mpd->GetType() == "dynamic") + { + uint32_t currTime = TimeResolver::getCurrentTimeInSec(); + 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; + } + return 0; +} + +uint32_t AbstractRepresentationStream::getCurrentSegmentNumber() +{ + if (this->mpd->GetType() == "dynamic") + { + uint32_t currTime = TimeResolver::getCurrentTimeInSec(); + uint32_t duration = this->getAverageSegmentDuration(); + uint32_t availStT = TimeResolver::getUTCDateTimeInSec(this->mpd->GetAvailabilityStarttime()); + + return (currTime - duration - availStT) / duration; + } + return 0; +} + +uint32_t AbstractRepresentationStream::getLastSegmentNumber () +{ + if (this->mpd->GetType() == "dynamic") + { + uint32_t currTime = TimeResolver::getCurrentTimeInSec(); + uint32_t duration = this->getAverageSegmentDuration(); + uint32_t availStT = TimeResolver::getUTCDateTimeInSec(this->mpd->GetAvailabilityStarttime()); + uint32_t checkTime = mpd->GetFetchTime() + + TimeResolver::getDurationInSec(this->mpd->GetMinimumUpdatePeriod()); + return ( ((checkTime > currTime) ? currTime : checkTime) - duration - availStT) / duration; + } + return 0; +} + +uint32_t AbstractRepresentationStream::getAverageSegmentDuration() +{ + return 1; +} diff --git a/MPD/AbstractRepresentationStream.h b/MPD/AbstractRepresentationStream.h new file mode 100644 index 00000000..e0f354b4 --- /dev/null +++ b/MPD/AbstractRepresentationStream.h @@ -0,0 +1,61 @@ +/* + * AbstracRepresenationStream.h + ***************************************************************************** + * Copyright (C) 2012, bitmovin Softwareentwicklung OG, All Rights Reserved + * + * Email: libdash-dev@vicky.bitmovin.net + * + * This source code and its use and distribution, is subject to the terms + * and conditions of the applicable license agreement. + *****************************************************************************/ + +#ifndef LIBDASH_FRAMEWORK_MPD_ABSTRACTREPRESENTATIONSTREAM_H_ +#define LIBDASH_FRAMEWORK_MPD_ABSTRACTREPRESENTATIONSTREAM_H_ + +#include "IRepresentationStream.h" +#include "IBaseUrl.h" +#include "IRepresentation.h" +#include "IAdaptationSet.h" +#include "IMPD.h" +#include "IPeriod.h" +#include "BaseUrlResolver.h" +#include "TimeResolver.h" + +namespace libdash +{ +namespace framework +{ +namespace mpd +{ +class AbstractRepresentationStream : public IRepresentationStream +{ +public: + AbstractRepresentationStream(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, + dash::mpd::IRepresentation *representation); + virtual ~AbstractRepresentationStream(); + + 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* getBitstreamSwitchingSegment() = 0; + virtual RepresentationStreamType getStreamType() = 0; + + virtual uint32_t getSize(); + virtual uint32_t getFirstSegmentNumber(); + virtual uint32_t getCurrentSegmentNumber(); + virtual uint32_t getLastSegmentNumber(); + virtual uint32_t getAverageSegmentDuration(); + +protected: + virtual void setBaseUrls(const std::vector<dash::mpd::IBaseUrl *> baseurls); + + std::vector<dash::mpd::IBaseUrl *> baseUrls; + dash::mpd::IMPD *mpd; + dash::mpd::IPeriod *period; + dash::mpd::IAdaptationSet *adaptationSet; + dash::mpd::IRepresentation *representation; +}; +} +} +} +#endif /* LIBDASH_FRAMEWORK_ADAPTATION_ABSTRACTADAPTATIONLOGIC_H_ */ diff --git a/MPD/AdaptationSetHelper.cpp b/MPD/AdaptationSetHelper.cpp new file mode 100644 index 00000000..b5deefc7 --- /dev/null +++ b/MPD/AdaptationSetHelper.cpp @@ -0,0 +1,58 @@ +/* + * AdaptationSetHelper.cpp + ***************************************************************************** + * Copyright (C) 2012, bitmovin Softwareentwicklung OG, All Rights Reserved + * + * Email: libdash-dev@vicky.bitmovin.net + * + * This source code and its use and distribution, is subject to the terms + * and conditions of the applicable license agreement. + *****************************************************************************/ + +#include "AdaptationSetHelper.h" + +using namespace libdash::framework::mpd; +using namespace dash::mpd; + +std::vector<IAdaptationSet *> AdaptationSetHelper::getAudioAdaptationSets (dash::mpd::IPeriod *period) +{ + std::vector<IAdaptationSet *> audioAdaptationSets; + std::vector<IAdaptationSet *> adaptationSets = period->GetAdaptationSets(); + for (size_t i = 0; i < adaptationSets.size(); i++) + if (AdaptationSetHelper::isAudioAdaptationSet(adaptationSets.at(i))) + audioAdaptationSets.push_back(adaptationSets.at(i)); + + return audioAdaptationSets; +} + +std::vector<IAdaptationSet *> AdaptationSetHelper::getVideoAdaptationSets (dash::mpd::IPeriod *period) +{ + std::vector<IAdaptationSet *> videoAdaptationSets; + std::vector<IAdaptationSet *> adaptationSets = period->GetAdaptationSets(); + for (size_t i = 0; i < adaptationSets.size(); i++) { + if (AdaptationSetHelper::isVideoAdaptationSet(adaptationSets.at(i))) { + videoAdaptationSets.push_back(adaptationSets.at(i)); + } + } + return videoAdaptationSets; +} + +bool AdaptationSetHelper::isAudioAdaptationSet(dash::mpd::IAdaptationSet *adaptationSet) +{ + return isContainedInMimeType(adaptationSet, "audio"); +} + +bool AdaptationSetHelper::isVideoAdaptationSet(dash::mpd::IAdaptationSet *adaptationSet) +{ + return isContainedInMimeType(adaptationSet, "video"); +} + +bool AdaptationSetHelper::isContainedInMimeType (dash::mpd::IAdaptationSet *adaptationSet, std::string value) +{ + for (size_t i = 0; i < adaptationSet->GetRepresentation().size(); i++) + if (adaptationSet->GetRepresentation().at(i)->GetMimeType() != "") + if (adaptationSet->GetRepresentation().at(i)->GetMimeType().find(value) != std::string::npos) + return true; + + return false; +} diff --git a/MPD/AdaptationSetHelper.h b/MPD/AdaptationSetHelper.h new file mode 100644 index 00000000..683d0f0c --- /dev/null +++ b/MPD/AdaptationSetHelper.h @@ -0,0 +1,36 @@ +/* + * AdaptationSetHelper.h + ***************************************************************************** + * Copyright (C) 2012, bitmovin Softwareentwicklung OG, All Rights Reserved + * + * Email: libdash-dev@vicky.bitmovin.net + * + * This source code and its use and distribution, is subject to the terms + * and conditions of the applicable license agreement. + *****************************************************************************/ + +#ifndef LIBDASH_FRAMEWORK_MPD_ADAPTATIONSETHELPER_H_ +#define LIBDASH_FRAMEWORK_MPD_ADAPTATIONSETHELPER_H_ + +#include "IMPD.h" +#include <QMessageLogger> + +namespace libdash +{ +namespace framework +{ +namespace mpd +{ +class AdaptationSetHelper +{ +public: + static std::vector<dash::mpd::IAdaptationSet *> getAudioAdaptationSets(dash::mpd::IPeriod *period); + static std::vector<dash::mpd::IAdaptationSet *> getVideoAdaptationSets(dash::mpd::IPeriod *period); + static bool isAudioAdaptationSet(dash::mpd::IAdaptationSet *adaptationSet); + static bool isVideoAdaptationSet(dash::mpd::IAdaptationSet *adaptationSet); + static bool isContainedInMimeType(dash::mpd::IAdaptationSet *adaptationSet, std::string value); +}; +} +} +} +#endif /* LIBDASH_FRAMEWORK_MPD_ADAPTATIONSETHELPER_H_ */ diff --git a/MPD/AdaptationSetStream.cpp b/MPD/AdaptationSetStream.cpp new file mode 100644 index 00000000..62bc1912 --- /dev/null +++ b/MPD/AdaptationSetStream.cpp @@ -0,0 +1,82 @@ +/* + * AdaptationSetStream.cpp + ***************************************************************************** + * Copyright (C) 2012, bitmovin Softwareentwicklung OG, All Rights Reserved + * + * Email: libdash-dev@vicky.bitmovin.net + * + * This source code and its use and distribution, is subject to the terms + * and conditions of the applicable license agreement. + *****************************************************************************/ + +#include "AdaptationSetStream.h" + +using namespace libdash::framework::mpd; +using namespace dash::mpd; + +AdaptationSetStream::AdaptationSetStream(IMPD *mpd, IPeriod *period, IAdaptationSet *adaptationSet) : + mpd (mpd), + period (period), + adaptationSet (adaptationSet) +{ + initialize(); +} + +AdaptationSetStream::~AdaptationSetStream() +{ + std::map<IRepresentation *, IRepresentationStream *>::iterator iter; + for (iter = representations.begin(); iter != representations.end(); ++iter) + { + delete(iter->second); + } +} + +IRepresentationStream* AdaptationSetStream::getRepresentationStream(IRepresentation *representation) +{ + return this->representations.find(representation)->second; +} + +RepresentationStreamType AdaptationSetStream::determineRepresentationStreamType (IRepresentation *representation) +{ + /* check on Representation Level */ + if (representation->GetSegmentList()) + return libdash::framework::mpd::SegmentList; + + if (representation->GetSegmentTemplate()) + return libdash::framework::mpd::SegmentTemplate; + + if (representation->GetSegmentBase() || representation->GetBaseURLs().size() > 0) + return libdash::framework::mpd::SingleMediaSegment; + + /* check on AdaptationSet Level */ + if (this->adaptationSet->GetSegmentList()) + return libdash::framework::mpd::SegmentList; + + if (this->adaptationSet->GetSegmentTemplate()) + return libdash::framework::mpd::SegmentTemplate; + + if (this->adaptationSet->GetSegmentBase()) + return libdash::framework::mpd::SingleMediaSegment; + + /* check on Period Level */ + if (this->period->GetSegmentList()) + return libdash::framework::mpd::SegmentList; + + if (this->period->GetSegmentTemplate()) + return libdash::framework::mpd::SegmentTemplate; + + if (this->period->GetSegmentBase()) + return libdash::framework::mpd::SingleMediaSegment; + + return libdash::framework::mpd::UNDEFINED; +} + +void AdaptationSetStream::initialize() +{ + for (size_t i = 0; i < adaptationSet->GetRepresentation().size(); i++) + { + IRepresentation *representation = adaptationSet->GetRepresentation().at(i); + RepresentationStreamType type = determineRepresentationStreamType(representation); + representations[representation] = RepresentationStreamFactory::create(type, mpd, period, adaptationSet, representation); + } +} diff --git a/MPD/AdaptationSetStream.h b/MPD/AdaptationSetStream.h new file mode 100644 index 00000000..3ad9788f --- /dev/null +++ b/MPD/AdaptationSetStream.h @@ -0,0 +1,50 @@ +/* + * AdaptationSetStream.h + ***************************************************************************** + * Copyright (C) 2012, bitmovin Softwareentwicklung OG, All Rights Reserved + * + * Email: libdash-dev@vicky.bitmovin.net + * + * This source code and its use and distribution, is subject to the terms + * and conditions of the applicable license agreement. + *****************************************************************************/ + +#ifndef LIBDASH_FRAMEWORK_MPD_ADAPTATIONSETSTREAM_H_ +#define LIBDASH_FRAMEWORK_MPD_ADAPTATIONSETSTREAM_H_ + +#include "IRepresentationStream.h" +#include "IRepresentation.h" +#include "IMPD.h" +#include "IPeriod.h" +#include "IAdaptationSet.h" +#include "RepresentationStreamFactory.h" +#include "BaseUrlResolver.h" + +namespace libdash +{ +namespace framework +{ +namespace mpd +{ +class AdaptationSetStream +{ +public: + AdaptationSetStream(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet); + virtual ~AdaptationSetStream(); + + IRepresentationStream* getRepresentationStream(dash::mpd::IRepresentation *representation); + +private: + RepresentationStreamType determineRepresentationStreamType(dash::mpd::IRepresentation *representation); + void initialize(); + + std::map<dash::mpd::IRepresentation *, IRepresentationStream *> representations; + dash::mpd::IMPD *mpd; + dash::mpd::IPeriod *period; + dash::mpd::IAdaptationSet *adaptationSet; + +}; +} +} +} +#endif /* LIBDASH_FRAMEWORK_MPD_ADAPTATIONSETSTREAM_H_ */ diff --git a/MPD/BaseUrlResolver.cpp b/MPD/BaseUrlResolver.cpp new file mode 100644 index 00000000..54b586cd --- /dev/null +++ b/MPD/BaseUrlResolver.cpp @@ -0,0 +1,64 @@ +/* + * BaseUrlResolver.cpp + ***************************************************************************** + * Copyright (C) 2012, bitmovin Softwareentwicklung OG, All Rights Reserved + * + * Email: libdash-dev@vicky.bitmovin.net + * + * This source code and its use and distribution, is subject to the terms + * and conditions of the applicable license agreement. + *****************************************************************************/ + +#include "BaseUrlResolver.h" + +using namespace dash::mpd; +using namespace libdash::framework::mpd; + +std::vector<dash::mpd::IBaseUrl *> BaseUrlResolver::resolveBaseUrl(IMPD *mpd, IPeriod *period, IAdaptationSet *adaptationSet, + size_t mpdBaseUrl, size_t periodBaseUrl, size_t adaptationSetBaseUrl) +{ + std::vector<dash::mpd::IBaseUrl *> urls; + + if (mpd->GetBaseUrls().size() > 0) + { + if (mpd->GetBaseUrls().size() > mpdBaseUrl) + urls.push_back(mpd->GetBaseUrls().at(mpdBaseUrl)); + else + urls.push_back(mpd->GetBaseUrls().at(0)); + } + if (period->GetBaseURLs().size() > 0) + { + if (period->GetBaseURLs().size() > periodBaseUrl) + urls.push_back(period->GetBaseURLs().at(periodBaseUrl)); + else + urls.push_back(period->GetBaseURLs().at(0)); + } + if (adaptationSet->GetBaseURLs().size() > 0) + { + if (adaptationSet->GetBaseURLs().size() > adaptationSetBaseUrl) + urls.push_back(adaptationSet->GetBaseURLs().at(adaptationSetBaseUrl)); + else + urls.push_back(adaptationSet->GetBaseURLs().at(0)); + } + + if (urls.size() > 0) + { + if (urls.at(0)->GetUrl().substr(0,7) != "http://" && urls.at(0)->GetUrl().substr(0,8) != "https://") + { + urls.push_back(mpd->GetMPDPathBaseUrl()); + size_t lastPos = urls.size() - 1; + IBaseUrl *absoluteUrl = urls.at(lastPos); + for (size_t i = lastPos; i > 0; i--) + { + urls[i] = urls[i-1]; + } + urls[0] = absoluteUrl; + } + } + else + { + urls.push_back(mpd->GetMPDPathBaseUrl()); + } + + return urls; +} diff --git a/MPD/BaseUrlResolver.h b/MPD/BaseUrlResolver.h new file mode 100644 index 00000000..6956a00e --- /dev/null +++ b/MPD/BaseUrlResolver.h @@ -0,0 +1,33 @@ +/* + * BaseUrlResolver.h + ***************************************************************************** + * Copyright (C) 2012, bitmovin Softwareentwicklung OG, All Rights Reserved + * + * Email: libdash-dev@vicky.bitmovin.net + * + * This source code and its use and distribution, is subject to the terms + * and conditions of the applicable license agreement. + *****************************************************************************/ + +#ifndef LIBDASH_FRAMEWORK_MPD_BASEURLRESOLVER_H_ +#define LIBDASH_FRAMEWORK_MPD_BASEURLRESOLVER_H_ + +#include "IMPD.h" + +namespace libdash +{ +namespace framework +{ +namespace mpd +{ +class BaseUrlResolver +{ +public: + static std::vector<dash::mpd::IBaseUrl *> resolveBaseUrl(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, + size_t mpdBaseUrl, size_t periodBaseUrl, size_t adaptationSetBaseUrl); +}; +} +} +} + +#endif /* LIBDASH_FRAMEWORK_MPD_BASEURLRESOLVER_H_ */ diff --git a/MPD/IRepresentationStream.h b/MPD/IRepresentationStream.h new file mode 100644 index 00000000..370c84ed --- /dev/null +++ b/MPD/IRepresentationStream.h @@ -0,0 +1,50 @@ +/* + * IRepresentationStream.h + ***************************************************************************** + * Copyright (C) 2012, bitmovin Softwareentwicklung OG, All Rights Reserved + * + * Email: libdash-dev@vicky.bitmovin.net + * + * This source code and its use and distribution, is subject to the terms + * and conditions of the applicable license agreement. + *****************************************************************************/ + +#ifndef LIBDASH_FRAMEWORK_MPD_IREPRESENTATIONSTREAM_H_ +#define LIBDASH_FRAMEWORK_MPD_IREPRESENTATIONSTREAM_H_ + +#include "ISegment.h" + +namespace libdash +{ +namespace framework +{ +namespace mpd +{ +enum RepresentationStreamType +{ + SingleMediaSegment, + SegmentList, + SegmentTemplate, + UNDEFINED +}; + +class IRepresentationStream +{ +public: + virtual ~IRepresentationStream() {} + + 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* getBitstreamSwitchingSegment() = 0; + virtual RepresentationStreamType getStreamType() = 0; + virtual uint32_t getSize() = 0; + virtual uint32_t getFirstSegmentNumber() = 0; + virtual uint32_t getCurrentSegmentNumber() = 0; + virtual uint32_t getLastSegmentNumber() = 0; + virtual uint32_t getAverageSegmentDuration() = 0; +}; +} +} +} +#endif /* LIBDASH_FRAMEWORK_MPD_IREPRESENTATIONSTREAM_H_ */ diff --git a/MPD/RepresentationStreamFactory.cpp b/MPD/RepresentationStreamFactory.cpp new file mode 100644 index 00000000..b84bf558 --- /dev/null +++ b/MPD/RepresentationStreamFactory.cpp @@ -0,0 +1,27 @@ +/* + * RepresentationStreamFactory.cpp + ***************************************************************************** + * Copyright (C) 2012, bitmovin Softwareentwicklung OG, All Rights Reserved + * + * Email: libdash-dev@vicky.bitmovin.net + * + * This source code and its use and distribution, is subject to the terms + * and conditions of the applicable license agreement. + *****************************************************************************/ + +#include "RepresentationStreamFactory.h" + +using namespace libdash::framework::mpd; +using namespace dash::mpd; + +IRepresentationStream* RepresentationStreamFactory::create(RepresentationStreamType type, IMPD *mpd, IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation) +{ + switch(type) + { + case SingleMediaSegment: return new SingleMediaSegmentStream(mpd, period, adaptationSet, representation); + case SegmentList: return new SegmentListStream (mpd, period, adaptationSet, representation); + case SegmentTemplate: return new SegmentTemplateStream (mpd, period, adaptationSet, representation); + + default: return NULL; + } +} diff --git a/MPD/RepresentationStreamFactory.h b/MPD/RepresentationStreamFactory.h new file mode 100644 index 00000000..22c70b96 --- /dev/null +++ b/MPD/RepresentationStreamFactory.h @@ -0,0 +1,38 @@ +/* + * RepresentationStreamFactory.h + ***************************************************************************** + * Copyright (C) 2012, bitmovin Softwareentwicklung OG, All Rights Reserved + * + * Email: libdash-dev@vicky.bitmovin.net + * + * This source code and its use and distribution, is subject to the terms + * and conditions of the applicable license agreement. + *****************************************************************************/ + +#ifndef LIBDASH_FRAMEWORK_MPD_RERPRESENTATIONSTREAMFACTORY_H_ +#define LIBDASH_FRAMEWORK_MPD_RERPRESENTATIONSTREAMFACTORY_H_ + +#include "IRepresentationStream.h" +#include "SingleMediaSegmentStream.h" +#include "SegmentListStream.h" +#include "SegmentTemplateStream.h" +#include "IRepresentation.h" + +namespace libdash +{ +namespace framework +{ +namespace mpd +{ +class RepresentationStreamFactory +{ +public: + static IRepresentationStream* create(libdash::framework::mpd::RepresentationStreamType type, dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, + dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation); + +}; +} +} +} + +#endif /* LIBDASH_FRAMEWORK_MPD_RERPRESENTATIONSTREAMFACTORY_H_ */ diff --git a/MPD/SegmentListStream.cpp b/MPD/SegmentListStream.cpp new file mode 100644 index 00000000..3a475e71 --- /dev/null +++ b/MPD/SegmentListStream.cpp @@ -0,0 +1,88 @@ +/* + * SegmentListStream.cpp + ***************************************************************************** + * Copyright (C) 2012, bitmovin Softwareentwicklung OG, All Rights Reserved + * + * Email: libdash-dev@vicky.bitmovin.net + * + * This source code and its use and distribution, is subject to the terms + * and conditions of the applicable license agreement. + *****************************************************************************/ + +#include "SegmentListStream.h" + +using namespace dash::mpd; +using namespace libdash::framework::mpd; + +SegmentListStream::SegmentListStream(IMPD *mpd, IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation) : + AbstractRepresentationStream (mpd, period, adaptationSet, representation) +{ + this->baseUrls = BaseUrlResolver::resolveBaseUrl(mpd, period, adaptationSet, 0, 0, 0); + this->segmentList = findSegmentList(); +} + +SegmentListStream::~SegmentListStream() +{ +} + +ISegment* SegmentListStream::getInitializationSegment() +{ + if (this->segmentList->GetInitialization()) + return this->segmentList->GetInitialization()->ToSegment(this->baseUrls); + + return NULL; +} + +ISegment* SegmentListStream::getIndexSegment(size_t segmentNumber) +{ + if (this->segmentList->GetSegmentURLs().size() > segmentNumber) + return this->segmentList->GetSegmentURLs().at(segmentNumber)->ToIndexSegment(this->baseUrls); + + return NULL; +} + +ISegment* SegmentListStream::getMediaSegment(size_t segmentNumber) +{ + if (this->segmentList->GetSegmentURLs().size() > segmentNumber) + return this->segmentList->GetSegmentURLs().at(segmentNumber)->ToMediaSegment(this->baseUrls); + + return NULL; +} + +ISegment* SegmentListStream::getBitstreamSwitchingSegment () +{ + if (this->segmentList->GetBitstreamSwitching()) + return this->segmentList->GetBitstreamSwitching()->ToSegment(baseUrls); + + return NULL; +} + +RepresentationStreamType SegmentListStream::getStreamType() +{ + return SegmentList; +} + +uint32_t SegmentListStream::getSize() +{ + return this->segmentList->GetSegmentURLs().size(); +} + +ISegmentList* SegmentListStream::findSegmentList() +{ + if (this->representation->GetSegmentList()) + return this->representation->GetSegmentList(); + + if (this->adaptationSet->GetSegmentList()) + return this->adaptationSet->GetSegmentList(); + + if (this->period->GetSegmentList()) + return this->period->GetSegmentList(); + + return NULL; +} + +uint32_t SegmentListStream::getAverageSegmentDuration() +{ + /* TODO calculate average segment durations for SegmentTimeline */ + return this->segmentList->GetDuration(); +} diff --git a/MPD/SegmentListStream.h b/MPD/SegmentListStream.h new file mode 100644 index 00000000..323852f0 --- /dev/null +++ b/MPD/SegmentListStream.h @@ -0,0 +1,49 @@ +/* + * SegmentListStream.h + ***************************************************************************** + * Copyright (C) 2012, bitmovin Softwareentwicklung OG, All Rights Reserved + * + * Email: libdash-dev@vicky.bitmovin.net + * + * This source code and its use and distribution, is subject to the terms + * and conditions of the applicable license agreement. + *****************************************************************************/ + +#ifndef LIBDASH_FRAMEWORK_MPD_SEGMENTLISTSTREAM_H_ +#define LIBDASH_FRAMEWORK_MPD_SEGMENTLISTSTREAM_H_ + +#include "IMPD.h" +#include "AbstractRepresentationStream.h" +#include "ISegment.h" +#include "ISegmentList.h" + +namespace libdash +{ +namespace framework +{ +namespace mpd +{ +class SegmentListStream: public AbstractRepresentationStream +{ +public: + SegmentListStream(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation); + virtual ~SegmentListStream(); + + 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* getBitstreamSwitchingSegment(); + virtual RepresentationStreamType getStreamType(); + virtual uint32_t getSize(); + virtual uint32_t getAverageSegmentDuration(); + +private: + dash::mpd::ISegmentList* findSegmentList(); + dash::mpd::ISegmentList *segmentList; + +}; +} +} +} + +#endif /* LIBDASH_FRAMEWORK_MPD_SEGMENTLISTSTREAM_H_ */ diff --git a/MPD/SegmentTemplateStream.cpp b/MPD/SegmentTemplateStream.cpp new file mode 100644 index 00000000..f0f475e6 --- /dev/null +++ b/MPD/SegmentTemplateStream.cpp @@ -0,0 +1,158 @@ +/* + * SegmentTemplateStream.cpp + ***************************************************************************** + * Copyright (C) 2012, bitmovin Softwareentwicklung OG, All Rights Reserved + * + * Email: libdash-dev@vicky.bitmovin.net + * + * This source code and its use and distribution, is subject to the terms + * and conditions of the applicable license agreement. + *****************************************************************************/ + +#include "SegmentTemplateStream.h" + +using namespace dash::mpd; +using namespace libdash::framework::mpd; + +SegmentTemplateStream::SegmentTemplateStream(IMPD *mpd, IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation) : + AbstractRepresentationStream (mpd, period, adaptationSet, representation) +{ + this->baseUrls = BaseUrlResolver::resolveBaseUrl(mpd, period, adaptationSet, 0, 0, 0); + this->segmentTemplate = findSegmentTemplate(); + calculateSegmentStartTimes(); +} +SegmentTemplateStream::~SegmentTemplateStream() +{ +} + +ISegment* SegmentTemplateStream::getInitializationSegment() +{ + if (this->segmentTemplate->GetInitialization()) + return this->segmentTemplate->GetInitialization()->ToSegment(baseUrls); + + return this->segmentTemplate->ToInitializationSegment(baseUrls, representation->GetId(), representation->GetBandwidth()); +} + +ISegment* SegmentTemplateStream::getIndexSegment(size_t segmentNumber) +{ + /* time-based template */ + if (this->segmentTemplate->GetSegmentTimeline()) + { + if (this->segmentStartTimes.size() > segmentNumber) + return this->segmentTemplate->GetIndexSegmentFromTime(baseUrls, representation->GetId(), representation->GetBandwidth(), this->segmentStartTimes.at(segmentNumber)); + + return NULL; + } + + /* number-based template */ + return this->segmentTemplate->GetIndexSegmentFromNumber(baseUrls, representation->GetId(), representation->GetBandwidth(), + this->segmentTemplate->GetStartNumber() + segmentNumber); +} + +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)); + + return NULL; + } + + /* number-based template */ + return this->segmentTemplate->GetMediaSegmentFromNumber(baseUrls, representation->GetId(), representation->GetBandwidth(), + this->segmentTemplate->GetStartNumber() + segmentNumber); + +} + +ISegment* SegmentTemplateStream::getBitstreamSwitchingSegment () +{ + if (this->segmentTemplate->GetBitstreamSwitching()) + return this->segmentTemplate->GetBitstreamSwitching()->ToSegment(baseUrls); + return this->segmentTemplate->ToBitstreamSwitchingSegment(baseUrls, representation->GetId(), representation->GetBandwidth()); +} + +RepresentationStreamType SegmentTemplateStream::getStreamType() +{ + return SegmentList; +} + +uint32_t SegmentTemplateStream::getSize() +{ + if (!this->segmentStartTimes.empty()) + return this->segmentStartTimes.size(); + + uint32_t numberOfSegments = 0; + double mediaPresentationDuration = 0; + + if (this->mpd->GetType() == "static") + { + mediaPresentationDuration = TimeResolver::getDurationInSec(this->mpd->GetMediaPresentationDuration()); + numberOfSegments = (uint32_t) ceil(mediaPresentationDuration / (this->segmentTemplate->GetDuration() / this->segmentTemplate->GetTimescale())); + } + else + { + numberOfSegments = UINT32_MAX - 1; + } + return numberOfSegments; +} + +uint32_t SegmentTemplateStream::getAverageSegmentDuration() +{ + /* TODO calculate average segment durations for SegmentTimeline */ + return this->segmentTemplate->GetDuration(); +} + +ISegmentTemplate* SegmentTemplateStream::findSegmentTemplate() +{ + if (this->representation->GetSegmentTemplate()) + return this->representation->GetSegmentTemplate(); + + if (this->adaptationSet->GetSegmentTemplate()) + return this->adaptationSet->GetSegmentTemplate(); + + if (this->period->GetSegmentTemplate()) + return this->period->GetSegmentTemplate(); + + return NULL; +} + +void SegmentTemplateStream::calculateSegmentStartTimes() +{ + if (!this->segmentTemplate->GetSegmentTimeline()) + return; + + size_t numOfTimelines = 0; + uint32_t segStartTime = 0; + uint32_t segDuration = 0; + size_t repeatCount = 0; + + numOfTimelines = this->segmentTemplate->GetSegmentTimeline()->GetTimelines().size(); + + for (size_t i = 0; i < numOfTimelines; i++) + { + repeatCount = this->segmentTemplate->GetSegmentTimeline()->GetTimelines().at(i)->GetRepeatCount(); + segStartTime = this->segmentTemplate->GetSegmentTimeline()->GetTimelines().at(i)->GetStartTime(); + segDuration = this->segmentTemplate->GetSegmentTimeline()->GetTimelines().at(i)->GetDuration(); + + if (repeatCount > 0) + { + for (size_t j = 0; j <= repeatCount; j++) + { + if (segStartTime > 0) + { + this->segmentStartTimes.push_back(segStartTime + segDuration * j); + } + else + { + /* TODO: implement if SegmentTemplate.SegmentTimeline.S@t is not specified */ + } + } + } + else + { + this->segmentStartTimes.push_back(segStartTime); + } + } +} diff --git a/MPD/SegmentTemplateStream.h b/MPD/SegmentTemplateStream.h new file mode 100644 index 00000000..ea85ab1a --- /dev/null +++ b/MPD/SegmentTemplateStream.h @@ -0,0 +1,53 @@ +/* + * SegmentTemplateStream.h + ***************************************************************************** + * Copyright (C) 2012, bitmovin Softwareentwicklung OG, All Rights Reserved + * + * Email: libdash-dev@vicky.bitmovin.net + * + * This source code and its use and distribution, is subject to the terms + * and conditions of the applicable license agreement. + *****************************************************************************/ + +#ifndef LIBDASH_FRAMEWORK_MPD_SEGMENTTEMPLATESTREAM_H_ +#define LIBDASH_FRAMEWORK_MPD_SEGMENTTEMPLATESTREAM_H_ + +#include <math.h> + +#include "IMPD.h" +#include "AbstractRepresentationStream.h" +#include "ISegment.h" +#include "ISegmentTemplate.h" + +namespace libdash +{ +namespace framework +{ +namespace mpd +{ +class SegmentTemplateStream: public AbstractRepresentationStream +{ +public: + SegmentTemplateStream(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation); + virtual ~SegmentTemplateStream(); + + 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* getBitstreamSwitchingSegment(); + virtual RepresentationStreamType getStreamType(); + virtual uint32_t getSize(); + virtual uint32_t getAverageSegmentDuration(); + +private: + dash::mpd::ISegmentTemplate* findSegmentTemplate(); + void calculateSegmentStartTimes(); + + dash::mpd::ISegmentTemplate *segmentTemplate; + std::vector<uint32_t> segmentStartTimes; +}; +} +} +} + +#endif /* LIBDASH_FRAMEWORK_MPD_SEGMENTTEMPLATESTREAM_H_ */ diff --git a/MPD/SingleMediaSegmentStream.cpp b/MPD/SingleMediaSegmentStream.cpp new file mode 100644 index 00000000..ff4540e2 --- /dev/null +++ b/MPD/SingleMediaSegmentStream.cpp @@ -0,0 +1,76 @@ +/* + * SingleMediaSegmentStream.cpp + ***************************************************************************** + * Copyright (C) 2012, bitmovin Softwareentwicklung OG, All Rights Reserved + * + * Email: libdash-dev@vicky.bitmovin.net + * + * This source code and its use and distribution, is subject to the terms + * and conditions of the applicable license agreement. + *****************************************************************************/ + +#include "SingleMediaSegmentStream.h" + +using namespace dash::mpd; +using namespace libdash::framework::mpd; + +SingleMediaSegmentStream::SingleMediaSegmentStream(IMPD *mpd, IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation) : + AbstractRepresentationStream (mpd, period, adaptationSet, representation) +{ + this->baseUrls = BaseUrlResolver::resolveBaseUrl(mpd, period, adaptationSet, 0, 0, 0); +} +SingleMediaSegmentStream::~SingleMediaSegmentStream() +{ +} +ISegment* SingleMediaSegmentStream::getInitializationSegment() +{ + if (this->representation->GetSegmentBase()) + { + /* TODO: check whether @sourceURL and/or @range is available in SegmentBase.Initialization, see Table 13 */ + + if (this->representation->GetSegmentBase()->GetInitialization()) + return this->representation->GetSegmentBase()->GetInitialization()->ToSegment(baseUrls); + } + + return NULL; +} +ISegment* SingleMediaSegmentStream::getIndexSegment(size_t segmentNumber) +{ + /* segmentNumber is not used in this case */ + if (this->representation->GetSegmentBase()) + { + if (this->representation->GetSegmentBase()->GetRepresentationIndex()) + return this->representation->GetSegmentBase()->GetRepresentationIndex()->ToSegment(baseUrls); + } + + return NULL; +} +ISegment* SingleMediaSegmentStream::getMediaSegment(size_t segmentNumber) +{ + /* segmentNumber equals the desired BaseUrl */ + if (this->representation->GetBaseURLs().size() > segmentNumber) + return this->representation->GetBaseURLs().at(segmentNumber)->ToMediaSegment(baseUrls); + + return this->representation->GetBaseURLs().at(0)->ToMediaSegment(baseUrls); +} +ISegment* SingleMediaSegmentStream::getBitstreamSwitchingSegment() +{ + /* not possible */ + return NULL; +} +RepresentationStreamType SingleMediaSegmentStream::getStreamType() +{ + return SingleMediaSegment; +} +uint32_t SingleMediaSegmentStream::getFirstSegmentNumber() +{ + return 0; +} +uint32_t SingleMediaSegmentStream::getCurrentSegmentNumber() +{ + return 0; +} +uint32_t SingleMediaSegmentStream::getLastSegmentNumber() +{ + return 0; +} diff --git a/MPD/SingleMediaSegmentStream.h b/MPD/SingleMediaSegmentStream.h new file mode 100644 index 00000000..afc919ee --- /dev/null +++ b/MPD/SingleMediaSegmentStream.h @@ -0,0 +1,46 @@ +/* + * SingleMediaSegmentStream.h + ***************************************************************************** + * Copyright (C) 2012, bitmovin Softwareentwicklung OG, All Rights Reserved + * + * Email: libdash-dev@vicky.bitmovin.net + * + * This source code and its use and distribution, is subject to the terms + * and conditions of the applicable license agreement. + *****************************************************************************/ + +#ifndef LIBDASH_FRAMEWORK_MPD_SINGLEMEDIASEGMENTSTREAM_H_ +#define LIBDASH_FRAMEWORK_MPD_SINGLEMEDIASEGMENTSTREAM_H_ + +#include "IMPD.h" +#include "AbstractRepresentationStream.h" +#include "ISegment.h" + +namespace libdash +{ +namespace framework +{ +namespace mpd +{ +class SingleMediaSegmentStream: public AbstractRepresentationStream +{ +public: + SingleMediaSegmentStream(dash::mpd::IMPD *mpd, dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation); + virtual ~SingleMediaSegmentStream(); + + 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* getBitstreamSwitchingSegment(); + virtual RepresentationStreamType getStreamType(); + + virtual uint32_t getFirstSegmentNumber(); + virtual uint32_t getCurrentSegmentNumber(); + virtual uint32_t getLastSegmentNumber(); + +}; +} +} +} + +#endif /* LIBDASH_FRAMEWORK_MPD_SINGLEMEDIASEGMENTSTREAM_H_ */ diff --git a/MPD/TimeResolver.cpp b/MPD/TimeResolver.cpp new file mode 100644 index 00000000..8ce044ae --- /dev/null +++ b/MPD/TimeResolver.cpp @@ -0,0 +1,148 @@ +/* + * TimeResolver.cpp + ***************************************************************************** + * Copyright (C) 2012, bitmovin Softwareentwicklung OG, All Rights Reserved + * + * Email: libdash-dev@vicky.bitmovin.net + * + * This source code and its use and distribution, is subject to the terms + * and conditions of the applicable license agreement. + *****************************************************************************/ + +#include "TimeResolver.h" +#include "sstream" + +using namespace libdash::framework::mpd; + +bool TimeResolver::checkTimeInterval(std::string availabilityStartTime, std::string availabilityEndTime) +{ + struct tm* startTime = TimeResolver::resolveUTCDateTime(availabilityStartTime); + struct tm* currentTime = TimeResolver::getCurrentUTCTime(); + struct tm* endTime = TimeResolver::resolveUTCDateTime(availabilityEndTime); + + if (!startTime) + { + if (!endTime) + return true; + + if (difftime(mktime(endTime),mktime(currentTime)) > 0) + return true; + } + else + { + if (difftime(mktime(currentTime),mktime(startTime)) > 0) + { + if (!endTime) + return true; + + if (difftime(mktime(endTime),mktime(currentTime)) > 0) + return true; + } + } + + return false; +} + +uint32_t TimeResolver::getCurrentTimeInSec() +{ + return mktime(TimeResolver::getCurrentUTCTime()); +} +uint32_t TimeResolver::getUTCDateTimeInSec(const std::string& datetime) +{ + return mktime(TimeResolver::resolveUTCDateTime(datetime)); +} +double TimeResolver::getDurationInSec(const std::string& duration) +{ + /* no check for duration with yyyy,dd,mm */ + if (duration == "" || duration.substr(0, 2) != "PT") + return 0; + + size_t startPos = 2; + size_t endPos = std::string::npos; + uint32_t hours = 0; + uint32_t mins = 0; + double secs = 0; + + char designators[] = { 'H', 'M', 'S' }; + + endPos = duration.find(designators[0], startPos); + if (endPos != std::string::npos) + { + hours = strtol(duration.substr(startPos, endPos - startPos).c_str(), NULL, 10); + startPos = endPos + 1; + } + + endPos = duration.find(designators[1], startPos); + if (endPos != std::string::npos) + { + mins = strtol(duration.substr(startPos, endPos - startPos).c_str(), NULL, 10); + startPos = endPos + 1; + } + + endPos = duration.find(designators[2], startPos); + if (endPos != std::string::npos) + secs = strtod(duration.substr(startPos, endPos - startPos).c_str(), NULL); + + return hours*3600 + mins*60 + secs; +} + +struct tm* TimeResolver::resolveUTCDateTime(const std::string& dateTimeString) +{ + if (dateTimeString == "") + return NULL; + + time_t rawtime; + struct tm* timeInfo; + time ( &rawtime ); + timeInfo = gmtime ( &rawtime ); + + std::string timeString = dateTimeString.substr(); + + timeString = timeString.substr(0, timeString.size()-1); + + std::vector<std::string> dateTime = splitToStr(timeString, 'T'); + std::vector<int> dateChunks = splitToI(dateTime.at(0), '-'); + std::vector<int> timeChunks = splitToI(dateTime.at(1), ':'); + + timeInfo->tm_year = dateChunks.at(0) - 1900; + timeInfo->tm_mon = dateChunks.at(1) - 1; + timeInfo->tm_mday = dateChunks.at(2); + + timeInfo->tm_hour = timeChunks.at(0); + timeInfo->tm_min = timeChunks.at(1); + timeInfo->tm_sec = timeChunks.at(2); + + return timeInfo; +} + +struct tm* TimeResolver::getCurrentUTCTime() +{ + time_t rawTime; + + time(&rawTime); + return gmtime(&rawTime); +} + +std::vector<int> TimeResolver::splitToI(const std::string &s, char delim) +{ + std::stringstream ss(s); + std::string item; + std::vector<int> integers; + + while(std::getline(ss, item, delim)) + integers.push_back((int)strtol(item.c_str(), NULL, 10)); + + return integers; +} + +std::vector<std::string> TimeResolver::splitToStr(const std::string &s, char delim) +{ + std::stringstream ss(s); + std::string item; + std::vector<std::string> strings; + + while(std::getline(ss, item, delim)) + strings.push_back(item); + + return strings; +} diff --git a/MPD/TimeResolver.h b/MPD/TimeResolver.h new file mode 100644 index 00000000..fe320e8d --- /dev/null +++ b/MPD/TimeResolver.h @@ -0,0 +1,43 @@ +/* + * TimeResolver.h + ***************************************************************************** + * Copyright (C) 2012, bitmovin Softwareentwicklung OG, All Rights Reserved + * + * Email: libdash-dev@vicky.bitmovin.net + * + * This source code and its use and distribution, is subject to the terms + * and conditions of the applicable license agreement. + *****************************************************************************/ + +#ifndef LIBDASH_FRAMEWORK_MPD_TIMERESOLVER_H_ +#define LIBDASH_FRAMEWORK_MPD_TIMERESOLVER_H_ + +#include <time.h> +#include "config.h" + +namespace libdash +{ +namespace framework +{ +namespace mpd +{ +class TimeResolver +{ +public: + static bool checkTimeInterval(std::string availabilityStartTime, std::string availabilityEndTime); + static uint32_t getCurrentTimeInSec(); + static uint32_t getUTCDateTimeInSec(const std::string& datetime); + static double getDurationInSec(const std::string& duration); + +private: + static struct tm* resolveUTCDateTime(const std::string& timeString); + static struct tm* getCurrentUTCTime(); + static std::vector<int> splitToI(const std::string &s, char delim); + static std::vector<std::string> splitToStr(const std::string &s, char delim); + +}; +} +} +} + +#endif /* LIBDASH_FRAMEWORK_MPD_TIMERESOLVER_H_ */ |