Added skipDynamic optional argument to most binary representations of metadata/tracks, which skips sending dynamic parts of the metadata if true.

This commit is contained in:
Thulinma 2016-02-15 11:48:45 +01:00
parent 10af060ab4
commit 668560ff05
11 changed files with 344 additions and 111 deletions

View file

@ -23,7 +23,9 @@ namespace Analysers {
std::cerr << "Not a valid DTSC file" << std::endl;
return 1;
}
F.getMeta().toPrettyString(std::cout,0, 0x03);
if (F.getMeta().vod || F.getMeta().live){
F.getMeta().toPrettyString(std::cout,0, 0x03);
}
int bPos = 0;
F.seek_bpos(0);
@ -42,6 +44,10 @@ namespace Analysers {
std::cout << "DTSC header: " << F.getPacket().getScan().toPrettyString() << std::endl;
break;
}
case DTSC::DTCM: {
std::cout << "DTCM command: " << F.getPacket().getScan().toPrettyString() << std::endl;
break;
}
default:
DEBUG_MSG(DLVL_WARN,"Invalid dtsc packet @ bpos %d", bPos);
break;

View file

@ -240,6 +240,58 @@ namespace Mist {
//end player functionality
}
/// Main loop for stream-style inputs.
/// This loop will start the buffer without resume support, and then repeatedly call ..... followed by ....
void Input::stream(){
char userPageName[NAME_BUFFER_SIZE];
snprintf(userPageName, NAME_BUFFER_SIZE, SHM_USERS, streamName.c_str());
/*LTS-START*/
if(Triggers::shouldTrigger("STREAM_READY", config->getString("streamname"))){
std::string payload = config->getString("streamname")+"\n" +capa["name"].asStringRef()+"\n";
if (!Triggers::doTrigger("STREAM_READY", payload, config->getString("streamname"))){
config->is_active = false;
}
}
/*LTS-END*/
userPage.init(userPageName, PLAY_EX_SIZE, true);
if (!isBuffer) {
for (std::map<unsigned int, DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++) {
bufferFrame(it->first, 1);
}
}
DEBUG_MSG(DLVL_DEVEL, "Input for stream %s started", streamName.c_str());
long long int activityCounter = Util::bootSecs();
while ((Util::bootSecs() - activityCounter) < 10 && config->is_active) { //10 second timeout
userPage.parseEach(callbackWrapper);
removeUnused();
if (userPage.amount) {
activityCounter = Util::bootSecs();
DEBUG_MSG(DLVL_INSANE, "Connected users: %d", userPage.amount);
} else {
DEBUG_MSG(DLVL_INSANE, "Timer running");
}
/*LTS-START*/
if ((Util::bootSecs() - activityCounter) >= 10 || !config->is_active){//10 second timeout
if(Triggers::shouldTrigger("STREAM_UNLOAD", config->getString("streamname"))){
std::string payload = config->getString("streamname")+"\n" +capa["name"].asStringRef()+"\n";
if (!Triggers::doTrigger("STREAM_UNLOAD", payload, config->getString("streamname"))){
activityCounter = Util::bootSecs();
config->is_active = true;
}
}
}
/*LTS-END*/
if (config->is_active){
Util::sleep(1000);
}
}
finish();
DEBUG_MSG(DLVL_DEVEL, "Input for stream %s closing clean", streamName.c_str());
//end player functionality
}
void Input::finish() {
for (std::map<unsigned int, std::map<unsigned int, unsigned int> >::iterator it = pageCounter.begin(); it != pageCounter.end(); it++) {
for (std::map<unsigned int, unsigned int>::iterator it2 = it->second.begin(); it2 != it->second.end(); it2++) {

View file

@ -338,10 +338,12 @@ namespace Mist {
}
if (!found){
for (std::map<unsigned int,DTSC::Track>::iterator trit = myMeta.tracks.begin(); trit != myMeta.tracks.end(); trit++){
if (trit->second.codec == (*itc).asStringRef()){
if (trit->second.codec == (*itc).asStringRef() || (*itc).asStringRef() == "*"){
genCounter++;
found = true;
break;
if ((*itc).asStringRef() != "*"){
break;
}
}
}
}
@ -368,6 +370,7 @@ namespace Mist {
if ((*itb).size() && myMeta.tracks.size()){
bool found = false;
jsonForEach((*itb), itc) {
INFO_MSG("Filling codec: '%s'", (*itc).asStringRef().c_str());
if (found) {
break;
}
@ -379,10 +382,12 @@ namespace Mist {
}
if (!found){
for (std::map<unsigned int,DTSC::Track>::iterator trit = myMeta.tracks.begin(); trit != myMeta.tracks.end(); trit++){
if (trit->second.codec == (*itc).asStringRef()){
if (trit->second.codec == (*itc).asStringRef() || (*itc).asStringRef() == "*"){
selectedTracks.insert(trit->first);
found = true;
break;
if ((*itc).asStringRef() != "*"){
break;
}
}
}
}

147
src/output/output_dtsc.cpp Normal file
View file

@ -0,0 +1,147 @@
#include "output_dtsc.h"
#include <mist/defines.h>
#include <mist/stream.h>
#include <mist/triggers.h>
#include <mist/auth.h>
#include <mist/bitfields.h>
#include <sys/stat.h>
#include <cstring>
#include <cstdlib>
namespace Mist {
OutDTSC::OutDTSC(Socket::Connection & conn) : Output(conn) {
setBlocking(true);
JSON::Value prep;
prep["cmd"] = "hi";
prep["version"] = "MistServer " PACKAGE_VERSION;
#ifdef BIGMETA
prep["pack_method"] = 2ll;
#else
prep["pack_method"] = 1ll;
#endif
salt = Secure::md5("mehstuff"+JSON::Value((long long)time(0)).asString());
prep["salt"] = salt;
/// \todo Make this securererer.
unsigned long sendSize = prep.packedSize();
myConn.SendNow("DTCM");
char sSize[4] = {0, 0, 0, 0};
Bit::htobl(sSize, prep.packedSize());
myConn.SendNow(sSize, 4);
prep.sendTo(myConn);
pushing = false;
}
OutDTSC::~OutDTSC() {}
void OutDTSC::init(Util::Config * cfg){
Output::init(cfg);
capa["name"] = "DTSC";
capa["desc"] = "Enables the DTSC protocol for efficient inter-server stream exchange.";
capa["deps"] = "";
capa["codecs"][0u][0u].append("*");
cfg->addConnectorOptions(4200, capa);
config = cfg;
}
void OutDTSC::sendNext(){
myConn.SendNow(thisPacket.getData(), thisPacket.getDataLen());
}
void OutDTSC::sendHeader(){
sentHeader = true;
myMeta.send(myConn, true);
}
void OutDTSC::onRequest(){
while (myConn.Received().available(8)){
if (myConn.Received().copy(4) == "DTCM"){
// Command message
std::string toRec = myConn.Received().copy(8);
unsigned long rSize = Bit::btohl(toRec.c_str()+4);
if (!myConn.Received().available(8+rSize)){return;}//abort - not enough data yet
myConn.Received().remove(8);
std::string dataPacket = myConn.Received().remove(rSize);
DTSC::Scan dScan((char*)dataPacket.data(), rSize);
if (dScan.getMember("cmd").asString() == "push"){handlePush(dScan); continue;}
if (dScan.getMember("cmd").asString() == "play"){handlePlay(dScan); continue;}
WARN_MSG("Unhandled DTCM command: '%s'", dScan.getMember("cmd").asString().c_str());
}else{
// Non-command message
//
}
}
}
void OutDTSC::handlePlay(DTSC::Scan & dScan){
streamName = dScan.getMember("stream").asString();
Util::sanitizeName(streamName);
parseData = true;
}
void OutDTSC::handlePush(DTSC::Scan & dScan){
streamName = dScan.getMember("stream").asString();
std::string passString = dScan.getMember("password").asString();
Util::sanitizeName(streamName);
//pull the server configuration
std::string smp = streamName.substr(0,(streamName.find_first_of("+ ")));
IPC::sharedPage serverCfg("!mistConfig", DEFAULT_CONF_PAGE_SIZE); ///< Contains server configuration and capabilities
IPC::semaphore configLock("!mistConfLock", O_CREAT | O_RDWR, ACCESSPERMS, 1);
configLock.wait();
DTSC::Scan streamCfg = DTSC::Scan(serverCfg.mapped, serverCfg.len).getMember("streams").getMember(smp);
if (streamCfg){
if (streamCfg.getMember("source").asString().substr(0, 7) != "push://"){
DEBUG_MSG(DLVL_FAIL, "Push rejected - stream %s not a push-able stream. (%s != push://*)", streamName.c_str(), streamCfg.getMember("source").asString().c_str());
myConn.close();
}else{
std::string source = streamCfg.getMember("source").asString().substr(7);
std::string IP = source.substr(0, source.find('@'));
/*LTS-START*/
std::string password;
if (source.find('@') != std::string::npos){
password = source.substr(source.find('@')+1);
if (password != ""){
if (passString == Secure::md5(salt + password)){
DEBUG_MSG(DLVL_DEVEL, "Password accepted - ignoring IP settings.");
IP = "";
}else{
DEBUG_MSG(DLVL_DEVEL, "Password rejected - checking IP.");
if (IP == ""){
IP = "deny-all.invalid";
}
}
}
}
if(Triggers::shouldTrigger("STREAM_PUSH", smp)){
std::string payload = streamName+"\n" + myConn.getHost() +"\n"+capa["name"].asStringRef()+"\n"+reqUrl;
if (!Triggers::doTrigger("STREAM_PUSH", payload, smp)){
DEBUG_MSG(DLVL_FAIL, "Push from %s to %s rejected - STREAM_PUSH trigger denied the push", myConn.getHost().c_str(), streamName.c_str());
myConn.close();
configLock.post();
configLock.close();
return;
}
}
/*LTS-END*/
if (IP != ""){
if (!myConn.isAddress(IP)){
DEBUG_MSG(DLVL_FAIL, "Push from %s to %s rejected - source host not whitelisted", myConn.getHost().c_str(), streamName.c_str());
myConn.close();
}
}
}
}else{
DEBUG_MSG(DLVL_FAIL, "Push from %s rejected - stream '%s' not configured.", myConn.getHost().c_str(), streamName.c_str());
myConn.close();
}
configLock.post();
configLock.close();
if (!myConn){return;}//do not initialize if rejected
initialize();
pushing = true;
}
}

22
src/output/output_dtsc.h Normal file
View file

@ -0,0 +1,22 @@
#include "output.h"
namespace Mist {
class OutDTSC : public Output {
public:
OutDTSC(Socket::Connection & conn);
~OutDTSC();
static void init(Util::Config * cfg);
void onRequest();
void sendNext();
void sendHeader();
private:
std::string salt;
bool pushing;
void handlePush(DTSC::Scan & dScan);
void handlePlay(DTSC::Scan & dScan);
};
}
typedef Mist::OutDTSC mistOut;

View file

@ -4,11 +4,11 @@ namespace Mist {
OutRaw::OutRaw(Socket::Connection & conn) : Output(conn) {
streamName = config->getString("streamname");
initialize();
selectedTracks.clear();
std::string tracks = config->getString("tracks");
unsigned int currTrack = 0;
//loop over tracks, add any found track IDs to selectedTracks
if (tracks != ""){
if (tracks.size()){
selectedTracks.clear();
unsigned int currTrack = 0;
//loop over tracks, add any found track IDs to selectedTracks
for (unsigned int i = 0; i < tracks.size(); ++i){
if (tracks[i] >= '0' && tracks[i] <= '9'){
currTrack = currTrack*10 + (tracks[i] - '0');
@ -46,8 +46,7 @@ namespace Mist {
capa["optional"]["seek"]["help"] = "The time in milliseconds to seek to, 0 by default.";
capa["optional"]["seek"]["type"] = "int";
capa["optional"]["seek"]["option"] = "--seek";
capa["codecs"][0u][0u].append("H264");
capa["codecs"][0u][1u].append("AAC");
capa["codecs"][0u][0u].append("*");
cfg->addOption("streamname",
JSON::fromString("{\"arg\":\"string\",\"short\":\"s\",\"long\":\"stream\",\"help\":\"The name of the stream that this connector will transmit.\"}"));
cfg->addOption("tracks",
@ -68,3 +67,4 @@ namespace Mist {
}
}