Nieuwe flv parser, nieuwe unix sockets support...
This commit is contained in:
		
							parent
							
								
									5f3d64ba0b
								
							
						
					
					
						commit
						6949269ccc
					
				
					 2 changed files with 131 additions and 29 deletions
				
			
		|  | @ -1,13 +1,34 @@ | |||
| #include <sys/types.h> | ||||
| #include <sys/socket.h> | ||||
| #include <sys/un.h> | ||||
| #include <arpa/inet.h> | ||||
| #include <unistd.h> | ||||
| #include <stdio.h> | ||||
| #include <errno.h> | ||||
| #include <string.h> | ||||
| #include <fcntl.h> | ||||
| 
 | ||||
| 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; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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;} | ||||
| //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
 | ||||
| 
 | ||||
| //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 (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;} | ||||
|   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 (ss.frecv(FLVbuffer+11, FLV_len-11, &SWBerr) == FLV_len-11){return true;} | ||||
|         //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{ | ||||
|     //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
 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Thulinma
						Thulinma