From: Siegfried L. <si...@us...> - 2003-03-08 17:26:44
|
Update of /cvsroot/xine/xine-lib/src/input In directory sc8-pr-cvs1:/tmp/cvs-serv30441/src/input Modified Files: Tag: broadcast Makefile.am Added Files: Tag: broadcast input_slave.c Log Message: slightly cleaned up version of the broadcast patch, should be merged to HEAD after review... --- NEW FILE: input_slave.c --- /* * Copyright (C) 2000-2002 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * $Id: input_slave.c,v 1.1.2.1 2003/03/08 17:26:02 siggi Exp $ * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <errno.h> #include <sys/time.h> #include <sys/types.h> #include "xine_internal.h" #include "xineutils.h" #include "input_plugin.h" #include "net_buf_ctrl.h" #ifdef __GNUC__ #define LOG_MSG(xine, message, args...) { \ xine_log(xine, XINE_LOG_MSG, message, ##args); \ printf(message, ##args); \ } #else #define LOG_MSG(xine, ...) { \ xine_log(xine, XINE_LOG_MSG, __VA_ARGS__); \ printf(__VA_ARGS__); \ } #endif /* #define LOG */ #define BROADCAST_PORT 2345 typedef struct { input_plugin_t input_plugin; xine_stream_t *stream; struct in_addr src_addr; int skfd; char *mrl; off_t curpos; nbc_t *nbc; } net_input_plugin_t; typedef struct { input_class_t input_class; xine_t *xine; config_values_t *config; } net_input_class_t; /* **************************************************************** */ /* Private functions */ /* **************************************************************** */ #define LOW_WATER_MARK 50 #define HIGH_WATER_MARK 100 static off_t net_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) { net_input_plugin_t *this = (net_input_plugin_t *) this_gen; off_t total; struct sockaddr_in Addr; int AddrLen; fd_set rset; struct timeval timeout; #ifdef LOG printf ("input_net: reading %d bytes...\n", len); #endif nbc_check_buffers (this->nbc); do { FD_ZERO (&rset); FD_SET (this->skfd, &rset); timeout.tv_sec = 0; timeout.tv_usec = 500000; if (select (this->skfd+1, &rset, NULL, NULL, &timeout) <= 0) { return 0; } AddrLen = sizeof(Addr); total = recvfrom(this->skfd, buf, len, 0, (struct sockaddr *) &Addr, &AddrLen); } while( this->src_addr.s_addr && Addr.sin_addr.s_addr != this->src_addr.s_addr ); this->curpos += total; return total; } static off_t net_plugin_get_length (input_plugin_t *this_gen) { return 0; } static uint32_t net_plugin_get_capabilities (input_plugin_t *this_gen) { return INPUT_CAP_NOCAP; } static off_t net_plugin_get_current_pos (input_plugin_t *this_gen){ net_input_plugin_t *this = (net_input_plugin_t *) this_gen; return this->curpos; } static off_t net_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { net_input_plugin_t *this = (net_input_plugin_t *) this_gen; return this->curpos; } static char* net_plugin_get_mrl (input_plugin_t *this_gen) { net_input_plugin_t *this = (net_input_plugin_t *) this_gen; return this->mrl; } static int net_plugin_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { /* net_input_plugin_t *this = (net_input_plugin_t *) this_gen; */ return INPUT_OPTIONAL_UNSUPPORTED; } static void net_plugin_dispose (input_plugin_t *this_gen ) { net_input_plugin_t *this = (net_input_plugin_t *) this_gen; close(this->skfd); this->skfd = -1; free (this->mrl); if (this->nbc) { nbc_close (this->nbc); this->nbc = NULL; } free (this_gen); } #define SEND_BUFFER 0 #define RECEIVE_BUFFER 1 static int SetMaxSocketBuffer( int recv, int size ) { int fd; char str[20]; static char sys_file[2][80] = { "/proc/sys/net/core/wmem_max", "/proc/sys/net/core/rmem_max" }; if ((fd = open(sys_file[recv], O_WRONLY)) < 0) return 0; memset( str, 0, sizeof(str) ); snprintf( str, sizeof(str), "%d\n", size ); write(fd, str, strlen(str) ); close(fd); return 1; } static int SetCurrentSocketBuffer( int skfd, int recv, int size ) { static int option[2] = { SO_SNDBUF, SO_RCVBUF }; if( setsockopt(skfd,SOL_SOCKET,option[recv],(void *)&size,sizeof(size)) != 0 ) return 0; return 1; } static input_plugin_t *net_plugin_open (input_class_t *cls_gen, xine_stream_t *stream, const char *mrl) { /* net_input_plugin_t *this = (net_input_plugin_t *) this_gen; */ net_input_plugin_t *this = xine_xmalloc(sizeof(net_input_plugin_t)); char *filename; int bufsize; this->mrl = strdup(mrl); this->stream = stream; printf("input_slave: open called\n"); if (!strncasecmp (mrl, "oc:/", 4)) { filename = (char *) &this->mrl[4]; if( !inet_aton(filename, &this->src_addr) ) { memset(&this->src_addr,0,sizeof(this->src_addr)); } } else { free (this->mrl); free (this); return NULL; } /* try to set max receive buffer. probably only root can do that. */ bufsize = 1024*1024; SetMaxSocketBuffer( RECEIVE_BUFFER, bufsize ); /* Create a channel to the NET kernel. */ if ((this->skfd = socket(AF_INET, SOCK_DGRAM, 0) ) >= 0) { struct sockaddr_in servAddr; /* adjust current buffer size */ while(1) { if( SetCurrentSocketBuffer( this->skfd, RECEIVE_BUFFER, bufsize ) ) { break; } bufsize /= 2; if( bufsize <= 32*1024 ) { printf("udp: error setting network buffer size\n"); this->skfd = -1; break; } } if( this->skfd > 0 ) { /* bind local server port */ servAddr.sin_family = AF_INET; servAddr.sin_addr.s_addr = htonl(INADDR_ANY); servAddr.sin_port = htons(BROADCAST_PORT); if( bind (this->skfd, (struct sockaddr *) &servAddr,sizeof(servAddr)) < 0 ) { printf("udp: cannot bind port number %d\n", BROADCAST_PORT); this->skfd = -1; } } } else { printf("udp: error opening channel to NET kernel\n"); } this->curpos = 0; if (this->skfd == -1) { free (this->mrl); free (this); return NULL; } this->nbc = nbc_init (this->stream); this->input_plugin.get_capabilities = net_plugin_get_capabilities; this->input_plugin.read = net_plugin_read; this->input_plugin.read_block = NULL; this->input_plugin.seek = net_plugin_seek; this->input_plugin.get_current_pos = net_plugin_get_current_pos; this->input_plugin.get_length = net_plugin_get_length; this->input_plugin.get_blocksize = NULL; this->input_plugin.get_mrl = net_plugin_get_mrl; this->input_plugin.get_optional_data = net_plugin_get_optional_data; this->input_plugin.dispose = net_plugin_dispose; this->input_plugin.input_class = cls_gen; this->stream->stream_info[XINE_STREAM_INFO_VIDEO_HAS_STILL] = 1; return &this->input_plugin; } /* * net plugin class */ static char *net_class_get_description (input_class_t *this_gen) { return _(""); } static char *net_class_get_identifier (input_class_t *this_gen) { return "OC"; } static void net_class_dispose (input_class_t *this_gen) { net_input_class_t *this = (net_input_class_t *) this_gen; free (this); } static void *init_class (xine_t *xine, void *data) { net_input_class_t *this; this = (net_input_class_t *) xine_xmalloc(sizeof(net_input_class_t)); this->config = xine->config; this->xine = xine; this->input_class.open_plugin = net_plugin_open; this->input_class.get_description = net_class_get_description; this->input_class.get_identifier = net_class_get_identifier; this->input_class.get_dir = NULL; this->input_class.get_autoplay_list = NULL; this->input_class.dispose = net_class_dispose; this->input_class.eject_media = NULL; return this; } /* * exported plugin catalog entry */ plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_INPUT, 11, "oc", XINE_VERSION_CODE, NULL, init_class }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; Index: Makefile.am =================================================================== RCS file: /cvsroot/xine/xine-lib/src/input/Makefile.am,v retrieving revision 1.56 retrieving revision 1.56.2.1 diff -u -r1.56 -r1.56.2.1 --- Makefile.am 7 Mar 2003 01:20:22 -0000 1.56 +++ Makefile.am 8 Mar 2003 17:25:58 -0000 1.56.2.1 @@ -67,7 +67,8 @@ xineplug_inp_net.la \ $(in_pvr) \ xineplug_inp_dvb.la \ - xineplug_inp_cdda.la + xineplug_inp_cdda.la \ + xineplug_inp_slave.la #lib_LTLIBRARIES = \ @@ -137,6 +138,10 @@ xineplug_inp_gnome_vfs_la_SOURCES = input_gnome_vfs.c xineplug_inp_gnome_vfs_la_LIBADD = $(GNOME_VFS_LIBS) $(XINE_LIB) xineplug_inp_gnome_vfs_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@ + +xineplug_inp_slave_la_SOURCES = input_slave.c net_buf_ctrl.c +xineplug_inp_slave_la_LIBADD = $(XINE_LIB) +xineplug_inp_slave_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@ xineplug_inp_pvr_la_SOURCES = input_pvr.c xineplug_inp_pvr_la_LIBADD = $(XINE_LIB) |