diff --git a/util/ddv_socket.cpp b/util/ddv_socket.cpp index 4e1341d2..caece508 100644 --- a/util/ddv_socket.cpp +++ b/util/ddv_socket.cpp @@ -1,13 +1,34 @@ #include #include +#include #include #include #include #include #include +#include bool socketError = false; +int DDV_OpenUnix(const char adres[], bool nonblock = false){ + int s = socket(AF_UNIX, SOCK_STREAM, 0); + sockaddr_un addr; + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path, adres); + int r = connect(s, (sockaddr*)&adres, sizeof(addr)); + if (r == 0){ + if (nonblock){ + int flags = fcntl(s, F_GETFL, 0); + flags |= O_NONBLOCK; + fcntl(s, F_SETFL, flags); + } + return s; + }else{ + close(s); + return 0; + } +} + int DDV_Listen(int port){ int s = socket(AF_INET, SOCK_STREAM, 0); @@ -36,9 +57,8 @@ int DDV_Accept(int sock){ return accept(sock, 0, 0); } -bool DDV_write(void * buffer, int width, int count, int sock){ +bool DDV_write(void * buffer, int todo, int sock){ int sofar = 0; - int todo = width*count; while (sofar != todo){ int r = send(sock, (char*)buffer + sofar, todo-sofar, 0); if (r <= 0){ @@ -51,9 +71,8 @@ bool DDV_write(void * buffer, int width, int count, int sock){ return true; } -bool DDV_read(void * buffer, int width, int count, int sock){ +bool DDV_read(void * buffer, int todo, int sock){ int sofar = 0; - int todo = width*count; while (sofar != todo){ int r = recv(sock, (char*)buffer + sofar, todo-sofar, 0); if (r <= 0){ @@ -65,3 +84,28 @@ bool DDV_read(void * buffer, int width, int count, int sock){ } return true; } + + +bool DDV_read(void * buffer, int width, int count, int sock){return DDV_read(buffer, width*count, sock);} +bool DDV_write(void * buffer, int width, int count, int sock){return DDV_write(buffer, width*count, sock);} + + +int DDV_iwrite(void * buffer, int todo, int sock){ + int r = send(sock, buffer, todo, 0); + if (r < 0){ + socketError = true; + printf("Could not write! %s\n", strerror(errno)); + } + return r; +} + +int DDV_iread(void * buffer, int todo, int sock){ + int r = recv(sock, buffer, todo, 0); + if (r < 0){ + socketError = true; + printf("Could not write! %s\n", strerror(errno)); + } + return r; +} + + diff --git a/util/flv_sock.cpp b/util/flv_sock.cpp index 60bc3abe..ac520b43 100644 --- a/util/flv_sock.cpp +++ b/util/flv_sock.cpp @@ -1,34 +1,92 @@ -SWBaseSocket::SWBaseError SWBerr; -char * FLVbuffer; -int FLV_len; -int FLVbs = 0; -bool HeaderDone = false; -static char FLVheader[13]; -void FLV_Readheader(SWUnixSocket & ss){ -}//FLV_Readheader +struct FLV_Pack { + int len; + int buf; + bool isKeyframe; + char * data; +};//FLV_Pack -void FLV_Dump(){FLV_len = 0;} +char FLVHeader[13]; +bool All_Hell_Broke_Loose = false; -bool FLV_GetPacket(SWUnixSocket & ss){ - if (!HeaderDone){ - if (ss.frecv(FLVheader, 13, &SWBerr) == 13){HeaderDone = true;} - return false; - } +//checks FLV Header for correctness +//returns true if everything is alright, false otherwise +bool FLV_Checkheader(char * header){ + if (header[0] != 'F') return false; + if (header[1] != 'L') return false; + if (header[2] != 'V') return false; + if (header[8] != 0x09) return false; + if (header[9] != 0) return false; + if (header[10] != 0) return false; + if (header[11] != 0) return false; + if (header[12] != 0) return false; + return true; +}//FLV_Checkheader - - if (FLVbs < 15){FLVbuffer = (char*)realloc(FLVbuffer, 15); FLVbs = 15;} - //if received a whole header, receive a whole packet - //if not, retry header next pass - if (FLV_len == 0){ - if (ss.frecv(FLVbuffer, 11, &SWBerr) == 11){ - FLV_len = FLVbuffer[3] + 15; - FLV_len += (FLVbuffer[2] << 8); - FLV_len += (FLVbuffer[1] << 16); - if (FLVbs < FLV_len){FLVbuffer = (char*)realloc(FLVbuffer, FLV_len);FLVbs = FLV_len;} +//returns true if header is an FLV header +bool FLV_Isheader(char * header){ + if (header[0] != 'F') return false; + if (header[1] != 'L') return false; + if (header[2] != 'V') return false; + return true; +}//FLV_Isheader + +bool ReadUntil(char * buffer, unsigned int count, unsigned int & sofar, int sock){ + if (sofar >= count){return true;} + int r = 0; + r = DDV_iread(buffer + sofar,count-sofar,sock); + if (r < 0){All_Hell_Broke_Loose = true; return false;} + sofar += r; + if (sofar >= count){return true;} + return false; +} + +//gets a packet, storing in given FLV_Pack pointer. +//will assign pointer if null +//resizes FLV_Pack data field bigger if data doesn't fit +// (does not auto-shrink for speed!) +bool FLV_GetPacket(FLV_Pack *& p, int sock){ + int preflags = fcntl(sock, F_GETFL, 0); + int postflags = preflags | O_NONBLOCK; + fcntl(sock, F_SETFL, postflags); + static bool done = true; + static unsigned int sofar = 0; + if (!p){p = (FLV_Pack*)calloc(1, sizeof(FLV_Pack));} + if (p->buf < 15){p->data = (char*)realloc(p->data, 15); p->buf = 15;} + + if (done){ + //read a header + if (ReadUntil(p->data, 11, sofar, sock)){ + //if its a correct FLV header, throw away and read tag header + if (FLV_Isheader(p->data)){ + if (ReadUntil(p->data, 13, sofar, sock)){ + if (FLV_Checkheader(p->data)){ + sofar = 0; + memcpy(FLVHeader, p->data, 13); + }else{All_Hell_Broke_Loose = true;} + } + }else{ + //if a tag header, calculate length and read tag body + p->len = p->data[3] + 15; + p->len += (p->data[2] << 8); + p->len += (p->data[1] << 16); + if (p->buf < p->len){p->data = (char*)realloc(p->data, p->len);p->buf = p->len;} + done = false; + } } }else{ - if (ss.frecv(FLVbuffer+11, FLV_len-11, &SWBerr) == FLV_len-11){return true;} + //read tag body + if (ReadUntil(p->data, p->len, sofar, sock)){ + //calculate keyframeness, next time read header again, return true + p->isKeyframe = false; + if ((p->data[0] == 0x09) && (((p->data[11] & 0xf0) >> 4) == 1)){p->isKeyframe = true;} + done = true; + sofar = 0; + fcntl(sock, F_SETFL, preflags); + return true; + } } + fcntl(sock, F_SETFL, preflags); return false; }//FLV_GetPacket +