aboutsummaryrefslogtreecommitdiffstats
path: root/Input
diff options
context:
space:
mode:
Diffstat (limited to 'Input')
-rw-r--r--Input/DASHManager.cpp161
-rw-r--r--Input/DASHManager.h80
-rw-r--r--Input/DASHReceiver.cpp453
-rw-r--r--Input/DASHReceiver.h129
-rw-r--r--Input/ICNConnectionConsumerApi.cpp283
-rw-r--r--Input/ICNConnectionConsumerApi.h138
-rw-r--r--Input/IDASHManagerObserver.h41
-rw-r--r--Input/IDASHReceiverObserver.h35
-rw-r--r--Input/IDataReceiver.h34
-rw-r--r--Input/IICNConnection.h44
-rw-r--r--Input/MediaObject.cpp175
-rw-r--r--Input/MediaObject.h78
12 files changed, 1651 insertions, 0 deletions
diff --git a/Input/DASHManager.cpp b/Input/DASHManager.cpp
new file mode 100644
index 00000000..a86263dc
--- /dev/null
+++ b/Input/DASHManager.cpp
@@ -0,0 +1,161 @@
+/*
+ * DASHManager.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 "DASHManager.h"
+
+using namespace libdash::framework::input;
+using namespace libdash::framework::buffer;
+
+using namespace dash;
+using namespace dash::network;
+using namespace dash::mpd;
+
+DASHManager::DASHManager(viper::managers::StreamType type, uint32_t maxCapacity, IDASHManagerObserver* stream, IMPD* mpd, bool icnEnabled, double icnAlpha, bool nodecoding, float beta, float drop) :
+ readSegmentCount (0),
+ receiver (NULL),
+ multimediaStream (stream),
+ isRunning (false),
+ icn (icnEnabled),
+ icnAlpha (icnAlpha),
+ noDecoding (nodecoding),
+ beta (beta),
+ drop (drop)
+{
+
+ this->buffer = new Buffer<MediaObject>(maxCapacity,libdash::framework::buffer::VIDEO);
+ this->buffer->attachObserver(this);
+
+ this->receiver = new DASHReceiver(mpd, this, this->buffer, maxCapacity, this->isICN(), this->icnAlpha, this->beta, this->drop);
+}
+DASHManager::~DASHManager()
+{
+ this->stop();
+ delete this->receiver;
+ delete this->buffer;
+
+ this->receiver = NULL;
+ this->buffer = NULL;
+}
+
+bool DASHManager::isICN()
+{
+ return this->icn;
+}
+
+void DASHManager::shouldAbort()
+{
+ Debug("DASH MANAGER: ABORT REQUEST\n");
+ this->receiver->ShouldAbort();
+}
+
+bool DASHManager::start()
+{
+ this->receiver->SetAdaptationLogic(this->adaptationLogic);
+ if (!this->receiver->Start())
+ return false;
+
+ this->isRunning = true;
+ return true;
+}
+
+void DASHManager::stop()
+{
+ if (!this->isRunning)
+ return;
+
+ this->isRunning = false;
+
+ this->receiver->Stop();
+ this->buffer->clear();
+}
+
+uint32_t DASHManager::getPosition()
+{
+ return this->receiver->GetPosition();
+}
+
+void DASHManager::setLooping(bool looping)
+{
+ this->receiver->SetLooping(looping);
+}
+
+void DASHManager::setPosition(uint32_t segmentNumber)
+{
+ this->receiver->SetPosition(segmentNumber);
+}
+
+void DASHManager::setPositionInMsec(uint32_t milliSecs)
+{
+ this->receiver->SetPositionInMsecs(milliSecs);
+}
+
+void DASHManager::setAdaptationLogic(libdash::framework::adaptation::IAdaptationLogic *_adaptationLogic)
+{
+ this->adaptationLogic = _adaptationLogic;
+}
+
+void DASHManager::clear()
+{
+ this->buffer->clear();
+}
+
+void DASHManager::setRepresentation(IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation)
+{
+ this->receiver->SetRepresentation(period, adaptationSet, representation);
+}
+
+void DASHManager::enqueueRepresentation(IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation)
+{
+ this->receiver->SetRepresentation(period, adaptationSet, representation);
+}
+
+void DASHManager::onSegmentDownloaded()
+{
+ this->readSegmentCount++;
+}
+
+void DASHManager::notifyStatistics(int segNum, uint32_t bitrate, int fps, uint32_t quality)
+{
+ this->multimediaStream->notifyStatistics(segNum, bitrate, fps, quality);
+}
+
+void DASHManager::notifyQualityDownloading(uint32_t quality)
+{
+ this->multimediaStream->notifyQualityDownloading(quality);
+}
+
+int DASHManager::getBufferLevel()
+{
+ int res = this->multimediaStream->getBufferLevel();
+ return this->multimediaStream->getBufferLevel();
+}
+
+bool DASHManager::canPush()
+{
+ this->multimediaStream->canPush();
+}
+
+MediaObject* DASHManager::getSegment()
+{
+ return this->buffer->getFront();
+}
+
+void DASHManager::setTargetDownloadingTime(double target)
+{
+ this->receiver->SetTargetDownloadingTime(target);
+}
+
+void DASHManager::onBufferStateChanged(BufferType type, uint32_t fillstateInPercent, int maxC)
+{
+ this->multimediaStream->onSegmentBufferStateChanged(fillstateInPercent, maxC);
+ if(this->adaptationLogic->isBufferBased())
+ this->receiver->OnSegmentBufferStateChanged(fillstateInPercent, maxC);
+}
diff --git a/Input/DASHManager.h b/Input/DASHManager.h
new file mode 100644
index 00000000..2b723426
--- /dev/null
+++ b/Input/DASHManager.h
@@ -0,0 +1,80 @@
+/*
+ * DASHManager.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_INPUT_DASHMANAGER_H_
+#define LIBDASH_FRAMEWORK_INPUT_DASHMANAGER_H_
+
+#include "DASHReceiver.h"
+#include "IDASHReceiverObserver.h"
+#include "libdash.h"
+#include "IMPD.h"
+#include <QtMultimedia/qaudioformat.h>
+#include "IDASHManagerObserver.h"
+//#include "../Buffer/Segment.h"
+#include "../Managers/IStreamObserver.h"
+#include "../Buffer/IBufferObserver.h"
+
+
+namespace libdash
+{
+namespace framework
+{
+namespace input
+{
+
+class DASHManager : public IDASHReceiverObserver, public IBufferObserver
+{
+public:
+ DASHManager (viper::managers::StreamType type, uint32_t maxCapacity, IDASHManagerObserver *multimediaStream, dash::mpd::IMPD *mpd, bool icnEnabled, double icnAlpha, bool nodecoding, float beta, float drop);
+ virtual ~DASHManager ();
+
+ bool start();
+ void stop();
+ uint32_t getPosition();
+ void setPosition(uint32_t segmentNumber); // to implement
+ void setLooping(bool looping);
+ void setPositionInMsec(uint32_t millisec);
+ void clear();
+ void setRepresentation(dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation);
+ void enqueueRepresentation(dash::mpd::IPeriod *period, dash::mpd::IAdaptationSet *adaptationSet, dash::mpd::IRepresentation *representation);
+
+ void onSegmentDownloaded();
+ void notifyStatistics(int, uint32_t, int, uint32_t);
+ void notifyQualityDownloading (uint32_t);
+ bool canPush();
+ int getBufferLevel();
+ void setAdaptationLogic(libdash::framework::adaptation::IAdaptationLogic *_adaptationLogic);
+ bool isICN();
+ void shouldAbort();
+
+ void setTargetDownloadingTime(double);
+ MediaObject* getSegment();
+ void onBufferStateChanged(BufferType type, uint32_t fillstateInPercent, int maxC);
+
+private:
+ float beta;
+ float drop;
+ buffer::Buffer<MediaObject> *buffer;
+ DASHReceiver *receiver;
+ uint32_t readSegmentCount;
+ IDASHManagerObserver *multimediaStream;
+ bool isRunning;
+ bool icn;
+ double icnAlpha;
+ bool noDecoding;
+
+ libdash::framework::adaptation::IAdaptationLogic *adaptationLogic;
+};
+}
+}
+}
+
+#endif /* LIBDASH_FRAMEWORK_INPUT_DASHMANAGER_H_ */
diff --git a/Input/DASHReceiver.cpp b/Input/DASHReceiver.cpp
new file mode 100644
index 00000000..df9d019b
--- /dev/null
+++ b/Input/DASHReceiver.cpp
@@ -0,0 +1,453 @@
+/*
+ * DASHReceiver.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 "DASHReceiver.h"
+#include<stdio.h>
+
+using namespace libdash::framework::input;
+using namespace libdash::framework::buffer;
+using namespace libdash::framework::mpd;
+using namespace dash::mpd;
+
+using duration_in_seconds = std::chrono::duration<double, std::ratio<1, 1> >;
+
+DASHReceiver::DASHReceiver (IMPD *mpd, IDASHReceiverObserver *obs, Buffer<MediaObject> *buffer, uint32_t bufferSize, bool icnEnabled, double icnAlpha, float beta, float drop) :
+ mpd (mpd),
+ period (NULL),
+ adaptationSet (NULL),
+ representation (NULL),
+ adaptationSetStream (NULL),
+ representationStream (NULL),
+ segmentNumber (0),
+ observer (obs),
+ buffer (buffer),
+ bufferSize (bufferSize),
+ isBuffering (false),
+ withFeedBack (false),
+ icn (icnEnabled),
+ icnAlpha (icnAlpha),
+ previousQuality (0),
+ isPaused (false),
+ threadComplete (false),
+ isScheduledPaced (false),
+ targetDownload (0.0),
+ downloadingTime (0.0),
+ bufferLevelAtUpdate (0),
+ isBufferBased (false),
+ isLooping (false),
+ beta (beta),
+ drop (drop)
+{
+ readMax = 32768;
+ readBuffer = (uint8_t*)malloc(sizeof(uint8_t)*readMax);
+ this->period = this->mpd->GetPeriods().at(0);
+ this->adaptationSet = this->period->GetAdaptationSets().at(0);
+ this->representation = this->adaptationSet->GetRepresentation().at(0);
+
+ this->adaptationSetStream = new AdaptationSetStream(mpd, period, adaptationSet);
+ this->representationStream = adaptationSetStream->getRepresentationStream(this->representation);
+ this->segmentOffset = CalculateSegmentOffset();
+
+ this->conn = NULL;
+ this->initConn = NULL;
+ readMax = 32768;
+ readBuffer = (uint8_t *)malloc(sizeof(uint8_t) * readMax);
+
+ if(icn)
+ {
+ this->conn = new ICNConnectionConsumerApi(this->icnAlpha, this->beta, this->drop);
+ this->initConn = new ICNConnectionConsumerApi(this->icnAlpha, this->beta, this->drop);
+ }
+ InitializeCriticalSection(&this->monitorMutex);
+ InitializeCriticalSection(&this->monitorPausedMutex);
+ InitializeConditionVariable(&this->paused);
+}
+DASHReceiver::~DASHReceiver ()
+{
+ free(readBuffer);
+ if(this->initConn)
+ delete(this->initConn);
+ if(this->conn)
+ delete(this->conn);
+ delete(this->adaptationSetStream);
+ DeleteCriticalSection(&this->monitorMutex);
+ DeleteCriticalSection(&this->monitorPausedMutex);
+ DeleteConditionVariable(&this->paused);
+}
+
+void DASHReceiver::SetAdaptationLogic(adaptation::IAdaptationLogic *_adaptationLogic)
+{
+ this->adaptationLogic = _adaptationLogic;
+ this->isBufferBased = this->adaptationLogic->isBufferBased();
+ this->withFeedBack = this->adaptationLogic->isRateBased();
+}
+bool DASHReceiver::Start ()
+{
+ if(this->isBuffering)
+ return false;
+
+ this->isBuffering = true;
+ this->bufferingThread = createThreadPortable(DoBuffering, this);
+
+ if(this->bufferingThread == NULL)
+ {
+ this->isBuffering = false;
+ return false;
+ }
+
+ return true;
+}
+void DASHReceiver::Stop()
+{
+ if(!this->isBuffering)
+ return;
+
+ this->isBuffering = false;
+ this->buffer->setEOS(true);
+
+ if(this->bufferingThread != NULL)
+ {
+ JoinThread(this->bufferingThread);
+ destroyThreadPortable(this->bufferingThread);
+ }
+ this->period = this->mpd->GetPeriods().at(0);
+ this->adaptationSet = this->period->GetAdaptationSets().at(0);
+ this->representation = this->adaptationSet->GetRepresentation().at(0);
+}
+
+MediaObject* DASHReceiver::GetNextSegment ()
+{
+ ISegment *seg = NULL;
+
+ EnterCriticalSection(&this->monitorPausedMutex);
+ while(this->isPaused)
+ SleepConditionVariableCS(&this->paused, &this->monitorPausedMutex, INFINITE);
+
+ if(this->segmentNumber >= this->representationStream->getSize())
+ {
+ 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);
+
+ if (seg != NULL)
+ {
+ std::vector<IRepresentation *> rep = this->adaptationSet->GetRepresentation();
+
+ this->NotifyQualityDownloading(this->representation->GetBandwidth());
+
+ MediaObject *media = new MediaObject(seg, this->representation,this->withFeedBack);
+ this->segmentNumber++;
+ LeaveCriticalSection(&this->monitorPausedMutex);
+ return media;
+ }
+ LeaveCriticalSection(&this->monitorPausedMutex);
+ return NULL;
+}
+MediaObject* DASHReceiver::GetSegment (uint32_t segNum)
+{
+ ISegment *seg = NULL;
+
+ if(segNum >= this->representationStream->getSize())
+ return NULL;
+
+ seg = this->representationStream->getMediaSegment(segNum + segmentOffset);
+
+ if (seg != NULL)
+ {
+ MediaObject *media = new MediaObject(seg, this->representation);
+ return media;
+ }
+
+ return NULL;
+}
+MediaObject* DASHReceiver::GetInitSegment ()
+{
+ ISegment *seg = NULL;
+
+ seg = this->representationStream->getInitializationSegment();
+
+ if (seg != NULL)
+ {
+ MediaObject *media = new MediaObject(seg, this->representation);
+ return media;
+ }
+
+ return NULL;
+}
+MediaObject* DASHReceiver::FindInitSegment (dash::mpd::IRepresentation *representation)
+{
+ if (!this->InitSegmentExists(representation))
+ return NULL;
+
+ return this->initSegments[representation];
+}
+uint32_t DASHReceiver::GetPosition ()
+{
+ return this->segmentNumber;
+}
+void DASHReceiver::SetLooping (bool looping)
+{
+ this->isLooping = looping;
+}
+void DASHReceiver::SetPosition (uint32_t segmentNumber)
+{
+ this->segmentNumber = segmentNumber;
+}
+void DASHReceiver::SetPositionInMsecs (uint32_t milliSecs)
+{
+ this->positionInMsecs = milliSecs;
+}
+
+void DASHReceiver::NotifyQualityDownloading (uint32_t quality)
+{
+ this->observer->notifyQualityDownloading(quality);
+}
+
+void DASHReceiver::SetRepresentation (IPeriod *period, IAdaptationSet *adaptationSet, IRepresentation *representation)
+{
+ EnterCriticalSection(&this->monitorMutex);
+
+ bool periodChanged = false;
+
+ if (this->representation == representation)
+ {
+ LeaveCriticalSection(&this->monitorMutex);
+ return;
+ }
+
+ this->representation = representation;
+
+ if (this->adaptationSet != adaptationSet)
+ {
+ this->adaptationSet = adaptationSet;
+
+ if (this->period != period)
+ {
+ this->period = period;
+ periodChanged = true;
+ }
+
+ delete this->adaptationSetStream;
+ this->adaptationSetStream = NULL;
+
+ this->adaptationSetStream = new AdaptationSetStream(this->mpd, this->period, this->adaptationSet);
+ }
+
+ this->representationStream = this->adaptationSetStream->getRepresentationStream(this->representation);
+ this->DownloadInitSegment(this->representation);
+
+ if (periodChanged)
+ {
+ this->segmentNumber = 0;
+ this->CalculateSegmentOffset();
+ }
+ LeaveCriticalSection(&this->monitorMutex);
+}
+
+libdash::framework::adaptation::IAdaptationLogic* DASHReceiver::GetAdaptationLogic ()
+{
+ return this->adaptationLogic;
+}
+dash::mpd::IRepresentation* DASHReceiver::GetRepresentation ()
+{
+ return this->representation;
+}
+uint32_t DASHReceiver::CalculateSegmentOffset ()
+{
+ if (mpd->GetType() == "static")
+ return 0;
+
+ uint32_t firstSegNum = this->representationStream->getFirstSegmentNumber();
+ uint32_t currSegNum = this->representationStream->getCurrentSegmentNumber();
+ uint32_t startSegNum = currSegNum - 2*bufferSize;
+
+ return (startSegNum > firstSegNum) ? startSegNum : firstSegNum;
+}
+void DASHReceiver::NotifySegmentDownloaded ()
+{
+ this->observer->onSegmentDownloaded();
+}
+
+void DASHReceiver::NotifyBitrateChange(dash::mpd::IRepresentation *representation)
+{
+ if(this->representation != representation)
+ {
+ this->representation = representation;
+ this->SetRepresentation(this->period,this->adaptationSet,this->representation);
+ }
+}
+void DASHReceiver::DownloadInitSegment (IRepresentation* rep)
+{
+ if (this->InitSegmentExists(rep))
+ return;
+
+ MediaObject *initSeg = NULL;
+ initSeg = this->GetInitSegment();
+
+ if (initSeg)
+ {
+ initSeg->StartDownload(this->initConn);
+ this->initSegments[rep] = initSeg;
+ initSeg->WaitFinished();
+ }
+}
+bool DASHReceiver::InitSegmentExists (IRepresentation* rep)
+{
+ if (this->initSegments.find(rep) != this->initSegments.end())
+ return true;
+
+ return false;
+}
+
+void DASHReceiver::Notifybps (uint64_t bps)
+{
+ if(this->adaptationLogic)
+ {
+ if(this->withFeedBack)
+ {
+ this->adaptationLogic->bitrateUpdate(bps, this->segmentNumber);
+ }
+ }
+}
+void DASHReceiver::NotifyDLTime (double time)
+{
+ if(this->adaptationLogic)
+ {
+ if(this->withFeedBack)
+ {
+ this->adaptationLogic->dLTimeUpdate(time);
+ }
+ }
+}
+
+void DASHReceiver::NotifyCheckedAdaptationLogic()
+{
+ this->adaptationLogic->checkedByDASHReceiver();
+}
+//Is only called when this->adaptationLogic->IsBufferBased
+void DASHReceiver::OnSegmentBufferStateChanged(uint32_t fillstateInPercent, int maxC)
+{
+ this->adaptationLogic->bufferUpdate(this->observer->getBufferLevel(), maxC);
+ this->bufferLevelAtUpdate = this->observer->getBufferLevel();
+}
+void DASHReceiver::OnEOS(bool value)
+{
+ this->adaptationLogic->onEOS(value);
+}
+
+bool DASHReceiver::PushBack(MediaObject *mediaObject)
+{
+ MediaObject *init = this->FindInitSegment(mediaObject->GetRepresentation());
+ mediaObject->AddInitSegment(init);
+ //TODO the read should be in a function
+
+ //Grab the infos for the analytics: bitrate, fps
+ dash::mpd::IRepresentation* datRep = mediaObject->GetRepresentation();
+ uint32_t bitrate = 0;
+ int fps = 0;
+ uint32_t quality = 0;
+ bitrate = datRep->GetBandwidth();
+ quality = datRep->GetHeight();
+ fps = this->bufferLevelAtUpdate;
+ this->observer->notifyStatistics((int)this->segmentNumber - 1, bitrate, fps, quality);
+
+ return(this->buffer->pushBack(mediaObject));
+}
+
+/* Thread that does the buffering of segments */
+void* DASHReceiver::DoBuffering (void *receiver)
+{
+ DASHReceiver *dashReceiver = (DASHReceiver *) receiver;
+
+ dashReceiver->DownloadInitSegment(dashReceiver->GetRepresentation());
+
+ MediaObject *media = dashReceiver->GetNextSegment();
+ dashReceiver->NotifyCheckedAdaptationLogic();
+ media->SetDASHReceiver(dashReceiver);
+ std::chrono::time_point<std::chrono::system_clock> m_start_time = std::chrono::system_clock::now();
+ while(media != NULL && dashReceiver->isBuffering)
+ {
+ //this is the case in PANDA
+ if(dashReceiver->isScheduledPaced)
+ {
+ double delay = std::chrono::duration_cast<duration_in_seconds>(std::chrono::system_clock::now() - m_start_time).count();
+ Debug("delay: %f, target: %f\n", delay, dashReceiver->targetDownload);
+ if(delay < dashReceiver->targetDownload)
+ {
+ sleep(dashReceiver->targetDownload - delay);
+ }
+ }
+ m_start_time = std::chrono::system_clock::now();
+ media->StartDownload(dashReceiver->conn);
+
+ media->WaitFinished();
+ bool canPush = dashReceiver->CanPush();
+ if (canPush && !dashReceiver->PushBack(media))
+ {
+ if(media)
+ {
+ delete(media);
+ }
+ media = NULL;
+ dashReceiver->threadComplete = true;
+ return NULL;
+ }
+
+ dashReceiver->NotifySegmentDownloaded();
+ media = dashReceiver->GetNextSegment();
+ dashReceiver->NotifyCheckedAdaptationLogic();
+ if(media)
+ media->SetDASHReceiver(dashReceiver);
+ }
+
+ dashReceiver->buffer->setEOS(true);
+ dashReceiver->threadComplete = true;
+ return NULL;
+}
+
+//can Push video to buffer in the renderer
+bool DASHReceiver::CanPush ()
+{
+ return this->observer->canPush();
+}
+void DASHReceiver::ShouldAbort ()
+{
+ Debug("DASH RECEIVER SEGMENT --\n");
+ this->segmentNumber--;
+ Debug("DASH RECEIVER ABORT REQUEST\n");
+}
+
+void DASHReceiver::SetTargetDownloadingTime (double target)
+{
+ this->isScheduledPaced = true;
+ this->targetDownload = target;
+}
+
+void DASHReceiver::SetBeta (float beta)
+{
+ this->beta = beta;
+}
+
+void DASHReceiver::SetDrop (float drop)
+{
+ this->drop = drop;
+}
+
+
diff --git a/Input/DASHReceiver.h b/Input/DASHReceiver.h
new file mode 100644
index 00000000..a2893b4d
--- /dev/null
+++ b/Input/DASHReceiver.h
@@ -0,0 +1,129 @@
+/*
+ * DASHReceiver.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_INPUT_DASHRECEIVER_H_
+#define LIBDASH_FRAMEWORK_INPUT_DASHRECEIVER_H_
+
+#include "libdash.h"
+#include "IMPD.h"
+
+#include "../Input/MediaObject.h"
+#include "IDASHReceiverObserver.h"
+#include "../MPD/AdaptationSetStream.h"
+#include "../MPD/IRepresentationStream.h"
+#include "../Portable/MultiThreading.h"
+#include "../Buffer/Buffer.h"
+#include <chrono>
+#include "ICNConnectionConsumerApi.h"
+
+namespace libdash
+{
+namespace framework
+{
+namespace adaptation
+{
+class IAdaptationLogic;
+}
+namespace buffer
+{
+class MediaObjectBuffer;
+template <class T>
+class Buffer;
+}
+namespace input
+{
+class MediaObject;
+class DASHReceiver
+{
+public:
+ DASHReceiver(dash::mpd::IMPD *mpd, IDASHReceiverObserver *obs, buffer::Buffer<MediaObject> *buffer, uint32_t bufferSize, bool icnEnabled, double icnAlpha, float beta, float drop);
+ virtual ~DASHReceiver();
+
+ bool Start();
+ void Stop();
+ input::MediaObject* GetNextSegment();
+ input::MediaObject* GetSegment(uint32_t segmentNumber);
+ input::MediaObject* GetInitSegment();
+ input::MediaObject* FindInitSegment(dash::mpd::IRepresentation *representation);
+ uint32_t GetPosition();
+ void SetPosition(uint32_t segmentNumber);
+ void SetLooping(bool isLoopinp);
+ void SetPositionInMsecs(uint32_t milliSecs);
+ dash::mpd::IRepresentation* GetRepresentation();
+ void SetRepresentation(dash::mpd::IPeriod *period,
+ dash::mpd::IAdaptationSet *adaptationSet,
+ dash::mpd::IRepresentation *representation);
+ void SetAdaptationLogic(adaptation::IAdaptationLogic *_adaptationLogic);
+ libdash::framework::adaptation::IAdaptationLogic* GetAdaptationLogic();
+ void NotifyQualityDownloading(uint32_t quality);
+ void Notifybps(uint64_t bps);
+ void NotifyDLTime(double time);
+ void NotifyBitrateChange(dash::mpd::IRepresentation *representation);
+ void OnSegmentBufferStateChanged(uint32_t fillstateInPercent, int maxC);
+ bool IsICN();
+ void ShouldAbort();
+ void OnEOS(bool value);
+ void SetTargetDownloadingTime(double);
+ void NotifyCheckedAdaptationLogic();
+ bool threadComplete;
+ bool PushBack(MediaObject* media);
+ bool CanPush();
+ void SetBeta(float beta);
+ void SetDrop(float drop);
+
+private:
+ float beta;
+ float drop;
+ bool withFeedBack;
+ bool isBufferBased;
+ std::map<dash::mpd::IRepresentation*, MediaObject*> initSegments;
+ libdash::framework::buffer::Buffer<MediaObject> *buffer;
+ IDASHReceiverObserver *observer;
+ dash::mpd::IMPD *mpd;
+ dash::mpd::IPeriod *period;
+ dash::mpd::IAdaptationSet *adaptationSet;
+ dash::mpd::IRepresentation *representation;
+ mpd::AdaptationSetStream *adaptationSetStream;
+ mpd::IRepresentationStream *representationStream;
+ uint32_t segmentNumber;
+ uint32_t positionInMsecs;
+ uint32_t segmentOffset;
+ uint32_t bufferSize;
+ mutable CRITICAL_SECTION monitorMutex;
+ mutable CRITICAL_SECTION monitorPausedMutex;
+ mutable CONDITION_VARIABLE paused;
+ bool isPaused;
+ bool isScheduledPaced;
+ bool isLooping;
+ double targetDownload;
+ double downloadingTime;
+ adaptation::IAdaptationLogic *adaptationLogic;
+ IICNConnection *conn;
+ IICNConnection *initConn;
+ THREAD_HANDLE bufferingThread;
+ bool isBuffering;
+ bool icn;
+ double icnAlpha;
+ int previousQuality;
+ int bufferLevelAtUpdate;
+ int readMax;
+ uint8_t *readBuffer;
+ uint32_t CalculateSegmentOffset();
+ void NotifySegmentDownloaded();
+ void DownloadInitSegment(dash::mpd::IRepresentation* rep);
+ bool InitSegmentExists(dash::mpd::IRepresentation* rep);
+ static void* DoBuffering(void *receiver);
+};
+}
+}
+}
+
+#endif /* LIBDASH_FRAMEWORK_INPUT_DASHRECEIVER_H_ */
diff --git a/Input/ICNConnectionConsumerApi.cpp b/Input/ICNConnectionConsumerApi.cpp
new file mode 100644
index 00000000..9de82908
--- /dev/null
+++ b/Input/ICNConnectionConsumerApi.cpp
@@ -0,0 +1,283 @@
+/*
+ * 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 ICNICPDOWNLOAD
+
+#include "ICNConnectionConsumerApi.h"
+
+#define DEFAULT_LIFETIME 250
+#define RETRY_TIMEOUTS 5
+
+using namespace dash;
+using namespace dash::network;
+using namespace dash::metrics;
+using namespace icnet;
+
+using std::bind;
+using std::placeholders::_1;
+using std::placeholders::_2;
+using std::placeholders::_3;
+
+using duration_in_seconds = std::chrono::duration<double, std::ratio<1, 1> >;
+
+
+namespace libdash {
+namespace framework {
+namespace input {
+ICNConnectionConsumerApi::ICNConnectionConsumerApi(double alpha, float beta, float drop) :
+ m_recv_name(ccnx::Name()),
+ m_first(1),
+ m_isFinished(false),
+ sizeDownloaded (0),
+ cumulativeBytesReceived(0),
+ icnAlpha(alpha),
+ beta(beta),
+ drop(drop)
+{
+ gamma = 1;
+ this->speed = 0.0;
+ this->dnltime = 0.0;
+ this->deezData = NULL;
+ this->deezDataSize = 0;
+ this->datSize = 0;
+ this->dataPos = 0;
+ InitializeConditionVariable (&this->contentRetrieved);
+ InitializeCriticalSection (&this->monitorMutex);
+
+ this->myConsumer = new ConsumerSocket(ccnx::Name(), TransportProtocolAlgorithms::RAAQM);
+ this->myConsumer->setSocketOption(RaaqmTransportOptions::GAMMA_VALUE, (int)gamma);
+
+ bool configFile = false;
+ //CHECK if we are not going to override the configuration file. (if !autotune)
+ if(FILE *fp = fopen("/usr/etc/consumer.conf", "r"))
+ {
+ fclose(fp);
+ configFile = true;
+ }
+ if(!configFile)
+ {
+ qDebug("beta %f, drop %f", this->beta, this->drop);
+ this->myConsumer->setSocketOption(RaaqmTransportOptions::BETA_VALUE, this->beta);
+ this->myConsumer->setSocketOption(RaaqmTransportOptions::DROP_FACTOR, this->drop);
+ }
+ this->myConsumer->setSocketOption(RateEstimationOptions::RATE_ESTIMATION_OBSERVER, this);
+ this->myConsumer->setSocketOption(ConsumerCallbacksOptions::CONTENT_RETRIEVED, (ConsumerContentCallback) bind(&ICNConnectionConsumerApi::processPayload, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
+ this->myConsumer->setSocketOption(ConsumerCallbacksOptions::CONTENT_OBJECT_TO_VERIFY, (ConsumerContentObjectVerificationCallback)bind(&ICNConnectionConsumerApi::onPacket, this, std::placeholders::_1, std::placeholders::_2));
+#ifdef NO_GUI
+ if(this->icnAlpha != 20)
+ this->icnRateBased = true;
+#else
+ this->icnRateBased = true;
+#endif
+ Debug("ICN class created\n");
+
+}
+
+ICNConnectionConsumerApi::~ICNConnectionConsumerApi() {
+ delete this->myConsumer;
+ if(this->deezData)
+ {
+ free(this->deezData);
+ this->deezData = NULL;
+ }
+ DeleteConditionVariable (&this->contentRetrieved);
+ DeleteCriticalSection (&this->monitorMutex);
+}
+
+void ICNConnectionConsumerApi::Init(IChunk *chunk) {
+ Debug("ICN Connection: STARTING\n");
+ m_first = 1;
+ sizeDownloaded = 0;
+ m_name = "ccnx:/" + chunk->Host() + chunk->Path();
+ m_isFinished = false;
+
+ res = false;
+ dataPos = 0;
+ datSize = 0;
+ if(this->deezData)
+ {
+ memset(this->deezData, 0, this->deezDataSize);
+ }
+
+ qDebug("ICN_Connection:\tINTIATED_to_name %s\n", m_name.c_str());
+ qDebug("ICN_Connection:\tSTARTING DOWNLOAD %s\n", m_name.c_str());
+}
+
+void ICNConnectionConsumerApi::InitForMPD(const std::string& url)
+{
+ m_first = 1;
+ sizeDownloaded = 0;
+
+ if(url.find("//") != std::string::npos)
+ {
+ int pos = url.find("//");
+ char* myName = (char*)malloc(strlen(url.c_str()) - 1);
+ strncpy(myName, url.c_str(), pos + 1);
+ strncpy(myName + pos + 1, url.c_str() + pos + 2, strlen(url.c_str()) - pos - 2);
+ m_name = std::string(myName);
+ free(myName);
+ }
+ else
+ {
+ m_name = url;
+ }
+ m_isFinished = false;
+
+ res = false;
+ dataPos = 0;
+ datSize = 0;
+ Debug("ICN_Connection:\tINTIATED_for_mpd %s\n", m_name.c_str());
+}
+
+int ICNConnectionConsumerApi::Read(uint8_t* data, size_t len, IChunk *chunk)
+{
+ return this->Read(data, len);
+}
+
+int ICNConnectionConsumerApi::Read(uint8_t *data, size_t len)
+{
+ if(!res)
+ m_start_time = std::chrono::system_clock::now();
+
+ if(res)
+ {
+ if(this->dataPos == this->datSize)
+ {
+ this->dnltime = std::chrono::duration_cast<duration_in_seconds>(std::chrono::system_clock::now() - m_start_time).count();
+ if(speed == 0 || !this->icnRateBased)
+ speed = (double) (sizeDownloaded * 8 / this->dnltime);
+ cumulativeBytesReceived += sizeDownloaded;
+ Debug("ICN_Connection:\tFINISHED DOWNLOADING %s Average_DL: %f size: %lu cumulative: %lu Throughput: %f\n", m_name.c_str(), speed, sizeDownloaded, cumulativeBytesReceived, (double) (sizeDownloaded * 8 / this->dnltime));
+ return 0;
+ }
+ if((this->datSize - this->dataPos) > (int)len)
+ {
+ memcpy(data, this->deezData + this->dataPos, len);
+ this->dataPos += len;
+ sizeDownloaded += len;
+ return len;
+ }
+ else
+ {
+ assert(this->datSize - this->dataPos > 0);
+ memcpy(data, this->deezData + this->dataPos, this->datSize - this->dataPos);
+ int temp = this->datSize - this->dataPos;
+ this->dataPos += this->datSize - this->dataPos;
+ sizeDownloaded += temp;
+ return temp;
+ }
+ }
+
+ Debug("will consume: %s\n", m_name.c_str());
+ this->myConsumer->consume(m_name);
+ EnterCriticalSection(&this->monitorMutex);
+
+ while(this->m_isFinished == false)
+ SleepConditionVariableCS(&this->contentRetrieved, &this->monitorMutex, INFINITE);
+
+ assert(this->datSize != 0);
+ this->res = true;
+ LeaveCriticalSection(&this->monitorMutex);
+ if(this->datSize > (int)len)
+ {
+ memcpy(data, this->deezData, len);
+ this->dataPos += len;
+ sizeDownloaded += len;
+ return len;
+ }
+ else
+ {
+ memcpy(data, this->deezData, this->datSize);
+ this->dataPos += this->datSize;
+ sizeDownloaded += this->datSize;
+ return this->datSize;
+ }
+}
+
+int ICNConnectionConsumerApi::Peek(uint8_t *data, size_t len, IChunk *chunk) {
+ return -1;
+}
+
+bool ICNConnectionConsumerApi::onPacket(ConsumerSocket& c, const ContentObject& data)
+{
+ return true;
+}
+
+void ICNConnectionConsumerApi::processPayload(ConsumerSocket& c, const uint8_t* buffer, size_t bufferSize)
+{
+ EnterCriticalSection(&this->monitorMutex);
+ if(this->deezData == NULL)
+ {
+ this->deezData = (char *)malloc(bufferSize*sizeof(uint8_t));
+ this->deezDataSize = bufferSize;
+ }
+ else
+ {
+ if(bufferSize > this->deezDataSize)
+ {
+ this->deezData = (char *)realloc(this->deezData, bufferSize * (sizeof(uint8_t)));
+ this->deezDataSize = bufferSize;
+ }
+ }
+ memcpy(this->deezData, buffer, bufferSize*sizeof(uint8_t));
+ this->m_isFinished = true;
+ this->datSize = (int) bufferSize;
+ WakeAllConditionVariable(&this->contentRetrieved);
+ LeaveCriticalSection(&this->monitorMutex);
+}
+
+double ICNConnectionConsumerApi::GetAverageDownloadingSpeed()
+{
+ Debug("ICNConnection: DL speed is %f\n", this->speed);
+ return this->speed;
+}
+
+double ICNConnectionConsumerApi::GetDownloadingTime()
+{
+ Debug("ICNConnection: DL time is %f\n", this->dnltime);
+ return this->dnltime;
+}
+
+const std::vector<ITCPConnection *> &ICNConnectionConsumerApi::GetTCPConnectionList() const {
+ return tcpConnections;
+}
+
+const std::vector<IHTTPTransaction *> &ICNConnectionConsumerApi::GetHTTPTransactionList() const {
+ return httpTransactions;
+}
+
+void ICNConnectionConsumerApi::notifyStats(double winSize)
+{
+ this->speed = (winSize); // * 1000000 * 1400 * 8;
+ Debug("ICNConnection:\tNotificationICPDL\t%f\t%f\n", winSize, speed);
+}
+
+void ICNConnectionConsumerApi::SetBeta(float beta)
+{
+ this->beta = beta;
+}
+
+
+void ICNConnectionConsumerApi::SetDrop(float drop)
+{
+ this->drop = drop;
+}
+
+} /* namespace input */
+} /* namespace framework */
+} /* namespace libdash */
+
+
+#endif //NDEF ICNICPDOWNLOAD
diff --git a/Input/ICNConnectionConsumerApi.h b/Input/ICNConnectionConsumerApi.h
new file mode 100644
index 00000000..a0343443
--- /dev/null
+++ b/Input/ICNConnectionConsumerApi.h
@@ -0,0 +1,138 @@
+/*
+ * 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 QTPLAYER_INPUT_ICNCONNECTIONCONSUMERAPI_H_
+#define QTPLAYER_INPUT_ICNCONNECTIONCONSUMERAPI_H_
+
+#include <QMessageLogger>
+#include "../Portable/Networking.h"
+#include "IICNConnection.h"
+#include "../debug.h"
+
+#include <sys/types.h>
+#include <string>
+#include <stdint.h>
+#include <iostream>
+#include <sstream>
+#include <chrono>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <algorithm>
+#include <icnet/icnet_socket_consumer.h>
+#include <icnet/icnet_download_observer.h>
+#include <future>
+#include <inttypes.h>
+#include <time.h>
+#include <limits.h>
+#include <errno.h>
+
+#include "../Portable/MultiThreading.h"
+#include <boost/exception/diagnostic_information.hpp>
+
+//logging purpose
+#include <chrono>
+#include <stdarg.h>
+
+
+namespace libdash {
+namespace framework {
+namespace input {
+
+class ICNConnectionConsumerApi : public IICNConnection, public icnet::IcnObserver {
+public:
+ ICNConnectionConsumerApi(double alpha, float beta, float drop);
+ virtual ~ICNConnectionConsumerApi();
+
+ virtual void Init(dash::network::IChunk *chunk);
+
+ void InitForMPD(const std::string& url);
+
+ virtual int Read(uint8_t *data, size_t len, dash::network::IChunk *chunk);
+
+ int Read(uint8_t *data, size_t len);
+
+ virtual int Peek(uint8_t *data, size_t len, dash::network::IChunk *chunk);
+
+ virtual double GetAverageDownloadingSpeed();
+
+ virtual double GetDownloadingTime();
+
+ void processPayload(icnet::ConsumerSocket& , const uint8_t*, size_t);
+
+ bool onPacket(icnet::ConsumerSocket& , const icnet::ContentObject&);
+
+ const std::vector<dash::metrics::ITCPConnection *> &GetTCPConnectionList() const;
+
+ const std::vector<dash::metrics::IHTTPTransaction *> &GetHTTPTransactionList() const;
+ virtual void SetBeta(float beta);
+ virtual void SetDrop(float drop);
+ virtual void notifyStats(double throughput);
+
+private:
+ float beta;
+ float drop;
+ uint64_t i_chunksize;
+ int i_lifetime;
+ int i_missed_co;
+ /**< number of content objects we missed in ICNBlock */
+
+ std::string m_name;
+ icnet::ccnx::Name m_recv_name;
+ icnet::ccnx::Portal m_portal;
+ int m_first;
+ bool m_isFinished;
+ uint64_t m_nextSeg;
+
+ double icnAlpha;
+ bool icnRateBased;
+
+ bool allow_stale;
+ int sysTimeout;
+ unsigned InitialMaxwindow;
+ unsigned int timer;
+ double drop_factor;
+ double p_min;
+ unsigned int gamma;
+ unsigned int samples;
+ unsigned int nchunks; // XXX chunks=-1 means: download the whole file!
+ bool output;
+ bool report_path;
+ icnet::ConsumerSocket* myConsumer;
+ bool res;
+ std::vector<char> mdata;
+ char* deezData;
+ int deezDataSize;
+ int datSize;
+ int dataPos;
+ int firstChunk;
+ double speed; // in bps
+ double dnltime; //in seconds
+ uint64_t sizeDownloaded;
+ std::chrono::time_point<std::chrono::system_clock> m_start_time;
+
+ std::vector<dash::metrics::ITCPConnection *> tcpConnections;
+ std::vector<dash::metrics::IHTTPTransaction *> httpTransactions;
+ uint64_t cumulativeBytesReceived;
+
+ mutable CRITICAL_SECTION monitorMutex;
+ mutable CONDITION_VARIABLE contentRetrieved;
+};
+
+} /* namespace input */
+} /* namespace framework */
+} /* namespace libdash */
+
+#endif /* QTPLAYER_INPUT_ICNCONNECTIONCONSUMERAPI_H_ */
diff --git a/Input/IDASHManagerObserver.h b/Input/IDASHManagerObserver.h
new file mode 100644
index 00000000..c5df8fe9
--- /dev/null
+++ b/Input/IDASHManagerObserver.h
@@ -0,0 +1,41 @@
+/*
+ * IDASHManagerObserver.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_INPUT_IDASHMANAGEROBSERVER_H_
+#define LIBDASH_FRAMEWORK_INPUT_IDASHMANAGEROBSERVER_H_
+
+#include <QImage>
+#include "../Buffer/Buffer.h"
+
+namespace libdash
+{
+namespace framework
+{
+namespace input
+{
+class IDASHManagerObserver
+{
+public:
+ virtual ~IDASHManagerObserver() {}
+
+ virtual void addFrame(QImage *frame) = 0;
+ virtual void setEOS(bool value)= 0;
+
+ virtual void onSegmentBufferStateChanged(uint32_t fillstateInPercent, int maxC) = 0;
+ virtual void notifyStatistics(int segNum, uint32_t bitrate, int fps, uint32_t quality) = 0;
+ virtual void notifyQualityDownloading (uint32_t quality) = 0;
+ virtual bool canPush() = 0;
+ virtual int getBufferLevel() = 0;
+};
+}
+}
+}
+#endif /* LIBDASH_FRAMEWORK_INPUT_IDASHMANAGEROBSERVER_H_ */
diff --git a/Input/IDASHReceiverObserver.h b/Input/IDASHReceiverObserver.h
new file mode 100644
index 00000000..0a334aa2
--- /dev/null
+++ b/Input/IDASHReceiverObserver.h
@@ -0,0 +1,35 @@
+/*
+ * IDASHReceiverObserver.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_INPUT_IDASHRECEIVEROBSERVER_H_
+#define LIBDASH_FRAMEWORK_INPUT_IDASHRECEIVEROBSERVER_H_
+
+namespace libdash
+{
+namespace framework
+{
+namespace input
+{
+class IDASHReceiverObserver
+{
+public:
+ virtual ~IDASHReceiverObserver() {}
+
+ virtual void onSegmentDownloaded() = 0;
+ virtual void notifyStatistics(int segNum, uint32_t bitrate, int fps, uint32_t quality) = 0;
+ virtual void notifyQualityDownloading(uint32_t quality) = 0;
+ virtual bool canPush() = 0;
+ virtual int getBufferLevel() = 0;
+};
+}
+}
+}
+#endif /* LIBDASH_FRAMEWORK_INPUT_IDASHRECEIVEROBSERVER_H_ */
diff --git a/Input/IDataReceiver.h b/Input/IDataReceiver.h
new file mode 100644
index 00000000..15d7e0f6
--- /dev/null
+++ b/Input/IDataReceiver.h
@@ -0,0 +1,34 @@
+/*
+ * IDataReceiver.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_INPUT_IDATARECEIVER_H_
+#define LIBDASH_FRAMEWORK_INPUT_IDATARECEIVER_H_
+
+#include <stdint.h>
+
+namespace libdash
+{
+namespace framework
+{
+namespace input
+{
+class IDataReceiver
+{
+public:
+ virtual ~IDataReceiver() {}
+
+ virtual int read(uint8_t *buf, int buf_size ) = 0;
+ virtual bool isAudio() = 0;
+};
+}
+}
+}
+#endif /* LIBDASH_FRAMEWORK_INPUT_IDATARECEIVER_H_ */
diff --git a/Input/IICNConnection.h b/Input/IICNConnection.h
new file mode 100644
index 00000000..260f0450
--- /dev/null
+++ b/Input/IICNConnection.h
@@ -0,0 +1,44 @@
+/*
+ * 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 QTPLAYER_INPUT_IICNCONNECTION_H_
+#define QTPLAYER_INPUT_IICNCONNECTION_H_
+
+#include "IConnection.h"
+#include "IChunk.h"
+
+
+namespace libdash {
+namespace framework {
+
+namespace input {
+
+class IICNConnection : public dash::network::IConnection {
+
+public:
+ virtual ~IICNConnection(){};
+
+ virtual int Read(uint8_t* data, size_t len) = 0;
+ virtual void Init(dash::network::IChunk *chunk) = 0;
+ virtual void InitForMPD(const std::string&) = 0;
+ virtual void SetBeta(float beta) = 0;
+ virtual void SetDrop(float drop) = 0;
+};
+}
+}
+}
+
+
+#endif // QTPLAYER_INPUT_IICNCONNECTION_H_
diff --git a/Input/MediaObject.cpp b/Input/MediaObject.cpp
new file mode 100644
index 00000000..ae6b9f6b
--- /dev/null
+++ b/Input/MediaObject.cpp
@@ -0,0 +1,175 @@
+/*
+ * MediaObject.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 "MediaObject.h"
+#include <inttypes.h>
+#include<stdio.h>
+
+using namespace libdash::framework::input;
+using namespace dash::mpd;
+using namespace dash::network;
+using namespace dash::metrics;
+
+MediaObject::MediaObject(ISegment *segment, IRepresentation *rep, bool withFeedBack) :
+ segment (segment),
+ rep (rep),
+ withFeedBack (withFeedBack)
+{
+ this->initSeg = NULL;
+ InitializeConditionVariable (&this->stateChanged);
+ InitializeCriticalSection (&this->stateLock);
+}
+
+MediaObject::~MediaObject()
+{
+ if(this->state == IN_PROGRESS)
+ {
+ this->segment->AbortDownload();
+ this->OnDownloadStateChanged(ABORTED);
+ }
+ this->segment->DetachDownloadObserver(this);
+ this->WaitFinished();
+
+ DeleteConditionVariable (&this->stateChanged);
+ DeleteCriticalSection (&this->stateLock);
+ delete this->segment;
+ this->segment = NULL;
+}
+
+void MediaObject::SetFeedBack(bool flag)
+{
+ this->withFeedBack = flag;
+}
+
+void MediaObject::AddInitSegment(MediaObject* initSeg)
+{
+ this->initSeg = initSeg;
+}
+
+int MediaObject::ReadInitSegment(uint8_t* data, size_t len)
+{
+ if(this->initSeg)
+ return this->initSeg->Peek(data,len);
+ else
+ return 0;
+}
+
+bool MediaObject::StartDownload()
+{
+ this->segment->AttachDownloadObserver(this);
+ return this->segment->StartDownload();
+}
+
+bool MediaObject::StartDownload(IICNConnection* conn)
+{
+ if(conn == NULL)
+ return this->StartDownload();
+
+ conn->Init(this->segment);
+
+ this->segment->AttachDownloadObserver(this);
+ return this->segment->StartDownload(conn);
+}
+
+const char* MediaObject::GetPath()
+{
+ return ((IChunk*)this->segment)->Path().c_str();
+}
+
+void MediaObject::AbortDownload()
+{
+ this->segment->AbortDownload();
+ this->OnDownloadStateChanged(ABORTED);
+}
+
+void MediaObject::WaitFinished()
+{
+ EnterCriticalSection(&this->stateLock);
+
+ while(this->state != COMPLETED && this->state != ABORTED){
+ SleepConditionVariableCS(&this->stateChanged, &this->stateLock, INFINITE);
+ }
+
+ LeaveCriticalSection(&this->stateLock);
+ if(this->state != ABORTED)
+ {
+ if(this->withFeedBack && this->dashReceiver)
+ {
+ this->dashReceiver->Notifybps(this->bps);
+ this->dashReceiver->NotifyDLTime(this->dnltime);
+ }
+ }
+}
+
+int MediaObject::Read(uint8_t *data, size_t len)
+{
+ return this->segment->Read(data, len);
+}
+
+int MediaObject::Peek(uint8_t *data, size_t len)
+{
+ return this->segment->Peek(data, len);
+}
+
+int MediaObject::Peek(uint8_t *data, size_t len, size_t offset)
+{
+ return this->segment->Peek(data, len, offset);
+}
+
+IRepresentation* MediaObject::GetRepresentation()
+{
+ return this->rep;
+}
+
+ISegment* MediaObject::GetSegment()
+{
+ return this->segment;
+}
+
+void MediaObject::OnDownloadTimeChanged(double dnltime)
+{
+ this->dnltime = dnltime;
+}
+
+void MediaObject::OnDownloadStateChanged(DownloadState state)
+{
+ EnterCriticalSection(&this->stateLock);
+
+ this->state = state;
+
+ WakeAllConditionVariable(&this->stateChanged);
+ LeaveCriticalSection(&this->stateLock);
+}
+
+void MediaObject::OnDownloadRateChanged(uint64_t bitsPerSecond)
+{
+ this->bps = bitsPerSecond;
+}
+
+void MediaObject::SetDASHReceiver(input::DASHReceiver *_dashReceiver)
+{
+ this->dashReceiver = _dashReceiver;
+}
+
+void MediaObject::SetAdaptationLogic(adaptation::IAdaptationLogic *_adaptationLogic)
+{
+ this->adaptationLogic = _adaptationLogic;
+}
+
+const std::vector<ITCPConnection *>& MediaObject::GetTCPConnectionList() const
+{
+ return this->segment->GetTCPConnectionList();
+}
+
+const std::vector<IHTTPTransaction *>& MediaObject::GetHTTPTransactionList () const
+{
+ return this->segment->GetHTTPTransactionList();
+}
diff --git a/Input/MediaObject.h b/Input/MediaObject.h
new file mode 100644
index 00000000..9d5c7826
--- /dev/null
+++ b/Input/MediaObject.h
@@ -0,0 +1,78 @@
+/*
+ * MediaObject.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_INPUT_MEDIAOBJECT_H_
+#define LIBDASH_FRAMEWORK_INPUT_MEDIAOBJECT_H_
+
+#include "../Adaptation/IAdaptationLogic.h"
+#include "IMPD.h"
+#include "IDownloadObserver.h"
+#include "IDASHMetrics.h"
+#include "../Portable/MultiThreading.h"
+#include "ICNConnectionConsumerApi.h"
+
+namespace libdash
+{
+namespace framework
+{
+namespace adaptation
+{
+class IAdaptationLogic;
+}
+namespace input
+{
+class DASHReceiver;
+class MediaObject : public dash::network::IDownloadObserver, public dash::metrics::IDASHMetrics
+{
+public:
+ MediaObject(dash::mpd::ISegment *segment, dash::mpd::IRepresentation *rep, bool withFeedBack = false);
+ virtual ~MediaObject();
+
+ bool StartDownload();
+ bool StartDownload(IICNConnection* conn);
+ void AbortDownload();
+ void WaitFinished();
+ int Read(uint8_t *data, size_t len);
+ int Peek(uint8_t *data, size_t len);
+ int Peek(uint8_t *data, size_t len, size_t offset);
+ dash::mpd::IRepresentation* GetRepresentation();
+ dash::mpd::ISegment* GetSegment();
+ const char* GetPath();
+ void SetFeedBack(bool flag);
+ virtual void OnDownloadStateChanged(dash::network::DownloadState state);
+ virtual void OnDownloadRateChanged(uint64_t bytesDownloaded); //Here the bytesDownloaded is in fact the bitrate bps
+ virtual void OnDownloadTimeChanged(double dnltime);
+
+ void AddInitSegment(MediaObject* initSeg);
+ int ReadInitSegment(uint8_t* data, size_t len);
+ const std::vector<dash::metrics::ITCPConnection *>& GetTCPConnectionList() const;
+ const std::vector<dash::metrics::IHTTPTransaction *>& GetHTTPTransactionList() const;
+ void SetAdaptationLogic(framework::adaptation::IAdaptationLogic *_adaptationLogic);
+ void SetDASHReceiver(input::DASHReceiver *_dashReceiver);
+
+private:
+ dash::mpd::ISegment *segment;
+ MediaObject *initSeg;
+ dash::mpd::IRepresentation *rep;
+ dash::network::DownloadState state;
+ uint64_t bps;
+ bool withFeedBack;
+ double dnltime;
+ input::DASHReceiver *dashReceiver;
+ adaptation::IAdaptationLogic *adaptationLogic;
+ mutable CRITICAL_SECTION stateLock;
+ mutable CONDITION_VARIABLE stateChanged;
+};
+}
+}
+}
+
+#endif /* LIBDASH_FRAMEWORK_INPUT_MEDIAOBJECT_H_ */