Fixed TS, added several parameters for MistConnTS, controller now builds parameters correctly (spaces issue)
This commit is contained in:
parent
67815bcce4
commit
2cc27efcae
4 changed files with 154 additions and 16 deletions
|
@ -293,7 +293,7 @@ namespace Connector_HTTP {
|
|||
}
|
||||
}
|
||||
ToPack.prepend(TS::Packet::getPESVideoLeadIn(0ul, Strm.getPacket()["time"].asInt() * 90));
|
||||
PIDno = 0x100;
|
||||
PIDno = 0x100 - 1 + Strm.getPacket()["trackid"].asInt();
|
||||
ContCounter = &VideoCounter;
|
||||
}else if (Strm.lastType() == DTSC::AUDIO){
|
||||
ToPack.append(TS::GetAudioHeader(Strm.lastData().size(), Strm.getTrackById(audioTrackID)["init"].asString()));
|
||||
|
@ -303,7 +303,7 @@ namespace Connector_HTTP {
|
|||
}else{
|
||||
ToPack.prepend(TS::Packet::getPESAudioLeadIn(ToPack.bytes(1073741824ul), Strm.getPacket()["time"].asInt() * 90));
|
||||
}
|
||||
PIDno = 0x101;
|
||||
PIDno = 0x100 - 1 + Strm.getPacket()["trackid"].asInt();
|
||||
ContCounter = &AudioCounter;
|
||||
IsKeyFrame = false;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace Connector_TS {
|
|||
///\param conn A socket describing the connection the client.
|
||||
///\param streamName The stream to connect to.
|
||||
///\return The exit code of the connector.
|
||||
int tsConnector(Socket::Connection conn, std::string streamName){
|
||||
int tsConnector(Socket::Connection conn, std::string streamName, std::string trackIDs){
|
||||
std::string ToPack;
|
||||
TS::Packet PackData;
|
||||
std::string DTMIData;
|
||||
|
@ -59,15 +59,54 @@ namespace Connector_TS {
|
|||
conn.close();
|
||||
break;
|
||||
}
|
||||
ss.SendNow("p\n");
|
||||
|
||||
if(trackIDs == ""){
|
||||
// no track ids given? Find the first video and first audio track (if available) and use those!
|
||||
int videoID = -1;
|
||||
int audioID = -1;
|
||||
|
||||
//make sure metadata is received
|
||||
while ( !Strm.metadata && ss.connected()){
|
||||
if (ss.spool()){
|
||||
while (Strm.parsePacket(ss.Received())){
|
||||
//do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Strm.metadata.isMember("tracks")){
|
||||
|
||||
for (JSON::ObjIter trackIt = Strm.metadata["tracks"].ObjBegin(); trackIt != Strm.metadata["tracks"].ObjEnd(); trackIt++){
|
||||
|
||||
if (audioID == -1 && trackIt->second["type"].asString() == "audio"){
|
||||
audioID = trackIt->second["trackid"].asInt();
|
||||
if( trackIDs != ""){
|
||||
trackIDs += " " + trackIt->second["trackid"].asString();
|
||||
}else{
|
||||
trackIDs = trackIt->second["trackid"].asString();
|
||||
}
|
||||
}
|
||||
|
||||
if (videoID == -1 && trackIt->second["type"].asString() == "video"){
|
||||
videoID = trackIt->second["trackid"].asInt();
|
||||
if( trackIDs != ""){
|
||||
trackIDs += " " + trackIt->second["trackid"].asString();
|
||||
}else{
|
||||
trackIDs = trackIt->second["trackid"].asString();
|
||||
}
|
||||
}
|
||||
|
||||
} // for iterator
|
||||
} // if isMember("tracks")
|
||||
} // if trackIDs == ""
|
||||
|
||||
std::string cmd = "t " + trackIDs + "\np\n";
|
||||
ss.SendNow( cmd );
|
||||
inited = true;
|
||||
}
|
||||
if (ss.spool()){
|
||||
while (Strm.parsePacket(ss.Received())){
|
||||
if ( !haveAvcc){
|
||||
avccbox.setPayload(Strm.metadata["video"]["init"].asString());
|
||||
haveAvcc = true;
|
||||
}
|
||||
|
||||
std::stringstream TSBuf;
|
||||
Socket::Buffer ToPack;
|
||||
//write PAT and PMT TS packets
|
||||
|
@ -82,12 +121,17 @@ namespace Connector_TS {
|
|||
int PIDno = 0;
|
||||
char * ContCounter = 0;
|
||||
if (Strm.lastType() == DTSC::VIDEO){
|
||||
if ( !haveAvcc){
|
||||
avccbox.setPayload(Strm.getTrackById(Strm.getPacket()["trackid"].asInt())["init"].asString());
|
||||
haveAvcc = true;
|
||||
}
|
||||
|
||||
IsKeyFrame = Strm.getPacket().isMember("keyframe");
|
||||
if (IsKeyFrame){
|
||||
TimeStamp = (Strm.getPacket()["time"].asInt() * 27000);
|
||||
}
|
||||
ToPack.append(avccbox.asAnnexB());
|
||||
while (Strm.lastData().size()){
|
||||
while (Strm.lastData().size() > 4){
|
||||
ThisNaluSize = (Strm.lastData()[0] << 24) + (Strm.lastData()[1] << 16) + (Strm.lastData()[2] << 8) + Strm.lastData()[3];
|
||||
Strm.lastData().replace(0, 4, TS::NalHeader, 4);
|
||||
if (ThisNaluSize + 4 == Strm.lastData().size()){
|
||||
|
@ -99,14 +143,15 @@ namespace Connector_TS {
|
|||
}
|
||||
}
|
||||
ToPack.prepend(TS::Packet::getPESVideoLeadIn(0ul, Strm.getPacket()["time"].asInt() * 90));
|
||||
PIDno = 0x100;
|
||||
PIDno = 0x100 - 1 + Strm.getPacket()["trackid"].asInt();
|
||||
ContCounter = &VideoCounter;
|
||||
}else if (Strm.lastType() == DTSC::AUDIO){
|
||||
ToPack.append(TS::GetAudioHeader(Strm.lastData().size(), Strm.metadata["audio"]["init"].asString()));
|
||||
ToPack.append(TS::GetAudioHeader(Strm.lastData().size(), Strm.getTrackById(Strm.getPacket()["trackid"].asInt())["init"].asString()));
|
||||
ToPack.append(Strm.lastData());
|
||||
ToPack.prepend(TS::Packet::getPESAudioLeadIn(ToPack.bytes(1073741824ul), Strm.getPacket()["time"].asInt() * 90));
|
||||
PIDno = 0x101;
|
||||
PIDno = 0x100 - 1 + Strm.getPacket()["trackid"].asInt();
|
||||
ContCounter = &AudioCounter;
|
||||
IsKeyFrame = false;
|
||||
}
|
||||
|
||||
//initial packet
|
||||
|
@ -154,6 +199,8 @@ int main(int argc, char ** argv){
|
|||
Util::Config conf(argv[0], PACKAGE_VERSION);
|
||||
conf.addOption("streamname",
|
||||
JSON::fromString("{\"arg\":\"string\",\"arg_num\":1,\"help\":\"The name of the stream that this connector will transmit.\"}"));
|
||||
conf.addOption("tracks",
|
||||
JSON::fromString("{\"arg\":\"string\",\"default\":\"\",\"short\": \"t\",\"long\":\"tracks\",\"help\":\"The track IDs of the stream that this connector will transmit separated by spaces.\"}"));
|
||||
conf.addConnectorOptions(8888);
|
||||
conf.parseArgs(argc, argv);
|
||||
Socket::Server server_socket = Socket::Server(conf.getInteger("listen_port"), conf.getString("listen_interface"));
|
||||
|
@ -167,7 +214,7 @@ int main(int argc, char ** argv){
|
|||
if (S.connected()){ //check if the new connection is valid
|
||||
pid_t myid = fork();
|
||||
if (myid == 0){ //if new child, start MAINHANDLER
|
||||
return Connector_TS::tsConnector(S, conf.getString("streamname"));
|
||||
return Connector_TS::tsConnector(S, conf.getString("streamname"), conf.getString("tracks"));
|
||||
}else{ //otherwise, do nothing or output debugging text
|
||||
#if DEBUG >= 5
|
||||
fprintf(stderr, "Spawned new process %i for socket %i\n", (int)myid, S.getSocket());
|
||||
|
|
|
@ -184,6 +184,9 @@ namespace Controller {
|
|||
capa["connectors"]["TS"]["optional"]["username"]["name"] = "Username";
|
||||
capa["connectors"]["TS"]["optional"]["username"]["help"] = "Username to drop privileges to - default if unprovided means do not drop privileges";
|
||||
capa["connectors"]["TS"]["optional"]["username"]["type"] = "str";
|
||||
capa["connectors"]["TS"]["optional"]["tracks"]["name"] = "Tracks";
|
||||
capa["connectors"]["TS"]["optional"]["tracks"]["help"] = "The track IDs of the stream that this connector will transmit separated by spaces";
|
||||
capa["connectors"]["TS"]["optional"]["tracks"]["type"] = "str";
|
||||
capa["connectors"]["HTTP"]["desc"] =
|
||||
"Enables the generic HTTP listener, required by all other HTTP protocols. Needs other HTTP protocols enabled to do much of anything.";
|
||||
capa["connectors"]["HTTP"]["deps"] = "";
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#include <stdio.h> // cout, cerr
|
||||
#include <string>
|
||||
#include <cstring> // strcpy
|
||||
#include <mist/json.h>
|
||||
#include <mist/config.h>
|
||||
#include <mist/procs.h>
|
||||
|
@ -10,6 +13,8 @@ namespace Controller {
|
|||
|
||||
static std::map<std::string, std::string> currentConnectors; ///<The currently running connectors.
|
||||
|
||||
|
||||
|
||||
///\brief Checks if the binary mentioned in the protocol argument is currently active, if so, restarts it.
|
||||
///\param protocol The protocol to check.
|
||||
void UpdateProtocol(std::string protocol){
|
||||
|
@ -32,7 +37,64 @@ namespace Controller {
|
|||
}
|
||||
}
|
||||
|
||||
///\brief Checks current protocol configuration, updates state of enabled connectors if neccesary.
|
||||
|
||||
|
||||
void buildPipedArguments(JSON::Value & p, std::string conn, char * argarr[]){
|
||||
int argnum = 2; //first two are progname and -n
|
||||
std::string arg;
|
||||
|
||||
std::string conname;
|
||||
|
||||
for (JSON::ArrIter ait = p.ArrBegin(); ait != p.ArrEnd(); ait++){
|
||||
|
||||
conname = (std::string("MistConn") + ( *ait)["connector"].asString());
|
||||
conn = conn.substr(0, conn.find(" ") );
|
||||
|
||||
if ( !( *ait).isMember("connector") || ( *ait)["connector"].asString() == "" || conn != conname){
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string tmppath = Util::getMyPath() + std::string("MistConn") + ( *ait)["connector"].asString();
|
||||
argarr[0] = new char[ tmppath.size() + 1]; std::strncpy(argarr[0], tmppath.c_str(), tmppath.size() + 1);
|
||||
|
||||
argarr[1] = new char[3]; std::strncpy(argarr[1], "-n\0", 3);
|
||||
|
||||
if (( *ait).isMember("port") && ( *ait)["port"].asInt() != 0){
|
||||
arg = ( *ait)["port"].asString();
|
||||
argarr[argnum] = new char[3]; std::strncpy(argarr[argnum], "-p\0", 3); argnum++;
|
||||
argarr[argnum] = new char[arg.size() + 1]; std::strncpy(argarr[argnum], arg.c_str(), arg.size() + 1); argnum++;
|
||||
}
|
||||
|
||||
if (( *ait).isMember("interface") && ( *ait)["interface"].asString() != "" && ( *ait)["interface"].asString() != "0.0.0.0"){
|
||||
arg = ( *ait)["interface"].asString();
|
||||
argarr[argnum] = new char[3]; std::strncpy(argarr[argnum], "-i\0", 3); argnum++;
|
||||
argarr[argnum] = new char[arg.size() + 1]; std::strncpy(argarr[argnum], arg.c_str(), arg.size() + 1 ); argnum++;
|
||||
}
|
||||
|
||||
if (( *ait).isMember("username") && ( *ait)["username"].asString() != "" && ( *ait)["username"].asString() != "root"){
|
||||
arg = ( *ait)["username"].asString();
|
||||
argarr[argnum] = new char[3]; std::strncpy(argarr[argnum], "-u\0", 3); argnum++;
|
||||
argarr[argnum] = new char[arg.size() + 1]; std::strncpy(argarr[argnum], arg.c_str(), arg.size() + 1); argnum++;
|
||||
}
|
||||
|
||||
if (( *ait).isMember("tracks") && ( *ait)["tracks"].asString() != ""){
|
||||
arg = ( *ait)["tracks"].asString();
|
||||
argarr[argnum] = new char[3]; std::strncpy(argarr[argnum], "-t\0", 3); argnum++;
|
||||
argarr[argnum] = new char[arg.size() + 1]; std::strncpy(argarr[argnum], arg.c_str(), arg.size() + 1); argnum++;
|
||||
}
|
||||
|
||||
if (( *ait).isMember("args") && ( *ait)["args"].asString() != ""){
|
||||
arg = ( *ait)["args"].asString();
|
||||
argarr[argnum] = new char[arg.size() + 1]; std::strncpy(argarr[argnum], arg.c_str(), arg.size() + 1); argnum++;
|
||||
}
|
||||
}
|
||||
|
||||
argarr[argnum] = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///\brief Checks current protocol coguration, updates state of enabled connectors if neccesary.
|
||||
///\param p An object containing all protocols.
|
||||
void CheckProtocols(JSON::Value & p){
|
||||
std::map<std::string, std::string> new_connectors;
|
||||
|
@ -40,6 +102,13 @@ namespace Controller {
|
|||
bool haveHTTPgeneric = false;
|
||||
bool haveHTTPspecific = false;
|
||||
|
||||
// used for building args
|
||||
int zero = 0;
|
||||
int out = fileno(stdout);
|
||||
int err = fileno(stderr);
|
||||
char * argarr[15]; // approx max # of args (with a wide margin)
|
||||
int i;
|
||||
|
||||
std::string tmp;
|
||||
JSON::Value counter = (long long int)0;
|
||||
|
||||
|
@ -48,7 +117,9 @@ namespace Controller {
|
|||
continue;
|
||||
}
|
||||
|
||||
tmp = std::string("MistConn") + ( *ait)["connector"].asString() + std::string(" -n");
|
||||
tmp = std::string("MistConn") + ( *ait)["connector"].asString();
|
||||
tmp += std::string(" -n");
|
||||
|
||||
if (( *ait)["connector"].asString() == "HTTP"){
|
||||
haveHTTPgeneric = true;
|
||||
}
|
||||
|
@ -62,12 +133,17 @@ namespace Controller {
|
|||
|
||||
if (( *ait).isMember("interface") && ( *ait)["interface"].asString() != "" && ( *ait)["interface"].asString() != "0.0.0.0"){
|
||||
tmp += std::string(" -i ") + ( *ait)["interface"].asString();
|
||||
|
||||
}
|
||||
|
||||
if (( *ait).isMember("username") && ( *ait)["username"].asString() != "" && ( *ait)["username"].asString() != "root"){
|
||||
tmp += std::string(" -u ") + ( *ait)["username"].asString();
|
||||
}
|
||||
|
||||
if (( *ait).isMember("tracks") && ( *ait)["tracks"].asString() != ""){
|
||||
tmp += std::string(" -t \"") + ( *ait)["tracks"].asString() + "\"";
|
||||
}
|
||||
|
||||
if (( *ait).isMember("args") && ( *ait)["args"].asString() != ""){
|
||||
tmp += std::string(" ") + ( *ait)["args"].asString();
|
||||
}
|
||||
|
@ -93,7 +169,19 @@ namespace Controller {
|
|||
for (iter = new_connectors.begin(); iter != new_connectors.end(); iter++){
|
||||
if (currentConnectors.count(iter->first) != 1 || currentConnectors[iter->first] != iter->second || !Util::Procs::isActive(iter->first)){
|
||||
Log("CONF", "Starting connector: " + iter->second);
|
||||
Util::Procs::Start(iter->first, Util::getMyPath() + iter->second);
|
||||
|
||||
// clear out old args
|
||||
for (i=0;i<15;i++)
|
||||
{
|
||||
argarr[i] = NULL;
|
||||
}
|
||||
|
||||
// get args for this connector
|
||||
buildPipedArguments(p, iter->second, (char **)&argarr);
|
||||
|
||||
// start piped w/ generated args
|
||||
Util::Procs::StartPiped(iter->first, argarr, &zero, &out, &err);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue