aboutsummaryrefslogtreecommitdiffstats
path: root/Adaptation/AdapTech.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Adaptation/AdapTech.cpp')
-rw-r--r--Adaptation/AdapTech.cpp210
1 files changed, 210 insertions, 0 deletions
diff --git a/Adaptation/AdapTech.cpp b/Adaptation/AdapTech.cpp
new file mode 100644
index 00000000..dc88fae6
--- /dev/null
+++ b/Adaptation/AdapTech.cpp
@@ -0,0 +1,210 @@
+/*
+ * 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 "AdapTech.h"
+#include<stdio.h>
+
+using namespace dash::mpd;
+using namespace libdash::framework::adaptation;
+using namespace libdash::framework::input;
+using namespace libdash::framework::mpd;
+
+AdapTechAdaptation::AdapTechAdaptation(viper::managers::StreamType type, MPDWrapper *mpdWrapper, struct AdaptationParameters *params) :
+ AbstractAdaptationLogic(type, mpdWrapper)
+{
+ this->alphaRate = params->Adaptech_Alpha;
+ this->reservoirThreshold = params->Adaptech_FirstThreshold;
+ this->maxThreshold = params->Adaptech_SecondThreshold;
+ this->switchUpThreshold = params->Adaptech_SwitchUpThreshold;
+ this->slackParam = params->Adaptech_SlackParameter;
+
+ this->m_count = 0;
+ this->instantBw = 0;
+ this->averageBw = 0;
+// this->representation = this->adaptationSet->GetRepresentation().at(0);
+
+ this->multimediaManager = NULL;
+ this->lastBufferFill = 0;
+ this->bufferEOS = false;
+ this->shouldAbort = false;
+ this->isCheckedForReceiver = false;
+ this->myQuality = 0;
+ this->currentBitrate = 0;
+ Debug("BufferRateBasedParams:\talpha:%f\tfirst threshold: %f\tsecond threshold: %f\tswitch-up margin: %d\tSlack: %f\n",this->alphaRate, (double)reservoirThreshold/100, (double)maxThreshold/100, this->switchUpThreshold, this->slackParam);
+ Debug("Buffer Adaptation: STARTED\n");
+}
+AdapTechAdaptation::~AdapTechAdaptation()
+{
+}
+
+LogicType AdapTechAdaptation::getType()
+{
+ return adaptation::BufferBased;
+}
+
+bool AdapTechAdaptation::isUserDependent()
+{
+ return false;
+}
+
+bool AdapTechAdaptation::isRateBased()
+{
+ return true;
+}
+bool AdapTechAdaptation::isBufferBased()
+{
+ return true;
+}
+
+void AdapTechAdaptation::setMultimediaManager(viper::managers::IMultimediaManagerBase *_mmManager)
+{
+ this->multimediaManager = _mmManager;
+}
+
+void AdapTechAdaptation::notifyBitrateChange()
+{
+ this->mpdWrapper->setRepresentation(this->type, this->representation);
+ if(this->multimediaManager)
+ if(this->multimediaManager->isStarted() && !this->multimediaManager->isStopping())
+ if(this->type==viper::managers::StreamType::VIDEO)
+ this->multimediaManager->setVideoQuality();
+ else
+ this->multimediaManager->setAudioQuality();
+ //Should Abort is done here to avoid race condition with DASHReceiver::DoBuffering()
+// if(this->shouldAbort)
+// {
+// this->multimediaManager->shouldAbort((this->type == viper::managers::StreamType::VIDEO));
+// }
+// this->shouldAbort = false;
+}
+
+uint64_t AdapTechAdaptation::getBitrate()
+{
+ return this->currentBitrate;
+}
+
+void AdapTechAdaptation::setBitrate(uint32_t bufferFill)
+{
+ uint32_t phi1, phi2;
+ std::vector<IRepresentation *> representations;
+ representations = this->mpdWrapper->getRepresentations(this->type);
+ size_t i = 0;
+
+ Debug("bufferlevel: %u, instant rate %lu, average rate %lu\n", bufferFill, this->instantBw, this->averageBw);
+ phi1 = 0;
+ phi2 = 0;
+ while(i < representations.size())
+ {
+ if(phi1 == 0 && representations.at(i)->GetBandwidth() > slackParam * this->instantBw)
+ {
+ phi1 = representations.at((i == 0) ? i : i -1)->GetBandwidth();
+ }
+ if(phi2 == 0 && representations.at(i)->GetBandwidth() > slackParam * this->averageBw)
+ {
+ phi2 = representations.at((i == 0) ? i : i -1)->GetBandwidth();
+ }
+ i++;
+ }
+
+ if(!phi1)
+ phi1 = representations.at(representations.size() - 1)->GetBandwidth();
+
+ if(!phi2)
+ phi2 = representations.at(representations.size() - 1)->GetBandwidth();
+
+ if(bufferFill < this->reservoirThreshold)
+ {
+ this->m_count = 0;
+ this->myQuality = 0;
+ }
+ else
+ {
+ if(bufferFill < this->maxThreshold)
+ {
+ this->m_count = 0;
+ if(this->currentBitrate > phi1)
+ {
+ if(this->myQuality > 0)
+ {
+ this->myQuality--;
+ }
+ }
+ else
+ {
+ if(this->currentBitrate < phi1)
+ {
+ if(this->myQuality < representations.size() - 1)
+ {
+ this->myQuality++;
+ }
+ }
+ }
+ }
+ else
+ { // bufferFill > this->maxThreshold
+ if(this->currentBitrate < phi2)
+ {
+ m_count++;
+
+ if(m_count >= switchUpThreshold && this->myQuality < representations.size() - 1)
+ {
+ this->m_count = 0;
+ this->myQuality++;
+ }
+ }
+ }
+ }
+ this->representation = representations.at(this->myQuality);
+ this->currentBitrate = (uint64_t) this->representation->GetBandwidth();
+ Debug("ADAPTATION_LOGIC:\tFor %s:\tlast_buffer: %f\tbuffer_level: %f, instantaneousBw: %lu, AverageBW: %lu, choice: %d\n",(this->type == viper::managers::StreamType::VIDEO) ? "video" : "audio",(double)lastBufferFill/100 , (double)bufferFill/100, this->instantBw, this->averageBw , this->myQuality);
+}
+
+void AdapTechAdaptation::bitrateUpdate(uint64_t bps, uint32_t segNum)
+{
+ Debug("rate estimation: %lu\n", bps);
+ this->instantBw = bps;
+ if(this->averageBw == 0)
+ {
+ this->averageBw = bps;
+ }
+ else
+ {
+ this->averageBw = this->alphaRate*this->averageBw + (1 - this->alphaRate)*bps;
+ }
+}
+
+void AdapTechAdaptation::onEOS(bool value)
+{
+ this->bufferEOS = value;
+}
+
+void AdapTechAdaptation::checkedByDASHReceiver()
+{
+ this->isCheckedForReceiver = false;
+}
+void AdapTechAdaptation::bufferUpdate(uint32_t bufferFill, int maxC)
+{
+ Debug("buffer update: %u\n", bufferFill);
+ EnterCriticalSection(&this->monitorLock);
+ this->setBitrate(bufferFill);
+ this->notifyBitrateChange();
+ LeaveCriticalSection(&this->monitorLock);
+}
+
+void AdapTechAdaptation::dLTimeUpdate(double time)
+{
+}
+
+