diff --git a/.gitignore b/.gitignore index 755b1999..d81a8893 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,11 @@ #ignore object files and nonsense like that *.[oa] Admin/main -Connector_HTTP/Connector_HTTP -Buffer/Buffer -Connector_RTMP/Connector_RTMP -Connector_RTSP/Connector_RTSP +Connector_HTTP/DDV_Conn_HTTP +Buffer/DDV_Buffer +Connector_RTMP/DDV_Conn_RTMP +Connector_RTSP/DDV_Conn_RTSP +Connector_RAW/DDV_Conn_RAW *~ bin/* docs diff --git a/Buffer/Makefile b/Buffer/Makefile index beae6c91..63cc2524 100644 --- a/Buffer/Makefile +++ b/Buffer/Makefile @@ -1,6 +1,6 @@ -SRC = main.cpp +SRC = main.cpp ../util/ddv_socket.cpp ../util/flv_tag.cpp OBJ = $(SRC:.cpp=.o) -OUT = Buffer +OUT = DDV_Buffer INCLUDES = CCFLAGS = -Wall -Wextra -funsigned-char -g CC = $(CROSS)g++ diff --git a/Buffer/main.cpp b/Buffer/main.cpp index 344ddb9d..10eee8b1 100644 --- a/Buffer/main.cpp +++ b/Buffer/main.cpp @@ -7,11 +7,13 @@ #include #include #include -#include "../util/flv.cpp" //FLV format parser -#include "../util/ddv_socket.cpp" //DDV Socket lib +#include "../util/flv_tag.h" //FLV format parser +#include "../util/ddv_socket.h" //DDV Socket lib #include +namespace Buffer{ + void termination_handler (int signum){ switch (signum){ case SIGPIPE: return; break; @@ -19,81 +21,90 @@ void termination_handler (int signum){ } } - +///holds FLV::Tag objects and their numbers struct buffer{ int number; - bool iskeyframe; - FLV_Pack * FLV; - buffer(){ - number = -1; - iskeyframe = false; - FLV = 0; - }//constructor + FLV::Tag FLV; };//buffer +/// Holds connected users. +/// Keeps track of what buffer users are using and the connection status. class user{ public: - int MyBuffer; - int MyBuffer_num; - int MyBuffer_len; - int MyNum; - int currsend; - bool gotproperaudio; - void * lastpointer; - static int UserCount; - int s; - user(int fd){ - s = fd; + int MyBuffer; ///< Index of currently used buffer. + int MyBuffer_num; ///< Number of currently used buffer. + int MyBuffer_len; ///< Length in bytes of currently used buffer. + int MyNum; ///< User ID of this user. + int currsend; ///< Current amount of bytes sent. + bool gotproperaudio; ///< Whether the user received proper audio yet. + void * lastpointer; ///< Pointer to data part of current buffer. + static int UserCount; ///< Global user counter. + DDV::Socket S; ///< Connection to user + /// Creates a new user from a newly connected socket. + /// Also prints "User connected" text to stdout. + user(DDV::Socket fd){ + S = fd; MyNum = UserCount++; gotproperaudio = false; std::cout << "User " << MyNum << " connected" << std::endl; }//constructor + /// Disconnects the current user. Doesn't do anything if already disconnected. + /// Prints "Disconnected user" to stdout if disconnect took place. void Disconnect(std::string reason) { - if (s != -1) { - close(s); - s = -1; + if (S.connected()) { + S.close(); std::cout << "Disconnected user " << MyNum << ": " << reason << std::endl; } }//Disconnect - bool doSend(char * buffer, int todo){ - int r = send(s, buffer+currsend, todo-currsend, 0); + /// Tries to send the current buffer, returns true if success, false otherwise. + /// Has a side effect of dropping the connection if send will never complete. + bool doSend(){ + int r = S.iwrite((char*)lastpointer+currsend, MyBuffer_len-currsend); if (r <= 0){ if ((r < 0) && (errno == EWOULDBLOCK)){return false;} Disconnect("Connection closed"); return false; } currsend += r; - return (currsend == todo); - } + return (currsend == MyBuffer_len); + }//doSend + /// Try to send data to this user. Disconnects if any problems occur. + /// \param ringbuf Array of buffers (FLV:Tag with ID attached) + /// \param buffers Count of elements in ringbuf void Send(buffer ** ringbuf, int buffers){ //TODO: Bij MP3: gotproperaudio - if false, stuur alleen als eerste byte is 0xFF en set op true - //not connected? cancel - if (s < 0){return;} + if (!S.connected()){return;}//cancel if not connected + //still waiting for next buffer? check it if (MyBuffer_num < 0){ MyBuffer_num = ringbuf[MyBuffer]->number; - //still waiting? don't crash - wait longer. if (MyBuffer_num < 0){ - return; + return; //still waiting? don't crash - wait longer. }else{ - MyBuffer_len = ringbuf[MyBuffer]->FLV->len; - lastpointer = ringbuf[MyBuffer]->FLV->data; + MyBuffer_len = ringbuf[MyBuffer]->FLV.len; + lastpointer = ringbuf[MyBuffer]->FLV.data; } } - if (lastpointer != ringbuf[MyBuffer]->FLV->data){ + + //do check for buffer resizes + if (lastpointer != ringbuf[MyBuffer]->FLV.data){ Disconnect("Buffer resize at wrong time... had to disconnect"); return; } - if (doSend(ringbuf[MyBuffer]->FLV->data, MyBuffer_len)){ - //completed a send - switch to next buffer + + //try to complete a send + if (doSend()){ + //switch to next buffer if ((ringbuf[MyBuffer]->number != MyBuffer_num)){ + //if corrupt data, warn and find keyframe std::cout << "Warning: User " << MyNum << " was send corrupt video data and send to the next keyframe!" << std::endl; int nocrashcount = 0; do{ MyBuffer++; nocrashcount++; MyBuffer %= buffers; - }while(!ringbuf[MyBuffer]->FLV->isKeyframe && (nocrashcount < buffers)); + }while(!ringbuf[MyBuffer]->FLV.isKeyframe && (nocrashcount < buffers)); + //if keyframe not available, try again later if (nocrashcount >= buffers){ std::cout << "Warning: No keyframe found in buffers! Skipping search for now..." << std::endl; return; @@ -110,25 +121,27 @@ class user{ }; int user::UserCount = 0; -int main( int argc, char * argv[] ) { +/// Starts a loop, waiting for connections to send video data to. +int Start(int argc, char ** argv) { + //first make sure no segpipe signals will kill us struct sigaction new_action; new_action.sa_handler = termination_handler; sigemptyset (&new_action.sa_mask); new_action.sa_flags = 0; sigaction (SIGPIPE, &new_action, NULL); - - if (argc < 2) { - std::cout << "usage: " << argv[0] << " buffers_count [streamname]" << std::endl; + + //then check and parse the commandline + if (argc < 3) { + std::cout << "usage: " << argv[0] << " buffers_count streamname" << std::endl; return 1; } - std::string shared_socket = "/tmp/shared_socket"; - if (argc > 2){ - shared_socket = argv[2]; - shared_socket = "/tmp/shared_socket_" + shared_socket; - } + std::string shared_socket = "/tmp/shared_socket_"; + shared_socket += argv[2]; - int metabuflen = 0; - char * metabuffer = 0; + DDV::ServerSocket SS(shared_socket, true); + FLV::Tag metadata; + FLV::Tag video_init; + FLV::Tag audio_init; int buffers = atoi(argv[1]); buffer ** ringbuf = (buffer**) calloc (buffers,sizeof(buffer*)); std::vector users; @@ -137,14 +150,15 @@ int main( int argc, char * argv[] ) { int current_buffer = 0; int lastproper = 0;//last properly finished buffer number unsigned int loopcount = 0; - int listener = DDV_UnixListen(shared_socket, true); - int incoming = 0; + DDV::Socket incoming; unsigned char packtype; bool gotVideoInfo = false; bool gotAudioInfo = false; - int infile = fileno(stdin); + int infile = fileno(stdin);//get file number for stdin + + //add stdin to an epoll int poller = epoll_create(1); struct epoll_event ev; ev.events = EPOLLIN; @@ -153,54 +167,46 @@ int main( int argc, char * argv[] ) { struct epoll_event events[1]; - while(!feof(stdin) && !All_Hell_Broke_Loose){ + while(!feof(stdin) && !FLV::Parse_Error){ //invalidate the current buffer ringbuf[current_buffer]->number = -1; - if ((epoll_wait(poller, events, 1, 10) > 0) && FLV_GetPacket(ringbuf[current_buffer]->FLV)){ + if ((epoll_wait(poller, events, 1, 10) > 0) && ringbuf[current_buffer]->FLV.FileLoader(stdin)){ loopcount++; - packtype = ringbuf[current_buffer]->FLV->data[0]; + packtype = ringbuf[current_buffer]->FLV.data[0]; //store metadata, if available if (packtype == 0x12){ - metabuflen = ringbuf[current_buffer]->FLV->len; - metabuffer = (char*)realloc(metabuffer, metabuflen); - memcpy(metabuffer, ringbuf[current_buffer]->FLV->data, metabuflen); + metadata = ringbuf[current_buffer]->FLV; std::cout << "Received metadata!" << std::endl; if (gotVideoInfo && gotAudioInfo){ - All_Hell_Broke_Loose = true; + FLV::Parse_Error = true; std::cout << "... after proper video and audio? Cancelling broadcast!" << std::endl; } gotVideoInfo = false; gotAudioInfo = false; } - if (!gotVideoInfo && ringbuf[current_buffer]->FLV->isKeyframe){ - if ((ringbuf[current_buffer]->FLV->data[11] & 0x0f) == 7){//avc packet - if (ringbuf[current_buffer]->FLV->data[12] == 0){ - ringbuf[current_buffer]->FLV->data[4] = 0;//timestamp to zero - ringbuf[current_buffer]->FLV->data[5] = 0;//timestamp to zero - ringbuf[current_buffer]->FLV->data[6] = 0;//timestamp to zero - metabuffer = (char*)realloc(metabuffer, metabuflen + ringbuf[current_buffer]->FLV->len); - memcpy(metabuffer+metabuflen, ringbuf[current_buffer]->FLV->data, ringbuf[current_buffer]->FLV->len); - metabuflen += ringbuf[current_buffer]->FLV->len; + //store video init data, if available + if (!gotVideoInfo && ringbuf[current_buffer]->FLV.isKeyframe){ + if ((ringbuf[current_buffer]->FLV.data[11] & 0x0f) == 7){//avc packet + if (ringbuf[current_buffer]->FLV.data[12] == 0){ + ringbuf[current_buffer]->FLV.tagTime(0);//timestamp to zero + video_init = ringbuf[current_buffer]->FLV; gotVideoInfo = true; std::cout << "Received video configuration!" << std::endl; } }else{gotVideoInfo = true;}//non-avc = no config... } + //store audio init data, if available if (!gotAudioInfo && (packtype == 0x08)){ - if (((ringbuf[current_buffer]->FLV->data[11] & 0xf0) >> 4) == 10){//aac packet - ringbuf[current_buffer]->FLV->data[4] = 0;//timestamp to zero - ringbuf[current_buffer]->FLV->data[5] = 0;//timestamp to zero - ringbuf[current_buffer]->FLV->data[6] = 0;//timestamp to zero - metabuffer = (char*)realloc(metabuffer, metabuflen + ringbuf[current_buffer]->FLV->len); - memcpy(metabuffer+metabuflen, ringbuf[current_buffer]->FLV->data, ringbuf[current_buffer]->FLV->len); - metabuflen += ringbuf[current_buffer]->FLV->len; + if (((ringbuf[current_buffer]->FLV.data[11] & 0xf0) >> 4) == 10){//aac packet + ringbuf[current_buffer]->FLV.tagTime(0);//timestamp to zero + audio_init = ringbuf[current_buffer]->FLV; gotAudioInfo = true; std::cout << "Received audio configuration!" << std::endl; }else{gotAudioInfo = true;}//no aac = no config... } - //on keyframe set start point + //on keyframe set possible start point if (packtype == 0x09){ - if (((ringbuf[current_buffer]->FLV->data[11] & 0xf0) >> 4) == 1){ + if (((ringbuf[current_buffer]->FLV.data[11] & 0xf0) >> 4) == 1){ lastproper = current_buffer; } } @@ -209,29 +215,35 @@ int main( int argc, char * argv[] ) { current_buffer++; current_buffer %= buffers; } - + //check for new connections, accept them if there are any - incoming = DDV_Accept(listener, true); - if (incoming >= 0){ + incoming = SS.accept(true); + if (incoming.connected()){ users.push_back(incoming); //send the FLV header users.back().currsend = 0; users.back().MyBuffer = lastproper; users.back().MyBuffer_num = -1; //TODO: Do this more nicely? - if (!DDV_write(FLVHeader, 13, incoming)){ + if (!incoming.write(FLV::Header, 13)){ users.back().Disconnect("failed to receive the header!"); }else{ - if (!DDV_write(metabuffer, metabuflen, incoming)){ + if (!incoming.write(metadata.data, metadata.len)){ users.back().Disconnect("failed to receive metadata!"); } + if (!incoming.write(video_init.data, video_init.len)){ + users.back().Disconnect("failed to receive video init!"); + } + if (!incoming.write(audio_init.data, audio_init.len)){ + users.back().Disconnect("failed to receive audio init!"); + } } } - + //send all connections what they need, if and when they need it if (users.size() > 0){ for (usersIt = users.begin(); usersIt != users.end(); usersIt++){ - if ((*usersIt).s == -1){ + if (!(*usersIt).S.connected()){ users.erase(usersIt); break; }else{ (*usersIt).Send(ringbuf, buffers); @@ -241,13 +253,23 @@ int main( int argc, char * argv[] ) { }//main loop // disconnect listener - std::cout << "Reached EOF of input" << std::endl; - close(listener); + if (FLV::Parse_Error){ + std::cout << "FLV parse error" << std::endl; + }else{ + std::cout << "Reached EOF of input" << std::endl; + } + SS.close(); while (users.size() > 0){ for (usersIt = users.begin(); usersIt != users.end(); usersIt++){ (*usersIt).Disconnect("Shutting down..."); - if ((*usersIt).s == -1){users.erase(usersIt);break;} + if (!(*usersIt).S.connected()){users.erase(usersIt);break;} } } return 0; } + +};//Buffer namespace + +int main(int argc, char ** argv){ + Buffer::Start(argc, argv); +}//main diff --git a/Connector_HTTP/HTTP_Conn b/Connector_HTTP/HTTP_Conn index e06cbc29..9ad03e7f 100755 --- a/Connector_HTTP/HTTP_Conn +++ b/Connector_HTTP/HTTP_Conn @@ -3,8 +3,8 @@ # description: DDVTech HTTP Connector # processname: Connector_HTTP -prog="Connector_HTTP" -fullprog="/usr/bin/Connector_HTTP" +prog="DDV_Conn_HTTP" +fullprog="/usr/bin/DDV_Conn_HTTP" RETVAL=0 start() { diff --git a/Connector_HTTP/Makefile b/Connector_HTTP/Makefile index 22ef3c3f..56ba16e1 100644 --- a/Connector_HTTP/Makefile +++ b/Connector_HTTP/Makefile @@ -1,6 +1,6 @@ SRC = main.cpp ../util/ddv_socket.cpp ../util/http_parser.cpp ../util/flv_tag.cpp OBJ = $(SRC:.cpp=.o) -OUT = Connector_HTTP +OUT = DDV_Conn_HTTP INCLUDES = CCFLAGS = -Wall -Wextra -funsigned-char -g CC = $(CROSS)g++ diff --git a/Connector_RAW/Makefile b/Connector_RAW/Makefile index fc992f72..aaf541a1 100644 --- a/Connector_RAW/Makefile +++ b/Connector_RAW/Makefile @@ -1,6 +1,6 @@ -SRC = main.cpp ../sockets/sw_base.cpp ../sockets/sw_inet.cpp ../sockets/sw_unix.cpp +SRC = main.cpp ../util/ddv_socket.cpp OBJ = $(SRC:.cpp=.o) -OUT = Connector_RAW +OUT = DDV_Conn_RAW INCLUDES = CCFLAGS = -Wall -Wextra -funsigned-char -g CC = $(CROSS)g++ diff --git a/Connector_RAW/main.cpp b/Connector_RAW/main.cpp index 12bb6638..15f2b9b9 100644 --- a/Connector_RAW/main.cpp +++ b/Connector_RAW/main.cpp @@ -1,5 +1,5 @@ #include -#include "../sockets/SocketW.h" +#include "../util/ddv_socket.h" #include #include #include @@ -7,19 +7,24 @@ #include #include -int main() { - SWUnixSocket mySocket; - std::string input; - std::cin >> input; - input = "/tmp/shared_socket_"+input; - mySocket.connect(input); - char buffer[500000]; - int msg; - while(std::cout.good()) { - msg = mySocket.recv(&buffer[0],10000); - std::cout.write(buffer,msg); +int main(int argc, char ** argv) { + if (argc < 2){ + std::cout << "Usage: " << argv[0] << " stream_name" << std::endl; + return 1; } - // disconnect - mySocket.disconnect(); + std::string input; + input = "/tmp/shared_socket_"; + input += argv[1]; + DDV::Socket S(input); + if (!S.connected()){ + std::cout << "Could not open stream " << argv[1] << std::endl; + return 1; + } + char buffer[50000]; + int msg; + while(std::cout.good() && S.read(buffer,50000)){ + std::cout.write(buffer,50000); + } + S.close(); return 0; } diff --git a/Connector_RTMP/Makefile b/Connector_RTMP/Makefile index 71f3ffb0..f33e7118 100644 --- a/Connector_RTMP/Makefile +++ b/Connector_RTMP/Makefile @@ -1,6 +1,6 @@ -SRC = main.cpp +SRC = main.cpp ../util/ddv_socket.cpp ../util/flv_tag.cpp OBJ = $(SRC:.cpp=.o) -OUT = Connector_RTMP +OUT = DDV_Conn_RTMP INCLUDES = STATIC = CCFLAGS = -Wall -Wextra -funsigned-char -g diff --git a/Connector_RTMP/main.cpp b/Connector_RTMP/main.cpp index e7e246c0..8a70bec0 100644 --- a/Connector_RTMP/main.cpp +++ b/Connector_RTMP/main.cpp @@ -16,164 +16,159 @@ #include #include #include +#include "../util/ddv_socket.h" +#include "../util/flv_tag.h" -//for connection to server -bool ready4data = false;//set to true when streaming starts -bool inited = false; -bool stopparsing = false; -timeval lastrec; - -#define DEFAULT_PORT 1935 -#include "../util/server_setup.cpp" - -int CONN_fd = 0; #include "parsechunks.cpp" //chunkstream parsing #include "handshake.cpp" //handshaking -int mainHandler(int connection){ - CONN_fd = connection; - unsigned int ts; - unsigned int fts = 0; - unsigned int ftst; - int ss; - FLV_Pack * tag = 0; +/// Holds all functions and data unique to the RTMP Connector +namespace Connector_RTMP{ - //first timestamp set - firsttime = getNowMS(); + //for connection to server + bool ready4data = false; ///< Set to true when streaming starts. + bool inited = false; ///< Set to true when ready to connect to Buffer. + bool stopparsing = false; ///< Set to true when all parsing needs to be cancelled. + timeval lastrec; ///< Timestamp of last received data. - if (doHandshake()){ - #if DEBUG >= 4 - fprintf(stderr, "Handshake succcess!\n"); + DDV::Socket Socket; ///< Socket connected to user + + /// Main Connector_RTMP function + int Connector_RTMP(DDV::Socket conn){ + Socket = conn; + unsigned int ts; + unsigned int fts = 0; + unsigned int ftst; + DDV::Socket SS; + FLV::Tag tag = 0; + + //first timestamp set + firsttime = getNowMS(); + + if (doHandshake()){ + #if DEBUG >= 4 + fprintf(stderr, "Handshake succcess!\n"); + #endif + }else{ + #if DEBUG >= 1 + fprintf(stderr, "Handshake fail!\n"); + #endif + return 0; + } + + int retval; + int poller = epoll_create(1); + int sspoller = epoll_create(1); + struct epoll_event ev; + ev.events = EPOLLIN; + ev.data.fd = CONN_fd; + epoll_ctl(poller, EPOLL_CTL_ADD, CONN_fd, &ev); + struct epoll_event events[1]; + #if DEBUG >= 5 + //for writing whole stream to a file + FILE * tmpfile = 0; + char tmpstr[200]; + #endif + + while (Socket.connected() && !FLV::Parse_Error){ + //only parse input if available or not yet init'ed + //rightnow = getNowMS(); + retval = epoll_wait(poller, events, 1, 1); + if ((retval > 0) || !ready4data){// || (snd_cnt - snd_window_at >= snd_window_size) + switch (Socket.ready()){ + case -1: break; //disconnected + case 0: break; //not ready yet + default: parseChunk(); break; //new data is waiting + } + } + if (ready4data){ + if (!inited){ + //we are ready, connect the socket! + SS = DDV::Socket(streamname); + if (!SS.connected()){ + #if DEBUG >= 1 + fprintf(stderr, "Could not connect to server!\n"); + #endif + Socket.close();//disconnect user + break; + } + ev.events = EPOLLIN; + ev.data.fd = SS.getSocket(); + epoll_ctl(sspoller, EPOLL_CTL_ADD, SS.getSocket(), &ev); + #if DEBUG >= 3 + fprintf(stderr, "Everything connected, starting to send video data...\n"); + #endif + inited = true; + } + + retval = epoll_wait(sspoller, events, 1, 1); + switch (SS.ready()){ + case -1: + #if DEBUG >= 1 + fprintf(stderr, "Source socket is disconnected.\n"); + #endif + Socket.close();//disconnect user + break; + case 0: break;//not ready yet + default: + if (tag.SockLoader(SS)){//able to read a full packet? + ts = tag.tagTime(); + if (ts != 0){ + if (fts == 0){fts = ts;ftst = getNowMS();} + ts -= fts; + tag.tagTime(ts); + ts += ftst; + }else{ + ftst = getNowMS(); + tag.tagTime(ftst); + } + SendMedia((unsigned char)tag.data[0], (unsigned char *)tag.data+11, tag.len-15, ts); + #if DEBUG >= 5 + //write whole stream to a file + if (tmpfile == 0){ + sprintf(tmpstr, "./tmpfile_socket_%i.flv", CONN_fd); + tmpfile = fopen(tmpstr, "w"); + fwrite(FLVHeader, 13, 1, tmpfile); + } + fwrite(tag->data, tag->len, 1, tmpfile); + #endif + #if DEBUG >= 4 + fprintf(stderr, "Sent a tag to %i\n", CONN_fd); + #endif + } + break; + } + } + //send ACK if we received a whole window + if ((rec_cnt - rec_window_at > rec_window_size)){ + rec_window_at = rec_cnt; + SendCTL(3, rec_cnt);//send ack (msg 3) + } + } + SS.close(); + Socket.close(); + #if DEBUG >= 5 + fclose(tmpfile); #endif - }else{ #if DEBUG >= 1 - fprintf(stderr, "Handshake fail!\n"); + if (FLV::Parse_Error){fprintf(stderr, "FLV Parse Error\n");} + fprintf(stderr, "User %i disconnected.\n", conn.getSocket()); + if (inited){ + fprintf(stderr, "Status was: inited\n"); + }else{ + if (ready4data){ + fprintf(stderr, "Status was: ready4data\n"); + }else{ + fprintf(stderr, "Status was: connected\n"); + } + } #endif return 0; - } + }//Connector_RTMP - int retval; - int poller = epoll_create(1); - int sspoller = epoll_create(1); - struct epoll_event ev; - ev.events = EPOLLIN; - ev.data.fd = CONN_fd; - epoll_ctl(poller, EPOLL_CTL_ADD, CONN_fd, &ev); - struct epoll_event events[1]; - #if DEBUG >= 5 - //for writing whole stream to a file - FILE * tmpfile = 0; - char tmpstr[200]; - #endif - - while (!socketError && !All_Hell_Broke_Loose){ - //only parse input if available or not yet init'ed - //rightnow = getNowMS(); - retval = epoll_wait(poller, events, 1, 1); - if ((retval > 0) || !ready4data){// || (snd_cnt - snd_window_at >= snd_window_size) - switch (DDV_ready(CONN_fd)){ - case 0: - socketError = true; - #if DEBUG >= 1 - fprintf(stderr, "User socket is disconnected.\n"); - #endif - break; - case -1: break;//not ready yet - default: - parseChunk(); - break; - } - } - if (ready4data){ - if (!inited){ - //we are ready, connect the socket! - ss = DDV_OpenUnix(streamname); - if (ss <= 0){ - #if DEBUG >= 1 - fprintf(stderr, "Could not connect to server!\n"); - #endif - socketError = 1; - break; - } - ev.events = EPOLLIN; - ev.data.fd = ss; - epoll_ctl(sspoller, EPOLL_CTL_ADD, ss, &ev); - #if DEBUG >= 3 - fprintf(stderr, "Everything connected, starting to send video data...\n"); - #endif - inited = true; - } +};//Connector_RTMP namespace - retval = epoll_wait(sspoller, events, 1, 1); - switch (DDV_ready(ss)){ - case 0: - socketError = true; - #if DEBUG >= 1 - fprintf(stderr, "Source socket is disconnected.\n"); - #endif - break; - case -1: break;//not ready yet - default: - if (FLV_GetPacket(tag, ss)){//able to read a full packet? - ts = tag->data[7] * 256*256*256; - ts += tag->data[4] * 256*256; - ts += tag->data[5] * 256; - ts += tag->data[6]; - if (ts != 0){ - if (fts == 0){fts = ts;ftst = getNowMS();} - ts -= fts; - tag->data[7] = ts / (256*256*256); - tag->data[4] = ts / (256*256); - tag->data[5] = ts / 256; - tag->data[6] = ts % 256; - ts += ftst; - }else{ - ftst = getNowMS(); - tag->data[7] = ftst / (256*256*256); - tag->data[4] = ftst / (256*256); - tag->data[5] = ftst / 256; - tag->data[6] = ftst % 256; - } - SendMedia((unsigned char)tag->data[0], (unsigned char *)tag->data+11, tag->len-15, ts); - #if DEBUG >= 5 - //write whole stream to a file - if (tmpfile == 0){ - sprintf(tmpstr, "./tmpfile_socket_%i.flv", CONN_fd); - tmpfile = fopen(tmpstr, "w"); - fwrite(FLVHeader, 13, 1, tmpfile); - } - fwrite(tag->data, tag->len, 1, tmpfile); - #endif - #if DEBUG >= 4 - fprintf(stderr, "Sent a tag to %i\n", CONN_fd); - #endif - } - break; - } - } - //send ACK if we received a whole window - if ((rec_cnt - rec_window_at > rec_window_size)){ - rec_window_at = rec_cnt; - SendCTL(3, rec_cnt);//send ack (msg 3) - } - } - close(CONN_fd); - #if DEBUG >= 5 - fclose(tmpfile); - #endif - if (inited) close(ss); - #if DEBUG >= 1 - if (All_Hell_Broke_Loose){fprintf(stderr, "All Hell Broke Loose\n");} - fprintf(stderr, "User %i disconnected.\n", CONN_fd); - if (inited){ - fprintf(stderr, "Status was: inited\n"); - }else{ - if (ready4data){ - fprintf(stderr, "Status was: ready4data\n"); - }else{ - fprintf(stderr, "Status was: connected\n"); - } - } - #endif - return 0; -}//mainHandler +// Load main server setup file, default port 1935, handler is Connector_RTMP::Connector_RTMP +#define DEFAULT_PORT 1935 +#define MAINHANDLER Connector_RTMP::Connector_RTMP +#include "../util/server_setup.cpp" diff --git a/util/ddv_socket.cpp b/util/ddv_socket.cpp index 2835a5cf..6c5027b7 100644 --- a/util/ddv_socket.cpp +++ b/util/ddv_socket.cpp @@ -8,6 +8,14 @@ DDV::Socket::Socket(int sockNo){ Blocking = false; }//DDV::Socket basic constructor +/// Create a new disconnected base socket. This is a basic constructor for placeholder purposes. +/// A socket created like this is always disconnected and should/could be overwritten at some point. +DDV::Socket::Socket(){ + sock = -1; + Error = false; + Blocking = false; +}//DDV::Socket basic constructor + /// Close connection. The internal socket is closed and then set to -1. void DDV::Socket::close(){ #if DEBUG >= 3 diff --git a/util/ddv_socket.h b/util/ddv_socket.h index cc9421ae..298b5954 100644 --- a/util/ddv_socket.h +++ b/util/ddv_socket.h @@ -19,6 +19,7 @@ namespace DDV{ private: int sock; ///< Internally saved socket number. public: + Socket(); ///< Create a new disconnected base socket. Socket(int sockNo); ///< Create a new base socket. Socket(std::string adres, bool nonblock = false); ///< Create a new Unix Socket. bool Error; ///< Set to true if a socket error happened.