Backported various little edits from Pro edition.
This commit is contained in:
parent
ef9938da0c
commit
4c9c6fa7ba
78 changed files with 2334 additions and 1266 deletions
|
@ -7,6 +7,9 @@
|
|||
#include <mist/stream.h>
|
||||
#include <mist/defines.h>
|
||||
|
||||
#include <mist/util.h>
|
||||
#include <mist/bitfields.h>
|
||||
|
||||
#include "input_dtsc.h"
|
||||
|
||||
namespace Mist {
|
||||
|
@ -14,7 +17,8 @@ namespace Mist {
|
|||
capa["name"] = "DTSC";
|
||||
capa["desc"] = "Enables DTSC Input";
|
||||
capa["priority"] = 9ll;
|
||||
capa["source_match"] = "/*.dtsc";
|
||||
capa["source_match"].append("/*.dtsc");
|
||||
capa["source_match"].append("dtsc://*");
|
||||
capa["codecs"][0u][0u].append("H264");
|
||||
capa["codecs"][0u][0u].append("H263");
|
||||
capa["codecs"][0u][0u].append("VP6");
|
||||
|
@ -24,7 +28,142 @@ namespace Mist {
|
|||
capa["codecs"][0u][1u].append("vorbis");
|
||||
}
|
||||
|
||||
bool inputDTSC::needsLock(){
|
||||
return config->getString("input").substr(0, 7) != "dtsc://";
|
||||
}
|
||||
|
||||
void parseDTSCURI(const std::string & src, std::string & host, uint16_t & port, std::string & password, std::string & streamName) {
|
||||
host = "";
|
||||
port = 4200;
|
||||
password = "";
|
||||
streamName = "";
|
||||
std::deque<std::string> matches;
|
||||
if (Util::stringScan(src, "%s:%s@%s/%s", matches)) {
|
||||
host = matches[0];
|
||||
port = atoi(matches[1].c_str());
|
||||
password = matches[2];
|
||||
streamName = matches[3];
|
||||
return;
|
||||
}
|
||||
//Using default streamname
|
||||
if (Util::stringScan(src, "%s:%s@%s", matches)) {
|
||||
host = matches[0];
|
||||
port = atoi(matches[1].c_str());
|
||||
password = matches[2];
|
||||
return;
|
||||
}
|
||||
//Without password
|
||||
if (Util::stringScan(src, "%s:%s/%s", matches)) {
|
||||
host = matches[0];
|
||||
port = atoi(matches[1].c_str());
|
||||
streamName = matches[2];
|
||||
return;
|
||||
}
|
||||
//Using default port
|
||||
if (Util::stringScan(src, "%s@%s/%s", matches)) {
|
||||
host = matches[0];
|
||||
password = matches[1];
|
||||
streamName = matches[2];
|
||||
return;
|
||||
}
|
||||
//Default port, no password
|
||||
if (Util::stringScan(src, "%s/%s", matches)) {
|
||||
host = matches[0];
|
||||
streamName = matches[1];
|
||||
return;
|
||||
}
|
||||
//No password, default streamname
|
||||
if (Util::stringScan(src, "%s:%s", matches)) {
|
||||
host = matches[0];
|
||||
port = atoi(matches[1].c_str());
|
||||
return;
|
||||
}
|
||||
//Default port and streamname
|
||||
if (Util::stringScan(src, "%s@%s", matches)) {
|
||||
host = matches[0];
|
||||
password = matches[1];
|
||||
return;
|
||||
}
|
||||
//Default port and streamname, no password
|
||||
if (Util::stringScan(src, "%s", matches)) {
|
||||
host = matches[0];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void inputDTSC::parseStreamHeader() {
|
||||
while (srcConn.connected()){
|
||||
srcConn.spool();
|
||||
if (srcConn.Received().available(8)){
|
||||
if (srcConn.Received().copy(4) == "DTCM" || srcConn.Received().copy(4) == "DTSC") {
|
||||
// Command message
|
||||
std::string toRec = srcConn.Received().copy(8);
|
||||
unsigned long rSize = Bit::btohl(toRec.c_str() + 4);
|
||||
if (!srcConn.Received().available(8 + rSize)) {
|
||||
continue; //abort - not enough data yet
|
||||
}
|
||||
//Ignore initial DTCM message, as this is a "hi" message from the server
|
||||
if (srcConn.Received().copy(4) == "DTCM"){
|
||||
srcConn.Received().remove(8 + rSize);
|
||||
}else{
|
||||
std::string dataPacket = srcConn.Received().remove(8+rSize);
|
||||
DTSC::Packet metaPack(dataPacket.data(), dataPacket.size());
|
||||
myMeta.reinit(metaPack);
|
||||
for (std::map<unsigned int, DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){
|
||||
continueNegotiate(it->first, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
INFO_MSG("Received a wrong type of packet - '%s'", srcConn.Received().copy(4).c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool inputDTSC::openStreamSource() {
|
||||
std::string source = config->getString("input");
|
||||
if (source.find("dtsc://") == 0) {
|
||||
source.erase(0, 7);
|
||||
}
|
||||
std::string host;
|
||||
uint16_t port;
|
||||
std::string password;
|
||||
std::string streamName;
|
||||
parseDTSCURI(source, host, port, password, streamName);
|
||||
std::string givenStream = config->getString("streamname");
|
||||
if (streamName == "") {
|
||||
streamName = givenStream;
|
||||
}else{
|
||||
if (givenStream.find("+") != std::string::npos){
|
||||
streamName += givenStream.substr(givenStream.find("+"));
|
||||
}
|
||||
}
|
||||
srcConn = Socket::Connection(host, port, true);
|
||||
if (!srcConn.connected()){
|
||||
return false;
|
||||
}
|
||||
JSON::Value prep;
|
||||
prep["cmd"] = "play";
|
||||
prep["version"] = "MistServer " PACKAGE_VERSION;
|
||||
prep["stream"] = streamName;
|
||||
srcConn.SendNow("DTCM");
|
||||
char sSize[4] = {0, 0, 0, 0};
|
||||
Bit::htobl(sSize, prep.packedSize());
|
||||
srcConn.SendNow(sSize, 4);
|
||||
prep.sendTo(srcConn);
|
||||
return true;
|
||||
}
|
||||
|
||||
void inputDTSC::closeStreamSource(){
|
||||
srcConn.close();
|
||||
}
|
||||
|
||||
bool inputDTSC::setup() {
|
||||
if (!needsLock()) {
|
||||
return true;
|
||||
} else {
|
||||
if (config->getString("input") == "-") {
|
||||
std::cerr << "Input from stdin not yet supported" << std::endl;
|
||||
return false;
|
||||
|
@ -46,10 +185,14 @@ namespace Mist {
|
|||
if (!inFile) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool inputDTSC::readHeader() {
|
||||
if (!needsLock()) {
|
||||
return true;
|
||||
}
|
||||
if (!inFile) {
|
||||
return false;
|
||||
}
|
||||
|
@ -69,12 +212,62 @@ namespace Mist {
|
|||
}
|
||||
|
||||
void inputDTSC::getNext(bool smart) {
|
||||
if (!needsLock()){
|
||||
thisPacket.reInit(srcConn);
|
||||
if (thisPacket.getVersion() == DTSC::DTCM){
|
||||
std::string cmd;
|
||||
thisPacket.getString("cmd", cmd);
|
||||
if (cmd == "reset"){
|
||||
//Read next packet
|
||||
thisPacket.reInit(srcConn);
|
||||
if (thisPacket.getVersion() == DTSC::DTSC_HEAD){
|
||||
DTSC::Meta newMeta;
|
||||
newMeta.reinit(thisPacket);
|
||||
//Detect new tracks
|
||||
std::set<unsigned int> newTracks;
|
||||
for (std::map<unsigned int, DTSC::Track>::iterator it = newMeta.tracks.begin(); it != newMeta.tracks.end(); it++){
|
||||
if (!myMeta.tracks.count(it->first)){
|
||||
newTracks.insert(it->first);
|
||||
}
|
||||
}
|
||||
|
||||
for (std::set<unsigned int>::iterator it = newTracks.begin(); it != newTracks.end(); it++){
|
||||
INFO_MSG("Adding track %d to internal metadata", *it);
|
||||
myMeta.tracks[*it] = newMeta.tracks[*it];
|
||||
continueNegotiate(*it, true);
|
||||
}
|
||||
|
||||
//Detect removed tracks
|
||||
std::set<unsigned int> deletedTracks;
|
||||
for (std::map<unsigned int, DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){
|
||||
if (!newMeta.tracks.count(it->first)){
|
||||
deletedTracks.insert(it->first);
|
||||
}
|
||||
}
|
||||
|
||||
for(std::set<unsigned int>::iterator it = deletedTracks.begin(); it != deletedTracks.end(); it++){
|
||||
INFO_MSG("Deleting track %d from internal metadata", *it);
|
||||
myMeta.tracks.erase(*it);
|
||||
}
|
||||
|
||||
//Read next packet before returning
|
||||
thisPacket.reInit(srcConn);
|
||||
}else{
|
||||
myMeta = DTSC::Meta();
|
||||
}
|
||||
}else{
|
||||
//Read next packet before returning
|
||||
thisPacket.reInit(srcConn);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if (smart){
|
||||
inFile.seekNext();
|
||||
}else{
|
||||
inFile.parseNext();
|
||||
}
|
||||
thisPacket = inFile.getPacket();
|
||||
}
|
||||
}
|
||||
|
||||
void inputDTSC::seek(int seekTime) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue