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