[xiph-commits] r14190 - experimental/ribamar/etheora/examples/client-server-ssl

ribamar at svn.xiph.org ribamar at svn.xiph.org
Mon Nov 19 12:18:26 PST 2007


Author: ribamar
Date: 2007-11-19 12:18:26 -0800 (Mon, 19 Nov 2007)
New Revision: 14190

Added:
   experimental/ribamar/etheora/examples/client-server-ssl/server-encoder.c
Modified:
   experimental/ribamar/etheora/examples/client-server-ssl/README.txt
   experimental/ribamar/etheora/examples/client-server-ssl/client-decoder.c
Log:
client-decoder x server-encoder implemented. 

Modified: experimental/ribamar/etheora/examples/client-server-ssl/README.txt
===================================================================
--- experimental/ribamar/etheora/examples/client-server-ssl/README.txt	2007-11-19 19:39:23 UTC (rev 14189)
+++ experimental/ribamar/etheora/examples/client-server-ssl/README.txt	2007-11-19 20:18:26 UTC (rev 14190)
@@ -3,5 +3,13 @@
 connections from clients. 
 
 
-command line example: 
+
+
+command line example - client: 
+ gcc client-decoder.c etheora.c  -I. -ltheora -lSDL -o client-decoder
  gcc client-decoder.c etheora.c  -I. -ltheora -lssl -lSDL -o client-decoder
+
+command line example - server: 
+ gcc server-encoder.c etheora.c  -I. -ltheora  -o server-encoder
+
+gcc fe.c -lssl -o fe

Modified: experimental/ribamar/etheora/examples/client-server-ssl/client-decoder.c
===================================================================
--- experimental/ribamar/etheora/examples/client-server-ssl/client-decoder.c	2007-11-19 19:39:23 UTC (rev 14189)
+++ experimental/ribamar/etheora/examples/client-server-ssl/client-decoder.c	2007-11-19 20:18:26 UTC (rev 14190)
@@ -3,31 +3,78 @@
 /*
   a bit more sofisticated theora video decoder using etheora. this 
   example is an client which reads data from a (encoder) server. data
-  is read from the server though an SSL layer. Video is outputted 
+  is read from the server though a socket. Video is outputted 
   into an SDL window. 
 
   note this doesn't have a good performance yet and can't deal with 
-  the real fps rate. 
+  the real fps rate. Its performance is improved by defining OVERLAY, 
+  however, as of this writing (19-nov-2007) etheora doesn't provide
+  a good way to use overlays. 
 
   usage: 
-  ./client-decoder [file.ogv] 
-  file.ogv: file to read video input. if none is passed, data is read
-  from standard input.
+  ./client-decoder server_hostname server_port
 
   build command line example (with gcc): 
   gcc client-decoder.c path/to/etheora.c  -I/path/to/etheora.h/dir \
-  		-ltheora -lssl -lSDL -o client-decoder
+  		-ltheora -lSDL -o client-decoder
 
 */
 
 #include <etheora.h>
 #include <stdio.h>
+#include <unistd.h>
 #include <SDL/SDL.h>
 #include <SDL/SDL_endian.h>
 
-#define OVERLAY 1
+/*tcp includes*/
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <netdb.h>
 
 
+#define RGB_DECODING 1
+//#define YUV_DECODING 1
+//#define OVERLAY 1
+
+int tcp_socket_connect(char *host, int port, FILE *finfo){
+        struct hostent *h;
+        int sock;
+        struct sockaddr_in addr;
+
+	/* getting the host address. */
+        if(! (h = gethostbyname(host)) ){
+                fprintf(finfo, "Couldn't resolve host.\n");
+                return -1;
+        }
+
+	/* getting a socket. */
+        if((sock = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP)) < 0){
+                fprintf(finfo, "Couldn't create socket.\n");
+                return -2;
+        }
+
+	/* connecting to the address. */
+        memset(&addr, '\0', sizeof(addr));
+        addr.sin_family = AF_INET;
+        addr.sin_addr = *(struct in_addr*) h->h_addr_list[0];
+        addr.sin_port = htons(port);
+
+        if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0){
+                fprintf(finfo, "Couldn't connect socket.\n");
+                return -3;
+        }
+
+        return sock;
+}
+
+
+
+
+
+/*taken from theora player_example.c, but not cropping it yet. */
+
 static void video_write(SDL_Surface *screen, SDL_Overlay *yuv_overlay, 
 	yuv_buffer *yuv, SDL_Rect rect){
 	int i;
@@ -74,36 +121,47 @@
 }
 
 
