Fully implemented DTSC pull support
This commit is contained in:
parent
668560ff05
commit
dda0ea669c
27 changed files with 930 additions and 272 deletions
|
@ -278,6 +278,16 @@ namespace Mist {
|
|||
onFail();
|
||||
return;
|
||||
}
|
||||
if (!source.size()){
|
||||
std::string strName = streamName;
|
||||
Util::sanitizeName(strName);
|
||||
IPC::sharedPage serverCfg("!mistConfig", DEFAULT_CONF_PAGE_SIZE, false, false); ///< 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(strName);
|
||||
source = streamCfg.getMember("source").asString();
|
||||
configLock.post();
|
||||
}
|
||||
char pageId[NAME_BUFFER_SIZE];
|
||||
snprintf(pageId, NAME_BUFFER_SIZE, SHM_STREAM_INDEX, streamName.c_str());
|
||||
nProxy.metaPages.clear();
|
||||
|
@ -416,9 +426,20 @@ namespace Mist {
|
|||
// when we don't see this explicitly it makes debugging the recording feature
|
||||
// a bit painfull :)
|
||||
if (selectedTracks.size() == 0) {
|
||||
WARN_MSG("We didn't find any tracks which that we can use. selectedTrack.size() is 0.");
|
||||
INSANE_MSG("We didn't find any tracks which that we can use. selectedTrack.size() is 0.");
|
||||
for (std::map<unsigned int,DTSC::Track>::iterator trit = myMeta.tracks.begin(); trit != myMeta.tracks.end(); trit++){
|
||||
WARN_MSG("Found track/codec: %s", trit->second.codec.c_str());
|
||||
INSANE_MSG("Found track/codec: %s", trit->second.codec.c_str());
|
||||
}
|
||||
if (!myMeta.tracks.size() && (source.find("dtsc://") == 0)){
|
||||
//Wait 5 seconds and try again. Keep a counter, try at most 3 times
|
||||
static int counter = 0;
|
||||
if (counter++ < 10){
|
||||
Util::wait(1000);
|
||||
nProxy.userClient.keepAlive();
|
||||
stats();
|
||||
updateMeta();
|
||||
selectDefaultTracks();
|
||||
}
|
||||
}
|
||||
}
|
||||
/*end-roxlu*/
|
||||
|
@ -898,6 +919,25 @@ namespace Mist {
|
|||
}
|
||||
if ( !sentHeader){
|
||||
DEBUG_MSG(DLVL_DONTEVEN, "sendHeader");
|
||||
bool waitLonger = false;
|
||||
if (!myMeta.tracks.size()){
|
||||
waitLonger = true;
|
||||
}else{
|
||||
for (std::map<unsigned int, DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){
|
||||
if (!it->second.keys.size()){
|
||||
waitLonger = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (waitLonger){
|
||||
updateMeta();
|
||||
Util::sleep(1000);
|
||||
static unsigned int metaTries = 0;
|
||||
if(++metaTries < 7){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
sendHeader();
|
||||
}
|
||||
prepareNext();
|
||||
|
|
|
@ -108,6 +108,7 @@ namespace Mist {
|
|||
bool sought;///<If a seek has been done, this is set to true. Used for seeking on prepareNext().
|
||||
bool completeKeyReadyTimeOut;//a bool to see if there has been a keyframe TimeOut for complete keys in Live
|
||||
protected://these are to be messed with by child classes
|
||||
std::string source;
|
||||
|
||||
virtual std::string getConnectedHost();
|
||||
virtual std::string getConnectedBinHost();
|
||||
|
|
|
@ -29,6 +29,7 @@ namespace Mist {
|
|||
myConn.SendNow(sSize, 4);
|
||||
prep.sendTo(myConn);
|
||||
pushing = false;
|
||||
fastAsPossibleTime = 0;
|
||||
}
|
||||
|
||||
OutDTSC::~OutDTSC() {}
|
||||
|
@ -44,12 +45,52 @@ namespace Mist {
|
|||
}
|
||||
|
||||
void OutDTSC::sendNext(){
|
||||
if (!realTime && thisPacket.getTime() >= fastAsPossibleTime){
|
||||
realTime = 1000;
|
||||
}
|
||||
if (thisPacket.getFlag("keyframe")){
|
||||
std::set<unsigned long> availableTracks;
|
||||
for (std::map<unsigned int, DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){
|
||||
if (it->second.type == "video" || it->second.type == "audio"){
|
||||
availableTracks.insert(it->first);
|
||||
}
|
||||
}
|
||||
if (availableTracks != selectedTracks){
|
||||
//reset, resendheader
|
||||
JSON::Value prep;
|
||||
prep["cmd"] = "reset";
|
||||
/// \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);
|
||||
}
|
||||
}
|
||||
myConn.SendNow(thisPacket.getData(), thisPacket.getDataLen());
|
||||
}
|
||||
|
||||
void OutDTSC::sendHeader(){
|
||||
sentHeader = true;
|
||||
myMeta.send(myConn, true);
|
||||
selectedTracks.clear();
|
||||
for (std::map<unsigned int, DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){
|
||||
if (it->second.type == "video" || it->second.type == "audio"){
|
||||
selectedTracks.insert(it->first);
|
||||
}
|
||||
}
|
||||
myMeta.send(myConn, true, selectedTracks);
|
||||
if (myMeta.live){
|
||||
for (std::map<unsigned int, DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){
|
||||
if (!fastAsPossibleTime || it->second.lastms < fastAsPossibleTime){
|
||||
fastAsPossibleTime = it->second.lastms;
|
||||
realTime = 0;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
fastAsPossibleTime = 50000;//50 seconds
|
||||
realTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void OutDTSC::onRequest(){
|
||||
|
@ -76,6 +117,8 @@ namespace Mist {
|
|||
streamName = dScan.getMember("stream").asString();
|
||||
Util::sanitizeName(streamName);
|
||||
parseData = true;
|
||||
INFO_MSG("Handled play for stream %s", streamName.c_str());
|
||||
setBlocking(false);
|
||||
}
|
||||
|
||||
void OutDTSC::handlePush(DTSC::Scan & dScan){
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace Mist {
|
|||
bool pushing;
|
||||
void handlePush(DTSC::Scan & dScan);
|
||||
void handlePlay(DTSC::Scan & dScan);
|
||||
unsigned long long fastAsPossibleTime;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,27 @@ namespace Mist {
|
|||
///\brief Builds an index file for HTTP Live streaming.
|
||||
///\return The index file for HTTP Live Streaming.
|
||||
std::string OutHLS::liveIndex() {
|
||||
|
||||
static int timer = 0;
|
||||
bool checkWait = true;
|
||||
while (checkWait && ++timer < 10){
|
||||
checkWait = false;
|
||||
if (!myMeta.tracks.size()){
|
||||
checkWait = true;
|
||||
}
|
||||
for (std::map<unsigned int,DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){
|
||||
if (it->second.keys.size() <= 3){
|
||||
checkWait = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (checkWait){
|
||||
Util::sleep(500);
|
||||
INFO_MSG("SLeeping timer %d", timer);
|
||||
updateMeta();
|
||||
}
|
||||
}
|
||||
|
||||
std::stringstream result;
|
||||
result << "#EXTM3U\r\n";
|
||||
int audioId = -1;
|
||||
|
|
|
@ -43,6 +43,9 @@ namespace Mist {
|
|||
|
||||
///\todo This function does not indicate errors anywhere... maybe fix this...
|
||||
std::string OutProgressiveMP4::DTSCMeta2MP4Header(long long & size, int fragmented) {
|
||||
if (myMeta.live){
|
||||
completeKeysOnly = true;
|
||||
}
|
||||
//Make sure we have a proper being value for the size...
|
||||
size = 0;
|
||||
//Stores the result of the function
|
||||
|
@ -745,6 +748,28 @@ namespace Mist {
|
|||
|
||||
void OutProgressiveMP4::setvidTrack() {
|
||||
vidTrack = 0;
|
||||
static int timer = 0;
|
||||
bool checkWait = true;
|
||||
while (checkWait && ++timer < 10){
|
||||
checkWait = false;
|
||||
if (!myMeta.tracks.size()){
|
||||
checkWait = true;
|
||||
}
|
||||
for (std::map<unsigned int,DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){
|
||||
if (!it->second.keys.size()){
|
||||
checkWait = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (checkWait){
|
||||
Util::sleep(500);
|
||||
updateMeta();
|
||||
}
|
||||
}
|
||||
|
||||
if (!selectedTracks.size()){
|
||||
selectDefaultTracks();
|
||||
}
|
||||
for (std::set<long unsigned int>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++) {
|
||||
//Find video track
|
||||
if (myMeta.tracks[*it].type == "video") {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue