diff options
| -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; +  } +} | 
