Representationselectors.cpp 4.78 KB
Newer Older
1 2 3
/*
 * Representationselectors.cpp
 *****************************************************************************
4
 * Copyright (C) 2014 - VideoLAN and VLC authors
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
 *
 * 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.
 *****************************************************************************/
20 21 22 23
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

24
#include "Representationselectors.hpp"
25 26 27
#include "../playlist/BaseRepresentation.h"
#include "../playlist/BaseAdaptationSet.h"
#include "../playlist/BasePeriod.h"
28
#include <limits>
29
#include <algorithm>
30

31
using namespace adaptive::logic;
32

33
RepresentationSelector::RepresentationSelector(int maxwidth, int maxheight)
34
{
35 36
    this->maxwidth = maxwidth;
    this->maxheight = maxheight;
37 38
}

39 40 41 42
RepresentationSelector::~RepresentationSelector()
{
}

43 44 45
BaseRepresentation * RepresentationSelector::lowest(BaseAdaptationSet *adaptSet) const
{
    std::vector<BaseRepresentation *> reps = adaptSet->getRepresentations();
46 47 48 49 50
    /* No maxsize check here */
    BaseRepresentation *rep = (reps.empty()) ? NULL : *(reps.begin());
    if(rep && rep->getWidth() <= maxwidth && rep->getHeight() <= maxheight)
        return rep;
    return NULL;
51 52 53 54 55
}

BaseRepresentation * RepresentationSelector::highest(BaseAdaptationSet *adaptSet) const
{
    std::vector<BaseRepresentation *> reps = adaptSet->getRepresentations();
56 57 58 59 60 61 62 63

    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;
64 65 66 67 68 69 70
}

BaseRepresentation * RepresentationSelector::higher(BaseAdaptationSet *adaptSet, BaseRepresentation *rep) const
{
    std::vector<BaseRepresentation *> reps = adaptSet->getRepresentations();
    std::vector<BaseRepresentation *>::iterator it = std::upper_bound(reps.begin(), reps.end(), rep,
                                                                      BaseRepresentation::bwCompare);
71 72 73 74
    BaseRepresentation *upperRep = (it == reps.end()) ? rep : *it;
    if( upperRep->getWidth() > maxwidth || upperRep->getHeight() > maxheight )
        upperRep = rep;
    return upperRep;
75 76 77 78 79 80 81 82 83 84
}

BaseRepresentation * RepresentationSelector::lower(BaseAdaptationSet *adaptSet, BaseRepresentation *rep) const
{
    std::vector<BaseRepresentation *> reps = adaptSet->getRepresentations();
    std::vector<BaseRepresentation *>::iterator it = std::lower_bound(reps.begin(), reps.end(), rep,
                                                                      BaseRepresentation::bwCompare);
    return (it > reps.begin()) ? *(--it) : rep;
}

85
BaseRepresentation * RepresentationSelector::select(BaseAdaptationSet *adaptSet) const
86
{
87
    return select(adaptSet, std::numeric_limits<uint64_t>::max());
88
}
89
BaseRepresentation * RepresentationSelector::select(BaseAdaptationSet *adaptSet, uint64_t bitrate) const
90
{
91
    if (adaptSet == NULL)
92 93
        return NULL;

94
    BaseRepresentation *best = NULL;
95 96 97
    std::vector<BaseRepresentation *> reps = adaptSet->getRepresentations();
    BaseRepresentation *candidate = select(reps, (best)?best->getBandwidth():0, bitrate);
    if (candidate)
98
    {
99 100 101
        if (candidate->getBandwidth() > bitrate) /* none matched, returned lowest */
            return candidate;
        best = candidate;
102
    }
103

104 105 106
    return best;
}

107
BaseRepresentation * RepresentationSelector::select(std::vector<BaseRepresentation *>& reps,
108 109
                                                uint64_t minbitrate, uint64_t maxbitrate) const
{
110 111
    BaseRepresentation  *candidate = NULL, *lowest = NULL;
    std::vector<BaseRepresentation *>::const_iterator repIt;
112
    for(repIt=reps.begin(); repIt!=reps.end(); ++repIt)
113
    {
114 115 116
        if( (*repIt)->getWidth() > maxwidth || (*repIt)->getHeight() > maxheight )
            continue;

117 118 119
        if ( !lowest || (*repIt)->getBandwidth() < lowest->getBandwidth())
            lowest = *repIt;

120 121 122 123 124 125 126
        if ( (*repIt)->getBandwidth() < maxbitrate &&
             (*repIt)->getBandwidth() > minbitrate )
        {
            candidate = (*repIt);
            minbitrate = (*repIt)->getBandwidth();
        }
    }
127 128 129 130

    if (!candidate)
        return candidate = lowest;

131 132
    return candidate;
}