diff options
author | Daniel Caujolle-Bert <f1rmb@users.sourceforge.net> | 2001-05-06 02:37:59 +0000 |
---|---|---|
committer | Daniel Caujolle-Bert <f1rmb@users.sourceforge.net> | 2001-05-06 02:37:59 +0000 |
commit | 8eb4cb861c548b58f229abf6008e4cc681e711e7 (patch) | |
tree | 317705cd28512251b24fc61c709730476e829676 /src | |
parent | f2181d0641c5ebd684f8e9113d14bb49bb390eef (diff) | |
download | xine-lib-8eb4cb861c548b58f229abf6008e4cc681e711e7.tar.gz xine-lib-8eb4cb861c548b58f229abf6008e4cc681e711e7.tar.bz2 |
Re-enable and sync input plugins. RTP one should be broken.
CVS patchset: 63
CVS date: 2001/05/06 02:37:59
Diffstat (limited to 'src')
-rw-r--r-- | src/input/Makefile.am | 24 | ||||
-rw-r--r-- | src/input/input_dvd.c | 4 | ||||
-rw-r--r-- | src/input/input_net.c | 195 | ||||
-rw-r--r-- | src/input/input_plugin.h | 3 | ||||
-rw-r--r-- | src/input/input_rtp.c | 552 | ||||
-rw-r--r-- | src/input/input_stdin_fifo.c | 200 | ||||
-rw-r--r-- | src/input/input_vcd.c | 542 |
7 files changed, 978 insertions, 542 deletions
diff --git a/src/input/Makefile.am b/src/input/Makefile.am index 272eda927..dae4648bd 100644 --- a/src/input/Makefile.am +++ b/src/input/Makefile.am @@ -14,11 +14,9 @@ libdir = $(XINE_PLUGINDIR) # --------- # All of xine input plugins should be named like the scheme "xineplug_inp_" # - -#lib_LTLIBRARIES = xineplug_inp_net.la xineplug_inp_dvd.la \ -# xineplug_inp_vcd.la xineplug_inp_stdin_fifo.la \ -# xineplug_inp_rtp.la -lib_LTLIBRARIES = xineplug_inp_file.la xineplug_inp_dvd.la +lib_LTLIBRARIES = xineplug_inp_file.la xineplug_inp_dvd.la \ + xineplug_inp_stdin_fifo.la xineplug_inp_net.la \ + xineplug_inp_vcd.la xineplug_inp_rtp.la xineplug_inp_file_la_SOURCES = input_file.c xineplug_inp_file_la_LDFLAGS = -avoid-version -module @@ -26,17 +24,17 @@ xineplug_inp_file_la_LDFLAGS = -avoid-version -module xineplug_inp_dvd_la_SOURCES = input_dvd.c dvd_udf.c xineplug_inp_dvd_la_LDFLAGS = -avoid-version -module -#xineplug_inp_net_la_SOURCES = input_net.c -#xineplug_inp_net_la_LDFLAGS = -avoid-version -module +xineplug_inp_net_la_SOURCES = input_net.c +xineplug_inp_net_la_LDFLAGS = -avoid-version -module -#xineplug_inp_vcd_la_SOURCES = input_vcd.c -#xineplug_inp_vcd_la_LDFLAGS = -avoid-version -module +xineplug_inp_vcd_la_SOURCES = input_vcd.c +xineplug_inp_vcd_la_LDFLAGS = -avoid-version -module -#xineplug_inp_stdin_fifo_la_SOURCES = input_stdin_fifo.c -#xineplug_inp_stdin_fifo_la_LDFLAGS = -avoid-version -module +xineplug_inp_stdin_fifo_la_SOURCES = input_stdin_fifo.c +xineplug_inp_stdin_fifo_la_LDFLAGS = -avoid-version -module -#xineplug_inp_rtp_la_SOURCES = input_rtp.c -#xineplug_inp_rtp_la_LDFLAGS = -avoid-version -module +xineplug_inp_rtp_la_SOURCES = input_rtp.c +xineplug_inp_rtp_la_LDFLAGS = -avoid-version -module include_HEADERS = input_plugin.h noinst_HEADERS = dvd_udf.h diff --git a/src/input/input_dvd.c b/src/input/input_dvd.c index e821ca728..56d714903 100644 --- a/src/input/input_dvd.c +++ b/src/input/input_dvd.c @@ -17,7 +17,7 @@ * 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_dvd.c,v 1.3 2001/05/05 23:44:33 f1rmb Exp $ + * $Id: input_dvd.c,v 1.4 2001/05/06 02:37:59 f1rmb Exp $ */ #ifdef HAVE_CONFIG_H @@ -541,7 +541,7 @@ input_plugin_t *init_input_plugin (int iface, config_values_t *config) { break; default: fprintf(stderr, - "File input plugin doesn't support plugin API version %d.\n" + "Dvd input plugin doesn't support plugin API version %d.\n" "PLUGIN DISABLED.\n" "This means there's a version mismatch between xine and this input" "plugin.\nInstalling current input plugins should help.\n", diff --git a/src/input/input_net.c b/src/input/input_net.c index d450f9716..4d1a11e91 100644 --- a/src/input/input_net.c +++ b/src/input/input_net.c @@ -42,7 +42,23 @@ static uint32_t xine_debug; -static int input_file_handle; +#define NET_BS_LEN 2324 + +typedef struct { + input_plugin_t input_plugin; + + int fh; + char *mrl; + config_values_t *config; + + off_t curpos; + +} net_input_plugin_t; + +/* **************************************************************** */ +/* Private functions */ +/* **************************************************************** */ + static int host_connect_attempt(struct in_addr ia, int port) { int s=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); @@ -122,17 +138,21 @@ static int host_connect(const char *host, int port) { fprintf(stderr, "unable to connect to '%s'.\n", host); return -1; } +/* **************************************************************** */ +/* END OF PRIVATES */ +/* **************************************************************** */ -static void input_plugin_init (void) { - input_file_handle = -1; -} - -static int input_plugin_open (const char *mrl) { - +/* + * + */ +static int net_plugin_open (input_plugin_t *this_gen, char *mrl) { + net_input_plugin_t *this = (net_input_plugin_t *) this_gen; char *filename; char *pptr; int port = 7658; + this->mrl = mrl; + if (!strncasecmp (mrl, "tcp:",4)) filename = (char *) &mrl[4]; else @@ -150,75 +170,150 @@ static int input_plugin_open (const char *mrl) { sscanf(pptr,"%d", &port); } - input_file_handle = host_connect(filename, port); + this->fh = host_connect(filename, port); + this->curpos = 0; - if (input_file_handle == -1) { + if (this->fh == -1) { return 0; } return 1; } -static uint32_t input_plugin_read (char *buf, uint32_t nlen) { - return read (input_file_handle, buf, nlen); -} +/* + * + */ +static off_t net_plugin_read (input_plugin_t *this_gen, + char *buf, off_t nlen) { + net_input_plugin_t *this = (net_input_plugin_t *) this_gen; + off_t n; + + n = read (this->fh, buf, nlen); -static off_t input_plugin_seek (off_t offset, int origin) { + this->curpos += n; - return -1; + return n; } -static off_t input_plugin_get_length (void) { +/* + * + */ +static off_t net_plugin_get_length (input_plugin_t *this_gen) { + return 0; } -static uint32_t input_plugin_get_capabilities (void) { - return 0; +/* + * + */ +static uint32_t net_plugin_get_capabilities (input_plugin_t *this_gen) { + + return INPUT_CAP_NOCAP; } -static uint32_t input_plugin_get_blocksize (void) { - return 2324; +/* + * + */ +static uint32_t net_plugin_get_blocksize (input_plugin_t *this_gen) { + + return NET_BS_LEN; +; } -static int input_plugin_eject (void) { +/* + * + */ +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 int net_plugin_eject_media (input_plugin_t *this_gen) { return 1; } -static void input_plugin_close (void) { - close(input_file_handle); - input_file_handle = -1; +/* + * + */ +static void net_plugin_close (input_plugin_t *this_gen) { + net_input_plugin_t *this = (net_input_plugin_t *) this_gen; + + close(this->fh); + this->fh = -1; +} + +/* + * + */ +static char *net_plugin_get_description (input_plugin_t *this_gen) { + return "net input plugin as shipped with xine"; } -static char *input_plugin_get_identifier (void) { +/* + * + */ +static char *net_plugin_get_identifier (input_plugin_t *this_gen) { return "TCP"; } -static int input_plugin_is_branch_possible (const char *next_mrl) { - return 0; +/* + * + */ +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 input_plugin_t plugin_op = { - NULL, - NULL, - input_plugin_init, - input_plugin_open, - input_plugin_read, - input_plugin_seek, - input_plugin_get_length, - input_plugin_get_capabilities, - NULL, - input_plugin_get_blocksize, - input_plugin_eject, - input_plugin_close, - input_plugin_get_identifier, - NULL, - input_plugin_is_branch_possible, - NULL -}; - -input_plugin_t *input_plugin_getinfo(uint32_t dbglvl) { - - xine_debug = dbglvl; - - return &plugin_op; +/* + * + */ +input_plugin_t *init_input_plugin (int iface, config_values_t *config) { + + net_input_plugin_t *this; + + xine_debug = config->lookup_int (config, "xine_debug", 0); + + switch (iface) { + case 1: + this = (net_input_plugin_t *) malloc (sizeof (net_input_plugin_t)); + + this->input_plugin.interface_version = INPUT_PLUGIN_IFACE_VERSION; + this->input_plugin.get_capabilities = net_plugin_get_capabilities; + this->input_plugin.open = net_plugin_open; + this->input_plugin.read = net_plugin_read; + this->input_plugin.read_block = NULL; + this->input_plugin.seek = NULL; + 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 = net_plugin_get_blocksize; + this->input_plugin.get_dir = NULL; + this->input_plugin.eject_media = net_plugin_eject_media; + this->input_plugin.get_mrl = net_plugin_get_mrl; + this->input_plugin.close = net_plugin_close; + this->input_plugin.get_description = net_plugin_get_description; + this->input_plugin.get_identifier = net_plugin_get_identifier; + this->input_plugin.get_autoplay_list = NULL; + this->input_plugin.get_clut = NULL; + + this->fh = -1; + this->mrl = NULL; + this->config = config; + this->curpos = 0; + + return (input_plugin_t *) this; + break; + default: + fprintf(stderr, + "Net input plugin doesn't support plugin API version %d.\n" + "PLUGIN DISABLED.\n" + "This means there's a version mismatch between xine and this input" + "plugin.\nInstalling current input plugins should help.\n", + iface); + return NULL; + } } diff --git a/src/input/input_plugin.h b/src/input/input_plugin.h index f944a1127..c9d01b71d 100644 --- a/src/input/input_plugin.h +++ b/src/input/input_plugin.h @@ -17,7 +17,7 @@ * 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_plugin.h,v 1.4 2001/05/03 00:02:42 f1rmb Exp $ + * $Id: input_plugin.h,v 1.5 2001/05/06 02:37:59 f1rmb Exp $ */ #ifndef HAVE_INPUT_PLUGIN_H @@ -162,6 +162,7 @@ struct input_plugin_s * possible capabilites an input plugin can have: */ +#define INPUT_CAP_NOCAP 0x00000000 #define INPUT_CAP_SEEKABLE 0x00000001 #define INPUT_CAP_BLOCK 0x00000002 #define INPUT_CAP_AUTOPLAY 0x00000004 diff --git a/src/input/input_rtp.c b/src/input/input_rtp.c index 88fa5784d..ec01a1d26 100644 --- a/src/input/input_rtp.c +++ b/src/input/input_rtp.c @@ -38,13 +38,13 @@ * fd is open for read on mpeg stream, sock for write on a multicast socket. * * while (1) { - * /* read pack */ + * \/\* read pack *\/ * read(fd, buf, 2048) - * /* end of stream */ + * \/\* end of stream *\/ * if (buf[3] == 0xb9) * return 0; * - * /* extract the system reference clock, srcb, from the pack */ + * \/\* extract the system reference clock, srcb, from the pack *\/ * * send_at = srcb/90000.0; * while (time_now < send_at) { @@ -80,116 +80,191 @@ #include <sys/time.h> #include <stdlib.h> +#include "xine_internal.h" +#include "monitor.h" #include "input_plugin.h" -static int last_input_error; -static int input_eof; +#define RTP_BLOCKSIZE 2048 + static uint32_t xine_debug; typedef struct _input_buffer { - struct _input_buffer *next; - unsigned char *buf; -} input_buffer; - + struct _input_buffer *next; + unsigned char *buf; +} input_buffer_t; + #define N_BUFFERS 128 #define IBUFFER_SIZE 2048 -static int input_file_handle = -1; +typedef struct { + input_plugin_t input_plugin; + + char *mrl; + config_values_t *config; -input_buffer *free_buffers; -input_buffer **fifo_head; -input_buffer fifo_tail; + int fh; + + input_buffer_t *free_buffers; + input_buffer_t **fifo_head; + input_buffer_t fifo_tail; + + pthread_mutex_t buffer_mutex; + pthread_cond_t buffer_notempty; + + int last_input_error; + int input_eof; -pthread_mutex_t buffer_mutex; -pthread_cond_t buffer_notempty; + pthread_t reader_thread; -static pthread_t reader_thread; + int curpos; -static void * input_plugin_read_loop(void *); +} rtp_input_plugin_t; +/* ***************************************************************** */ +/* Private functions */ +/* ***************************************************************** */ + +/* + * + */ static int host_connect_attempt(struct in_addr ia, int port) { - int s=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); - struct sockaddr_in sin; + int s=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + struct sockaddr_in sin; + + if(s==-1) { + perror("socket"); + return -1; + } + + sin.sin_family = AF_INET; + sin.sin_addr = ia; + sin.sin_port = htons(port); + + /* datagram socket */ + if (bind(s, (struct sockaddr *)&sin, sizeof(sin))) { + perror("bind failed"); + exit(1); + } + /* multicast ? */ + if ((ntohl(sin.sin_addr.s_addr) >> 28) == 0xe) { + struct ip_mreqn mreqn; - if(s==-1) { - perror("socket"); - return -1; - } - - sin.sin_family = AF_INET; - sin.sin_addr = ia; - sin.sin_port = htons(port); - - /* datagram socket */ - if (bind(s, (struct sockaddr *)&sin, sizeof(sin))) { - perror("bind failed"); - exit(1); - } - /* multicast ? */ - if ((ntohl(sin.sin_addr.s_addr) >> 28) == 0xe) { - struct ip_mreqn mreqn; - - mreqn.imr_multiaddr.s_addr = sin.sin_addr.s_addr; - mreqn.imr_address.s_addr = INADDR_ANY; - mreqn.imr_ifindex = 0; - if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn))) { - perror("setsockopt IP_ADD_MEMBERSHIP failed (multicast kernel?)"); - exit(1); - } + mreqn.imr_multiaddr.s_addr = sin.sin_addr.s_addr; + mreqn.imr_address.s_addr = INADDR_ANY; + mreqn.imr_ifindex = 0; + if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn))) { + perror("setsockopt IP_ADD_MEMBERSHIP failed (multicast kernel?)"); + exit(1); } - - return s; + } + + return s; } +/* + * + */ static int host_connect(const char *host, int port) { - struct hostent *h; - int i; - int s; - - h=gethostbyname(host); - if(h==NULL) - { - fprintf(stderr,"unable to resolve '%s'.\n", host); - return -1; - } - - - for(i=0; h->h_addr_list[i]; i++) - { - struct in_addr ia; - memcpy(&ia, h->h_addr_list[i],4); - s=host_connect_attempt(ia, port); - if(s != -1) - return s; - } - fprintf(stderr, "unable to connect to '%s'.\n", host); - return -1; + struct hostent *h; + int i; + int s; + + h=gethostbyname(host); + if(h==NULL) + { + fprintf(stderr,"unable to resolve '%s'.\n", host); + return -1; + } + + + for(i=0; h->h_addr_list[i]; i++) + { + struct in_addr ia; + memcpy(&ia, h->h_addr_list[i],4); + s=host_connect_attempt(ia, port); + if(s != -1) + return s; + } + fprintf(stderr, "unable to connect to '%s'.\n", host); + return -1; } -static void input_plugin_init (void) { - int bufn; - - for (bufn = 0; bufn < N_BUFFERS; bufn++) { - input_buffer *buf = malloc(sizeof(input_buffer)); - if (!buf) { - fprintf(stderr, "unable to allocate input buffer.\n"); - exit(1); - } - buf->buf = malloc(IBUFFER_SIZE); - if (!buf->buf) { - fprintf(stderr, "unable to allocate input buffer.\n"); - exit(1); - } - buf->next = free_buffers; - free_buffers = buf; +/* + * + */ +static void * input_plugin_read_loop(void *arg) { + rtp_input_plugin_t **this = (rtp_input_plugin_t **) arg; + input_buffer_t *buf; + int r; + unsigned short seq = 0; + static int warned = 0; + /* char whirly[] = "/-\\|"; */ + /* int gig = 0; */ + + while (1) { + pthread_mutex_lock (&(*this)->buffer_mutex); + /* we expect to be able to get a free buffer - possibly we + could be a bit more reasonable but this will do for now. */ + if (!(*this)->free_buffers) { + (*this)->input_eof = 1; + if (!warned) { + printf("OUCH - ran out of buffers\n"); + warned = 1; + } + pthread_cond_signal(&(*this)->buffer_notempty); + continue; + } + warned = 0; + buf = (*this)->free_buffers; + (*this)->free_buffers = (*this)->free_buffers->next; + pthread_mutex_unlock (&(*this)->buffer_mutex); + + /* printf("%c\r", whirly[(gig++ % 4)]); */ + /* fflush(stdout); */ + r = read((*this)->fh, buf->buf, IBUFFER_SIZE); + if (r < 0) { + /* descriptor may be closed by main thread */ + if (r != EBADF) + (*this)->last_input_error = r; + (*this)->curpos = 0; + return 0; + } + if (r == 0) { + (*this)->input_eof = 1; + (*this)->curpos = 0; + return 0; } + (*this)->curpos += r; + + /* For now - check whether we're dropping input */ + if (++seq != *(unsigned short *)buf->buf) { + printf("OUCH - dropped input packet %d %d\n", seq, *(unsigned short *)buf->buf); + seq = *(unsigned short *)buf->buf; + } + buf->buf[1] = buf->buf[0] = 0; + pthread_mutex_lock (&(*this)->buffer_mutex); + buf->next = *(*this)->fifo_head; + *(*this)->fifo_head = buf; + (*this)->fifo_head = &buf->next; + pthread_cond_signal(&(*this)->buffer_notempty); + pthread_mutex_unlock (&(*this)->buffer_mutex); + } } +/* ***************************************************************** */ +/* END OF PRIVATES */ +/* ***************************************************************** */ + +/* + * + */ +static int rtp_plugin_open (input_plugin_t *this_gen, char *mrl ) { + rtp_input_plugin_t *this = (rtp_input_plugin_t *) this_gen; + char *filename; + char *pptr; + int port = 7658; + pthread_attr_t thread_attrs; -static int input_plugin_open (char *mrl) { - char *filename; - char *pptr; - int port = 7658; - pthread_attr_t thread_attrs; + this->mrl = mrl; if (!strncmp (mrl, "rtp:",4)) { filename = &mrl[4]; @@ -210,175 +285,206 @@ static int input_plugin_open (char *mrl) { sscanf(pptr,"%d", &port); } - if (input_file_handle != -1) - close(input_file_handle); - input_file_handle = host_connect(filename, port); + if (this->fh != -1) + close(this->fh); + this->fh = host_connect(filename, port); - if (input_file_handle == -1) { + if (this->fh == -1) { return 0; } - last_input_error = 0; - input_eof = 0; - fifo_tail.next = &fifo_tail; - fifo_head = &fifo_tail.next; + this->last_input_error = 0; + this->input_eof = 0; + this->fifo_tail.next = &this->fifo_tail; + this->fifo_head = &this->fifo_tail.next; + this->curpos = 0; - pthread_cond_init(&buffer_notempty, NULL); + pthread_cond_init(&this->buffer_notempty, NULL); pthread_attr_init(&thread_attrs); pthread_attr_setdetachstate(&thread_attrs, PTHREAD_CREATE_DETACHED); - pthread_create(&reader_thread, &thread_attrs, input_plugin_read_loop, (void *)input_file_handle); + pthread_create(&this->reader_thread, &thread_attrs, + input_plugin_read_loop, (void *)&this); pthread_attr_destroy(&thread_attrs); return 1; } -static uint32_t input_plugin_read (char *buf, uint32_t nlen) { - input_buffer *ibuf; - - pthread_mutex_lock (&buffer_mutex); - while (fifo_tail.next == &fifo_tail) { - if (input_eof) { - pthread_mutex_unlock (&buffer_mutex); - return 0; +/* + * + */ +static off_t rtp_plugin_read (input_plugin_t *this_gen, + char *buf, off_t nlen) { + rtp_input_plugin_t *this = (rtp_input_plugin_t *) this_gen; + input_buffer_t *ibuf; + + pthread_mutex_lock (&this->buffer_mutex); + while (this->fifo_tail.next == &this->fifo_tail) { + if (this->input_eof) { + pthread_mutex_unlock (&this->buffer_mutex); + return 0; } - if (last_input_error) { - pthread_mutex_unlock (&buffer_mutex); - return last_input_error; + if (this->last_input_error) { + pthread_mutex_unlock (&this->buffer_mutex); + return this->last_input_error; } - pthread_cond_wait(&buffer_notempty, &buffer_mutex); - } - ibuf = fifo_tail.next; - fifo_tail.next = fifo_tail.next->next; - - /* Is FIFO now empty */ - if (fifo_tail.next == &fifo_tail) - fifo_head = &fifo_tail.next; - - pthread_mutex_unlock (&buffer_mutex); - - memcpy(buf, ibuf->buf, nlen < IBUFFER_SIZE ? nlen : IBUFFER_SIZE); + pthread_cond_wait(&this->buffer_notempty, &this->buffer_mutex); + } + ibuf = this->fifo_tail.next; + this->fifo_tail.next = this->fifo_tail.next->next; + + /* Is FIFO now empty */ + if (this->fifo_tail.next == &this->fifo_tail) + this->fifo_head = &this->fifo_tail.next; + + pthread_mutex_unlock (&this->buffer_mutex); + + memcpy(buf, ibuf->buf, nlen < IBUFFER_SIZE ? nlen : IBUFFER_SIZE); + + pthread_mutex_lock (&this->buffer_mutex); + ibuf->next = this->free_buffers; + this->free_buffers = ibuf; + pthread_mutex_unlock (&this->buffer_mutex); + + return nlen < IBUFFER_SIZE ? nlen : IBUFFER_SIZE; +} - pthread_mutex_lock (&buffer_mutex); - ibuf->next = free_buffers; - free_buffers = ibuf; - pthread_mutex_unlock (&buffer_mutex); +/* + * + */ +static off_t rtp_plugin_get_length (input_plugin_t *this_gen) { - return nlen < IBUFFER_SIZE ? nlen : IBUFFER_SIZE; + return 0; } -static void * input_plugin_read_loop(void *arg) { - int inf = (int) arg; - input_buffer *buf; - int r; - unsigned short seq = 0; - static int warned = 0; - - char whirly[] = "/-\\|"; - int gig = 0; - - while (1) { - pthread_mutex_lock (&buffer_mutex); - /* we expect to be able to get a free buffer - possibly we - could be a bit more reasonable but this will do for now. */ - if (!free_buffers) { - input_eof = 1; - if (!warned) { - printf("OUCH - ran out of buffers\n"); - warned = 1; - } - pthread_cond_signal(&buffer_notempty); - continue; - } - warned = 0; - buf = free_buffers; - free_buffers = free_buffers->next; - pthread_mutex_unlock (&buffer_mutex); - - /* printf("%c\r", whirly[(gig++ % 4)]); */ - /* fflush(stdout); */ - r = read(inf, buf->buf, IBUFFER_SIZE); - if (r < 0) { - /* descriptor may be closed by main thread */ - if (r != EBADF) - last_input_error = r; - return 0; - } - if (r == 0) { - input_eof = 1; - return 0; - } - - /* For now - check whether we're dropping input */ - if (++seq != *(unsigned short *)buf->buf) { - printf("OUCH - dropped input packet %d %d\n", seq, *(unsigned short *)buf->buf); - seq = *(unsigned short *)buf->buf; - } - buf->buf[1] = buf->buf[0] = 0; - pthread_mutex_lock (&buffer_mutex); - buf->next = *fifo_head; - *fifo_head = buf; - fifo_head = &buf->next; - pthread_cond_signal(&buffer_notempty); - pthread_mutex_unlock (&buffer_mutex); - } +/* + * + */ +static off_t rtp_plugin_get_current_pos (input_plugin_t *this_gen){ + rtp_input_plugin_t *this = (rtp_input_plugin_t *) this_gen; + + return (this->curpos * IBUFFER_SIZE); } -static off_t input_plugin_seek (off_t offset, int origin) { +/* + * + */ +static uint32_t rtp_plugin_get_capabilities (input_plugin_t *this_gen) { - return -1; + return INPUT_CAP_NOCAP; } -static uint32_t input_plugin_get_length (void) { - return 0; -} +/* + * + */ +static uint32_t rtp_plugin_get_blocksize (input_plugin_t *this_gen) { -static uint32_t input_plugin_get_capabilities (void) { - return 0; + return RTP_BLOCKSIZE; } -static uint32_t input_plugin_get_blocksize (void) { - return 2048; -} +/* + * + */ +static void rtp_plugin_close (input_plugin_t *this_gen) { + rtp_input_plugin_t *this = (rtp_input_plugin_t *) this_gen; -static void input_plugin_close (void) { - close(input_file_handle); - input_file_handle = -1; + close(this->fh); + this->fh = -1; } -static int input_plugin_eject (void) { +/* + * + */ +static int rtp_plugin_eject_media (input_plugin_t *this_gen) { + return 1; } -static char *input_plugin_get_identifier (void) { +/* + * + */ +static char *rtp_plugin_get_description (input_plugin_t *this_gen) { + + return "rtp input plugin as shipped with xine"; +} + +/* + * + */ +static char *rtp_plugin_get_identifier (input_plugin_t *this_gen) { + return "RTP"; } -static int input_plugin_is_branch_possible (char *next_mrl) { - return 0; +/* + * + */ +static char* rtp_plugin_get_mrl (input_plugin_t *this_gen) { + rtp_input_plugin_t *this = (rtp_input_plugin_t *) this_gen; + + return this->mrl; } -static input_plugin_t plugin_op = { - NULL, - NULL, - input_plugin_init, - input_plugin_open, - input_plugin_read, - input_plugin_seek, - input_plugin_get_length, - input_plugin_get_capabilities, - NULL, - input_plugin_get_blocksize, - input_plugin_eject, - input_plugin_close, - input_plugin_get_identifier, - NULL, - input_plugin_is_branch_possible, - NULL -}; - -input_plugin_t *input_plugin_getinfo(uint32_t dbglvl) { - - xine_debug = dbglvl; - - return &plugin_op; +/* + * + */ +input_plugin_t *init_input_plugin (int iface, config_values_t *config) { + rtp_input_plugin_t *this; + + xine_debug = config->lookup_int (config, "xine_debug", 0); + + switch (iface) { + case 1: { + int bufn; + + this = (rtp_input_plugin_t *) malloc (sizeof (rtp_input_plugin_t)); + + for (bufn = 0; bufn < N_BUFFERS; bufn++) { + input_buffer_t *buf = malloc(sizeof(input_buffer_t)); + if (!buf) { + fprintf(stderr, "unable to allocate input buffer.\n"); + exit(1); + } + buf->buf = malloc(IBUFFER_SIZE); + if (!buf->buf) { + fprintf(stderr, "unable to allocate input buffer.\n"); + exit(1); + } + buf->next = this->free_buffers; + this->free_buffers = buf; + } + + this->input_plugin.interface_version = INPUT_PLUGIN_IFACE_VERSION; + this->input_plugin.get_capabilities = rtp_plugin_get_capabilities; + this->input_plugin.open = rtp_plugin_open; + this->input_plugin.read = rtp_plugin_read; + this->input_plugin.read_block = NULL; + this->input_plugin.seek = NULL; + this->input_plugin.get_current_pos = rtp_plugin_get_current_pos; + this->input_plugin.get_length = rtp_plugin_get_length; + this->input_plugin.get_blocksize = rtp_plugin_get_blocksize; + this->input_plugin.eject_media = rtp_plugin_eject_media; + this->input_plugin.close = rtp_plugin_close; + this->input_plugin.get_identifier = rtp_plugin_get_identifier; + this->input_plugin.get_description = rtp_plugin_get_description; + this->input_plugin.get_dir = NULL; + this->input_plugin.get_mrl = rtp_plugin_get_mrl; + this->input_plugin.get_autoplay_list = NULL; + this->input_plugin.get_clut = NULL; + + this->fh = -1; + this->mrl = NULL; + this->config = config; + + return (input_plugin_t *) this; + } + break; + default: + fprintf(stderr, + "Rtp input plugin doesn't support plugin API version %d.\n" + "PLUGIN DISABLED.\n" + "This means there's a version mismatch between xine and this input" + "plugin.\nInstalling current input plugins should help.\n", + iface); + return NULL; + } } diff --git a/src/input/input_stdin_fifo.c b/src/input/input_stdin_fifo.c index 488564795..e15b8be09 100644 --- a/src/input/input_stdin_fifo.c +++ b/src/input/input_stdin_fifo.c @@ -17,7 +17,7 @@ * 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_stdin_fifo.c,v 1.1 2001/04/18 22:34:05 f1rmb Exp $ + * $Id: input_stdin_fifo.c,v 1.2 2001/05/06 02:37:59 f1rmb Exp $ */ #ifdef HAVE_CONFIG_H @@ -31,28 +31,32 @@ #include <sys/stat.h> #include <errno.h> +#include "xine_internal.h" +#include "monitor.h" #include "input_plugin.h" static uint32_t xine_debug; -static int input_file_handle; +typedef struct { + input_plugin_t input_plugin; + + int fh; + char *mrl; + config_values_t *config; + off_t curpos; -/* ------------------------------------------------------------------------- */ -/* - * - */ -static void input_plugin_init(void) { +} stdin_input_plugin_t; - input_file_handle = -1; -} -/* ------------------------------------------------------------------------- */ /* * */ -static int input_plugin_open(const char *mrl) { +static int stdin_plugin_open(input_plugin_t *this_gen, char *mrl) { + stdin_input_plugin_t *this = (stdin_input_plugin_t *) this_gen; char *filename; char *pfn; + this->mrl = mrl; + if(!strncasecmp(mrl, "stdin:", 6) || !strncmp(mrl, "-", 1)) { filename = "/dev/stdin"; @@ -71,149 +75,165 @@ static int input_plugin_open(const char *mrl) { filename = (char *) mrl; } -#ifdef DEBUG - fprintf(stderr, "%s(%d): opening >%s< file\n", - __FILE__, __LINE__, filename); -#endif + xprintf (VERBOSE|INPUT, "Opening >%s<\n",filename); - input_file_handle = open(filename, O_RDONLY); - - if(input_file_handle == -1) { + this->fh = open (filename, O_RDONLY); + this->curpos = 0; + + if(this->fh == -1) { return 0; } return 1; } -/* ------------------------------------------------------------------------- */ + /* * */ -static uint32_t input_plugin_read(char *buf, uint32_t nlen) { - - int n, nBytesRead; +static off_t stdin_plugin_read (input_plugin_t *this_gen, + char *buf, off_t nlen) { - nBytesRead = 0; + stdin_input_plugin_t *this = (stdin_input_plugin_t *) this_gen; + off_t n, nBytesRead = 0; while (nBytesRead < nlen) { - n = read(input_file_handle, &buf[nBytesRead], nlen-nBytesRead); + n = read(this->fh, &buf[nBytesRead], nlen-nBytesRead); - if (n<0) + if (n < 0) { + this->curpos += n; return n; - else if (!n) + } + else if (!n) { + this->curpos += nBytesRead; return nBytesRead; + } nBytesRead += n; } + + this->curpos += nBytesRead; return nBytesRead; } -/* ------------------------------------------------------------------------- */ + /* * */ -static off_t input_plugin_seek(off_t offset, int origin) { +static off_t stdin_plugin_get_length(input_plugin_t *this_gen) { - return lseek(input_file_handle, offset, origin); + return 0; } -/* ------------------------------------------------------------------------- */ + /* * */ -static off_t input_plugin_get_length(void) { - struct stat buf ; - - if(fstat(input_file_handle, &buf) == 0) { - return buf.st_size; - } - else { - fprintf(stderr, "%s(%d): fstat() failed: %s\n", - __FILE__, __LINE__, strerror(errno)); - } - - return 0; +static uint32_t stdin_plugin_get_capabilities(input_plugin_t *this_gen) { + + return INPUT_CAP_NOCAP; } -/* ------------------------------------------------------------------------- */ + /* * */ -static uint32_t input_plugin_get_capabilities(void) { +static uint32_t stdin_plugin_get_blocksize(input_plugin_t *this_gen) { return 0; } -/* ------------------------------------------------------------------------- */ + /* * */ -static uint32_t input_plugin_get_blocksize(void) { +static off_t stdin_plugin_get_current_pos (input_plugin_t *this_gen){ + stdin_input_plugin_t *this = (stdin_input_plugin_t *) this_gen; - return 0; + return this->curpos; } -/* ------------------------------------------------------------------------- */ + /* * */ -static int input_plugin_eject (void) { +static int stdin_plugin_eject_media(input_plugin_t *this_gen) { return 1; } -/* ------------------------------------------------------------------------- */ + /* * */ -static void input_plugin_close(void) { - -#ifdef DEBUG - fprintf(stderr, "%s(%d): closing input\n", - __FILE__, __LINE__); -#endif +static char* stdin_plugin_get_mrl (input_plugin_t *this_gen) { + stdin_input_plugin_t *this = (stdin_input_plugin_t *) this_gen; - close(input_file_handle); - input_file_handle = -1; + return this->mrl; } -/* ------------------------------------------------------------------------- */ + /* * */ -static char *input_plugin_get_identifier(void) { +static void stdin_plugin_close(input_plugin_t *this_gen) { + stdin_input_plugin_t *this = (stdin_input_plugin_t *) this_gen; - return "stdin_fifo"; + close(this->fh); + this->fh = -1; } -/* ------------------------------------------------------------------------- */ + /* * */ -static int input_plugin_is_branch_possible (const char *next_mrl) { - - return 0; +static char *stdin_plugin_get_description (input_plugin_t *this_gen) { + return "stdin/fifo input plugin as shipped with xine"; } -/* ------------------------------------------------------------------------- */ + /* * */ -static input_plugin_t plugin_op = { - NULL, - NULL, - input_plugin_init, - input_plugin_open, - input_plugin_read, - input_plugin_seek, - input_plugin_get_length, - input_plugin_get_capabilities, - NULL, - input_plugin_get_blocksize, - input_plugin_eject, - input_plugin_close, - input_plugin_get_identifier, - NULL, - input_plugin_is_branch_possible, - NULL -}; -/* ------------------------------------------------------------------------- */ +static char *stdin_plugin_get_identifier(input_plugin_t *this_gen) { + return "stdin_fifo"; +} + /* * */ -input_plugin_t *input_plugin_getinfo(uint32_t dbglvl) { - - xine_debug = dbglvl; - - return &plugin_op; +input_plugin_t *init_input_plugin (int iface, config_values_t *config) { + + stdin_input_plugin_t *this; + + xine_debug = config->lookup_int (config, "xine_debug", 0); + + switch (iface) { + case 1: + this = (stdin_input_plugin_t *) malloc (sizeof (stdin_input_plugin_t)); + + this->input_plugin.interface_version = INPUT_PLUGIN_IFACE_VERSION; + this->input_plugin.get_capabilities = stdin_plugin_get_capabilities; + this->input_plugin.open = stdin_plugin_open; + this->input_plugin.read = stdin_plugin_read; + this->input_plugin.read_block = NULL; + this->input_plugin.seek = NULL; + this->input_plugin.get_current_pos = stdin_plugin_get_current_pos; + this->input_plugin.get_length = stdin_plugin_get_length; + this->input_plugin.get_blocksize = stdin_plugin_get_blocksize; + this->input_plugin.get_dir = NULL; + this->input_plugin.eject_media = stdin_plugin_eject_media; + this->input_plugin.get_mrl = stdin_plugin_get_mrl; + this->input_plugin.close = stdin_plugin_close; + this->input_plugin.get_description = stdin_plugin_get_description; + this->input_plugin.get_identifier = stdin_plugin_get_identifier; + this->input_plugin.get_autoplay_list = NULL; + this->input_plugin.get_clut = NULL; + + this->fh = -1; + this->mrl = NULL; + this->config = config; + this->curpos = 0; + + return (input_plugin_t *) this; + break; + default: + fprintf(stderr, + "Stdin input plugin doesn't support plugin API version %d.\n" + "PLUGIN DISABLED.\n" + "This means there's a version mismatch between xine and this input" + "plugin.\nInstalling current input plugins should help.\n", + iface); + return NULL; + } } /* ------------------------------------------------------------------------- */ diff --git a/src/input/input_vcd.c b/src/input/input_vcd.c index 1a4229eb4..2698a620a 100644 --- a/src/input/input_vcd.c +++ b/src/input/input_vcd.c @@ -17,7 +17,7 @@ * 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_vcd.c,v 1.2 2001/04/19 09:46:57 f1rmb Exp $ + * $Id: input_vcd.c,v 1.3 2001/05/06 02:37:59 f1rmb Exp $ */ #ifdef HAVE_CONFIG_H @@ -60,6 +60,12 @@ typedef struct { } cdsector_t; typedef struct { + + input_plugin_t input_plugin; + + char *mrl; + config_values_t *config; + int fd; #if defined (__linux__) @@ -79,101 +85,105 @@ typedef struct { char *filelist[100]; -} input_vcd_t; - -static input_vcd_t gVCD; - -static void input_plugin_init (void) { - int i; - - gVCD.fd = -1; - for (i=0; i<100; i++) - gVCD.filelist[i] = (char *) malloc (256); -} +} vcd_input_plugin_t; +/* ***************************************************************** */ +/* Private functions */ +/* ***************************************************************** */ #if defined (__linux__) -static int input_vcd_read_toc (void) { +static int input_vcd_read_toc (vcd_input_plugin_t *this) { int i; /* read TOC header */ - if ( ioctl(gVCD.fd, CDROMREADTOCHDR, &gVCD.tochdr) == -1 ) { + if ( ioctl(this->fd, CDROMREADTOCHDR, &this->tochdr) == -1 ) { fprintf (stderr, "input_vcd : error in ioctl CDROMREADTOCHDR\n"); return -1; } /* read individual tracks */ - for (i=gVCD.tochdr.cdth_trk0; i<=gVCD.tochdr.cdth_trk1; i++) { - gVCD.tocent[i-1].cdte_track = i; - gVCD.tocent[i-1].cdte_format = CDROM_MSF; - if ( ioctl(gVCD.fd, CDROMREADTOCENTRY, &gVCD.tocent[i-1]) == -1 ) { + for (i=this->tochdr.cdth_trk0; i<=this->tochdr.cdth_trk1; i++) { + this->tocent[i-1].cdte_track = i; + this->tocent[i-1].cdte_format = CDROM_MSF; + if ( ioctl(this->fd, CDROMREADTOCENTRY, &this->tocent[i-1]) == -1 ) { fprintf (stderr, "input_vcd: error in ioctl CDROMREADTOCENTRY\n"); return -1; } } /* read the lead-out track */ - gVCD.tocent[gVCD.tochdr.cdth_trk1].cdte_track = CDROM_LEADOUT; - gVCD.tocent[gVCD.tochdr.cdth_trk1].cdte_format = CDROM_MSF; + this->tocent[this->tochdr.cdth_trk1].cdte_track = CDROM_LEADOUT; + this->tocent[this->tochdr.cdth_trk1].cdte_format = CDROM_MSF; - if (ioctl(gVCD.fd, CDROMREADTOCENTRY, &gVCD.tocent[gVCD.tochdr.cdth_trk1]) == -1 ) { + if (ioctl(this->fd, CDROMREADTOCENTRY, + &this->tocent[this->tochdr.cdth_trk1]) == -1 ) { fprintf (stderr, "input_vcd: error in ioctl CDROMREADTOCENTRY\n"); return -1; } - gVCD.total_tracks = gVCD.tochdr.cdth_trk1; + this->total_tracks = this->tochdr.cdth_trk1; return 0; } #elif defined (__FreeBSD__) -static int input_vcd_read_toc (void) { +static int input_vcd_read_toc (vcd_input_plugin_t *this) { struct ioc_read_toc_entry te; int ntracks; /* read TOC header */ - if ( ioctl(gVCD.fd, CDIOREADTOCHEADER, &gVCD.tochdr) == -1 ) { + if ( ioctl(this->fd, CDIOREADTOCHEADER, &this->tochdr) == -1 ) { fprintf (stderr, "input_vcd : error in ioctl CDROMREADTOCHDR\n"); return -1; } - ntracks = gVCD.tochdr.ending_track - - gVCD.tochdr.starting_track + 2; - gVCD.tocent = (struct cd_toc_entry *)malloc(sizeof(*gVCD.tocent) * ntracks); + ntracks = this->tochdr.ending_track + - this->tochdr.starting_track + 2; + this->tocent = (struct cd_toc_entry *) + malloc(sizeof(*this->tocent) * ntracks); te.address_format = CD_LBA_FORMAT; te.starting_track = 0; te.data_len = ntracks * sizeof(struct cd_toc_entry); te.data = gVCD.tocent; - if ( ioctl(gVCD.fd, CDIOREADTOCENTRYS, &te) == -1 ){ + if ( ioctl(this->fd, CDIOREADTOCENTRYS, &te) == -1 ){ fprintf (stderr, "input_vcd: error in ioctl CDROMREADTOCENTRY\n"); return -1; } - gVCD.total_tracks = gVCD.tochdr.ending_track - - gVCD.tochdr.starting_track +1; + this->total_tracks = this->tochdr.ending_track + - this->tochdr.starting_track +1; return 0; } #endif +/* ***************************************************************** */ +/* END OF PRIVATES */ +/* ***************************************************************** */ -static int input_plugin_open (const char *mrl) { +/* + * + */ +static int vcd_plugin_open (input_plugin_t *this_gen, char *mrl) { + vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; char *filename; + this->mrl = mrl; + if (strncasecmp (mrl, "vcd://",6)) return 0; - gVCD.fd = open (CDROM, O_RDONLY); + this->fd = open (CDROM, O_RDONLY); - if (gVCD.fd == -1) { + if (this->fd == -1) { return 0; } - if (input_vcd_read_toc ()) { - close (gVCD.fd); - gVCD.fd = -1; + if (input_vcd_read_toc (this)) { + close (this->fd); + this->fd = -1; return 0; } @@ -181,36 +191,36 @@ static int input_plugin_open (const char *mrl) { xprintf (VERBOSE|INPUT, "Opening >%s<\n",filename); - if (sscanf (filename, "%d", &gVCD.cur_track) != 1) { + if (sscanf (filename, "%d", &this->cur_track) != 1) { fprintf (stderr, "input_vcd: malformed MRL. Use vcd://<track #>\n"); - close (gVCD.fd); - gVCD.fd = -1; + close (this->fd); + this->fd = -1; return 0; } - if (gVCD.cur_track>=gVCD.total_tracks) { + if (this->cur_track>=this->total_tracks) { fprintf (stderr, "input_vcd: invalid track %d (valid range: 0 .. %d)\n", - gVCD.cur_track, gVCD.total_tracks-1); - close (gVCD.fd); - gVCD.fd = -1; + this->cur_track, this->total_tracks-1); + close (this->fd); + this->fd = -1; return 0; } #if defined (__linux__) - gVCD.cur_min = gVCD.tocent[gVCD.cur_track].cdte_addr.msf.minute; - gVCD.cur_sec = gVCD.tocent[gVCD.cur_track].cdte_addr.msf.second; - gVCD.cur_frame = gVCD.tocent[gVCD.cur_track].cdte_addr.msf.frame; + this->cur_min = this->tocent[this->cur_track].cdte_addr.msf.minute; + this->cur_sec = this->tocent[this->cur_track].cdte_addr.msf.second; + this->cur_frame = this->tocent[this->cur_track].cdte_addr.msf.frame; #elif defined (__FreeBSD__) { int bsize = 2352; - if (ioctl (gVCD.fd, CDRIOCSETBLOCKSIZE, &bsize) == -1) { + if (ioctl (this->fd, CDRIOCSETBLOCKSIZE, &bsize) == -1) { fprintf (stderr, "input_vcd: error in CDRIOCSETBLOCKSIZE %d\n", errno); return 0; } - gVCD.cur_sector = - ntohl(gVCD.tocent - [gVCD.cur_track+1 - gVCD.tochdr.starting_track].addr.lba); + this->cur_sector = + ntohl(this->tocent + [this->cur_track+1 - this->tochdr.starting_track].addr.lba); } #endif @@ -218,11 +228,14 @@ static int input_plugin_open (const char *mrl) { return 1; } - - +/* + * + */ #if defined (__linux__) -static uint32_t input_plugin_read (char *buf, uint32_t nlen) { - +static off_t vcd_plugin_read (input_plugin_t *this_gen, + char *buf, off_t nlen) { + + vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; static struct cdrom_msf msf ; static cdsector_t data; struct cdrom_msf0 *end_msf; @@ -232,37 +245,37 @@ static uint32_t input_plugin_read (char *buf, uint32_t nlen) { do { - end_msf = &gVCD.tocent[gVCD.cur_track+1].cdte_addr.msf; + end_msf = &this->tocent[this->cur_track+1].cdte_addr.msf; /* printf ("cur: %02d:%02d:%02d end: %02d:%02d:%02d\n", - gVCD.cur_min, gVCD.cur_sec, gVCD.cur_frame, + this->cur_min, this->cur_sec, this->cur_frame, end_msf->minute, end_msf->second, end_msf->frame); */ - if ( (gVCD.cur_min>=end_msf->minute) && (gVCD.cur_sec>=end_msf->second) - && (gVCD.cur_frame>=end_msf->frame)) + if ( (this->cur_min>=end_msf->minute) && (this->cur_sec>=end_msf->second) + && (this->cur_frame>=end_msf->frame)) return 0; - msf.cdmsf_min0 = gVCD.cur_min; - msf.cdmsf_sec0 = gVCD.cur_sec; - msf.cdmsf_frame0 = gVCD.cur_frame; + msf.cdmsf_min0 = this->cur_min; + msf.cdmsf_sec0 = this->cur_sec; + msf.cdmsf_frame0 = this->cur_frame; memcpy (&data, &msf, sizeof (msf)); - if (ioctl (gVCD.fd, CDROMREADRAW, &data) == -1) { + if (ioctl (this->fd, CDROMREADRAW, &data) == -1) { fprintf (stderr, "input_vcd: error in CDROMREADRAW\n"); return 0; } - gVCD.cur_frame++; - if (gVCD.cur_frame>=75) { - gVCD.cur_frame = 0; - gVCD.cur_sec++; - if (gVCD.cur_sec>=60) { - gVCD.cur_sec = 0; - gVCD.cur_min++; + this->cur_frame++; + if (this->cur_frame>=75) { + this->cur_frame = 0; + this->cur_sec++; + if (this->cur_sec>=60) { + this->cur_sec = 0; + this->cur_min++; } } @@ -275,7 +288,9 @@ static uint32_t input_plugin_read (char *buf, uint32_t nlen) { return VCDSECTORSIZE; } #elif defined (__FreeBSD__) -static uint32_t input_plugin_read (char *buf, uint32_t nlen) { +static off_t vcd_plugin_read (input_plugin_t *this_gen, + char *buf, off_t nlen) { + vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; static cdsector_t data; int bsize = 2352; @@ -283,42 +298,137 @@ static uint32_t input_plugin_read (char *buf, uint32_t nlen) { return 0; do { - if (lseek (gVCD.fd, gVCD.cur_sector * bsize, SEEK_SET) == -1) { + if (lseek (this->fd, this->cur_sector * bsize, SEEK_SET) == -1) { fprintf (stderr, "input_vcd: seek error %d\n", errno); return 0; } - if (read (gVCD.fd, &data, bsize) == -1) { + if (read (this->fd, &data, bsize) == -1) { fprintf (stderr, "input_vcd: read error %d\n", errno); return 0; } - gVCD.cur_sector++; + this->cur_sector++; } while ((data.subheader[2]&~0x01)==0x60); memcpy (buf, data.data, VCDSECTORSIZE); return VCDSECTORSIZE; } #endif +/* + * + */ +#if defined (__linux__) +static buf_element_t *vcd_plugin_read_block (input_plugin_t *this_gen, + fifo_buffer_t *fifo, off_t nlen) { + + vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; + buf_element_t *buf = fifo->buffer_pool_alloc (fifo); + static struct cdrom_msf msf ; + static cdsector_t data; + struct cdrom_msf0 *end_msf; + + if (nlen != VCDSECTORSIZE) + return NULL; + + do + { + end_msf = &this->tocent[this->cur_track+1].cdte_addr.msf; + + /* + printf ("cur: %02d:%02d:%02d end: %02d:%02d:%02d\n", + this->cur_min, this->cur_sec, this->cur_frame, + end_msf->minute, end_msf->second, end_msf->frame); + */ + + if ( (this->cur_min>=end_msf->minute) && (this->cur_sec>=end_msf->second) + && (this->cur_frame>=end_msf->frame)) + return NULL; + + msf.cdmsf_min0 = this->cur_min; + msf.cdmsf_sec0 = this->cur_sec; + msf.cdmsf_frame0 = this->cur_frame; + + memcpy (&data, &msf, sizeof (msf)); + + if (ioctl (this->fd, CDROMREADRAW, &data) == -1) { + fprintf (stderr, "input_vcd: error in CDROMREADRAW\n"); + return NULL; + } + + + this->cur_frame++; + if (this->cur_frame>=75) { + this->cur_frame = 0; + this->cur_sec++; + if (this->cur_sec>=60) { + this->cur_sec = 0; + this->cur_min++; + } + } + + /* Header ID check for padding sector. VCD uses this to keep constant + bitrate so the CD doesn't stop/start */ + } + while((data.subheader[2]&~0x01)==0x60); + + memcpy (buf, data.data, VCDSECTORSIZE); /* FIXME */ + return buf; +} +#elif defined (__FreeBSD__) +static buf_element_t *vcd_plugin_read_block (input_plugin_t *this_gen, + fifo_buffer_t *fifo, off_t nlen) { + + vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; + buf_element_t *buf = fifo->buffer_pool_alloc (fifo); + static cdsector_t data; + int bsize = 2352; + + if (nlen != VCDSECTORSIZE) + return NULL; + + do { + if (lseek (this->fd, this->cur_sector * bsize, SEEK_SET) == -1) { + fprintf (stderr, "input_vcd: seek error %d\n", errno); + return NULL; + } + if (read (this->fd, &data, bsize) == -1) { + fprintf (stderr, "input_vcd: read error %d\n", errno); + return NULL; + } + this->cur_sector++; + } while ((data.subheader[2]&~0x01)==0x60); + memcpy (buf, data.data, VCDSECTORSIZE); + return buf; +} +#endif + +// +/* + * + */ #if defined (__linux__) -static off_t input_plugin_seek (off_t offset, int origin) { +static off_t vcd_plugin_seek (input_plugin_t *this_gen, + off_t offset, int origin) { + vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; struct cdrom_msf0 *start_msf; uint32_t dist ; off_t sector_pos; - start_msf = &gVCD.tocent[gVCD.cur_track].cdte_addr.msf; + start_msf = &this->tocent[this->cur_track].cdte_addr.msf; switch (origin) { case SEEK_SET: dist = offset / VCDSECTORSIZE; - gVCD.cur_min = dist / (60*75) + start_msf->minute; + this->cur_min = dist / (60*75) + start_msf->minute; dist %= 60; - gVCD.cur_sec = dist / 75 + start_msf->second; + this->cur_sec = dist / 75 + start_msf->second; dist %= 75; - gVCD.cur_frame = dist + start_msf->frame; + this->cur_frame = dist + start_msf->frame; - xprintf (VERBOSE|INPUT, "%d => %02d:%02d:%02d\n",offset,gVCD.cur_min,gVCD.cur_sec,gVCD.cur_frame); + xprintf (VERBOSE|INPUT, "%d => %02d:%02d:%02d\n", offset, + this->cur_min, this->cur_sec, this->cur_frame); break; case SEEK_CUR: @@ -330,12 +440,12 @@ static off_t input_plugin_seek (off_t offset, int origin) { if (start_msf->second<60) sector_pos += (59 - start_msf->second) * 75; - if ( gVCD.cur_min > start_msf->minute) { - sector_pos += (gVCD.cur_min - start_msf->minute-1) * 60 * 75; + if ( this->cur_min > start_msf->minute) { + sector_pos += (this->cur_min - start_msf->minute-1) * 60 * 75; - sector_pos += gVCD.cur_sec * 60; + sector_pos += this->cur_sec * 60; - sector_pos += gVCD.cur_frame ; + sector_pos += this->cur_frame ; } return sector_pos * VCDSECTORSIZE; @@ -350,16 +460,18 @@ static off_t input_plugin_seek (off_t offset, int origin) { return offset ; /* FIXME */ } #elif defined (__FreeBSD__) -static off_t input_plugin_seek (off_t offset, int origin) { +static off_t vcd_plugin_seek (input_plugin_t *this_gen, + off_t offset, int origin) { + vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; u_long start; uint32_t dist ; off_t sector_pos; start = - ntohl(gVCD.tocent - [gVCD.cur_track+1 - gVCD.tochdr.starting_track].addr.lba); + ntohl(this->tocent + [this->cur_track+1 - this->tochdr.starting_track].addr.lba); /* printf("seek: start sector:%lu, origin: %d, offset:%qu\n", start, origin, offset); @@ -368,14 +480,14 @@ static off_t input_plugin_seek (off_t offset, int origin) { switch (origin) { case SEEK_SET: dist = offset / VCDSECTORSIZE; - gVCD.cur_sector = start + dist; + this->cur_sector = start + dist; break; case SEEK_CUR: if (offset) fprintf (stderr, "input_vcd: SEEK_CUR not implemented for offset != 0\n"); - sector_pos = gVCD.cur_sector; + sector_pos = this->cur_sector; return sector_pos * VCDSECTORSIZE; @@ -390,13 +502,17 @@ static off_t input_plugin_seek (off_t offset, int origin) { } #endif +/* + * + */ #if defined (__linux__) -static off_t input_plugin_get_length (void) { +static off_t vcd_plugin_get_length (input_plugin_t *this_gen) { + vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; struct cdrom_msf0 *end_msf, *start_msf; off_t len ; - start_msf = &gVCD.tocent[gVCD.cur_track].cdte_addr.msf; - end_msf = &gVCD.tocent[gVCD.cur_track+1].cdte_addr.msf; + start_msf = &this->tocent[this->cur_track].cdte_addr.msf; + end_msf = &this->tocent[this->cur_track+1].cdte_addr.msf; len = 75 - start_msf->frame; @@ -414,46 +530,67 @@ static off_t input_plugin_get_length (void) { return len * VCDSECTORSIZE; } #elif defined (__FreeBSD__) -static off_t input_plugin_get_length (void) { - +static off_t vcd_plugin_get_length (input_plugin_t *this_gen) { + vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; off_t len ; len = - ntohl(gVCD.tocent - [gVCD.cur_track+2 - - gVCD.tochdr.starting_track].addr.lba) - - ntohl(gVCD.tocent - [gVCD.cur_track+1 - - gVCD.tochdr.starting_track].addr.lba); + ntohl(this->tocent + [this->cur_track+2 + - this->tochdr.starting_track].addr.lba) + - ntohl(this->tocent + [this->cur_track+1 + - this->tochdr.starting_track].addr.lba); return len * 2352; /*VCDSECTORSIZE;*/ } #endif -static uint32_t input_plugin_get_capabilities (void) { +/* + * + */ +static off_t vcd_plugin_get_current_pos (input_plugin_t *this_gen){ + + + return (vcd_plugin_seek (this_gen, 0, SEEK_CUR)); +} + +/* + * + */ +static uint32_t vcd_plugin_get_capabilities (input_plugin_t *this_gen) { + return INPUT_CAP_SEEKABLE | INPUT_CAP_BLOCK | INPUT_CAP_AUTOPLAY; } -static uint32_t input_plugin_get_blocksize (void) { +/* + * + */ +static uint32_t vcd_plugin_get_blocksize (input_plugin_t *this_gen) { + return VCDSECTORSIZE; } +/* + * + */ #if defined (__linux__) -static int input_plugin_eject (void) { +static int vcd_plugin_eject_media (input_plugin_t *this_gen) { + vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; int ret, status; - if((gVCD.fd = open(CDROM, O_RDONLY|O_NONBLOCK)) > -1) { - if((status = ioctl(gVCD.fd, CDROM_DRIVE_STATUS, CDSL_CURRENT)) > 0) { + if((this->fd = open(CDROM, O_RDONLY|O_NONBLOCK)) > -1) { + if((status = ioctl(this->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT)) > 0) { switch(status) { case CDS_TRAY_OPEN: - if((ret = ioctl(gVCD.fd, CDROMCLOSETRAY)) != 0) { + if((ret = ioctl(this->fd, CDROMCLOSETRAY)) != 0) { xprintf(VERBOSE|INPUT, "CDROMCLOSETRAY failed: %s\n", strerror(errno)); } break; case CDS_DISC_OK: - if((ret = ioctl(gVCD.fd, CDROMEJECT)) != 0) { + if((ret = ioctl(this->fd, CDROMEJECT)) != 0) { xprintf(VERBOSE|INPUT, "CDROMEJECT failed: %s\n", strerror(errno)); } break; @@ -462,17 +599,17 @@ static int input_plugin_eject (void) { else { xprintf(VERBOSE|INPUT, "CDROM_DRIVE_STATUS failed: %s\n", strerror(errno)); - close(gVCD.fd); + close(this->fd); return 0; } } - close(gVCD.fd); + close(this->fd); return 1; } #elif defined (__FreeBSD__) -static int input_plugin_eject (void) { +static int vcd_plugin_eject_media (input_plugin_t *this_gen) { int fd; if ((fd = open(CDROM, O_RDONLY|O_NONBLOCK)) > -1) { @@ -490,97 +627,176 @@ static int input_plugin_eject (void) { } #endif -static void input_plugin_close (void) { +/* + * + */ +static void vcd_plugin_close (input_plugin_t *this_gen) { + vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; + xprintf (VERBOSE|INPUT, "closing input\n"); - close(gVCD.fd); - gVCD.fd = -1; + close(this->fd); + this->fd = -1; } -static char *input_plugin_get_identifier (void) { +/* + * + */ +static char *vcd_plugin_get_description (input_plugin_t *this_gen) { + return "plain file input plugin as shipped with xine"; +} + +/* + * + */ +static char *vcd_plugin_get_identifier (input_plugin_t *this_gen) { return "VCD"; } -static char **input_plugin_get_autoplay_list (int *nFiles) { +/* + * + */ +static char **vcd_plugin_get_dir (input_plugin_t *this_gen, + char *filename, int *nEntries) { + vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; int i; - gVCD.fd = open (CDROM, O_RDONLY); + if (filename) { + *nEntries = 0; + return NULL; + } + + this->fd = open (CDROM, O_RDONLY); - if (gVCD.fd == -1) { + if (this->fd == -1) { perror ("unable to open /dev/cdrom"); return NULL; } - if (input_vcd_read_toc ()) { - close (gVCD.fd); - gVCD.fd = -1; + if (input_vcd_read_toc (this)) { + close (this->fd); + this->fd = -1; printf ("vcd_read_toc failed\n"); return NULL; } - close (gVCD.fd); - gVCD.fd = -1; + close (this->fd); + this->fd = -1; - *nFiles = gVCD.total_tracks; + *nEntries = this->total_tracks; - /* printf ("%d tracks\n",gVCD.total_tracks); */ + /* printf ("%d tracks\n", this->total_tracks); */ - for (i=1; i<gVCD.total_tracks; i++) { /* FIXME: check if track 0 contains valid data */ - sprintf (gVCD.filelist[i-1], "vcd://%d",i); - /* printf ("list[%d] : %d %s\n", i, gVCD.filelist[i-1], gVCD.filelist[i-1]); */ + for (i=1; i<this->total_tracks; i++) { /* FIXME: check if track 0 contains valid data */ + sprintf (this->filelist[i-1], "vcd://%d",i); + /* printf ("list[%d] : %d %s\n", i, this->filelist[i-1], this->filelist[i-1]); */ } - return gVCD.filelist; + return this->filelist; } -static int input_plugin_is_branch_possible (const char *next_mrl) { +/* + * + */ +static char **vcd_plugin_get_autoplay_list (input_plugin_t *this_gen, + int *nFiles) { + + vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; + int i; - char *filename; - int track; + this->fd = open (CDROM, O_RDONLY); - if (strncasecmp (next_mrl, "vcd://",6)) - return 0; - - filename = (char *) &next_mrl[6]; + if (this->fd == -1) { + perror ("unable to open /dev/cdrom"); + return NULL; + } - if (sscanf (filename, "%d", &track) != 1) { - return 0; + if (input_vcd_read_toc (this)) { + close (this->fd); + this->fd = -1; + + printf ("vcd_read_toc failed\n"); + + return NULL; } - if ((track>=gVCD.total_tracks) || (track != (gVCD.cur_track+1))) - return 0; + close (this->fd); + this->fd = -1; + + *nFiles = this->total_tracks; - return 1; + /* printf ("%d tracks\n", this->total_tracks); */ + + for (i=1; i<this->total_tracks; i++) { /* FIXME: check if track 0 contains valid data */ + sprintf (this->filelist[i-1], "vcd://%d",i); + /* printf ("list[%d] : %d %s\n", i, this->filelist[i-1], this->filelist[i-1]); */ + } + + return this->filelist; } +/* + * + */ +static char* vcd_plugin_get_mrl (input_plugin_t *this_gen) { + vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; -static input_plugin_t plugin_op = { - NULL, - NULL, - input_plugin_init, - input_plugin_open, - input_plugin_read, - input_plugin_seek, - input_plugin_get_length, - input_plugin_get_capabilities, - NULL, - input_plugin_get_blocksize, - input_plugin_eject, - input_plugin_close, - input_plugin_get_identifier, - input_plugin_get_autoplay_list, - input_plugin_is_branch_possible, - NULL -}; - -input_plugin_t *input_plugin_getinfo(uint32_t dbglvl) { - - xine_debug = dbglvl; - - return &plugin_op; + return this->mrl; } +/* + * + */ +input_plugin_t *init_input_plugin (int iface, config_values_t *config) { + vcd_input_plugin_t *this; + + xine_debug = config->lookup_int (config, "xine_debug", 0); + + switch (iface) { + case 1: { + int i; + + this = (vcd_input_plugin_t *) malloc (sizeof (vcd_input_plugin_t)); + + for (i=0; i<100; i++) + this->filelist[i] = (char *) malloc (256); + + this->input_plugin.interface_version = INPUT_PLUGIN_IFACE_VERSION; + this->input_plugin.get_capabilities = vcd_plugin_get_capabilities; + this->input_plugin.open = vcd_plugin_open; + this->input_plugin.read = vcd_plugin_read; + this->input_plugin.read_block = vcd_plugin_read_block; + this->input_plugin.seek = vcd_plugin_seek; + this->input_plugin.get_current_pos = vcd_plugin_get_current_pos; + this->input_plugin.get_length = vcd_plugin_get_length; + this->input_plugin.get_blocksize = vcd_plugin_get_blocksize; + this->input_plugin.eject_media = vcd_plugin_eject_media; + this->input_plugin.close = vcd_plugin_close; + this->input_plugin.get_identifier = vcd_plugin_get_identifier; + this->input_plugin.get_description = vcd_plugin_get_description; + this->input_plugin.get_dir = vcd_plugin_get_dir; + this->input_plugin.get_mrl = vcd_plugin_get_mrl; + this->input_plugin.get_autoplay_list = vcd_plugin_get_autoplay_list; + this->input_plugin.get_clut = NULL; + + this->fd = -1; + this->mrl = NULL; + this->config = config; + + return (input_plugin_t *) this; + } + break; + default: + fprintf(stderr, + "Dvd input plugin doesn't support plugin API version %d.\n" + "PLUGIN DISABLED.\n" + "This means there's a version mismatch between xine and this input" + "plugin.\nInstalling current input plugins should help.\n", + iface); + return NULL; + } +} |