Added per-protocol default track sorting option
This commit is contained in:
parent
01f11dcfda
commit
6042c1ea70
4 changed files with 159 additions and 56 deletions
149
lib/stream.cpp
149
lib/stream.cpp
|
@ -20,6 +20,8 @@
|
|||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
enum Util::trackSortOrder Util::defaultTrackSortOrder = TRKSORT_DEFAULT;
|
||||
|
||||
/// Calls strftime using the current local time, returning empty string on any error.
|
||||
static std::string strftime_now(const std::string &format){
|
||||
time_t rawtime;
|
||||
|
@ -1222,6 +1224,10 @@ std::set<size_t> Util::wouldSelect(const DTSC::Meta &M, const std::map<std::stri
|
|||
}
|
||||
|
||||
HIGH_MSG("Trying to fill: %s", capa["codecs"][bestSoFar].toString().c_str());
|
||||
|
||||
std::list<size_t> srtTrks;
|
||||
Util::sortTracks(validTracks, M, Util::defaultTrackSortOrder, srtTrks);
|
||||
|
||||
// try to fill as many codecs simultaneously as possible
|
||||
if (capa["codecs"][bestSoFar].size() > 0){
|
||||
jsonForEachConst(capa["codecs"][bestSoFar], itb){
|
||||
|
@ -1274,66 +1280,35 @@ std::set<size_t> Util::wouldSelect(const DTSC::Meta &M, const std::map<std::stri
|
|||
++shift;
|
||||
}
|
||||
if (found && !multiSel){continue;}
|
||||
if (M.getLive()){
|
||||
for (std::set<size_t>::reverse_iterator trit = validTracks.rbegin();
|
||||
trit != validTracks.rend(); trit++){
|
||||
if ((!byType && M.getCodec(*trit) == strRef.substr(shift)) ||
|
||||
(byType && M.getType(*trit) == strRef.substr(shift)) || strRef.substr(shift) == "*"){
|
||||
// user-agent-check
|
||||
bool problems = false;
|
||||
if (capa.isMember("exceptions") && capa["exceptions"].isObject() &&
|
||||
capa["exceptions"].size()){
|
||||
jsonForEachConst(capa["exceptions"], ex){
|
||||
if (ex.key() == "codec:" + strRef.substr(shift)){
|
||||
problems = !Util::checkException(*ex, UA);
|
||||
break;
|
||||
}
|
||||
|
||||
for (std::list<size_t>::iterator trit = srtTrks.begin();
|
||||
trit != srtTrks.end(); trit++){
|
||||
if ((!byType && M.getCodec(*trit) == strRef.substr(shift)) ||
|
||||
(byType && M.getType(*trit) == strRef.substr(shift)) || strRef.substr(shift) == "*"){
|
||||
// user-agent-check
|
||||
bool problems = false;
|
||||
if (capa.isMember("exceptions") && capa["exceptions"].isObject() &&
|
||||
capa["exceptions"].size()){
|
||||
jsonForEachConst(capa["exceptions"], ex){
|
||||
if (ex.key() == "codec:" + strRef.substr(shift)){
|
||||
problems = !Util::checkException(*ex, UA);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!allowBFrames && M.hasBFrames(*trit)){problems = true;}
|
||||
if (problems){break;}
|
||||
/*LTS-START*/
|
||||
if (noSelAudio && M.getType(*trit) == "audio"){continue;}
|
||||
if (noSelVideo && M.getType(*trit) == "video"){continue;}
|
||||
if (noSelSub &&
|
||||
(M.getType(*trit) == "subtitle" || M.getCodec(*trit) == "subtitle")){
|
||||
continue;
|
||||
}
|
||||
/*LTS-END*/
|
||||
result.insert(*trit);
|
||||
found = true;
|
||||
if (!multiSel){break;}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
for (std::set<size_t>::iterator trit = validTracks.begin(); trit != validTracks.end(); trit++){
|
||||
if ((!byType && M.getCodec(*trit) == strRef.substr(shift)) ||
|
||||
(byType && M.getType(*trit) == strRef.substr(shift)) || strRef.substr(shift) == "*"){
|
||||
// user-agent-check
|
||||
bool problems = false;
|
||||
if (capa.isMember("exceptions") && capa["exceptions"].isObject() &&
|
||||
capa["exceptions"].size()){
|
||||
jsonForEachConst(capa["exceptions"], ex){
|
||||
if (ex.key() == "codec:" + strRef.substr(shift)){
|
||||
problems = !Util::checkException(*ex, UA);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!allowBFrames && M.hasBFrames(*trit)){problems = true;}
|
||||
if (problems){break;}
|
||||
/*LTS-START*/
|
||||
if (noSelAudio && M.getType(*trit) == "audio"){continue;}
|
||||
if (noSelVideo && M.getType(*trit) == "video"){continue;}
|
||||
if (noSelSub &&
|
||||
(M.getType(*trit) == "subtitle" || M.getCodec(*trit) == "subtitle")){
|
||||
continue;
|
||||
}
|
||||
/*LTS-END*/
|
||||
result.insert(*trit);
|
||||
found = true;
|
||||
if (!multiSel){break;}
|
||||
if (!allowBFrames && M.hasBFrames(*trit)){problems = true;}
|
||||
if (problems){break;}
|
||||
/*LTS-START*/
|
||||
if (noSelAudio && M.getType(*trit) == "audio"){continue;}
|
||||
if (noSelVideo && M.getType(*trit) == "video"){continue;}
|
||||
if (noSelSub &&
|
||||
(M.getType(*trit) == "subtitle" || M.getCodec(*trit) == "subtitle")){
|
||||
continue;
|
||||
}
|
||||
/*LTS-END*/
|
||||
result.insert(*trit);
|
||||
found = true;
|
||||
if (!multiSel){break;}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1357,3 +1332,65 @@ std::set<size_t> Util::wouldSelect(const DTSC::Meta &M, const std::map<std::stri
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Sorts the given set of track IDs by the given sort order, according to the given metadata, and returns it by reference as the given list.
|
||||
/// Will clear the list automatically if not empty.
|
||||
void Util::sortTracks(std::set<size_t> & validTracks, const DTSC::Meta & M, Util::trackSortOrder sorting, std::list<size_t> & srtTrks){
|
||||
srtTrks.clear();
|
||||
if (sorting == TRKSORT_DEFAULT){
|
||||
if (M.getLive()){
|
||||
sorting = TRKSORT_ID_HTL;
|
||||
}else{
|
||||
sorting = TRKSORT_ID_LTH;
|
||||
}
|
||||
}
|
||||
if (!validTracks.size()){return;}
|
||||
for (std::set<size_t>::iterator it = validTracks.begin(); it != validTracks.end(); ++it){
|
||||
//The first element is always at the beginning of the list. Yeah. That makes sense.
|
||||
if (!srtTrks.size()){
|
||||
srtTrks.push_front(*it);
|
||||
continue;
|
||||
}
|
||||
if (sorting == TRKSORT_ID_LTH){
|
||||
//ID low to high needs no comparison, already sorted
|
||||
srtTrks.push_back(*it);
|
||||
continue;
|
||||
}else if (sorting == TRKSORT_ID_HTL){
|
||||
//ID high to low needs no comparison either, already sorted in reverse
|
||||
srtTrks.push_front(*it);
|
||||
continue;
|
||||
}
|
||||
bool inserted = false;
|
||||
for (std::list<size_t>::iterator lt = srtTrks.begin(); lt != srtTrks.end(); ++lt){
|
||||
if (sorting == TRKSORT_BPS_LTH){
|
||||
if (M.getBps(*it) <= M.getBps(*lt)){
|
||||
srtTrks.insert(lt, *it);
|
||||
inserted = true;
|
||||
break;
|
||||
}
|
||||
}else if (sorting == TRKSORT_BPS_HTL){
|
||||
if (M.getBps(*it) >= M.getBps(*lt)){
|
||||
srtTrks.insert(lt, *it);
|
||||
inserted = true;
|
||||
break;
|
||||
}
|
||||
}else if (sorting == TRKSORT_RES_LTH){
|
||||
if (M.getWidth(*it) * M.getHeight(*it) < M.getWidth(*lt) * M.getHeight(*lt) || M.getRate(*it) < M.getRate(*lt)){
|
||||
srtTrks.insert(lt, *it);
|
||||
inserted = true;
|
||||
break;
|
||||
}
|
||||
}else if (sorting == TRKSORT_RES_HTL){
|
||||
if (M.getWidth(*it) * M.getHeight(*it) > M.getWidth(*lt) * M.getHeight(*lt) || M.getRate(*it) > M.getRate(*lt)){
|
||||
srtTrks.insert(lt, *it);
|
||||
inserted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//Insert at end of list if not inserted yet
|
||||
if (!inserted){srtTrks.push_back(*it);}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
14
lib/stream.h
14
lib/stream.h
|
@ -8,6 +8,7 @@
|
|||
#include "socket.h"
|
||||
#include "util.h"
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
||||
const JSON::Value empty;
|
||||
|
||||
|
@ -37,6 +38,19 @@ namespace Util{
|
|||
std::set<size_t> wouldSelect(const DTSC::Meta &M, const std::map<std::string, std::string> &targetParams,
|
||||
const JSON::Value &capa = empty, const std::string &UA = "", uint64_t seekTarget = 0);
|
||||
|
||||
enum trackSortOrder{
|
||||
TRKSORT_DEFAULT = 0,
|
||||
TRKSORT_BPS_LTH,
|
||||
TRKSORT_BPS_HTL,
|
||||
TRKSORT_ID_LTH,
|
||||
TRKSORT_ID_HTL,
|
||||
TRKSORT_RES_LTH,
|
||||
TRKSORT_RES_HTL
|
||||
};
|
||||
extern trackSortOrder defaultTrackSortOrder;
|
||||
void sortTracks(std::set<size_t> & validTracks, const DTSC::Meta & M, trackSortOrder sorting, std::list<size_t> & srtTrks);
|
||||
|
||||
|
||||
class DTSCShmReader{
|
||||
public:
|
||||
DTSCShmReader(const std::string &pageName);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <mist/defines.h>
|
||||
#include <mist/socket.h>
|
||||
#include <mist/util.h>
|
||||
#include <mist/stream.h>
|
||||
|
||||
int spawnForked(Socket::Connection &S){
|
||||
mistOut tmp(S);
|
||||
|
@ -27,6 +28,20 @@ int main(int argc, char *argv[]){
|
|||
std::cout << mistOut::capa.toString() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
{
|
||||
std::string defTrkSrt = conf.getString("default_track_sorting");
|
||||
if (!defTrkSrt.size()){
|
||||
//defTrkSrt = Util::getGlobalConfig("default_track_sorting").asString();
|
||||
}
|
||||
if (defTrkSrt.size()){
|
||||
if (defTrkSrt == "bps_lth"){Util::defaultTrackSortOrder = Util::TRKSORT_BPS_LTH;}
|
||||
if (defTrkSrt == "bps_htl"){Util::defaultTrackSortOrder = Util::TRKSORT_BPS_HTL;}
|
||||
if (defTrkSrt == "id_lth"){Util::defaultTrackSortOrder = Util::TRKSORT_ID_LTH;}
|
||||
if (defTrkSrt == "id_htl"){Util::defaultTrackSortOrder = Util::TRKSORT_ID_HTL;}
|
||||
if (defTrkSrt == "res_lth"){Util::defaultTrackSortOrder = Util::TRKSORT_RES_LTH;}
|
||||
if (defTrkSrt == "res_htl"){Util::defaultTrackSortOrder = Util::TRKSORT_RES_HTL;}
|
||||
}
|
||||
}
|
||||
conf.activate();
|
||||
if (mistOut::listenMode()){
|
||||
{
|
||||
|
|
|
@ -45,6 +45,43 @@ namespace Mist{
|
|||
option["help"] = "Do not start input if not already started";
|
||||
option["value"].append(0);
|
||||
cfg->addOption("noinput", option);
|
||||
option.null();
|
||||
|
||||
|
||||
capa["optional"]["default_track_sorting"]["name"] = "Default track sorting";
|
||||
capa["optional"]["default_track_sorting"]["help"] = "What tracks are selected first when no specific track selector is used for playback.";
|
||||
capa["optional"]["default_track_sorting"]["default"] = "";
|
||||
capa["optional"]["default_track_sorting"]["type"] = "select";
|
||||
capa["optional"]["default_track_sorting"]["option"] = "--default_track_sorting";
|
||||
capa["optional"]["default_track_sorting"]["short"] = "S";
|
||||
option.append("");
|
||||
option.append("Default (last added for live, first added for VoD)");
|
||||
capa["optional"]["default_track_sorting"]["select"].append(option);
|
||||
option.null();
|
||||
option.append("bps_lth");
|
||||
option.append("Bit rate, low to high");
|
||||
capa["optional"]["default_track_sorting"]["select"].append(option);
|
||||
option.null();
|
||||
option.append("bps_htl");
|
||||
option.append("Bit rate, high to low");
|
||||
capa["optional"]["default_track_sorting"]["select"].append(option);
|
||||
option.null();
|
||||
option.append("id_lth");
|
||||
option.append("Track ID, low to high");
|
||||
capa["optional"]["default_track_sorting"]["select"].append(option);
|
||||
option.null();
|
||||
option.append("id_htl");
|
||||
option.append("Track ID, high to low");
|
||||
capa["optional"]["default_track_sorting"]["select"].append(option);
|
||||
option.null();
|
||||
option.append("res_lth");
|
||||
option.append("Resolution, low to high");
|
||||
capa["optional"]["default_track_sorting"]["select"].append(option);
|
||||
option.null();
|
||||
option.append("res_htl");
|
||||
option.append("Resolution, high to low");
|
||||
capa["optional"]["default_track_sorting"]["select"].append(option);
|
||||
|
||||
config = cfg;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue