[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