Commit 6dd2798f authored by Francois Cartegnie's avatar Francois Cartegnie

stream_filter: dash: split all logic and queues by stream type

parent dbcef6f7
......@@ -99,7 +99,10 @@ libdash_plugin_la_SOURCES = \
stream_filter/dash/DASHManager.cpp \
stream_filter/dash/DASHManager.h \
stream_filter/dash/Helper.cpp \
stream_filter/dash/Helper.h
stream_filter/dash/Helper.h \
stream_filter/dash/StreamsType.hpp \
stream_filter/dash/Streams.cpp \
stream_filter/dash/Streams.hpp
libdash_plugin_la_SOURCES += demux/mp4/libmp4.c demux/mp4/libmp4.h
......
......@@ -63,7 +63,7 @@ void* DASHDownloader::download (void *thread_sys)
do
{
block_t *block = NULL;
ret = conManager->read(&block);
ret = conManager->read(Streams::VIDEO, &block);
if(ret > 0)
buffer->put(block);
}while(ret > 0 && !buffer->getEOF());
......
......@@ -99,7 +99,7 @@ mtime_t DASHManager::getDuration() const
}
else
{
const Representation *rep = adaptationLogic->getCurrentRepresentation();
const Representation *rep = adaptationLogic->getCurrentRepresentation(Streams::VIDEO);
if ( !rep )
return 0;
else
......
/*
* Streams.cpp
*****************************************************************************
* Copyright (C) 2014 - VideoLAN authors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "Streams.hpp"
using namespace dash::Streams;
Stream::Stream(const std::string &mime)
{
type = mimeToType(mime);
}
Stream::Stream(const Type type)
{
this->type = type;
}
Type Stream::mimeToType(const std::string &mime)
{
Type mimetype;
if (mime == "video/mp4")
mimetype = Streams::VIDEO;
else if (mime == "audio/mp4")
mimetype = Streams::AUDIO;
else if (mime == "application/mp4")
mimetype = Streams::APPLICATION;
else /* unknown of unsupported */
mimetype = Streams::UNKNOWN;
return mimetype;
}
bool Stream::operator ==(const Stream &stream) const
{
return stream.type == type;
}
/*
* Streams.hpp
*****************************************************************************
* Copyright (C) 2014 - VideoLAN authors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef STREAM_HPP
#define STREAM_HPP
class Stream
#include <string>
#include "StreamsType.hpp"
namespace dash
{
public:
Stream();
};
namespace Streams
{
class AbstractStreamOutput;
class Stream
{
public:
Stream(const std::string &mime);
Stream(const Type);
bool operator==(const Stream &) const;
static Type mimeToType(const std::string &mime);
private:
Type type;
};
#endif // STREAM_HPP
}
}
#endif // STREAMS_HPP
/*
* StreamsType.hpp
*****************************************************************************
* Copyright (C) 2014 - VideoLAN authors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef STREAMSTYPE_HPP
#define STREAMSTYPE_HPP
namespace dash
{
namespace Streams
{
enum Type
{
UNKNOWN = 0,
VIDEO,
AUDIO,
APPLICATION
};
static const int count = APPLICATION + 1;
}
}
#endif
......@@ -35,29 +35,30 @@ using namespace dash::mpd;
AlwaysBestAdaptationLogic::AlwaysBestAdaptationLogic (MPDManager *mpdManager) :
AbstractAdaptationLogic (mpdManager)
{
this->count = 0;
this->initSchedule();
initSchedule();
}
AlwaysBestAdaptationLogic::~AlwaysBestAdaptationLogic ()
{
}
Chunk* AlwaysBestAdaptationLogic::getNextChunk()
Chunk* AlwaysBestAdaptationLogic::getNextChunk(Streams::Type type)
{
if ( this->count < this->schedule.size() )
if ( streams[type].count < streams[type].schedule.size() )
{
Chunk *chunk = new Chunk();
chunk->setUrl(this->schedule.at( this->count )->getUrlSegment());
this->count++;
chunk->setUrl(streams[type].schedule.at( streams[type].count )->getUrlSegment());
streams[type].count++;
return chunk;
}
return NULL;
}
const Representation *AlwaysBestAdaptationLogic::getCurrentRepresentation() const
const Representation *AlwaysBestAdaptationLogic::getCurrentRepresentation(Streams::Type type) const
{
if ( this->count < this->schedule.size() )
return this->schedule.at( this->count )->getRepresentation();
if ( streams[type].count < streams[type].schedule.size() )
return streams[type].schedule.at( streams[type].count )->getRepresentation();
return NULL;
}
......@@ -66,19 +67,22 @@ void AlwaysBestAdaptationLogic::initSchedule ()
if(mpdManager)
{
std::vector<Period *> periods = mpdManager->getPeriods();
std::vector<Period *>::const_iterator it;
if (periods.empty())
return;
RepresentationSelector selector;
for(it=periods.begin(); it!=periods.end(); it++)
for(int type=0; type<Streams::count; type++)
{
Representation *best = selector.select(*it);
streams[type].count = 0;
Representation *best = selector.select(periods.front(),
static_cast<Streams::Type>(type));
if(best)
{
std::vector<ISegment *> segments = best->getSegments();
std::vector<ISegment *>::const_iterator segIt;
for(segIt=segments.begin(); segIt!=segments.end(); segIt++)
{
schedule.push_back(*segIt);
streams[type].schedule.push_back(*segIt);
}
}
}
......
......@@ -32,6 +32,7 @@
#include "mpd/MPDManager.hpp"
#include "mpd/Period.h"
#include "mpd/Segment.h"
#include "Streams.hpp"
#include <vector>
namespace dash
......@@ -44,15 +45,17 @@ namespace dash
AlwaysBestAdaptationLogic (dash::mpd::MPDManager *mpdManager);
virtual ~AlwaysBestAdaptationLogic ();
dash::http::Chunk* getNextChunk();
const mpd::Representation *getCurrentRepresentation() const;
virtual dash::http::Chunk* getNextChunk(Streams::Type);
const mpd::Representation *getCurrentRepresentation(Streams::Type) const;
private:
struct
{
std::vector<mpd::ISegment *> schedule;
size_t count;
dash::mpd::Representation *bestRepresentation;
void initSchedule();
mpd::Representation *bestRepresentation;
} streams[Streams::count];
void initSchedule ();
};
}
}
......
......@@ -31,12 +31,12 @@ AlwaysLowestAdaptationLogic::AlwaysLowestAdaptationLogic(dash::mpd::MPDManager *
{
}
Chunk* AlwaysLowestAdaptationLogic::getNextChunk()
Chunk* AlwaysLowestAdaptationLogic::getNextChunk(Streams::Type type)
{
if(!currentPeriod)
return NULL;
const Representation *rep = getCurrentRepresentation();
const Representation *rep = getCurrentRepresentation(type);
if ( rep == NULL )
return NULL;
......@@ -45,7 +45,7 @@ Chunk* AlwaysLowestAdaptationLogic::getNextChunk()
{
currentPeriod = mpdManager->getNextPeriod(currentPeriod);
count = 0;
return getNextChunk();
return getNextChunk(type);
}
if ( segments.size() > count )
......@@ -61,8 +61,8 @@ Chunk* AlwaysLowestAdaptationLogic::getNextChunk()
return NULL;
}
const Representation *AlwaysLowestAdaptationLogic::getCurrentRepresentation() const
const Representation *AlwaysLowestAdaptationLogic::getCurrentRepresentation(Streams::Type type) const
{
RepresentationSelector selector;
return selector.select(currentPeriod, 0);
return selector.select(currentPeriod, type, 0);
}
......@@ -31,8 +31,8 @@ namespace dash
public:
AlwaysLowestAdaptationLogic(dash::mpd::MPDManager *mpdManager);
virtual dash::http::Chunk* getNextChunk ();
virtual const dash::mpd::Representation* getCurrentRepresentation() const;
virtual dash::http::Chunk* getNextChunk (Streams::Type);
virtual const dash::mpd::Representation* getCurrentRepresentation(Streams::Type) const;
private:
dash::mpd::Period *currentPeriod;
......
......@@ -29,6 +29,7 @@
#include <adaptationlogic/IDownloadRateObserver.h>
#include "mpd/Representation.h"
#include "buffer/IBufferObserver.h"
#include "Streams.hpp"
namespace dash
{
......@@ -46,8 +47,8 @@ namespace dash
RateBased
};
virtual dash::http::Chunk* getNextChunk () = 0;
virtual const dash::mpd::Representation* getCurrentRepresentation() const = 0;
virtual dash::http::Chunk* getNextChunk (Streams::Type) = 0;
virtual const dash::mpd::Representation* getCurrentRepresentation(Streams::Type) const = 0;
/**
* \return The average bitrate in bits per second.
*/
......
......@@ -45,12 +45,12 @@ RateBasedAdaptationLogic::RateBasedAdaptationLogic (MPDManager *mpdManager) :
height = var_InheritInteger(mpdManager->getMPD()->getVLCObject(), "dash-prefheight");
}
Chunk* RateBasedAdaptationLogic::getNextChunk()
Chunk* RateBasedAdaptationLogic::getNextChunk(Streams::Type type)
{
if(this->currentPeriod == NULL)
return NULL;
const Representation *rep = getCurrentRepresentation();
const Representation *rep = getCurrentRepresentation(type);
if (!rep)
return NULL;
......@@ -60,7 +60,7 @@ Chunk* RateBasedAdaptationLogic::getNextChunk()
{
this->currentPeriod = this->mpdManager->getNextPeriod(this->currentPeriod);
this->count = 0;
return this->getNextChunk();
return getNextChunk(type);
}
if ( segments.size() > this->count )
......@@ -76,7 +76,7 @@ Chunk* RateBasedAdaptationLogic::getNextChunk()
return NULL;
}
const Representation *RateBasedAdaptationLogic::getCurrentRepresentation() const
const Representation *RateBasedAdaptationLogic::getCurrentRepresentation(Streams::Type type) const
{
if(currentPeriod == NULL)
return NULL;
......@@ -86,10 +86,10 @@ const Representation *RateBasedAdaptationLogic::getCurrentRepresentation() const
bitrate = 0;
RepresentationSelector selector;
Representation *rep = selector.select(currentPeriod, bitrate, width, height);
Representation *rep = selector.select(currentPeriod, type, bitrate, width, height);
if ( rep == NULL )
{
rep = selector.select(currentPeriod);
rep = selector.select(currentPeriod, type);
if ( rep == NULL )
return NULL;
}
......
......@@ -41,8 +41,8 @@ namespace dash
public:
RateBasedAdaptationLogic (dash::mpd::MPDManager *mpdManager);
dash::http::Chunk* getNextChunk();
const dash::mpd::Representation *getCurrentRepresentation() const;
virtual dash::http::Chunk* getNextChunk(Streams::Type);
const dash::mpd::Representation *getCurrentRepresentation(Streams::Type) const;
private:
size_t count;
......
......@@ -26,18 +26,16 @@ RepresentationSelector::RepresentationSelector()
{
}
Representation * RepresentationSelector::select(Period *period) const
Representation * RepresentationSelector::select(Period *period, Streams::Type type) const
{
return select(period, std::numeric_limits<uint64_t>::max());
return select(period, type, std::numeric_limits<uint64_t>::max());
}
Representation * RepresentationSelector::select(Period *period, uint64_t bitrate) const
Representation * RepresentationSelector::select(Period *period, Streams::Type type, uint64_t bitrate) const
{
if (period == NULL)
return NULL;
std::vector<AdaptationSet *> adaptSets = period->getAdaptationSets();
std::vector<AdaptationSet *> adaptSets = period->getAdaptationSets(type);
Representation *best = NULL;
std::vector<AdaptationSet *>::const_iterator adaptIt;
......@@ -55,7 +53,7 @@ Representation * RepresentationSelector::select(Period *period, uint64_t bitrate
return best;
}
Representation * RepresentationSelector::select(Period *period, uint64_t bitrate,
Representation * RepresentationSelector::select(Period *period, Streams::Type type, uint64_t bitrate,
int width, int height) const
{
if(period == NULL)
......@@ -64,7 +62,7 @@ Representation * RepresentationSelector::select(Period *period, uint64_t bitrate
std::vector<Representation *> resMatchReps;
/* subset matching WxH */
std::vector<AdaptationSet *> adaptSets = period->getAdaptationSets();
std::vector<AdaptationSet *> adaptSets = period->getAdaptationSets(type);
std::vector<AdaptationSet *>::const_iterator adaptIt;
for(adaptIt=adaptSets.begin(); adaptIt!=adaptSets.end(); adaptIt++)
{
......@@ -78,7 +76,7 @@ Representation * RepresentationSelector::select(Period *period, uint64_t bitrate
}
if(resMatchReps.empty())
return select(period, bitrate);
return select(period, type, bitrate);
else
return select(resMatchReps, 0, bitrate);
}
......
......@@ -34,9 +34,9 @@ namespace dash
public:
RepresentationSelector();
virtual ~RepresentationSelector() {}
virtual Representation * select(Period *period) const;
virtual Representation * select(Period *period, uint64_t bitrate) const;
virtual Representation * select(Period *period, uint64_t bitrate,
virtual Representation * select(Period *period, Streams::Type) const;
virtual Representation * select(Period *period, Streams::Type, uint64_t bitrate) const;
virtual Representation * select(Period *period, Streams::Type, uint64_t bitrate,
int width, int height) const;
protected:
virtual Representation * select(std::vector<Representation *>&reps,
......
......@@ -38,6 +38,7 @@ using namespace dash::logic;
const uint64_t HTTPConnectionManager::CHUNKDEFAULTBITRATE = 1;
HTTPConnectionManager::HTTPConnectionManager (IAdaptationLogic *adaptationLogic, stream_t *stream) :
currentChunk (NULL),
adaptationLogic (adaptationLogic),
stream (stream),
chunkCount (0),
......@@ -58,23 +59,25 @@ HTTPConnectionManager::~HTTPConnectionManager ()
void HTTPConnectionManager::closeAllConnections ()
{
vlc_delete_all(this->connectionPool);
vlc_delete_all(this->downloadQueue);
for(int i=0; i<Streams::count; i++)
vlc_delete_all(downloadQueue[i]);
delete currentChunk;
}
ssize_t HTTPConnectionManager::read(block_t **pp_block)
ssize_t HTTPConnectionManager::read(Streams::Type type, block_t **pp_block)
{
Chunk *chunk;
if(downloadQueue.empty())
if(downloadQueue[type].empty())
{
chunk = adaptationLogic->getNextChunk();
chunk = adaptationLogic->getNextChunk(type);
if(!connectChunk(chunk))
return -1;
else
downloadQueue.push_back(chunk);
downloadQueue[type].push_back(chunk);
}
chunk = downloadQueue.front();
chunk = downloadQueue[type].front();
if(chunk->getBytesRead() == 0)
{
......@@ -106,9 +109,9 @@ ssize_t HTTPConnectionManager::read(block_t **pp_block)
this->timeChunk = 0;
delete(chunk);
downloadQueue.pop_front();
downloadQueue[type].pop_front();
return read(pp_block);
return read(type, pp_block);
}
else
{
......@@ -118,7 +121,7 @@ ssize_t HTTPConnectionManager::read(block_t **pp_block)
{
chunk->onDownload(block->p_buffer, block->i_buffer);
delete chunk;
downloadQueue.pop_front();
downloadQueue[type].pop_front();
}
}
......
......@@ -36,6 +36,7 @@
#include "http/PersistentConnection.h"
#include "adaptationlogic/IAdaptationLogic.h"
#include "Streams.hpp"
namespace dash
{
......@@ -48,13 +49,14 @@ namespace dash
virtual ~HTTPConnectionManager ();
void closeAllConnections ();
ssize_t read (block_t **);
ssize_t read (Streams::Type, block_t **);
void attach (dash::logic::IDownloadRateObserver *observer);
void notify ();
private:
std::vector<dash::logic::IDownloadRateObserver *> rateObservers;
std::deque<Chunk *> downloadQueue;
std::deque<Chunk *> downloadQueue[Streams::count];
Chunk *currentChunk;
std::vector<PersistentConnection *> connectionPool;
logic::IAdaptationLogic *adaptationLogic;
stream_t *stream;
......
......@@ -47,8 +47,31 @@ const std::vector<AdaptationSet*>& Period::getAdaptationSets() const
return this->adaptationSets;
}
const std::vector<AdaptationSet*> Period::getAdaptationSets(Streams::Type type) const
{
std::vector<AdaptationSet*> list;
std::vector<AdaptationSet*>::const_iterator it;
for(it = adaptationSets.begin(); it!= adaptationSets.end(); it++)
{
if( Streams::Stream::mimeToType((*it)->getMimeType()) == type )
list.push_back(*it);
}
return list;
}
void Period::addAdaptationSet(AdaptationSet *adaptationSet)
{
if ( adaptationSet != NULL )
this->adaptationSets.push_back(adaptationSet);
}
AdaptationSet * Period::getAdaptationSet(Streams::Type type) const
{
std::vector<AdaptationSet *>::const_iterator it;
for(it = adaptationSets.begin(); it != adaptationSets.end(); it++)
{
if ( Streams::Stream::mimeToType((*it)->getMimeType()) == type )
return *it;
}
return NULL;
}
......@@ -28,6 +28,7 @@
#include <string>
#include "mpd/AdaptationSet.h"
#include "Streams.hpp"
namespace dash
{
......@@ -40,6 +41,8 @@ namespace dash
virtual ~Period ();
const std::vector<AdaptationSet *>& getAdaptationSets () const;
const std::vector<AdaptationSet *> getAdaptationSets (Streams::Type) const;
AdaptationSet * getAdaptationSet (Streams::Type) const;
void addAdaptationSet (AdaptationSet *AdaptationSet);
private:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment