Implemented proper tsudp:// protocol push output, removed MistOutTSPush
This commit is contained in:
parent
172bdabf36
commit
856043ed55
5 changed files with 64 additions and 117 deletions
|
@ -376,7 +376,6 @@ makeOutput(HTTPTS httpts http ts)
|
||||||
makeOutput(HLS hls http ts)
|
makeOutput(HLS hls http ts)
|
||||||
makeOutput(Push push)#LTS
|
makeOutput(Push push)#LTS
|
||||||
makeOutput(RTSP rtsp)#LTS
|
makeOutput(RTSP rtsp)#LTS
|
||||||
makeOutput(TSPush ts_push ts)#LTS
|
|
||||||
makeOutput(DASH dash_mp4 http)#LTS
|
makeOutput(DASH dash_mp4 http)#LTS
|
||||||
|
|
||||||
if (DEFINED WITH_SANITY )
|
if (DEFINED WITH_SANITY )
|
||||||
|
|
|
@ -7,8 +7,39 @@ namespace Mist {
|
||||||
streamName = config->getString("streamname");
|
streamName = config->getString("streamname");
|
||||||
parseData = true;
|
parseData = true;
|
||||||
wantRequest = false;
|
wantRequest = false;
|
||||||
|
pushOut = false;
|
||||||
initialize();
|
initialize();
|
||||||
std::string tracks = config->getString("tracks");
|
std::string tracks = config->getString("tracks");
|
||||||
|
if (config->getString("target").size()){
|
||||||
|
std::string target = config->getString("target");
|
||||||
|
if (target.substr(0,8) != "tsudp://"){
|
||||||
|
FAIL_MSG("Target %s must begin with tsudp://, aborting", target.c_str());
|
||||||
|
parseData = false;
|
||||||
|
myConn.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//strip beginning off URL
|
||||||
|
target.erase(0, 8);
|
||||||
|
if (target.find(':') == std::string::npos){
|
||||||
|
FAIL_MSG("Target %s must contain a port, aborting", target.c_str());
|
||||||
|
parseData = false;
|
||||||
|
myConn.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pushOut = true;
|
||||||
|
udpSize = 5;
|
||||||
|
sendRepeatingHeaders = true;
|
||||||
|
if (target.find('?') != std::string::npos){
|
||||||
|
std::map<std::string, std::string> vars;
|
||||||
|
HTTP::parseVars(target.substr(target.find('?')+1), vars);
|
||||||
|
if (vars.count("tracks")){tracks = vars["tracks"];}
|
||||||
|
if (vars.count("pkts")){udpSize = atoi(vars["pkts"].c_str());}
|
||||||
|
}
|
||||||
|
packetBuffer.reserve(188*udpSize);
|
||||||
|
int port = atoi(target.substr(target.find(":") + 1).c_str());
|
||||||
|
target.erase(target.find(":"));//strip all after the colon
|
||||||
|
pushSock.SetDestination(target, port);
|
||||||
|
}
|
||||||
unsigned int currTrack = 0;
|
unsigned int currTrack = 0;
|
||||||
//loop over tracks, add any found track IDs to selectedTracks
|
//loop over tracks, add any found track IDs to selectedTracks
|
||||||
if (tracks != ""){
|
if (tracks != ""){
|
||||||
|
@ -54,9 +85,34 @@ namespace Mist {
|
||||||
capa["codecs"][0u][1u].append("AC3");
|
capa["codecs"][0u][1u].append("AC3");
|
||||||
cfg->addConnectorOptions(8888, capa);
|
cfg->addConnectorOptions(8888, capa);
|
||||||
config = cfg;
|
config = cfg;
|
||||||
|
capa["push_urls"].append("tsudp://*");
|
||||||
|
|
||||||
|
JSON::Value opt;
|
||||||
|
opt["arg"] = "string";
|
||||||
|
opt["default"] = "";
|
||||||
|
opt["arg_num"] = 1ll;
|
||||||
|
opt["help"] = "Target tsudp:// URL to push out towards.";
|
||||||
|
cfg->addOption("target", opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutTS::sendTS(const char * tsData, unsigned int len){
|
void OutTS::sendTS(const char * tsData, unsigned int len){
|
||||||
myConn.SendNow(tsData, len);
|
if (pushOut){
|
||||||
|
static int curFilled = 0;
|
||||||
|
if (curFilled == udpSize){
|
||||||
|
pushSock.SendNow(packetBuffer);
|
||||||
|
packetBuffer.clear();
|
||||||
|
packetBuffer.reserve(udpSize * len);
|
||||||
|
curFilled = 0;
|
||||||
|
}
|
||||||
|
packetBuffer.append(tsData, len);
|
||||||
|
curFilled ++;
|
||||||
|
}else{
|
||||||
|
myConn.SendNow(tsData, len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OutTS::listenMode(){
|
||||||
|
return !(config->getString("target").size());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,12 @@ namespace Mist {
|
||||||
~OutTS();
|
~OutTS();
|
||||||
static void init(Util::Config * cfg);
|
static void init(Util::Config * cfg);
|
||||||
void sendTS(const char * tsData, unsigned int len=188);
|
void sendTS(const char * tsData, unsigned int len=188);
|
||||||
|
static bool listenMode();
|
||||||
|
private:
|
||||||
|
unsigned int udpSize;
|
||||||
|
bool pushOut;
|
||||||
|
std::string packetBuffer;
|
||||||
|
Socket::UDPConnection pushSock;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
#include "output_ts_push.h"
|
|
||||||
#include <mist/http_parser.h>
|
|
||||||
#include <mist/defines.h>
|
|
||||||
|
|
||||||
namespace Mist {
|
|
||||||
OutTSPush::OutTSPush(Socket::Connection & conn) : TSOutput(conn){
|
|
||||||
streamName = config->getString("streamname");
|
|
||||||
parseData = true;
|
|
||||||
wantRequest = false;
|
|
||||||
sendRepeatingHeaders = true;
|
|
||||||
initialize();
|
|
||||||
std::string tracks = config->getString("tracks");
|
|
||||||
unsigned int currTrack = 0;
|
|
||||||
//loop over tracks, add any found track IDs to selectedTracks
|
|
||||||
if (tracks != ""){
|
|
||||||
selectedTracks.clear();
|
|
||||||
for (unsigned int i = 0; i < tracks.size(); ++i){
|
|
||||||
if (tracks[i] >= '0' && tracks[i] <= '9'){
|
|
||||||
currTrack = currTrack*10 + (tracks[i] - '0');
|
|
||||||
}else{
|
|
||||||
if (currTrack > 0){
|
|
||||||
selectedTracks.insert(currTrack);
|
|
||||||
}
|
|
||||||
currTrack = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (currTrack > 0){
|
|
||||||
selectedTracks.insert(currTrack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//For udp pushing, 7 ts packets a time
|
|
||||||
packetBuffer.reserve(config->getInteger("udpsize") * 188);
|
|
||||||
std::string host = config->getString("destination");
|
|
||||||
if (host.substr(0, 6) == "udp://"){
|
|
||||||
host = host.substr(6);
|
|
||||||
}
|
|
||||||
int port = atoi(host.substr(host.find(":") + 1).c_str());
|
|
||||||
host = host.substr(0, host.find(":"));
|
|
||||||
pushSock.SetDestination(host, port);
|
|
||||||
}
|
|
||||||
|
|
||||||
OutTSPush::~OutTSPush() {}
|
|
||||||
|
|
||||||
void OutTSPush::init(Util::Config * cfg){
|
|
||||||
Output::init(cfg);
|
|
||||||
capa["name"] = "TSPush";
|
|
||||||
capa["desc"] = "Push raw MPEG/TS over a TCP or UDP socket.";
|
|
||||||
capa["deps"] = "";
|
|
||||||
capa["required"]["streamname"]["name"] = "Stream";
|
|
||||||
capa["required"]["streamname"]["help"] = "What streamname to serve. For multiple streams, add this protocol multiple times using different ports.";
|
|
||||||
capa["required"]["streamname"]["type"] = "str";
|
|
||||||
capa["required"]["streamname"]["option"] = "--stream";
|
|
||||||
capa["required"]["streamname"]["short"] = "s";
|
|
||||||
capa["required"]["destination"]["name"] = "Destination";
|
|
||||||
capa["required"]["destination"]["help"] = "Where to push to, in the format protocol://hostname:port. Ie: udp://127.0.0.1:9876";
|
|
||||||
capa["required"]["destination"]["type"] = "str";
|
|
||||||
capa["required"]["destination"]["option"] = "--destination";
|
|
||||||
capa["required"]["destination"]["short"] = "D";
|
|
||||||
capa["required"]["udpsize"]["name"] = "UDP Size";
|
|
||||||
capa["required"]["udpsize"]["help"] = "The number of TS packets to push in a single UDP datagram";
|
|
||||||
capa["required"]["udpsize"]["type"] = "uint";
|
|
||||||
capa["required"]["udpsize"]["default"] = 5;
|
|
||||||
capa["required"]["udpsize"]["option"] = "--udpsize";
|
|
||||||
capa["required"]["udpsize"]["short"] = "u";
|
|
||||||
capa["optional"]["tracks"]["name"] = "Tracks";
|
|
||||||
capa["optional"]["tracks"]["help"] = "The track IDs of the stream that this connector will transmit separated by spaces";
|
|
||||||
capa["optional"]["tracks"]["type"] = "str";
|
|
||||||
capa["optional"]["tracks"]["option"] = "--tracks";
|
|
||||||
capa["optional"]["tracks"]["short"] = "t";
|
|
||||||
capa["optional"]["tracks"]["default"] = "";
|
|
||||||
capa["codecs"][0u][0u].append("HEVC");
|
|
||||||
capa["codecs"][0u][0u].append("H264");
|
|
||||||
capa["codecs"][0u][1u].append("AAC");
|
|
||||||
capa["codecs"][0u][1u].append("MP3");
|
|
||||||
cfg->addBasicConnectorOptions(capa);
|
|
||||||
config = cfg;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OutTSPush::fillBuffer(const char * data, size_t dataLen){
|
|
||||||
static int curFilled = 0;
|
|
||||||
if (curFilled == config->getInteger("udpsize")){
|
|
||||||
pushSock.SendNow(packetBuffer);
|
|
||||||
packetBuffer.clear();
|
|
||||||
packetBuffer.reserve(config->getInteger("udpsize") * 188);
|
|
||||||
curFilled = 0;
|
|
||||||
}
|
|
||||||
packetBuffer += std::string(data, 188);
|
|
||||||
curFilled ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OutTSPush::sendTS(const char * tsData, unsigned int len){
|
|
||||||
fillBuffer(tsData, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
#include "output_ts_base.h"
|
|
||||||
|
|
||||||
namespace Mist {
|
|
||||||
class OutTSPush : public TSOutput{
|
|
||||||
public:
|
|
||||||
OutTSPush(Socket::Connection & conn);
|
|
||||||
~OutTSPush();
|
|
||||||
static void init(Util::Config * cfg);
|
|
||||||
static bool listenMode(){return false;}
|
|
||||||
void sendTS(const char * tsData, unsigned int len=188);
|
|
||||||
protected:
|
|
||||||
void fillBuffer(const char * data, size_t dataLen);
|
|
||||||
std::string packetBuffer;
|
|
||||||
Socket::UDPConnection pushSock;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef Mist::OutTSPush mistOut;
|
|
Loading…
Add table
Reference in a new issue