Commit 458adc37 authored by Francois Cartegnie's avatar Francois Cartegnie

demux: adaptative: handle alternative streams

parent 69361064
...@@ -51,31 +51,37 @@ PlaylistManager::PlaylistManager( AbstractPlaylist *pl, ...@@ -51,31 +51,37 @@ PlaylistManager::PlaylistManager( AbstractPlaylist *pl,
stream ( stream ), stream ( stream ),
nextPlaylistupdate ( 0 ) nextPlaylistupdate ( 0 )
{ {
currentPeriod = playlist->getFirstPeriod();
} }
PlaylistManager::~PlaylistManager () PlaylistManager::~PlaylistManager ()
{ {
delete conManager; delete conManager;
delete streamOutputFactory; delete streamOutputFactory;
unsetPeriod();
}
void PlaylistManager::unsetPeriod()
{
std::vector<Stream *>::iterator it; std::vector<Stream *>::iterator it;
for(it=streams.begin(); it!=streams.end(); ++it) for(it=streams.begin(); it!=streams.end(); ++it)
delete *it; delete *it;
streams.clear(); streams.clear();
} }
bool PlaylistManager::start(demux_t *demux) bool PlaylistManager::setupPeriod()
{ {
const BasePeriod *period = playlist->getFirstPeriod(); if(!currentPeriod)
if(!period)
return false; return false;
for(int i=0; i<StreamTypeCount; i++) std::vector<BaseAdaptationSet*> sets = currentPeriod->getAdaptationSets();
std::vector<BaseAdaptationSet*>::iterator it;
for(it=sets.begin();it!=sets.end();++it)
{ {
StreamType type = static_cast<StreamType>(i); BaseAdaptationSet *set = *it;
const BaseAdaptationSet *set = period->getAdaptationSet(type);
if(set) if(set)
{ {
Stream *st = new (std::nothrow) Stream(demux, type, set->getStreamFormat()); Stream *st = new (std::nothrow) Stream(p_demux, set->getStreamFormat());
if(!st) if(!st)
continue; continue;
AbstractAdaptationLogic *logic = createLogic(logicType); AbstractAdaptationLogic *logic = createLogic(logicType);
...@@ -85,7 +91,7 @@ bool PlaylistManager::start(demux_t *demux) ...@@ -85,7 +91,7 @@ bool PlaylistManager::start(demux_t *demux)
continue; continue;
} }
SegmentTracker *tracker = new (std::nothrow) SegmentTracker(logic, playlist); SegmentTracker *tracker = new (std::nothrow) SegmentTracker(logic, set);
try try
{ {
if(!tracker || !streamOutputFactory) if(!tracker || !streamOutputFactory)
...@@ -101,6 +107,15 @@ bool PlaylistManager::start(demux_t *demux) ...@@ -101,6 +107,15 @@ bool PlaylistManager::start(demux_t *demux)
} }
} }
} }
return true;
}
bool PlaylistManager::start(demux_t *demux_)
{
p_demux = demux_;
if(!setupPeriod())
return false;
conManager = new (std::nothrow) HTTPConnectionManager(VLC_OBJECT(stream)); conManager = new (std::nothrow) HTTPConnectionManager(VLC_OBJECT(stream));
if(!conManager) if(!conManager)
...@@ -119,7 +134,17 @@ Stream::status PlaylistManager::demux(mtime_t nzdeadline, bool send) ...@@ -119,7 +134,17 @@ Stream::status PlaylistManager::demux(mtime_t nzdeadline, bool send)
std::vector<Stream *>::iterator it; std::vector<Stream *>::iterator it;
for(it=streams.begin(); it!=streams.end(); ++it) for(it=streams.begin(); it!=streams.end(); ++it)
{ {
Stream::status i_ret = (*it)->demux(conManager, nzdeadline, send); Stream *st = *it;
if (st->isDisabled())
{
if(st->isSelected() && !st->isEOF())
st->reactivate(getPCR());
else
continue;
}
Stream::status i_ret = st->demux(conManager, nzdeadline, send);
if(i_ret == Stream::status_buffering) if(i_ret == Stream::status_buffering)
{ {
...@@ -141,6 +166,8 @@ mtime_t PlaylistManager::getPCR() const ...@@ -141,6 +166,8 @@ mtime_t PlaylistManager::getPCR() const
std::vector<Stream *>::const_iterator it; std::vector<Stream *>::const_iterator it;
for(it=streams.begin(); it!=streams.end(); ++it) for(it=streams.begin(); it!=streams.end(); ++it)
{ {
if ((*it)->isDisabled())
continue;
if(pcr == VLC_TS_INVALID || pcr > (*it)->getPCR()) if(pcr == VLC_TS_INVALID || pcr > (*it)->getPCR())
pcr = (*it)->getPCR(); pcr = (*it)->getPCR();
} }
...@@ -153,6 +180,8 @@ mtime_t PlaylistManager::getFirstDTS() const ...@@ -153,6 +180,8 @@ mtime_t PlaylistManager::getFirstDTS() const
std::vector<Stream *>::const_iterator it; std::vector<Stream *>::const_iterator it;
for(it=streams.begin(); it!=streams.end(); ++it) for(it=streams.begin(); it!=streams.end(); ++it)
{ {
if ((*it)->isDisabled())
continue;
if(dts == VLC_TS_INVALID || dts > (*it)->getFirstDTS()) if(dts == VLC_TS_INVALID || dts > (*it)->getFirstDTS())
dts = (*it)->getFirstDTS(); dts = (*it)->getFirstDTS();
} }
......
...@@ -31,6 +31,7 @@ namespace adaptative ...@@ -31,6 +31,7 @@ namespace adaptative
namespace playlist namespace playlist
{ {
class AbstractPlaylist; class AbstractPlaylist;
class BasePeriod;
} }
namespace http namespace http
...@@ -67,6 +68,8 @@ namespace adaptative ...@@ -67,6 +68,8 @@ namespace adaptative
virtual bool updatePlaylist(); virtual bool updatePlaylist();
protected: protected:
bool setupPeriod();
void unsetPeriod();
/* local factories */ /* local factories */
virtual AbstractAdaptationLogic *createLogic(AbstractAdaptationLogic::LogicType); virtual AbstractAdaptationLogic *createLogic(AbstractAdaptationLogic::LogicType);
...@@ -75,8 +78,10 @@ namespace adaptative ...@@ -75,8 +78,10 @@ namespace adaptative
AbstractPlaylist *playlist; AbstractPlaylist *playlist;
AbstractStreamOutputFactory *streamOutputFactory; AbstractStreamOutputFactory *streamOutputFactory;
stream_t *stream; stream_t *stream;
demux_t *p_demux;
std::vector<Stream *> streams; std::vector<Stream *> streams;
mtime_t nextPlaylistupdate; mtime_t nextPlaylistupdate;
BasePeriod *currentPeriod;
}; };
} }
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "SegmentTracker.hpp" #include "SegmentTracker.hpp"
#include "playlist/AbstractPlaylist.hpp" #include "playlist/AbstractPlaylist.hpp"
#include "playlist/BaseRepresentation.h" #include "playlist/BaseRepresentation.h"
#include "playlist/BaseAdaptationSet.h"
#include "playlist/Segment.h" #include "playlist/Segment.h"
#include "logic/AbstractAdaptationLogic.h" #include "logic/AbstractAdaptationLogic.h"
...@@ -27,15 +28,14 @@ using namespace adaptative; ...@@ -27,15 +28,14 @@ using namespace adaptative;
using namespace adaptative::logic; using namespace adaptative::logic;
using namespace adaptative::playlist; using namespace adaptative::playlist;
SegmentTracker::SegmentTracker(AbstractAdaptationLogic *logic_, AbstractPlaylist *playlist_) SegmentTracker::SegmentTracker(AbstractAdaptationLogic *logic_, BaseAdaptationSet *adaptSet)
{ {
count = 0; count = 0;
initializing = true; initializing = true;
indexed = false; indexed = false;
prevRepresentation = NULL; prevRepresentation = NULL;
setAdaptationLogic(logic_); setAdaptationLogic(logic_);
playlist = playlist_; adaptationSet = adaptSet;
currentPeriod = playlist->getFirstPeriod();
} }
SegmentTracker::~SegmentTracker() SegmentTracker::~SegmentTracker()
...@@ -54,19 +54,19 @@ void SegmentTracker::resetCounter() ...@@ -54,19 +54,19 @@ void SegmentTracker::resetCounter()
prevRepresentation = NULL; prevRepresentation = NULL;
} }
SegmentChunk * SegmentTracker::getNextChunk(StreamType type, bool switch_allowed) SegmentChunk * SegmentTracker::getNextChunk(bool switch_allowed)
{ {
BaseRepresentation *rep; BaseRepresentation *rep;
ISegment *segment; ISegment *segment;
if(!currentPeriod) if(!adaptationSet)
return NULL; return NULL;
if( !switch_allowed || if( !switch_allowed ||
(prevRepresentation && prevRepresentation->getSwitchPolicy() == SegmentInformation::SWITCH_UNAVAILABLE) ) (prevRepresentation && prevRepresentation->getSwitchPolicy() == SegmentInformation::SWITCH_UNAVAILABLE) )
rep = prevRepresentation; rep = prevRepresentation;
else else
rep = logic->getCurrentRepresentation(type, currentPeriod); rep = logic->getCurrentRepresentation(adaptationSet);
if ( rep == NULL ) if ( rep == NULL )
return NULL; return NULL;
...@@ -96,9 +96,8 @@ SegmentChunk * SegmentTracker::getNextChunk(StreamType type, bool switch_allowed ...@@ -96,9 +96,8 @@ SegmentChunk * SegmentTracker::getNextChunk(StreamType type, bool switch_allowed
segment = rep->getSegment(BaseRepresentation::INFOTYPE_MEDIA, count); segment = rep->getSegment(BaseRepresentation::INFOTYPE_MEDIA, count);
if(!segment) if(!segment)
{ {
currentPeriod = playlist->getNextPeriod(currentPeriod);
resetCounter(); resetCounter();
return getNextChunk(type, switch_allowed); return NULL;
} }
SegmentChunk *chunk = segment->toChunk(count, rep); SegmentChunk *chunk = segment->toChunk(count, rep);
...@@ -135,6 +134,7 @@ mtime_t SegmentTracker::getSegmentStart() const ...@@ -135,6 +134,7 @@ mtime_t SegmentTracker::getSegmentStart() const
void SegmentTracker::pruneFromCurrent() void SegmentTracker::pruneFromCurrent()
{ {
AbstractPlaylist *playlist = adaptationSet->getPlaylist();
if(playlist->isLive()) if(playlist->isLive())
playlist->pruneBySegmentNumber(count); playlist->pruneBySegmentNumber(count);
} }
...@@ -36,8 +36,7 @@ namespace adaptative ...@@ -36,8 +36,7 @@ namespace adaptative
namespace playlist namespace playlist
{ {
class AbstractPlaylist; class BaseAdaptationSet;
class BasePeriod;
class BaseRepresentation; class BaseRepresentation;
class SegmentChunk; class SegmentChunk;
} }
...@@ -48,12 +47,12 @@ namespace adaptative ...@@ -48,12 +47,12 @@ namespace adaptative
class SegmentTracker class SegmentTracker
{ {
public: public:
SegmentTracker(AbstractAdaptationLogic *, AbstractPlaylist *); SegmentTracker(AbstractAdaptationLogic *, BaseAdaptationSet *);
~SegmentTracker(); ~SegmentTracker();
void setAdaptationLogic(AbstractAdaptationLogic *); void setAdaptationLogic(AbstractAdaptationLogic *);
void resetCounter(); void resetCounter();
SegmentChunk* getNextChunk(StreamType, bool); SegmentChunk* getNextChunk(bool);
bool setPosition(mtime_t, bool, bool); bool setPosition(mtime_t, bool, bool);
mtime_t getSegmentStart() const; mtime_t getSegmentStart() const;
void pruneFromCurrent(); void pruneFromCurrent();
...@@ -63,8 +62,7 @@ namespace adaptative ...@@ -63,8 +62,7 @@ namespace adaptative
bool indexed; bool indexed;
uint64_t count; uint64_t count;
AbstractAdaptationLogic *logic; AbstractAdaptationLogic *logic;
AbstractPlaylist *playlist; BaseAdaptationSet *adaptationSet;
BasePeriod *currentPeriod;
BaseRepresentation *prevRepresentation; BaseRepresentation *prevRepresentation;
}; };
} }
......
...@@ -31,15 +31,16 @@ using namespace adaptative; ...@@ -31,15 +31,16 @@ using namespace adaptative;
using namespace adaptative::http; using namespace adaptative::http;
using namespace adaptative::logic; using namespace adaptative::logic;
Stream::Stream(demux_t * demux_,const StreamType type_, const StreamFormat &format_) Stream::Stream(demux_t * demux_, const StreamFormat &format_)
{ {
p_demux = demux_; p_demux = demux_;
type = type_; type = StreamType::UNKNOWN;
format = format_; format = format_;
output = NULL; output = NULL;
adaptationLogic = NULL; adaptationLogic = NULL;
currentChunk = NULL; currentChunk = NULL;
eof = false; eof = false;
disabled = false;
segmentTracker = NULL; segmentTracker = NULL;
streamOutputFactory = NULL; streamOutputFactory = NULL;
} }
...@@ -129,7 +130,12 @@ SegmentChunk * Stream::getChunk() ...@@ -129,7 +130,12 @@ SegmentChunk * Stream::getChunk()
{ {
if (currentChunk == NULL && output) if (currentChunk == NULL && output)
{ {
currentChunk = segmentTracker->getNextChunk(type, output->switchAllowed()); if(esCount() && !isSelected())
{
disabled = true;
return NULL;
}
currentChunk = segmentTracker->getNextChunk(output->switchAllowed());
if (currentChunk == NULL) if (currentChunk == NULL)
eof = true; eof = true;
} }
...@@ -146,6 +152,25 @@ bool Stream::isSelected() const ...@@ -146,6 +152,25 @@ bool Stream::isSelected() const
return output && output->isSelected(); return output && output->isSelected();
} }
bool Stream::reactivate(mtime_t basetime)
{
if(setPosition(basetime, false))
{
disabled = false;
return true;
}
else
{
eof = true; /* can't reactivate */
return false;
}
}
bool Stream::isDisabled() const
{
return disabled;
}
Stream::status Stream::demux(HTTPConnectionManager *connManager, mtime_t nz_deadline, bool send) Stream::status Stream::demux(HTTPConnectionManager *connManager, mtime_t nz_deadline, bool send)
{ {
if(!output) if(!output)
......
...@@ -61,7 +61,7 @@ namespace adaptative ...@@ -61,7 +61,7 @@ namespace adaptative
class Stream class Stream
{ {
public: public:
Stream(demux_t *, const StreamType, const StreamFormat &); Stream(demux_t *, const StreamFormat &);
~Stream(); ~Stream();
bool operator==(const Stream &) const; bool operator==(const Stream &) const;
static StreamType mimeToType(const std::string &mime); static StreamType mimeToType(const std::string &mime);
...@@ -75,6 +75,8 @@ namespace adaptative ...@@ -75,6 +75,8 @@ namespace adaptative
int esCount() const; int esCount() const;
bool seekAble() const; bool seekAble() const;
bool isSelected() const; bool isSelected() const;
bool reactivate(mtime_t);
bool isDisabled() const;
typedef enum {status_eof, status_buffering, status_demuxed} status; typedef enum {status_eof, status_buffering, status_demuxed} status;
status demux(HTTPConnectionManager *, mtime_t, bool); status demux(HTTPConnectionManager *, mtime_t, bool);
bool setPosition(mtime_t, bool); bool setPosition(mtime_t, bool);
...@@ -91,6 +93,7 @@ namespace adaptative ...@@ -91,6 +93,7 @@ namespace adaptative
AbstractAdaptationLogic *adaptationLogic; AbstractAdaptationLogic *adaptationLogic;
SegmentTracker *segmentTracker; SegmentTracker *segmentTracker;
SegmentChunk *currentChunk; SegmentChunk *currentChunk;
bool disabled;
bool eof; bool eof;
const AbstractStreamOutputFactory *streamOutputFactory; const AbstractStreamOutputFactory *streamOutputFactory;
......
...@@ -26,14 +26,13 @@ ...@@ -26,14 +26,13 @@
#define ABSTRACTADAPTATIONLOGIC_H_ #define ABSTRACTADAPTATIONLOGIC_H_
#include "IDownloadRateObserver.h" #include "IDownloadRateObserver.h"
#include "../StreamsType.hpp"
namespace adaptative namespace adaptative
{ {
namespace playlist namespace playlist
{ {
class BaseRepresentation; class BaseRepresentation;
class BasePeriod; class BaseAdaptationSet;
} }
namespace logic namespace logic
...@@ -46,7 +45,7 @@ namespace adaptative ...@@ -46,7 +45,7 @@ namespace adaptative
AbstractAdaptationLogic (); AbstractAdaptationLogic ();
virtual ~AbstractAdaptationLogic (); virtual ~AbstractAdaptationLogic ();
virtual BaseRepresentation* getCurrentRepresentation(StreamType, BasePeriod *) const = 0; virtual BaseRepresentation* getCurrentRepresentation(BaseAdaptationSet *) const = 0;
virtual void updateDownloadRate (size_t, mtime_t); virtual void updateDownloadRate (size_t, mtime_t);
enum LogicType enum LogicType
......
...@@ -36,8 +36,8 @@ AlwaysBestAdaptationLogic::AlwaysBestAdaptationLogic () : ...@@ -36,8 +36,8 @@ AlwaysBestAdaptationLogic::AlwaysBestAdaptationLogic () :
{ {
} }
BaseRepresentation *AlwaysBestAdaptationLogic::getCurrentRepresentation(adaptative::StreamType type, BasePeriod *period) const BaseRepresentation *AlwaysBestAdaptationLogic::getCurrentRepresentation(BaseAdaptationSet *adaptSet) const
{ {
RepresentationSelector selector; RepresentationSelector selector;
return selector.select(period, type); return selector.select(adaptSet);
} }
...@@ -36,7 +36,7 @@ namespace adaptative ...@@ -36,7 +36,7 @@ namespace adaptative
public: public:
AlwaysBestAdaptationLogic (); AlwaysBestAdaptationLogic ();
virtual BaseRepresentation *getCurrentRepresentation(StreamType, BasePeriod *) const; virtual BaseRepresentation *getCurrentRepresentation(BaseAdaptationSet *) const;
}; };
} }
} }
......
...@@ -28,8 +28,8 @@ AlwaysLowestAdaptationLogic::AlwaysLowestAdaptationLogic(): ...@@ -28,8 +28,8 @@ AlwaysLowestAdaptationLogic::AlwaysLowestAdaptationLogic():
{ {
} }
BaseRepresentation *AlwaysLowestAdaptationLogic::getCurrentRepresentation(adaptative::StreamType type, BasePeriod *period) const BaseRepresentation *AlwaysLowestAdaptationLogic::getCurrentRepresentation(BaseAdaptationSet *adaptSet) const
{ {
RepresentationSelector selector; RepresentationSelector selector;
return selector.select(period, type, 0); return selector.select(adaptSet, 0);
} }
...@@ -31,7 +31,7 @@ namespace adaptative ...@@ -31,7 +31,7 @@ namespace adaptative
public: public:
AlwaysLowestAdaptationLogic(); AlwaysLowestAdaptationLogic();
virtual BaseRepresentation* getCurrentRepresentation(StreamType, BasePeriod *) const; virtual BaseRepresentation* getCurrentRepresentation(BaseAdaptationSet *) const;
}; };
} }
} }
......
...@@ -47,16 +47,16 @@ RateBasedAdaptationLogic::RateBasedAdaptationLogic (int w, int h) : ...@@ -47,16 +47,16 @@ RateBasedAdaptationLogic::RateBasedAdaptationLogic (int w, int h) :
stabilizer = 16; stabilizer = 16;
} }
BaseRepresentation *RateBasedAdaptationLogic::getCurrentRepresentation(adaptative::StreamType type, BasePeriod *period) const BaseRepresentation *RateBasedAdaptationLogic::getCurrentRepresentation(BaseAdaptationSet *adaptSet) const
{ {
if(period == NULL) if(adaptSet == NULL)
return NULL; return NULL;
RepresentationSelector selector; RepresentationSelector selector;
BaseRepresentation *rep = selector.select(period, type, currentBps, width, height); BaseRepresentation *rep = selector.select(adaptSet, currentBps, width, height);
if ( rep == NULL ) if ( rep == NULL )
{ {
rep = selector.select(period, type); rep = selector.select(adaptSet);
if ( rep == NULL ) if ( rep == NULL )
return NULL; return NULL;
} }
...@@ -98,16 +98,16 @@ FixedRateAdaptationLogic::FixedRateAdaptationLogic(size_t bps) : ...@@ -98,16 +98,16 @@ FixedRateAdaptationLogic::FixedRateAdaptationLogic(size_t bps) :
currentBps = bps; currentBps = bps;
} }
BaseRepresentation *FixedRateAdaptationLogic::getCurrentRepresentation(adaptative::StreamType type, BasePeriod *period) const BaseRepresentation *FixedRateAdaptationLogic::getCurrentRepresentation(BaseAdaptationSet *adaptSet) const
{ {
if(period == NULL) if(adaptSet == NULL)
return NULL; return NULL;
RepresentationSelector selector; RepresentationSelector selector;
BaseRepresentation *rep = selector.select(period, type, currentBps); BaseRepresentation *rep = selector.select(adaptSet, currentBps);
if ( rep == NULL ) if ( rep == NULL )
{ {
rep = selector.select(period, type); rep = selector.select(adaptSet);
if ( rep == NULL ) if ( rep == NULL )
return NULL; return NULL;
} }
......
...@@ -39,7 +39,7 @@ namespace adaptative ...@@ -39,7 +39,7 @@ namespace adaptative
public: public:
RateBasedAdaptationLogic (int, int); RateBasedAdaptationLogic (int, int);
BaseRepresentation *getCurrentRepresentation(StreamType, BasePeriod *) const; BaseRepresentation *getCurrentRepresentation(BaseAdaptationSet *) const;
virtual void updateDownloadRate(size_t, mtime_t); virtual void updateDownloadRate(size_t, mtime_t);
private: private:
...@@ -57,7 +57,7 @@ namespace adaptative ...@@ -57,7 +57,7 @@ namespace adaptative
public: public:
FixedRateAdaptationLogic(size_t); FixedRateAdaptationLogic(size_t);
BaseRepresentation *getCurrentRepresentation(StreamType, BasePeriod *) const; BaseRepresentation *getCurrentRepresentation(BaseAdaptationSet *) const;
private: private:
size_t currentBps; size_t currentBps;
......
...@@ -29,57 +29,47 @@ RepresentationSelector::RepresentationSelector() ...@@ -29,57 +29,47 @@ RepresentationSelector::RepresentationSelector()
{ {
} }
BaseRepresentation * RepresentationSelector::select(BasePeriod *period, adaptative::StreamType type) const BaseRepresentation * RepresentationSelector::select(BaseAdaptationSet *adaptSet) const
{ {
return select(period, type, std::numeric_limits<uint64_t>::max()); return select(adaptSet, std::numeric_limits<uint64_t>::max());
} }
BaseRepresentation * RepresentationSelector::select(BasePeriod *period, adaptative::StreamType type, uint64_t bitrate) const BaseRepresentation * RepresentationSelector::select(BaseAdaptationSet *adaptSet, uint64_t bitrate) const
{ {
if (period == NULL) if (adaptSet == NULL)
return NULL; return NULL;
std::vector<BaseAdaptationSet *> adaptSets = period->getAdaptationSets(type);
BaseRepresentation *best = NULL; BaseRepresentation *best = NULL;
std::vector<BaseRepresentation *> reps = adaptSet->getRepresentations();
std::vector<BaseAdaptationSet *>::const_iterator adaptIt; BaseRepresentation *candidate = select(reps, (best)?best->getBandwidth():0, bitrate);
for(adaptIt=adaptSets.begin(); adaptIt!=adaptSets.end(); ++adaptIt) if (candidate)
{ {
std::vector<BaseRepresentation *> reps = (*adaptIt)->getRepresentations(); if (candidate->getBandwidth() > bitrate) /* none matched, returned lowest */
BaseRepresentation *candidate = select(reps, (best)?best->getBandwidth():0, bitrate); return candidate;
if (candidate) best = candidate;
{
if (candidate->getBandwidth() > bitrate) /* none matched, returned lowest */
return candidate;
best = candidate;
}
} }
return best; return best;
} }
BaseRepresentation * RepresentationSelector::select(BasePeriod *period, adaptative::StreamType type, uint64_t bitrate, BaseRepresentation * RepresentationSelector::select(BaseAdaptationSet *adaptSet, uint64_t bitrate,
int width, int height) const int width, int height) const
{ {
if(period == NULL) if(adaptSet == NULL)
return NULL; return NULL;
std::vector<BaseRepresentation *> resMatchReps; std::vector<BaseRepresentation *> resMatchReps;
/* subset matching WxH */ /* subset matching WxH */
std::vector<BaseAdaptationSet *> adaptSets = period->getAdaptationSets(type); std::vector<BaseRepresentation *> reps = adaptSet->getRepresentations();
std::vector<BaseAdaptationSet *>::const_iterator adaptIt; std::vector<BaseRepresentation *>::const_iterator repIt;
for(adaptIt=adaptSets.begin(); adaptIt!=adaptSets.end(); ++adaptIt) for(repIt=reps.begin(); repIt!=reps.end(); ++repIt)
{ {
std::vector<BaseRepresentation *> reps = (*adaptIt)->getRepresentations(); if((*repIt)->getWidth() == width && (*repIt)->getHeight() == height)
std::vector<BaseRepresentation *>::const_iterator repIt; resMatchReps.push_back(*repIt);
for(repIt=reps.begin(); repIt!=reps.end(); ++repIt)
{
if((*repIt)->getWidth() == width && (*repIt)->getHeight() == height)
resMatchReps.push_back(*repIt);
}
} }
if(resMatchReps.empty()) if(resMatchReps.empty())
return select(period, type, bitrate); return select(adaptSet, bitrate);
else else
return select(resMatchReps, 0, bitrate); return select(resMatchReps, 0, bitrate);
} }
......
...@@ -20,15 +20,15 @@ ...@@ -20,15 +20,15 @@
#ifndef REPRESENTATIONSELECTORS_HPP #ifndef REPRESENTATIONSELECTORS_HPP
#define REPRESENTATIONSELECTORS_HPP #define REPRESENTATIONSELECTORS_HPP
#include "../Streams.hpp"
#include <vector> #include <vector>
#include <vlc_common.h>
namespace adaptative namespace adaptative
{ {
namespace playlist namespace playlist
{ {
class BaseRepresentation; class BaseRepresentation;
class BasePeriod; class BaseAdaptationSet;
} }
namespace logic namespace logic
...@@ -40,9 +40,9 @@ namespace adaptative ...@@ -40,9 +40,9 @@ namespace adaptative
public: public:
RepresentationSelector(); RepresentationSelector();
virtual ~RepresentationSelector() {} virtual ~RepresentationSelector() {}
virtual BaseRepresentation * select(BasePeriod *period, StreamType) const; virtual BaseRepresentation * select(BaseAdaptationSet *) const;
virtual BaseRepresentation * select(BasePeriod *period, StreamType, uint64_t bitrate) const; virtual BaseRepresentation * select(BaseAdaptationSet *, uint64_t bitrate) const;
virtual BaseRepresentation * select(BasePeriod *period, StreamType, uint64_t bitrate, virtual BaseRepresentation * select(BaseAdaptationSet *, uint64_t bitrate,
int width, int height) const; int width, int height) const;
protected: protected:
virtual BaseRepresentation * select(std::vector<BaseRepresentation *>&reps, virtual BaseRepresentation * select(std::vector<BaseRepresentation *>&reps,
......
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