summaryrefslogtreecommitdiffstats
path: root/UI/DASHPlayerNoGUI.cpp
diff options
context:
space:
mode:
authorLuca Muscariello <lumuscar+fdio@cisco.com>2017-02-25 23:42:31 +0100
committerLuca Muscariello <lumuscar+fdio@cisco.com>2017-02-25 23:42:31 +0100
commit05c1a838c881ea502888659848d8792843b28718 (patch)
treecf0b05b58bd725a1eb6c80325ba986c63dea42aa /UI/DASHPlayerNoGUI.cpp
parent9b30fc10fb1cbebe651e5a107e8ca5b24de54675 (diff)
Initial commit: video player - viper
Change-Id: Id5aa33598ce34659bad4a7a9ae5006bfb84f9bd1 Signed-off-by: Luca Muscariello <lumuscar+fdio@cisco.com>
Diffstat (limited to 'UI/DASHPlayerNoGUI.cpp')
-rw-r--r--UI/DASHPlayerNoGUI.cpp383
1 files changed, 383 insertions, 0 deletions
diff --git a/UI/DASHPlayerNoGUI.cpp b/UI/DASHPlayerNoGUI.cpp
new file mode 100644
index 00000000..729621ef
--- /dev/null
+++ b/UI/DASHPlayerNoGUI.cpp
@@ -0,0 +1,383 @@
+/*
+ * 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.
+ */
+
+#include "DASHPlayerNoGUI.h"
+#include <iostream>
+
+using namespace libdash::framework::adaptation;
+using namespace libdash::framework::mpd;
+using namespace libdash::framework::buffer;
+using namespace viper;
+using namespace viper::managers;
+using namespace dash::mpd;
+using namespace std;
+
+DASHPlayerNoGUI::DASHPlayerNoGUI(int argc, char ** argv, pthread_cond_t *mainCond, bool nodecoding) :
+ mainCond (mainCond),
+ running (true),
+ noDecoding (nodecoding)
+{
+ InitializeCriticalSection(&this->monitorMutex);
+
+ this->mpd = NULL;
+ 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));
+
+ this->parameterAdaptation->segmentDuration = 2.0;
+ this->parameterAdaptation->segmentBufferSize = 10;
+
+ this->parameterAdaptation->Rate_Alpha = 0.8;
+
+ this->parameterAdaptation->Bola_Alpha = 0.8;
+ this->parameterAdaptation->Bola_bufferTargetSeconds = 8.0;
+
+ this->parameterAdaptation->BufferBased_reservoirThreshold = 25;
+ this->parameterAdaptation->BufferBased_maxThreshold = 75;
+
+ this->parameterAdaptation->Adaptech_Alpha = 0.8;
+ this->parameterAdaptation->Adaptech_FirstThreshold = 25;
+ this->parameterAdaptation->Adaptech_SecondThreshold = 45;
+ this->parameterAdaptation->Adaptech_SwitchUpThreshold = 5;
+ this->parameterAdaptation->Adaptech_SlackParameter = 0.8;
+
+ this->parameterAdaptation->BufferThreeThreshold_FirstThreshold = 25;
+ this->parameterAdaptation->BufferThreeThreshold_SecondThreshold = 50;
+ this->parameterAdaptation->BufferThreeThreshold_ThirdThreshold = 75;
+
+ this->parameterAdaptation->Panda_Alpha = 0.2;
+ this->parameterAdaptation->Panda_Beta = 0.2;
+ this->parameterAdaptation->Panda_Bmin = 44;
+ this->parameterAdaptation->Panda_K = 0.14;
+ this->parameterAdaptation->Panda_W = 300000;
+ this->parameterAdaptation->Panda_Epsilon = 0.15;
+
+ this->repeat = false;
+ this->parseArgs(argc, argv);
+
+ this->multimediaManager = new MultimediaManager(NULL, this->parameterAdaptation->segmentBufferSize, "/tmp/", noDecoding);
+ this->multimediaManager->attachManagerObserver(this);
+
+ if(this->url == NULL)
+ {
+ this->running = false;
+ pthread_cond_broadcast(mainCond);
+ return;
+ }
+ else
+ {
+ if(this->onDownloadMPDPressed(string(this->url).c_str()))
+ {
+ this->graphData = new GraphDataSource(NULL);
+ WebSocketService webSocketService;
+ webSocketService.setGraphDataSource(this->graphData);
+ webSocketService.start();
+ this->onStartButtonPressed(0,0,0,0,0);
+ this->multimediaManager->setLooping(this->repeat);
+ }
+ else
+ {
+ this->running = false;
+ pthread_cond_broadcast(mainCond);
+ }
+ }
+}
+
+DASHPlayerNoGUI::~DASHPlayerNoGUI()
+{
+ this->multimediaManager->stop();
+ delete(this->multimediaManager);
+ if(this->graphData)
+ delete(this->graphData);
+ DeleteCriticalSection(&this->monitorMutex);
+}
+
+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;
+ }
+
+ if(!setOk)
+ {
+ return;
+ }
+
+ Debug("DASH PLAYER: STARTING VIDEO\n");
+ this->multimediaManager->start(this->isICN, this->alpha, 0);
+}
+
+void DASHPlayerNoGUI::onStopButtonPressed ()
+{
+ this->running = false;
+ pthread_cond_broadcast(mainCond);
+}
+
+bool DASHPlayerNoGUI::isRunning ()
+{
+ return this->running;
+}
+
+void DASHPlayerNoGUI::notifyStatistics(int segNum, uint32_t bitrate, int fps, uint32_t quality)
+{
+}
+
+void DASHPlayerNoGUI::notifyQualityDownloading(uint32_t quality)
+{
+ this->graphData->setAnaliticsValues(quality/1000000, 0, quality/1000000, 0);
+}
+
+void DASHPlayerNoGUI::parseArgs(int argc, char ** argv)
+{
+ if(argc == 1)
+ {
+ helpMessage(argv[0]);
+ return;
+ }
+ else
+ {
+ int i = 0;
+ while(i < argc)
+ {
+ if(!strcmp(argv[i],"-u"))
+ {
+ this->url = argv[i+1];
+ i++;
+ i++;
+ continue;
+ }
+ if(!strcmp(argv[i],"-n"))
+ {
+ this->isICN = true;
+ this->alpha = -1;
+ i++;
+ continue;
+ }
+ if(!strcmp(argv[i],"-loop"))
+ {
+ this->repeat = true;
+ i++;
+ continue;
+ }
+ if(!strcmp(argv[i],"-nr"))
+ {
+ this->isICN = true;
+ this->alpha = atof(argv[i+1]);
+ i++;
+ i++;
+ continue;
+ }
+ if(!strcmp(argv[i], "-b"))
+ {
+ this->adaptLogic = LogicType::BufferBased;
+ this->parameterAdaptation->BufferBased_reservoirThreshold = atoi(argv[i+1]);
+ this->parameterAdaptation->BufferBased_maxThreshold = atoi(argv[i+2]);
+ i = i + 3;
+ continue;
+ }
+ if(!strcmp(argv[i], "-br"))
+ {
+ this->adaptLogic = LogicType::BufferRateBased;
+ this->parameterAdaptation->Adaptech_Alpha = atof(argv[i+1]);
+ this->parameterAdaptation->Adaptech_FirstThreshold = atoi(argv[i+2]);
+ this->parameterAdaptation->Adaptech_SecondThreshold = atoi(argv[i+3]);
+ this->parameterAdaptation->Adaptech_SwitchUpThreshold = atoi(argv[i+4]);
+ i = i + 4;
+ continue;
+ }
+ if(!strcmp(argv[i], "-bola"))
+ {
+ this->adaptLogic = LogicType::Bola;
+ this->parameterAdaptation->Bola_Alpha = atof(argv[i+1]);
+ this->parameterAdaptation->Bola_bufferTargetSeconds = atoi(argv[i+2]);
+ i = i + 2;
+ continue;
+ }
+ if(!strcmp(argv[i], "-bt"))
+ {
+ this->adaptLogic = LogicType::BufferBasedThreeThreshold;
+ this->parameterAdaptation->BufferThreeThreshold_FirstThreshold = atoi(argv[i+1]);
+ this->parameterAdaptation->BufferThreeThreshold_SecondThreshold = atoi(argv[i+2]);
+ this->parameterAdaptation->BufferThreeThreshold_ThirdThreshold = atoi(argv[i+3]);
+ i = i + 3;
+ continue;
+ }
+ if(!strcmp(argv[i], "-r"))
+ {
+ this->adaptLogic = LogicType::RateBased;
+ this->parameterAdaptation->Rate_Alpha = atof(argv[i+1]);
+ i = i + 2;
+ continue;
+ }
+ if(!strcmp(argv[i], "-p"))
+ {
+ this->adaptLogic = LogicType::Panda;
+ this->parameterAdaptation->Panda_Alpha = atof(argv[i+1]);
+ i = i + 2;
+ continue;
+ }
+
+ if(!strcmp(argv[i],"-a"))
+ {
+ int j =0;
+ for(j = 0; j < LogicType::Count; j++)
+ {
+ if(!strcmp(LogicType_string[j],argv[i+1]))
+ {
+ this->adaptLogic = (LogicType)j;
+ break;
+ }
+ }
+ if(j == LogicType::Count)
+ {
+ std::cout << "the different adaptation logics implemented are:" << std::endl;
+ for(j = 0;j < LogicType::Count; j++)
+ {
+ std::cout << LogicType_string[j] << std::endl;
+ }
+ std::cout << "By default, the " << LogicType_string[this->adaptLogic] << " logic is selected." << std::endl;
+ }
+ i++;
+ i++;
+ continue;
+ }
+ i++;
+ }
+ }
+}
+
+void DASHPlayerNoGUI::helpMessage(char * name)
+{
+ std::cout << "Usage: " << name << " -u url -a adaptationLogic -n" << std::endl << \
+ "-u:\tThe MPD's url" << std::endl << \
+ "-a:\tThe adaptationLogic:" << std::endl << \
+ "\t*AlwaysLowest" << std::endl << \
+ "\t*RateBased(default)" << std::endl << \
+ "\t*BufferBased" << std::endl << \
+ "-n:\tFlag to use ICN instead of TCP" << std::endl << \
+ "-nr alpha:\tFlag to use ICN instead of TCP and estimation at packet lvl" << std::endl << \
+ "-b reservoirThreshold maxThreshold (both in %)" << std::endl << \
+ "-br alpha reservoirThreshold maxThreshold" << std::endl << \
+ "-r alpha" << std::endl;
+}
+
+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->settingsChanged(period, videoAdaptationSet, videoRepresentation, audioAdaptationSet, audioRepresentation))
+ return;
+
+ IPeriod *currentPeriod = this->multimediaManager->getMPD()->GetPeriods().at(period);
+ std::vector<IAdaptationSet *> videoAdaptationSets = AdaptationSetHelper::getVideoAdaptationSets(currentPeriod);
+ std::vector<IAdaptationSet *> 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);
+ }
+}
+
+void DASHPlayerNoGUI::onEOS()
+{
+ this->onStopButtonPressed();
+}
+
+bool DASHPlayerNoGUI::onDownloadMPDPressed(const std::string &url)
+{
+ if(this->isICN)
+ {
+ if(!this->multimediaManager->initICN(url))
+ {
+ std::cout << "Problem parsing the mpd. ICN is enabled." << std::endl;
+ return false;
+ }
+ }
+ else
+ {
+ if(!this->multimediaManager->init(url))
+ {
+ std::cout << "Problem parsing the mpd. ICN is disabled." << std::endl;
+ return false;
+ }
+ }
+ return true;
+}
+
+bool DASHPlayerNoGUI::settingsChanged(int period, int videoAdaptationSet, int videoRepresentation, int audioAdaptationSet, int audioRepresentation)
+{
+ return true;
+}
+
+void DASHPlayerNoGUI::onVideoBufferStateChanged(uint32_t fillstateInPercent)
+{
+}
+
+void DASHPlayerNoGUI::onVideoSegmentBufferStateChanged(uint32_t fillstateInPercent)
+{
+}
+
+void DASHPlayerNoGUI::onAudioBufferStateChanged(uint32_t fillstateInPercent)
+{
+}
+
+void DASHPlayerNoGUI::onAudioSegmentBufferStateChanged(uint32_t fillstateInPercent)
+{
+}