Fixes to playlist support

This commit is contained in:
Thulinma 2019-06-01 19:01:17 +02:00
parent 907be3b1f4
commit ead45b4fb8
10 changed files with 201 additions and 103 deletions

View file

@ -86,6 +86,8 @@ namespace DTSC {
Scan getMember(const std::string & indice) const;
Scan getMember(const char * indice) const;
Scan getMember(const char * indice, size_t ind_len) const;
void nullMember(const std::string & indice);
void nullMember(const char * indice, size_t ind_len);
Scan getIndice(size_t num) const;
std::string getIndiceName(size_t num) const;
size_t getSize() const;
@ -132,6 +134,7 @@ namespace DTSC {
void setKeyFrame(bool kf);
virtual uint64_t getTime() const;
void setTime(uint64_t _time);
void nullMember(const std::string & memb);
size_t getTrackId() const;
char * getData() const;
size_t getDataLen() const;
@ -141,6 +144,7 @@ namespace DTSC {
JSON::Value toJSON() const;
std::string toSummary() const;
Scan getScan() const;
Scan getScan();
protected:
bool master;
packType version;
@ -366,6 +370,7 @@ namespace DTSC {
Meta();
Meta(const DTSC::Packet & source);
Meta(JSON::Value & meta);
bool nextIsKey;
inline operator bool() const { //returns if the object contains valid meta data BY LOOKING AT vod/live FLAGS
return vod || live;

View file

@ -485,6 +485,14 @@ namespace DTSC {
Bit::htobll(data + 12, _time);
}
void Packet::nullMember(const std::string & memb){
if (!master){
INFO_MSG("Can't null '%s' for this packet, as it is not master.", memb.c_str());
return;
}
getScan().nullMember(memb);
}
///\brief Returns the track id of the packet.
///\return The track id of this packet.
size_t Packet::getTrackId() const {
@ -525,6 +533,15 @@ namespace DTSC {
return Scan(data + (getDataLen() - getPayloadLen()), getPayloadLen());
}
/// Returns a DTSC::Scan instance to the contents of this packet.
/// May return an invalid instance if this packet is invalid.
Scan Packet::getScan(){
if (!*this || !getDataLen() || !getPayloadLen() || getDataLen() <= getPayloadLen()){
return Scan();
}
return Scan(data + (getDataLen() - getPayloadLen()), getPayloadLen());
}
///\brief Converts the packet into a JSON value
///\return A JSON::Value representation of this packet.
JSON::Value Packet::toJSON() const {
@ -600,6 +617,32 @@ namespace DTSC {
return Scan();
}
/// If this is an object type and contains the given indice/len, sets the indice name to all zeroes.
void Scan::nullMember(const std::string & indice){
nullMember(indice.data(), indice.size());
}
/// If this is an object type and contains the given indice/len, sets the indice name to all zeroes.
void Scan::nullMember(const char * indice, const size_t ind_len){
if (getType() != DTSC_OBJ && getType() != DTSC_CON){return;}
char * i = p + 1;
//object, scan contents
while (i[0] + i[1] != 0 && i < p + len) { //while not encountering 0x0000 (we assume 0x0000EE)
if (i + 2 >= p + len) {
return;//out of packet!
}
uint16_t strlen = Bit::btohs(i);
i += 2;
if (ind_len == strlen && strncmp(indice, i, strlen) == 0) {
memset(i, 0, strlen);
return;
}
i = skipDTSC(i + strlen, p + len);
if (!i) {return;}
}
return;
}
/// Returns an object representing the named indice of this object.
/// Returns an invalid object if this indice doesn't exist or this isn't an object type.
bool Scan::hasMember(const std::string & indice) const{
@ -1476,6 +1519,7 @@ namespace DTSC {
///\brief Creates an empty meta object
Meta::Meta() {
nextIsKey = false;
vod = false;
live = false;
version = DTSH_VERSION;
@ -1582,6 +1626,10 @@ namespace DTSC {
}
void Meta::update(long long packTime, long long packOffset, long long packTrack, long long packDataSize, uint64_t packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size, const char * ivec){
if (nextIsKey){
isKeyframe = true;
nextIsKey = false;
}
DONTEVEN_MSG("Updating meta with: t=%lld, o=%lld, s=%lld, t=%lld, p=%lld", packTime, packOffset, packDataSize, packTrack, packBytePos);
if (!packSendSize){
//time and trackID are part of the 20-byte header.

View file

@ -354,6 +354,8 @@ bool Util::startInput(std::string streamname, std::string filename, bool forkFir
filename = stream_cfg["source"].asStringRef();
}
bool hadOriginal = getenv("MIST_ORIGINAL_SOURCE");
if (!hadOriginal){setenv("MIST_ORIGINAL_SOURCE", filename.c_str(), 1);}
streamVariables(filename, streamname);
const JSON::Value input = getInputBySource(filename, isProvider);
if (!input){return false;}
@ -366,13 +368,15 @@ bool Util::startInput(std::string streamname, std::string filename, bool forkFir
if (!prm->isMember("option")){continue;}
const std::string opt = (*prm)["option"].asStringRef();
// check for overrides
if (overrides.count(opt)){
str_args[opt] = overrides.at(opt);
if (overrides.count(prm.key())){
HIGH_MSG("Overriding option '%s' to '%s'", prm.key().c_str(), overrides.at(prm.key()).c_str());
str_args[opt] = overrides.at(prm.key());
}else{
if (!stream_cfg.isMember(prm.key())){
FAIL_MSG("Required parameter %s for stream %s missing", prm.key().c_str(), streamname.c_str());
return false;
}
HIGH_MSG("Setting option '%s' to '%s'", opt.c_str(), stream_cfg[prm.key()].asStringRef().c_str());
str_args[opt] = stream_cfg[opt].asStringRef();
}
}
@ -383,10 +387,14 @@ bool Util::startInput(std::string streamname, std::string filename, bool forkFir
if (!prm->isMember("option")){continue;}
const std::string opt = (*prm)["option"].asStringRef();
// check for overrides
if (overrides.count(opt)){
str_args[opt] = overrides.at(opt);
if (overrides.count(prm.key())){
HIGH_MSG("Overriding option '%s' to '%s'", prm.key().c_str(), overrides.at(prm.key()).c_str());
str_args[opt] = overrides.at(prm.key());
}else{
if (stream_cfg.isMember(prm.key())){str_args[opt] = stream_cfg[prm.key()].asStringRef();}
if (stream_cfg.isMember(prm.key()) && stream_cfg[prm.key()].asStringRef().size()){
HIGH_MSG("Setting option '%s' to '%s'", opt.c_str(), stream_cfg[prm.key()].asStringRef().c_str());
str_args[opt] = stream_cfg[prm.key()].asStringRef();
}
}
if (!prm->isMember("type") && str_args.count(opt)){str_args[opt] = "";}
}
@ -398,7 +406,6 @@ bool Util::startInput(std::string streamname, std::string filename, bool forkFir
}
std::string player_bin = Util::getMyPath() + "MistIn" + input["name"].asStringRef();
INFO_MSG("Starting %s -s %s %s", player_bin.c_str(), streamname.c_str(), filename.c_str());
char *argv[30] ={(char *)player_bin.c_str(), (char *)"-s", (char *)streamname.c_str(),
(char *)filename.c_str()};
int argNum = 3;
@ -422,6 +429,7 @@ bool Util::startInput(std::string streamname, std::string filename, bool forkFir
pid = fork();
if (pid == -1){
FAIL_MSG("Forking process for stream %s failed: %s", streamname.c_str(), strerror(errno));
if (!hadOriginal){unsetenv("MIST_ORIGINAL_SOURCE");}
return false;
}
if (pid && overrides.count("singular")){
@ -438,13 +446,19 @@ bool Util::startInput(std::string streamname, std::string filename, bool forkFir
}
Socket::Connection io(0, 1);
io.drop();
DONTEVEN_MSG("execvp");
std::stringstream args;
for (size_t i = 0; i < 30; ++i){
if (!argv[i] || !argv[i][0]){break;}
args << argv[i] << " ";
}
INFO_MSG("Starting %s", args.str().c_str());
execvp(argv[0], argv);
FAIL_MSG("Starting process %s for stream %s failed: %s", argv[0], streamname.c_str(), strerror(errno));
FAIL_MSG("Starting process %s failed: %s", argv[0], strerror(errno));
_exit(42);
}else if (spawn_pid != NULL){
*spawn_pid = pid;
}
if (!hadOriginal){unsetenv("MIST_ORIGINAL_SOURCE");}
unsigned int waiting = 0;
while (!streamAlive(streamname) && ++waiting < 240){
@ -947,7 +961,7 @@ std::set<size_t> Util::getSupportedTracks(const DTSC::Meta &M, const JSON::Value
if (found){break;}
}
if (!found){
HIGH_MSG("Track %zu with codec %s not supported!", *it, codec.c_str());
HIGH_MSG("Track %u with codec %s not supported!", it->first, codec.c_str());
continue;
}
}