-
-
 int main(int argc, char **args){
-	int i, j; 
+	int i, j, sock; 
 	etheora_ctx ec; 
 	FILE *finfo, *fin; 
-	float r, g, b; 
+#if YUV_DECODING
+	unsigned char r, g, b; 
+#else
+	float r, g, b;
+#endif
 	SDL_Surface *scr; 
 	SDL_Event sev; 
 #ifdef OVERLAY
 	SDL_Rect rect; 
 	SDL_Overlay *yuv_overlay;
 #endif
+
 	/* opening video input file and file to print debuf info. as 
 	   always, sockets could be used. Degub.txt can have a fast 
 	   increase, you may want open a null device file as 
 	   /dev/null. */
 	finfo = fopen("Debug.txt", "w"); 
-	if(argc > 1) {
-		fin = fopen(args[1], "r"); 
+	fprintf(stderr, "debug info in Debug.txt.\n"); 
+
+	if(argc > 2){
+		if( (sock = tcp_socket_connect(args[1], 
+					atoi(args[2]), stderr)) < 0){
+			fprintf(stderr, "Can't create socket.\n"); 
+			return 1; 
+		}
 	}
-	else {
-		fin = stdin; 
-		fprintf(stderr, "opening standard input as video file. \n"); 
+	else{
+		fprintf(stderr, "usage: \n%s host port\n", args[0]); 
+		return 1; 
 	}
+
+	/* getting the FILE * from the socket. */
+	fin = fdopen(sock, "r"); 
 	if(fin == NULL || finfo == NULL){
 		fprintf(stderr, "Debug.txt or input file couldn't be open.\n"); 
 		return 1; 
 	}
-	fprintf(stderr, "debug info in Debug.txt.\n"); 
 
 	/* configuring decoder. */
 	etheora_dec_setup(&ec, fin, finfo);
@@ -127,6 +185,7 @@
 		return 4; 
 	}
 	fprintf(stderr, "Bytes per pixel: %i.\n", scr->format->BytesPerPixel); 
+
 #ifdef OVERLAY
 	yuv_overlay = SDL_CreateYUVOverlay(etheora_get_width(&ec), etheora_get_height(&ec),
 			SDL_YV12_OVERLAY, scr);
@@ -164,14 +223,24 @@
 			for( j = 0; j < etheora_get_height(&ec); j++){
 				/* or use etheora_dec_yuv draw() to 
 			           read in yuv colorspace.*/
+#if YUV_DECODING
+				etheora_dec_yuv_read(&ec, i, j, 
+					 &r, &g, &b);  
+#else
 				etheora_dec_rgb_read(&ec, i, j, 
 					 &r, &g, &b);  
+#endif 
 
 				  /* sdl - drawing the pixel. */
 				  *((Uint16 *)scr->pixels + j*scr->pitch/2 + i)=
+#if YUV_DECODING
 					  SDL_MapRGB(scr->format, (Uint8)r, 
 					  		(Uint8)g, (Uint8)b); 
+#else
+					  SDL_MapRGB(scr->format, (Uint8)r, 
+					  		(Uint8)g, (Uint8)b); 
 
+#endif 
 			}
 
 		/* sdl stuff - unlocking screen/drawing. */
@@ -198,3 +267,16 @@
 }
 
 
+#if 0
+	if(argc > 1) {
+		fin = fopen(args[1], "r"); 
+	}
+	else {
+		fin = stdin; 
+		fprintf(stderr, "opening standard input as video file. \n"); 
+	}
+	if(fin == NULL || finfo == NULL){
+		fprintf(stderr, "Debug.txt or input file couldn't be open.\n"); 
+		return 1; 
+	}
+#endif 

Copied: experimental/ribamar/etheora/examples/client-server-ssl/server-encoder.c (from rev 14124, experimental/ribamar/etheora/examples/encoder-example.c)
===================================================================
--- experimental/ribamar/etheora/examples/client-server-ssl/server-encoder.c	                        (rev 0)
+++ experimental/ribamar/etheora/examples/client-server-ssl/server-encoder.c	2007-11-19 20:18:26 UTC (rev 14190)
@@ -0,0 +1,157 @@
+/*Copyright, 2007, by Ribamar Santarosa, ribamar at gmail.com */
+
+/*a very simple theora video encoder using etheora api.
+  play with etheora_enc_rgb_draw() r, g, b parameters and get
+  different videos. 
+  
+  usage: ./server-encoder [port] 
+  port - a tcp port where to listen incomming connections. it not
+  provided, 4443 is used. 
+
+  build command line example (with gcc): 
+  gcc server-encoder.c path/to/etheora.c  -Ipath/to/etheora.h/dir \
+  -ltheora   -o server-encoder
+*/
+
+#include <etheora.h>
+#include <stdio.h>
+#include <string.h>
+
+/*tcp includes.*/
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <netdb.h>
+
+
+#define NUMBER_OF_FRAMES 200 /* video with 20 frames.*/
+#define PORT 4443  /* tcp port where to listen. */
+
+int tcp_listen(FILE *finfo, int port) {
+        int sock;
+        struct sockaddr_in sin;
+        int v = 1;
+
+	/* getting a socket. */
+        if((sock = socket(AF_INET,SOCK_STREAM, 0)) < 0){
+                fprintf(finfo, "Can't create socket.\n");
+                return -1;
+        }
+
+	/* binding the socket to a port. */
+        memset(&sin, 0, sizeof(sin));
+        sin.sin_family = AF_INET;
+        sin.sin_addr.s_addr = INADDR_ANY;
+        sin.sin_port = htons(port);
+
+        setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &v,
+                        sizeof(v));
+
+        if(bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0){
+                fprintf(finfo, "Can't bind.\n");
+                return -2;
+        }
+
+	/* waiting for a conection. */
+        if(listen(sock, 1024) < 0){
+                fprintf(finfo, "Can't listen.\n");
+                return -3;
+	}
+
+        return(sock);
+}
+
+
+
+int main(int argc, char **args){
+	int f, i, j, sock_fd, port; 
+	etheora_ctx ec; 
+	char *vendor = "etheora/libtheora"; 
+	FILE *finfo, *fout; 
+
+	/* opening video output file and file to print debuf info. as 
+	   always, sockets could be used.Degub.txt can have a fast 
+	   increase, you may want open a null device file as 
+	   /dev/null. */
+
+	finfo = fopen("Debug.txt", "w"); 
+	fprintf(stderr, "debug info in Debug.txt.\n"); 
+
+	/* listening. */
+	(argc > 1) ? (port = atoi(args[1])) : (port = PORT); 
+	if( (sock_fd = tcp_listen(stderr, port)) < 0 ){
+		fprintf(stderr, "usage: \n%s [PORT]\n", args[0]);
+		return 1; 
+	}
+	if( (sock_fd = accept(sock_fd, 0, 0) ) < 0 ){
+		fprintf(stderr, "Can't accept connection.\n");
+		return 1;
+	}
+	fout = fdopen(sock_fd, "w");
+	if(fout == NULL || finfo == NULL){
+		fprintf(stderr, "Debug.txt or output file"
+			" couldn't be open.\n");
+		return 1;
+	}
+
+
+	/* configuring encoder: 640x480 video 12/1 frames per second. */
+	etheora_enc_setup(&ec, 640, 480, ETHEORA_ASPECT_NORMAL, 
+				12, 1, fout, finfo);
+
+	/* last chance to change theora parameters before encoding.
+	   the experienced user can change ec.ti parameters or edit
+	   the ec.tc structure. */
+	ec.ti.target_bitrate = 200000; /*200 kbps*/
+	ec.tc.vendor = vendor; 
+
+	/* start the encoder. */
+	if (etheora_enc_start(&ec)){
+		fprintf(stderr, "Can't start.\n"); 
+		return 2; 
+	}
+
+	for ( f = 0; f < NUMBER_OF_FRAMES - 1; f++){
+
+		/*now we're ready to draw the frames. */
+		for( i = 0; i < 640; i++)
+			for( j = 0; j < 480; j++)
+			/* or use etheora_enc_yuv_draw() to 
+			   draw in yuv colorspace.*/
+				etheora_enc_rgb_draw(&ec, i, j, 
+					/*r*/ 255, 
+					/*g*/ (3*i*i + j +f) % 256, 
+					/*b*/ (j*i-f) % 256);
+
+		/*submiting drawn frame to encoder.*/
+		etheora_enc_nextframe(&ec); 
+	}
+
+	/*drawing last frame.*/
+	for( i = 0; i < 640; i++)
+		for( j = 0; j < 480; j++)
+			etheora_enc_rgb_draw(&ec, i, j, 
+					/*r*/ 255, 
+					/*g*/ (i*i+i*j*j-f) % 256, 
+					/*b*/ (j*i+i*i-f) % 256);
+
+	/*submiting last frame to encoder and finishing the process. */
+	etheora_enc_finish(&ec); 
+
+	fprintf(stderr, "video generated. \n"); 
+	return 0; 
+
+}
+
+
+#if 0
+	if(argc > 1) {
+		fout = fopen(args[1], "w");
+		fprintf(stderr, "opening %s to write video file . \n", args[1]);
+	}
+	else {  
+		fout = stdout;
+		fprintf(stderr, "opening standard output to write video file. \n");
+	}
+#endif 



More information about the commits mailing list