TS input now follows generic code path, AlwaysOn made slightly more persistent
This commit is contained in:
parent
a7a8003f2c
commit
185fd6ebb8
3 changed files with 26 additions and 30 deletions
|
@ -465,6 +465,10 @@ namespace Mist {
|
||||||
// - INPUT_TIMEOUT seconds haven't passed yet,
|
// - INPUT_TIMEOUT seconds haven't passed yet,
|
||||||
// - this is a live stream and at least two of the biggest fragment haven't passed yet,
|
// - this is a live stream and at least two of the biggest fragment haven't passed yet,
|
||||||
bool ret = (config->is_active && ((Util::bootSecs() - activityCounter) < INPUT_TIMEOUT || (myMeta.live && (Util::bootSecs() - activityCounter) < myMeta.biggestFragment()/500)));
|
bool ret = (config->is_active && ((Util::bootSecs() - activityCounter) < INPUT_TIMEOUT || (myMeta.live && (Util::bootSecs() - activityCounter) < myMeta.biggestFragment()/500)));
|
||||||
|
if (!ret && config->is_active && isAlwaysOn()){
|
||||||
|
ret = true;
|
||||||
|
activityCounter = Util::bootSecs();
|
||||||
|
}
|
||||||
/*LTS-START*/
|
/*LTS-START*/
|
||||||
if (!ret){
|
if (!ret){
|
||||||
if(Triggers::shouldTrigger("STREAM_UNLOAD", config->getString("streamname"))){
|
if(Triggers::shouldTrigger("STREAM_UNLOAD", config->getString("streamname"))){
|
||||||
|
|
|
@ -375,18 +375,7 @@ namespace Mist {
|
||||||
Util::fseek(inFile, seekPos, SEEK_SET);//seek to the correct position
|
Util::fseek(inFile, seekPos, SEEK_SET);//seek to the correct position
|
||||||
}
|
}
|
||||||
|
|
||||||
void inputTS::stream() {
|
bool inputTS::openStreamSource(){
|
||||||
IPC::semaphore pullLock;
|
|
||||||
pullLock.open(std::string("/MstPull_" + streamName).c_str(), O_CREAT | O_RDWR, ACCESSPERMS, 1);
|
|
||||||
if (!pullLock){
|
|
||||||
FAIL_MSG("Could not open pull lock for stream '%s' - aborting!", streamName.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!pullLock.tryWait()){
|
|
||||||
WARN_MSG("A pull process for stream %s is already running", streamName.c_str());
|
|
||||||
pullLock.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const std::string & inpt = config->getString("input");
|
const std::string & inpt = config->getString("input");
|
||||||
if (inpt.substr(0, 8) == "tsudp://"){
|
if (inpt.substr(0, 8) == "tsudp://"){
|
||||||
HTTP::URL input_url(inpt);
|
HTTP::URL input_url(inpt);
|
||||||
|
@ -394,12 +383,19 @@ namespace Mist {
|
||||||
udpCon.bind(input_url.getPort(), input_url.host, input_url.path);
|
udpCon.bind(input_url.getPort(), input_url.host, input_url.path);
|
||||||
if (udpCon.getSock() == -1){
|
if (udpCon.getSock() == -1){
|
||||||
FAIL_MSG("Could not open UDP socket. Aborting.");
|
FAIL_MSG("Could not open UDP socket. Aborting.");
|
||||||
pullLock.post();
|
return false;
|
||||||
pullLock.close();
|
|
||||||
pullLock.unlink();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void inputTS::parseStreamHeader(){
|
||||||
|
//Placeholder to force normal code to continue despite no tracks available
|
||||||
|
myMeta.tracks[0].type = "audio";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string inputTS::streamMainLoop() {
|
||||||
|
myMeta.tracks.clear();//wipe the placeholder track from above
|
||||||
IPC::sharedClient statsPage = IPC::sharedClient(SHM_STATISTICS, STAT_EX_SIZE, true);
|
IPC::sharedClient statsPage = IPC::sharedClient(SHM_STATISTICS, STAT_EX_SIZE, true);
|
||||||
uint64_t downCounter = 0;
|
uint64_t downCounter = 0;
|
||||||
uint64_t startTime = Util::epoch();
|
uint64_t startTime = Util::epoch();
|
||||||
|
@ -409,7 +405,7 @@ namespace Mist {
|
||||||
cfgPointer = config;
|
cfgPointer = config;
|
||||||
globalStreamName = streamName;
|
globalStreamName = streamName;
|
||||||
unsigned long long threadCheckTimer = Util::bootSecs();
|
unsigned long long threadCheckTimer = Util::bootSecs();
|
||||||
while (config->is_active) {
|
while (config->is_active && nProxy.userClient.isAlive()) {
|
||||||
if (tcpCon) {
|
if (tcpCon) {
|
||||||
if (tcpCon.spool()){
|
if (tcpCon.spool()){
|
||||||
while (tcpCon.Received().available(188)){
|
while (tcpCon.Received().available(188)){
|
||||||
|
@ -431,7 +427,7 @@ namespace Mist {
|
||||||
}
|
}
|
||||||
if (!tcpCon){
|
if (!tcpCon){
|
||||||
config->is_active = false;
|
config->is_active = false;
|
||||||
INFO_MSG("End of streamed input");
|
return "end of streamed input";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::string leftData;
|
std::string leftData;
|
||||||
|
@ -499,10 +495,7 @@ namespace Mist {
|
||||||
if (statsPage.getData()){
|
if (statsPage.getData()){
|
||||||
if (!statsPage.isAlive()){
|
if (!statsPage.isAlive()){
|
||||||
config->is_active = false;
|
config->is_active = false;
|
||||||
pullLock.post();
|
return "received shutdown request from controller";
|
||||||
pullLock.close();
|
|
||||||
pullLock.unlink();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
IPC::statExchange tmpEx(statsPage.getData());
|
IPC::statExchange tmpEx(statsPage.getData());
|
||||||
tmpEx.now(now);
|
tmpEx.now(now);
|
||||||
|
@ -515,14 +508,15 @@ namespace Mist {
|
||||||
tmpEx.lastSecond(0);
|
tmpEx.lastSecond(0);
|
||||||
statsPage.keepAlive();
|
statsPage.keepAlive();
|
||||||
}
|
}
|
||||||
|
nProxy.userClient.keepAlive();
|
||||||
|
|
||||||
std::set<unsigned long> activeTracks = liveStream.getActiveTracks();
|
std::set<unsigned long> activeTracks = liveStream.getActiveTracks();
|
||||||
{
|
{
|
||||||
tthread::lock_guard<tthread::mutex> guard(threadClaimMutex);
|
tthread::lock_guard<tthread::mutex> guard(threadClaimMutex);
|
||||||
if (hasStarted && !threadTimer.size()){
|
if (hasStarted && !threadTimer.size()){
|
||||||
if (!isAlwaysOn()){
|
if (!isAlwaysOn()){
|
||||||
INFO_MSG("Shutting down because no active threads and we had input in the past");
|
|
||||||
config->is_active = false;
|
config->is_active = false;
|
||||||
|
return "no active threads and we had input in the past";
|
||||||
}else{
|
}else{
|
||||||
hasStarted = false;
|
hasStarted = false;
|
||||||
}
|
}
|
||||||
|
@ -551,18 +545,14 @@ namespace Mist {
|
||||||
}
|
}
|
||||||
if (Util::bootSecs() - noDataSince > 20){
|
if (Util::bootSecs() - noDataSince > 20){
|
||||||
if (!isAlwaysOn()){
|
if (!isAlwaysOn()){
|
||||||
WARN_MSG("No packets received for 20 seconds - terminating");
|
|
||||||
config->is_active = false;
|
config->is_active = false;
|
||||||
|
return "No packets received for 20 seconds - terminating";
|
||||||
}else{
|
}else{
|
||||||
noDataSince = Util::bootSecs();
|
noDataSince = Util::bootSecs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finish();
|
return "received shutdown request";
|
||||||
pullLock.post();
|
|
||||||
pullLock.close();
|
|
||||||
pullLock.unlink();
|
|
||||||
INFO_MSG("Input for stream %s closing clean", streamName.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void inputTS::finish() {
|
void inputTS::finish() {
|
||||||
|
|
|
@ -24,7 +24,9 @@ namespace Mist {
|
||||||
void seek(int seekTime);
|
void seek(int seekTime);
|
||||||
void trackSelect(std::string trackSpec);
|
void trackSelect(std::string trackSpec);
|
||||||
void readPMT();
|
void readPMT();
|
||||||
void stream();
|
bool openStreamSource();
|
||||||
|
void parseStreamHeader();
|
||||||
|
std::string streamMainLoop();
|
||||||
void finish();
|
void finish();
|
||||||
FILE * inFile;///<The input file with ts data
|
FILE * inFile;///<The input file with ts data
|
||||||
TS::Stream tsStream;///<Used for parsing the incoming ts stream
|
TS::Stream tsStream;///<Used for parsing the incoming ts stream
|
||||||
|
|
Loading…
Add table
Reference in a new issue