Commit 5ba9e880 authored by François Cartegnie's avatar François Cartegnie 🤞

demux: adaptive: replace width/height options with maxwidth/height

allows filtering out problematic resolution for a device
parent 79594cfe
...@@ -722,37 +722,49 @@ void PlaylistManager::updateControlsContentType() ...@@ -722,37 +722,49 @@ void PlaylistManager::updateControlsContentType()
AbstractAdaptationLogic *PlaylistManager::createLogic(AbstractAdaptationLogic::LogicType type, AbstractConnectionManager *conn) AbstractAdaptationLogic *PlaylistManager::createLogic(AbstractAdaptationLogic::LogicType type, AbstractConnectionManager *conn)
{ {
AbstractAdaptationLogic *logic = NULL;
switch(type) switch(type)
{ {
case AbstractAdaptationLogic::FixedRate: case AbstractAdaptationLogic::FixedRate:
{ {
size_t bps = var_InheritInteger(p_demux, "adaptive-bw") * 8192; size_t bps = var_InheritInteger(p_demux, "adaptive-bw") * 8192;
return new (std::nothrow) FixedRateAdaptationLogic(bps); logic = new (std::nothrow) FixedRateAdaptationLogic(bps);
break;
} }
case AbstractAdaptationLogic::AlwaysLowest: case AbstractAdaptationLogic::AlwaysLowest:
return new (std::nothrow) AlwaysLowestAdaptationLogic(); logic = new (std::nothrow) AlwaysLowestAdaptationLogic();
break;
case AbstractAdaptationLogic::AlwaysBest: case AbstractAdaptationLogic::AlwaysBest:
return new (std::nothrow) AlwaysBestAdaptationLogic(); logic = new (std::nothrow) AlwaysBestAdaptationLogic();
break;
case AbstractAdaptationLogic::RateBased: case AbstractAdaptationLogic::RateBased:
{ {
int width = var_InheritInteger(p_demux, "adaptive-width"); RateBasedAdaptationLogic *ratelogic =
int height = var_InheritInteger(p_demux, "adaptive-height"); new (std::nothrow) RateBasedAdaptationLogic(VLC_OBJECT(p_demux));
RateBasedAdaptationLogic *logic = if(ratelogic)
new (std::nothrow) RateBasedAdaptationLogic(VLC_OBJECT(p_demux), width, height); conn->setDownloadRateObserver(ratelogic);
if(logic) logic = ratelogic;
conn->setDownloadRateObserver(logic); break;
return logic;
} }
case AbstractAdaptationLogic::Default: case AbstractAdaptationLogic::Default:
case AbstractAdaptationLogic::Predictive: case AbstractAdaptationLogic::Predictive:
{ {
AbstractAdaptationLogic *logic = new (std::nothrow) PredictiveAdaptationLogic(VLC_OBJECT(p_demux)); AbstractAdaptationLogic *predictivelogic =
if(logic) new (std::nothrow) PredictiveAdaptationLogic(VLC_OBJECT(p_demux));
conn->setDownloadRateObserver(logic); if(predictivelogic)
return logic; conn->setDownloadRateObserver(predictivelogic);
logic = predictivelogic;
} }
default: default:
return NULL; break;
} }
if(logic)
{
logic->setMaxDeviceResolution( var_InheritInteger(p_demux, "adaptive-maxwidth"),
var_InheritInteger(p_demux, "adaptive-maxheight") );
}
return logic;
} }
...@@ -47,6 +47,8 @@ ...@@ -47,6 +47,8 @@
#include "../smooth/SmoothStream.hpp" #include "../smooth/SmoothStream.hpp"
#include "../smooth/playlist/Parser.hpp" #include "../smooth/playlist/Parser.hpp"
#include <limits>
using namespace adaptive::logic; using namespace adaptive::logic;
using namespace adaptive::playlist; using namespace adaptive::playlist;
using namespace adaptive::xml; using namespace adaptive::xml;
...@@ -63,9 +65,8 @@ using namespace smooth::playlist; ...@@ -63,9 +65,8 @@ using namespace smooth::playlist;
static int Open (vlc_object_t *); static int Open (vlc_object_t *);
static void Close (vlc_object_t *); static void Close (vlc_object_t *);
#define ADAPT_WIDTH_TEXT N_("Preferred Width") #define ADAPT_WIDTH_TEXT N_("Maximum device width")
#define ADAPT_HEIGHT_TEXT N_("Maximum device height")
#define ADAPT_HEIGHT_TEXT N_("Preferred Height")
#define ADAPT_BW_TEXT N_("Fixed Bandwidth in KiB/s") #define ADAPT_BW_TEXT N_("Fixed Bandwidth in KiB/s")
#define ADAPT_BW_LONGTEXT N_("Preferred bandwidth for non adaptive streams") #define ADAPT_BW_LONGTEXT N_("Preferred bandwidth for non adaptive streams")
...@@ -112,8 +113,10 @@ vlc_module_begin () ...@@ -112,8 +113,10 @@ vlc_module_begin ()
set_subcategory( SUBCAT_INPUT_DEMUX ) set_subcategory( SUBCAT_INPUT_DEMUX )
add_string( "adaptive-logic", "", ADAPT_LOGIC_TEXT, NULL, false ) add_string( "adaptive-logic", "", ADAPT_LOGIC_TEXT, NULL, false )
change_string_list( ppsz_logics_values, ppsz_logics ) change_string_list( ppsz_logics_values, ppsz_logics )
add_integer( "adaptive-width", 0, ADAPT_WIDTH_TEXT, ADAPT_WIDTH_TEXT, true ) add_integer( "adaptive-maxwidth", std::numeric_limits<int>::max(),
add_integer( "adaptive-height", 0, ADAPT_HEIGHT_TEXT, ADAPT_HEIGHT_TEXT, true ) ADAPT_WIDTH_TEXT, ADAPT_WIDTH_TEXT, false )
add_integer( "adaptive-maxheight", std::numeric_limits<int>::max(),
ADAPT_HEIGHT_TEXT, ADAPT_HEIGHT_TEXT, false )
add_integer( "adaptive-bw", 250, ADAPT_BW_TEXT, ADAPT_BW_LONGTEXT, false ) add_integer( "adaptive-bw", 250, ADAPT_BW_TEXT, ADAPT_BW_LONGTEXT, false )
add_bool ( "adaptive-use-access", false, ADAPT_ACCESS_TEXT, ADAPT_ACCESS_LONGTEXT, true ); add_bool ( "adaptive-use-access", false, ADAPT_ACCESS_TEXT, ADAPT_ACCESS_LONGTEXT, true );
set_callbacks( Open, Close ) set_callbacks( Open, Close )
......
...@@ -27,10 +27,14 @@ ...@@ -27,10 +27,14 @@
#include "AbstractAdaptationLogic.h" #include "AbstractAdaptationLogic.h"
#include <limits>
using namespace adaptive::logic; using namespace adaptive::logic;
AbstractAdaptationLogic::AbstractAdaptationLogic () AbstractAdaptationLogic::AbstractAdaptationLogic ()
{ {
maxwidth = std::numeric_limits<int>::max();
maxheight = std::numeric_limits<int>::max();
} }
AbstractAdaptationLogic::~AbstractAdaptationLogic () AbstractAdaptationLogic::~AbstractAdaptationLogic ()
...@@ -40,3 +44,9 @@ AbstractAdaptationLogic::~AbstractAdaptationLogic () ...@@ -40,3 +44,9 @@ AbstractAdaptationLogic::~AbstractAdaptationLogic ()
void AbstractAdaptationLogic::updateDownloadRate (const adaptive::ID &, size_t, mtime_t) void AbstractAdaptationLogic::updateDownloadRate (const adaptive::ID &, size_t, mtime_t)
{ {
} }
void AbstractAdaptationLogic::setMaxDeviceResolution (int w, int h)
{
maxwidth = w;
maxheight = h;
}
...@@ -50,6 +50,7 @@ namespace adaptive ...@@ -50,6 +50,7 @@ namespace adaptive
virtual BaseRepresentation* getNextRepresentation(BaseAdaptationSet *, BaseRepresentation *) = 0; virtual BaseRepresentation* getNextRepresentation(BaseAdaptationSet *, BaseRepresentation *) = 0;
virtual void updateDownloadRate (const ID &, size_t, mtime_t); virtual void updateDownloadRate (const ID &, size_t, mtime_t);
virtual void trackerEvent (const SegmentTrackerEvent &) {} virtual void trackerEvent (const SegmentTrackerEvent &) {}
void setMaxDeviceResolution (int, int);
enum LogicType enum LogicType
{ {
...@@ -60,6 +61,10 @@ namespace adaptive ...@@ -60,6 +61,10 @@ namespace adaptive
FixedRate, FixedRate,
Predictive Predictive
}; };
protected:
int maxwidth;
int maxheight;
}; };
} }
} }
......
...@@ -38,6 +38,6 @@ AlwaysBestAdaptationLogic::AlwaysBestAdaptationLogic () : ...@@ -38,6 +38,6 @@ AlwaysBestAdaptationLogic::AlwaysBestAdaptationLogic () :
BaseRepresentation *AlwaysBestAdaptationLogic::getNextRepresentation(BaseAdaptationSet *adaptSet, BaseRepresentation *) BaseRepresentation *AlwaysBestAdaptationLogic::getNextRepresentation(BaseAdaptationSet *adaptSet, BaseRepresentation *)
{ {
RepresentationSelector selector; RepresentationSelector selector(maxwidth, maxheight);
return selector.highest(adaptSet); return selector.highest(adaptSet);
} }
...@@ -34,6 +34,6 @@ AlwaysLowestAdaptationLogic::AlwaysLowestAdaptationLogic(): ...@@ -34,6 +34,6 @@ AlwaysLowestAdaptationLogic::AlwaysLowestAdaptationLogic():
BaseRepresentation *AlwaysLowestAdaptationLogic::getNextRepresentation(BaseAdaptationSet *adaptSet, BaseRepresentation *) BaseRepresentation *AlwaysLowestAdaptationLogic::getNextRepresentation(BaseAdaptationSet *adaptSet, BaseRepresentation *)
{ {
RepresentationSelector selector; RepresentationSelector selector(maxwidth, maxheight);
return selector.lowest(adaptSet); return selector.lowest(adaptSet);
} }
...@@ -63,7 +63,7 @@ PredictiveAdaptationLogic::~PredictiveAdaptationLogic() ...@@ -63,7 +63,7 @@ PredictiveAdaptationLogic::~PredictiveAdaptationLogic()
BaseRepresentation *PredictiveAdaptationLogic::getNextRepresentation(BaseAdaptationSet *adaptSet, BaseRepresentation *prevRep) BaseRepresentation *PredictiveAdaptationLogic::getNextRepresentation(BaseAdaptationSet *adaptSet, BaseRepresentation *prevRep)
{ {
RepresentationSelector selector; RepresentationSelector selector(maxwidth, maxheight);
BaseRepresentation *rep; BaseRepresentation *rep;
vlc_mutex_lock(&lock); vlc_mutex_lock(&lock);
......
...@@ -36,13 +36,11 @@ ...@@ -36,13 +36,11 @@
using namespace adaptive::logic; using namespace adaptive::logic;
using namespace adaptive; using namespace adaptive;
RateBasedAdaptationLogic::RateBasedAdaptationLogic (vlc_object_t *p_obj_, int w, int h) : RateBasedAdaptationLogic::RateBasedAdaptationLogic (vlc_object_t *p_obj_) :
AbstractAdaptationLogic (), AbstractAdaptationLogic (),
bpsAvg(0), bpsAvg(0),
currentBps(0) currentBps(0)
{ {
width = w;
height = h;
usedBps = 0; usedBps = 0;
dllength = 0; dllength = 0;
p_obj = p_obj_; p_obj = p_obj_;
...@@ -68,8 +66,8 @@ BaseRepresentation *RateBasedAdaptationLogic::getNextRepresentation(BaseAdaptati ...@@ -68,8 +66,8 @@ BaseRepresentation *RateBasedAdaptationLogic::getNextRepresentation(BaseAdaptati
else else
availBps = 0; availBps = 0;
RepresentationSelector selector; RepresentationSelector selector(maxwidth, maxheight);
BaseRepresentation *rep = selector.select(adaptSet, availBps, width, height); BaseRepresentation *rep = selector.select(adaptSet, availBps);
if ( rep == NULL ) if ( rep == NULL )
{ {
rep = selector.select(adaptSet); rep = selector.select(adaptSet);
...@@ -136,7 +134,7 @@ BaseRepresentation *FixedRateAdaptationLogic::getNextRepresentation(BaseAdaptati ...@@ -136,7 +134,7 @@ BaseRepresentation *FixedRateAdaptationLogic::getNextRepresentation(BaseAdaptati
if(adaptSet == NULL) if(adaptSet == NULL)
return NULL; return NULL;
RepresentationSelector selector; RepresentationSelector selector(maxwidth, maxheight);
BaseRepresentation *rep = selector.select(adaptSet, currentBps); BaseRepresentation *rep = selector.select(adaptSet, currentBps);
if ( rep == NULL ) if ( rep == NULL )
{ {
......
...@@ -36,7 +36,7 @@ namespace adaptive ...@@ -36,7 +36,7 @@ namespace adaptive
class RateBasedAdaptationLogic : public AbstractAdaptationLogic class RateBasedAdaptationLogic : public AbstractAdaptationLogic
{ {
public: public:
RateBasedAdaptationLogic (vlc_object_t *, int, int); RateBasedAdaptationLogic (vlc_object_t *);
virtual ~RateBasedAdaptationLogic (); virtual ~RateBasedAdaptationLogic ();
BaseRepresentation *getNextRepresentation(BaseAdaptationSet *, BaseRepresentation *); BaseRepresentation *getNextRepresentation(BaseAdaptationSet *, BaseRepresentation *);
...@@ -44,8 +44,6 @@ namespace adaptive ...@@ -44,8 +44,6 @@ namespace adaptive
virtual void trackerEvent(const SegmentTrackerEvent &); /* reimpl */ virtual void trackerEvent(const SegmentTrackerEvent &); /* reimpl */
private: private:
int width;
int height;
size_t bpsAvg; size_t bpsAvg;
size_t currentBps; size_t currentBps;
size_t usedBps; size_t usedBps;
......
...@@ -30,8 +30,10 @@ ...@@ -30,8 +30,10 @@
using namespace adaptive::logic; using namespace adaptive::logic;
RepresentationSelector::RepresentationSelector() RepresentationSelector::RepresentationSelector(int maxwidth, int maxheight)
{ {
this->maxwidth = maxwidth;
this->maxheight = maxheight;
} }
RepresentationSelector::~RepresentationSelector() RepresentationSelector::~RepresentationSelector()
...@@ -41,13 +43,24 @@ RepresentationSelector::~RepresentationSelector() ...@@ -41,13 +43,24 @@ RepresentationSelector::~RepresentationSelector()
BaseRepresentation * RepresentationSelector::lowest(BaseAdaptationSet *adaptSet) const BaseRepresentation * RepresentationSelector::lowest(BaseAdaptationSet *adaptSet) const
{ {
std::vector<BaseRepresentation *> reps = adaptSet->getRepresentations(); std::vector<BaseRepresentation *> reps = adaptSet->getRepresentations();
return (reps.empty()) ? NULL : *(reps.begin()); /* No maxsize check here */
BaseRepresentation *rep = (reps.empty()) ? NULL : *(reps.begin());
if(rep && rep->getWidth() <= maxwidth && rep->getHeight() <= maxheight)
return rep;
return NULL;
} }
BaseRepresentation * RepresentationSelector::highest(BaseAdaptationSet *adaptSet) const BaseRepresentation * RepresentationSelector::highest(BaseAdaptationSet *adaptSet) const
{ {
std::vector<BaseRepresentation *> reps = adaptSet->getRepresentations(); std::vector<BaseRepresentation *> reps = adaptSet->getRepresentations();
return (reps.empty()) ? NULL : *reps.rbegin();
std::vector<BaseRepresentation *>::const_reverse_iterator it;
for(it=reps.rbegin(); it!=reps.rend(); ++it)
{
if( (*it)->getWidth() <= maxwidth && (*it)->getHeight() <= maxheight )
return *it;
}
return NULL;
} }
BaseRepresentation * RepresentationSelector::higher(BaseAdaptationSet *adaptSet, BaseRepresentation *rep) const BaseRepresentation * RepresentationSelector::higher(BaseAdaptationSet *adaptSet, BaseRepresentation *rep) const
...@@ -55,7 +68,10 @@ BaseRepresentation * RepresentationSelector::higher(BaseAdaptationSet *adaptSet, ...@@ -55,7 +68,10 @@ BaseRepresentation * RepresentationSelector::higher(BaseAdaptationSet *adaptSet,
std::vector<BaseRepresentation *> reps = adaptSet->getRepresentations(); std::vector<BaseRepresentation *> reps = adaptSet->getRepresentations();
std::vector<BaseRepresentation *>::iterator it = std::upper_bound(reps.begin(), reps.end(), rep, std::vector<BaseRepresentation *>::iterator it = std::upper_bound(reps.begin(), reps.end(), rep,
BaseRepresentation::bwCompare); BaseRepresentation::bwCompare);
return (it == reps.end()) ? rep : *it; BaseRepresentation *upperRep = (it == reps.end()) ? rep : *it;
if( upperRep->getWidth() > maxwidth || upperRep->getHeight() > maxheight )
upperRep = rep;
return upperRep;
} }
BaseRepresentation * RepresentationSelector::lower(BaseAdaptationSet *adaptSet, BaseRepresentation *rep) const BaseRepresentation * RepresentationSelector::lower(BaseAdaptationSet *adaptSet, BaseRepresentation *rep) const
...@@ -88,38 +104,6 @@ BaseRepresentation * RepresentationSelector::select(BaseAdaptationSet *adaptSet, ...@@ -88,38 +104,6 @@ BaseRepresentation * RepresentationSelector::select(BaseAdaptationSet *adaptSet,
return best; return best;
} }
BaseRepresentation * RepresentationSelector::select(BaseAdaptationSet *adaptSet, uint64_t bitrate,
int width, int height) const
{
if(adaptSet == NULL)
return NULL;
std::vector<BaseRepresentation *> resMatchReps;
/* subset matching WxH */
std::vector<BaseRepresentation *> reps = adaptSet->getRepresentations();
std::vector<BaseRepresentation *>::const_iterator repIt;
if(width != 0 || height != 0)
{
for(repIt=reps.begin(); repIt!=reps.end(); ++repIt)
{
if(width && (*repIt)->getWidth() != width)
continue;
if(height && (*repIt)->getHeight() != height)
continue;
resMatchReps.push_back(*repIt);
}
}
if(resMatchReps.empty())
return select(adaptSet, bitrate);
else
return select(resMatchReps, 0, bitrate);
}
BaseRepresentation * RepresentationSelector::select(std::vector<BaseRepresentation *>& reps, BaseRepresentation * RepresentationSelector::select(std::vector<BaseRepresentation *>& reps,
uint64_t minbitrate, uint64_t maxbitrate) const uint64_t minbitrate, uint64_t maxbitrate) const
{ {
...@@ -127,6 +111,9 @@ BaseRepresentation * RepresentationSelector::select(std::vector<BaseRepresentati ...@@ -127,6 +111,9 @@ BaseRepresentation * RepresentationSelector::select(std::vector<BaseRepresentati
std::vector<BaseRepresentation *>::const_iterator repIt; std::vector<BaseRepresentation *>::const_iterator repIt;
for(repIt=reps.begin(); repIt!=reps.end(); ++repIt) for(repIt=reps.begin(); repIt!=reps.end(); ++repIt)
{ {
if( (*repIt)->getWidth() > maxwidth || (*repIt)->getHeight() > maxheight )
continue;
if ( !lowest || (*repIt)->getBandwidth() < lowest->getBandwidth()) if ( !lowest || (*repIt)->getBandwidth() < lowest->getBandwidth())
lowest = *repIt; lowest = *repIt;
......
...@@ -38,7 +38,7 @@ namespace adaptive ...@@ -38,7 +38,7 @@ namespace adaptive
class RepresentationSelector class RepresentationSelector
{ {
public: public:
RepresentationSelector(); RepresentationSelector(int, int);
~RepresentationSelector(); ~RepresentationSelector();
BaseRepresentation * lowest(BaseAdaptationSet *) const; BaseRepresentation * lowest(BaseAdaptationSet *) const;
BaseRepresentation * highest(BaseAdaptationSet *) const; BaseRepresentation * highest(BaseAdaptationSet *) const;
...@@ -46,9 +46,10 @@ namespace adaptive ...@@ -46,9 +46,10 @@ namespace adaptive
BaseRepresentation * lower(BaseAdaptationSet *, BaseRepresentation *) const; BaseRepresentation * lower(BaseAdaptationSet *, BaseRepresentation *) const;
BaseRepresentation * select(BaseAdaptationSet *) const; BaseRepresentation * select(BaseAdaptationSet *) const;
BaseRepresentation * select(BaseAdaptationSet *, uint64_t bitrate) const; BaseRepresentation * select(BaseAdaptationSet *, uint64_t bitrate) const;
BaseRepresentation * select(BaseAdaptationSet *, uint64_t bitrate,
int width, int height) const;
protected: protected:
int maxwidth;
int maxheight;
BaseRepresentation * select(std::vector<BaseRepresentation *>&reps, BaseRepresentation * select(std::vector<BaseRepresentation *>&reps,
uint64_t minbitrate, uint64_t maxbitrate) const; uint64_t minbitrate, uint64_t maxbitrate) const;
}; };
......
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