From a644414fd2c3a3f7f41e716b6875a78981e4cfe1 Mon Sep 17 00:00:00 2001 From: jacko Date: Fri, 23 Jun 2017 16:12:18 +0200 Subject: adding mpd live handling + automatic mpd fetching Change-Id: I2c05bdf6a4d940ad22bb8632268f4b63a08a80a8 Signed-off-by: jacko --- UI/DASHPlayer.cpp | 82 +++++++++++++++------------------------ UI/DASHPlayer.h | 57 +++++++++++++++------------- UI/DASHPlayerNoGUI.cpp | 101 +++++++++++++++++++++---------------------------- UI/DASHPlayerNoGUI.h | 47 ++++++++--------------- UI/IViperGui.h | 30 +++++++++++++++ UI/ViperGui.cpp | 43 ++++++++++++--------- UI/ViperGui.h | 3 +- 7 files changed, 176 insertions(+), 187 deletions(-) create mode 100644 UI/IViperGui.h (limited to 'UI') diff --git a/UI/DASHPlayer.cpp b/UI/DASHPlayer.cpp index 0f1db8cc..cdad7d5a 100644 --- a/UI/DASHPlayer.cpp +++ b/UI/DASHPlayer.cpp @@ -30,7 +30,6 @@ DASHPlayer::DASHPlayer(ViperGui &gui, Config *config) : this->icn = false; this->adaptLogic = LogicType::RateBased; 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()); @@ -40,15 +39,24 @@ DASHPlayer::DASHPlayer(ViperGui &gui, Config *config) : connect(this->gui->getVideoPlayer(), SIGNAL(stateChanged(QtAV::AVPlayer::State)), SLOT(manageGraph(QtAV::AVPlayer::State))); connect(this->gui->getVideoPlayer(), SIGNAL(error(QtAV::AVError)), this, SLOT(error(QtAV::AVError))); this->multimediaManager->attachManagerObserver(this); + this->mpdWrapper = new MPDWrapper(NULL); + this->multimediaManager->setMPDWrapper(this->mpdWrapper); } DASHPlayer::~DASHPlayer() { this->multimediaManager->stop(); delete(this->multimediaManager); + if(this->mpdWrapper) + delete(this->mpdWrapper); DeleteCriticalSection(&this->monitorMutex); } +void DASHPlayer::setMPDWrapper(MPDWrapper* mpdWrapper) +{ + this->mpdWrapper = mpdWrapper; +} + void DASHPlayer::onStartButtonPressed(int period, int videoAdaptationSet, int videoRepresentation, int audioAdaptationSet, int audioRepresentation, int adaptationLogic) { bool setOk = false; @@ -85,25 +93,27 @@ void DASHPlayer::onPauseButtonPressed() void DASHPlayer::onSettingsChanged(int period, int videoAdaptationSet, int videoRepresentation, int audioAdaptationSet, int audioRepresentation) { - if(this->multimediaManager->getMPD() == NULL) + if(this->mpdWrapper->getMPD() == NULL) return; if (!this->settingsChanged(period, videoAdaptationSet, videoRepresentation, audioAdaptationSet, audioRepresentation)) return; - IPeriod *currentPeriod = this->multimediaManager->getMPD()->GetPeriods().at(period); - std::vector videoAdaptationSets = AdaptationSetHelper::getVideoAdaptationSets(currentPeriod); - std::vector audioAdaptationSets = AdaptationSetHelper::getAudioAdaptationSets(currentPeriod); - if (videoAdaptationSet >= 0 && videoRepresentation >= 0) - { - this->multimediaManager->setVideoQuality(currentPeriod, - videoAdaptationSets.at(videoAdaptationSet), - videoAdaptationSets.at(videoAdaptationSet)->GetRepresentation().at(videoRepresentation)); - } - else - { - this->multimediaManager->setVideoQuality(currentPeriod, NULL, NULL); - } +// IPeriod *currentPeriod = this->multimediaManager->getMPD()->GetPeriods().at(period); +// std::vector videoAdaptationSets = AdaptationSetHelper::getVideoAdaptationSets(currentPeriod); +// std::vector audioAdaptationSets = AdaptationSetHelper::getAudioAdaptationSets(currentPeriod); +// if (videoAdaptationSet >= 0 && videoRepresentation >= 0) +// { +// this->multimediaManager->setVideoQuality(currentPeriod, +// videoAdaptationSets.at(videoAdaptationSet), +// videoAdaptationSets.at(videoAdaptationSet)->GetRepresentation().at(videoRepresentation)); +// } +// else +// { +// this->multimediaManager->setVideoQuality(currentPeriod, NULL, NULL); +// } + this->mpdWrapper->settingsChanged(period, videoAdaptationSet, videoRepresentation, audioAdaptationSet, audioRepresentation); + this->multimediaManager->setVideoQuality(); } void DASHPlayer::onVideoBufferStateChanged(uint32_t fillstateInPercent) @@ -149,7 +159,7 @@ bool DASHPlayer::onDownloadMPDPressed (const std::string &url) } } this->setSettings(-1, -1, -1, -1, -1); - this->gui->setGuiFields(this->multimediaManager->getMPD()); + this->gui->setGuiFields(this->mpdWrapper->getMPD()); return true; } @@ -205,42 +215,10 @@ bool DASHPlayer::downloadMPD(const QString &url, const QString &adaptationLogic, } if (!this->onDownloadMPDPressed(mUrl)) return false; - IPeriod *period = this->multimediaManager->getMPD()->GetPeriods().at(0); - IAdaptationSet *adaptation = period->GetAdaptationSets().at(0); - IRepresentation *representation = adaptation->GetRepresentation().at(0); - 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->segmentDuration = this->mpdWrapper->onFirstDownloadMPD(this->gui); + this->multimediaManager->setSegmentDuration(this->segmentDuration); + this->parametersAdaptation->segmentDuration = this->segmentDuration / 1000.0; //to have it in seconds this->onSettingsChanged(0,0,0,0,0); int j =0; std::string temp = adaptationLogic.toStdString(); diff --git a/UI/DASHPlayer.h b/UI/DASHPlayer.h index fad28710..6204f46a 100644 --- a/UI/DASHPlayer.h +++ b/UI/DASHPlayer.h @@ -60,6 +60,7 @@ public: virtual void notifyStatistics(int, uint32_t, int, uint32_t); virtual void notifyQualityDownloading(uint32_t); virtual bool onDownloadMPDPressed(const std::string &url); + void setMPDWrapper(libdash::framework::mpd::MPDWrapper* mpdWrapper); void setConfig(Config *config); Q_INVOKABLE bool downloadMPD(const QString &url, const QString &adaptationLogic, bool icn); Q_INVOKABLE void pause(); @@ -160,34 +161,36 @@ public: Q_INVOKABLE int getRateEstimator(); private: - float gamma; - float beta; - float drop; - bool seek; - bool isLive; - Config *config; - bool repeat; - float segmentDuration; - uint64_t offset; - uint64_t position; - int segment; - int adaptationLogic; - dash::mpd::IMPD *mpd; - ViperGui *gui = NULL; - viper::managers::MultimediaManager *multimediaManager; - settings_t currentSettings; - CRITICAL_SECTION monitorMutex; - const char *url; - bool icn; - std::string icnPrefix; - std::string httpPrefix; - std::string icnSuffix; - std::string httpSuffix; - double alpha; + float gamma; + float beta; + float drop; + bool seek; + bool isLive; + Config *config; + bool repeat; + float segmentDuration; + uint64_t offset; + uint64_t position; + int segment; + int adaptationLogic; + dash::mpd::IMPD *mpd; + libdash::framework::mpd::MPDWrapper *mpdWrapper; + ViperGui *gui = NULL; + viper::managers::MultimediaManager *multimediaManager; + settings_t currentSettings; + CRITICAL_SECTION monitorMutex; + const char *url; + bool icn; + std::string icnPrefix; + std::string httpPrefix; + std::string icnSuffix; + std::string httpSuffix; + double alpha; struct libdash::framework::adaptation::AdaptationParameters *parametersAdaptation; - libdash::framework::adaptation::LogicType adaptLogic; - std::map> mStats; - int qualityDownloading; + libdash::framework::adaptation::LogicType adaptLogic; + std::map> mStats; + int qualityDownloading; + bool settingsChanged(int period, int videoAdaptationSet, int videoRepresentation, int audioAdaptationSet, int audioRepresentation); void setSettings(int period, int videoAdaptationSet, int videoRepresentation, int audioAdaptationSet, int audioRepresentation); std::string msec2string(uint64_t milliseconds); diff --git a/UI/DASHPlayerNoGUI.cpp b/UI/DASHPlayerNoGUI.cpp index 729621ef..d212b556 100644 --- a/UI/DASHPlayerNoGUI.cpp +++ b/UI/DASHPlayerNoGUI.cpp @@ -30,11 +30,9 @@ DASHPlayerNoGUI::DASHPlayerNoGUI(int argc, char ** argv, pthread_cond_t *mainCon noDecoding (nodecoding) { InitializeCriticalSection(&this->monitorMutex); - - this->mpd = NULL; - this->url = NULL; - this->adaptLogic = LogicType::RateBased; - this->isICN = false; + this->url = NULL; + this->adaptLogic = LogicType::RateBased; + this->isICN = false; this->alpha = -1; this->graphData = NULL; this->parameterAdaptation = (struct libdash::framework::adaptation::AdaptationParameters *)malloc(sizeof(struct libdash::framework::adaptation::AdaptationParameters)); @@ -71,6 +69,8 @@ DASHPlayerNoGUI::DASHPlayerNoGUI(int argc, char ** argv, pthread_cond_t *mainCon this->parseArgs(argc, argv); this->multimediaManager = new MultimediaManager(NULL, this->parameterAdaptation->segmentBufferSize, "/tmp/", noDecoding); + this->mpdWrapper = new MPDWrapper(NULL); + this->multimediaManager->setMPDWrapper(this->mpdWrapper); this->multimediaManager->attachManagerObserver(this); if(this->url == NULL) @@ -87,6 +87,8 @@ DASHPlayerNoGUI::DASHPlayerNoGUI(int argc, char ** argv, pthread_cond_t *mainCon WebSocketService webSocketService; webSocketService.setGraphDataSource(this->graphData); webSocketService.start(); + this->parameterAdaptation->segmentDuration = this->mpdWrapper->onFirstDownloadMPD(NULL); + this->multimediaManager->setSegmentDuration(this->parameterAdaptation->segmentDuration); this->onStartButtonPressed(0,0,0,0,0); this->multimediaManager->setLooping(this->repeat); } @@ -102,40 +104,23 @@ DASHPlayerNoGUI::~DASHPlayerNoGUI() { this->multimediaManager->stop(); delete(this->multimediaManager); + if(this->mpdWrapper) + delete(this->mpdWrapper); if(this->graphData) delete(this->graphData); DeleteCriticalSection(&this->monitorMutex); } +void DASHPlayerNoGUI::setMPDWrapper(MPDWrapper *mpdWrapper) +{ + this->mpdWrapper = mpdWrapper; +} + void DASHPlayerNoGUI::onStartButtonPressed(int period, int videoAdaptationSet, int videoRepresentation, int audioAdaptationSet, int audioRepresentation) { this->onSettingsChanged(period,videoAdaptationSet,videoRepresentation, audioAdaptationSet, audioRepresentation); bool setOk = false; - - switch(adaptLogic) - { - case RateBased: - setOk = this->multimediaManager->setVideoAdaptationLogic((LogicType)adaptLogic, this->parameterAdaptation); - break; - case BufferBased: - setOk = this->multimediaManager->setVideoAdaptationLogic((LogicType)adaptLogic, this->parameterAdaptation); - break; - case BufferRateBased: - setOk = this->multimediaManager->setVideoAdaptationLogic((LogicType)adaptLogic, this->parameterAdaptation); - break; - case BufferBasedThreeThreshold: - setOk = this->multimediaManager->setVideoAdaptationLogic((LogicType)adaptLogic, this->parameterAdaptation); - break; - case Panda: - setOk = this->multimediaManager->setVideoAdaptationLogic((LogicType)adaptLogic, this->parameterAdaptation); - break; - case Bola: - setOk = this->multimediaManager->setVideoAdaptationLogic((LogicType)adaptLogic, this->parameterAdaptation); - break; - default: - setOk = this->multimediaManager->setVideoAdaptationLogic((LogicType)adaptLogic, this->parameterAdaptation); - break; - } + setOk = this->multimediaManager->setVideoAdaptationLogic((LogicType)adaptLogic, this->parameterAdaptation); if(!setOk) { @@ -302,37 +287,39 @@ void DASHPlayerNoGUI::helpMessage(char * name) void DASHPlayerNoGUI::onSettingsChanged(int period, int videoAdaptationSet, int videoRepresentation, int audioAdaptationSet, int audioRepresentation) { - if(this->multimediaManager->getMPD() == NULL) - return; // TODO dialog or symbol that indicates that error + if(this->mpdWrapper->getMPD() == NULL) + return; if (!this->settingsChanged(period, videoAdaptationSet, videoRepresentation, audioAdaptationSet, audioRepresentation)) return; - IPeriod *currentPeriod = this->multimediaManager->getMPD()->GetPeriods().at(period); - std::vector videoAdaptationSets = AdaptationSetHelper::getVideoAdaptationSets(currentPeriod); - std::vector audioAdaptationSets = AdaptationSetHelper::getAudioAdaptationSets(currentPeriod); - - if (videoAdaptationSet >= 0 && videoRepresentation >= 0 && !videoAdaptationSets.empty()) - { - this->multimediaManager->setVideoQuality(currentPeriod, - videoAdaptationSets.at(videoAdaptationSet), - videoAdaptationSets.at(videoAdaptationSet)->GetRepresentation().at(videoRepresentation)); - } - else - { - this->multimediaManager->setVideoQuality(currentPeriod, NULL, NULL); - } - - if (audioAdaptationSet >= 0 && audioRepresentation >= 0 && !audioAdaptationSets.empty()) - { - this->multimediaManager->setAudioQuality(currentPeriod, - audioAdaptationSets.at(audioAdaptationSet), - audioAdaptationSets.at(audioAdaptationSet)->GetRepresentation().at(audioRepresentation)); - } - else - { - this->multimediaManager->setAudioQuality(currentPeriod, NULL, NULL); - } +// IPeriod *currentPeriod = this->multimediaManager->getMPD()->GetPeriods().at(period); +// std::vector videoAdaptationSets = AdaptationSetHelper::getVideoAdaptationSets(currentPeriod); +// std::vector audioAdaptationSets = AdaptationSetHelper::getAudioAdaptationSets(currentPeriod); +// +// if (videoAdaptationSet >= 0 && videoRepresentation >= 0 && !videoAdaptationSets.empty()) +// { +// this->multimediaManager->setVideoQuality(currentPeriod, +// videoAdaptationSets.at(videoAdaptationSet), +// videoAdaptationSets.at(videoAdaptationSet)->GetRepresentation().at(videoRepresentation)); +// } +// else +// { +// this->multimediaManager->setVideoQuality(currentPeriod, NULL, NULL); +// } +// +// if (audioAdaptationSet >= 0 && audioRepresentation >= 0 && !audioAdaptationSets.empty()) +// { +// this->multimediaManager->setAudioQuality(currentPeriod, +// audioAdaptationSets.at(audioAdaptationSet), +// audioAdaptationSets.at(audioAdaptationSet)->GetRepresentation().at(audioRepresentation)); +// } +// else +// { +// this->multimediaManager->setAudioQuality(currentPeriod, NULL, NULL); +// } + this->mpdWrapper->settingsChanged(period, videoAdaptationSet, videoRepresentation, audioAdaptationSet, audioRepresentation); + this->multimediaManager->setVideoQuality(); } void DASHPlayerNoGUI::onEOS() diff --git a/UI/DASHPlayerNoGUI.h b/UI/DASHPlayerNoGUI.h index 58ba52c4..4b070de8 100644 --- a/UI/DASHPlayerNoGUI.h +++ b/UI/DASHPlayerNoGUI.h @@ -50,42 +50,25 @@ public: virtual void notifyStatistics(int, uint32_t, int, uint32_t); virtual void notifyQualityDownloading(uint32_t); virtual bool onDownloadMPDPressed(const std::string &url); + virtual void setMPDWrapper(libdash::framework::mpd::MPDWrapper* mpdWrapper); bool isRunning(); private: - dash::mpd::IMPD *mpd; - viper::managers::MultimediaManager *multimediaManager; - CRITICAL_SECTION monitorMutex; - char *url; - bool isICN; - libdash::framework::adaptation::LogicType adaptLogic; - pthread_cond_t *mainCond; - bool running; +// dash::mpd::IMPD *mpd; + libdash::framework::mpd::MPDWrapper *mpdWrapper; + viper::managers::MultimediaManager *multimediaManager; + CRITICAL_SECTION monitorMutex; + char *url; + bool isICN; + libdash::framework::adaptation::LogicType adaptLogic; + pthread_cond_t *mainCond; + bool running; struct libdash::framework::adaptation::AdaptationParameters *parameterAdaptation; - float segmentDuration; - int segmentBufferSize; - double alpha; - double rateAlpha; - double bolaAlpha; - double bolaBufferTargetSeconds; - int bufferBasedReservoirThreshold; - int bufferBasedMaxThreshold; - double adaptechAlpha; - int adaptechFirstThreshold; - int adaptechSecondThreshold; - int adaptechSwitchUpThreshold; - int bufferThreeThreshold_FirstThreshold; - int bufferThreeThreshold_SecondThreshold; - int bufferThreeThreshold_ThirdThreshold; - double pandaAlpha; - double pandaParam_Beta; - double pandaParam_Bmin; - double pandaParam_K; - double pandaParam_W; - double pandaParamEpsilon; - bool repeat; - GraphDataSource *graphData; - bool noDecoding; + double alpha; + bool repeat; + GraphDataSource *graphData; + bool noDecoding; + bool settingsChanged(int period, int videoAdaptationSet, int videoRepresentation, int audioAdaptationSet, int audioRepresentation); }; diff --git a/UI/IViperGui.h b/UI/IViperGui.h new file mode 100644 index 00000000..bf3cb5c3 --- /dev/null +++ b/UI/IViperGui.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACE_VIPER_H +#define INTERFACE_VIPER_H + +namespace viper +{ + +class IViperGui +{ +public: + virtual void setListSegmentSize(int listSegmentSize) = 0; + virtual void setSegmentDuration(long long int segmentDuration) = 0; +}; +} + +#endif // INTERFACE_VIPER_H diff --git a/UI/ViperGui.cpp b/UI/ViperGui.cpp index 11ba2e8e..24dcfad2 100644 --- a/UI/ViperGui.cpp +++ b/UI/ViperGui.cpp @@ -41,6 +41,7 @@ ViperGui::ViperGui(QObject *parent) : this->position = 0; this->videoPlayer = qvariant_cast(parent->property("mediaObject")); this->streamBuffer = new ViperBuffer(); + this->listSegmentSize = 0; pthread_mutex_init(&(this->monitorMutex), NULL); if (streamBuffer->open(QIODevice::ReadWrite)) { this->videoPlayer->setIODevice(streamBuffer); @@ -55,25 +56,28 @@ ViperGui::~ViperGui() void ViperGui::setGuiFields(dash::mpd::IMPD* mpd) { - this->setPeriodComboBox(mpd); - if (mpd->GetPeriods().size() > 0) +//USELESS CALLS +// this->setPeriodComboBox(mpd); +// if (mpd->GetPeriods().size() > 0) +// { +// IPeriod *period = mpd->GetPeriods().at(0); +// this->setVideoAdaptationSetComboBox(period); +// if (!AdaptationSetHelper::getVideoAdaptationSets(period).empty()) +// { +// IAdaptationSet *adaptationSet = AdaptationSetHelper::getVideoAdaptationSets(period).at(0); +// this->setRepresentationComoboBox(adaptationSet); +// } +// if (!AdaptationSetHelper::getAudioAdaptationSets(period).empty()) +// { +// IAdaptationSet *adaptationSet = AdaptationSetHelper::getAudioAdaptationSets(period).at(0); +// this->setRepresentationComoboBox(adaptationSet); +// } +// } + if(!strcmp(mpd->GetType().c_str(),"static")) { - IPeriod *period = mpd->GetPeriods().at(0); - this->setVideoAdaptationSetComboBox(period); - if (!AdaptationSetHelper::getVideoAdaptationSets(period).empty()) - { - IAdaptationSet *adaptationSet = AdaptationSetHelper::getVideoAdaptationSets(period).at(0); - this->setRepresentationComoboBox(adaptationSet); - } - if (!AdaptationSetHelper::getAudioAdaptationSets(period).empty()) - { - IAdaptationSet *adaptationSet = AdaptationSetHelper::getAudioAdaptationSets(period).at(0); - this->setRepresentationComoboBox(adaptationSet); - } + parse8601(mpd->GetMediaPresentationDuration()); + this->lifeLabel->setProperty("text", QVariant(this->durationString.c_str())); } - parse8601(mpd->GetMediaPresentationDuration()); - this->mpd = mpd; - this->lifeLabel->setProperty("text", QVariant(this->durationString.c_str())); } void ViperGui::parse8601(std::string durationISO8601) @@ -242,7 +246,10 @@ void ViperGui::writeData(libdash::framework::input::MediaObject* media) { this->streamBuffer->writeData(media); pthread_mutex_lock(&(this->monitorMutex)); - this->segment = (this->segment + 1) % this->listSegmentSize; + if(this->listSegmentSize) + this->segment = (this->segment + 1) % this->listSegmentSize; + else + this->segment = this->segment + 1; if( this->segment > 0) { this->bufferDuration += this->segmentDuration; diff --git a/UI/ViperGui.h b/UI/ViperGui.h index f4586753..1ce8e574 100644 --- a/UI/ViperGui.h +++ b/UI/ViperGui.h @@ -28,6 +28,7 @@ #include "../Common/QtQuick2ApplicationViewer.h" #include "../Managers/MultimediaStream.h" #include "GraphDataSource.h" +#include "IViperGui.h" #include @@ -35,7 +36,7 @@ namespace viper { class IDASHPlayerGuiObserver; -class ViperGui : public QObject +class ViperGui : public QObject,public IViperGui { Q_OBJECT -- cgit 1.2.3-korg