summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuenter Bartsch <guenter@users.sourceforge.net>2001-09-11 00:57:11 +0000
committerGuenter Bartsch <guenter@users.sourceforge.net>2001-09-11 00:57:11 +0000
commit949bc4183444bf5c259147c2c673897e0d45cd4b (patch)
tree10be8340a42afde2ca57de07c96e3055f24b939c
parent21c232aa49175be7c1b806d55cde46bf6f035e12 (diff)
downloadxine-lib-949bc4183444bf5c259147c2c673897e0d45cd4b.tar.gz
xine-lib-949bc4183444bf5c259147c2c673897e0d45cd4b.tar.bz2
read_cache enables xine to read DVD data in larger chunks (here 16*2048 bytes), this gives us a nice performance boost on raw devices, especially on FreeBSD
CVS patchset: 608 CVS date: 2001/09/11 00:57:11
-rw-r--r--src/input/Makefile.am6
-rw-r--r--src/input/dvd_udf.c2
-rw-r--r--src/input/dvd_udf.h13
-rw-r--r--src/input/input_dvd.c108
-rw-r--r--src/input/read_cache.c273
-rw-r--r--src/input/read_cache.h41
6 files changed, 365 insertions, 78 deletions
diff --git a/src/input/Makefile.am b/src/input/Makefile.am
index 8d9546c01..470428383 100644
--- a/src/input/Makefile.am
+++ b/src/input/Makefile.am
@@ -26,7 +26,7 @@ lib_LTLIBRARIES = xineplug_inp_file.la $(in_dvd) $(in_vcd) \
xineplug_inp_file_la_SOURCES = input_file.c
xineplug_inp_file_la_LDFLAGS = -avoid-version -module
-xineplug_inp_dvd_la_SOURCES = input_dvd.c dvd_udf.c
+xineplug_inp_dvd_la_SOURCES = input_dvd.c dvd_udf.c read_cache.c
xineplug_inp_dvd_la_LDFLAGS = -avoid-version -module
xineplug_inp_net_la_SOURCES = input_net.c
@@ -42,8 +42,8 @@ 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
-EXTRA_DIST = input_dvd.c dvd_udf.c input_vcd.c
+noinst_HEADERS = dvd_udf.h read_cache.h
+EXTRA_DIST = input_dvd.c dvd_udf.c input_vcd.c read_cache.c
##
diff --git a/src/input/dvd_udf.c b/src/input/dvd_udf.c
index c8064b0eb..6a3d839c5 100644
--- a/src/input/dvd_udf.c
+++ b/src/input/dvd_udf.c
@@ -549,8 +549,6 @@ off_t UDFFindFile (int fd, char *filename, off_t *size)
lb_number = partition.Start+File.Location ;
- printf ("lb_number : %Ld\n", lb_number);
-
retval = lb_number;
bail:
diff --git a/src/input/dvd_udf.h b/src/input/dvd_udf.h
index 77e8ed309..ec19af5ee 100644
--- a/src/input/dvd_udf.h
+++ b/src/input/dvd_udf.h
@@ -1,12 +1,14 @@
-/*
- * Copyright (C) 2000-2001 plitsch-platsch
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
*
- * xine_dvd_plugin is free software; you can redistribute it and/or modify
+ * xine is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
- * xine_dvd_plugin is distributed in the hope that it will be useful,
+ *
+ * xine is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
@@ -15,6 +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: dvd_udf.h,v 1.3 2001/09/11 00:57:11 guenter Exp $
*/
#ifndef DVD_UDF_H
diff --git a/src/input/input_dvd.c b/src/input/input_dvd.c
index b891e0c83..239997f2e 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.22 2001/09/10 00:47:37 miguelfreitas Exp $
+ * $Id: input_dvd.c,v 1.23 2001/09/11 00:57:11 guenter Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -48,6 +48,7 @@
#include "monitor.h"
#include "input_plugin.h"
#include "dvd_udf.h"
+#include "read_cache.h"
static uint32_t xine_debug;
@@ -68,6 +69,7 @@ typedef struct {
int dvd_fd;
int raw_fd;
+ read_cache_t *read_cache;
off_t file_size;
off_t file_size_left;
int file_lbstart;
@@ -110,6 +112,9 @@ static int openDrive (dvd_input_plugin_t *this) {
if (this->raw_fd < 0) {
this->raw_fd = this->dvd_fd;
}
+
+ read_cache_set_fd (this->read_cache, this->raw_fd);
+
return this->raw_fd;
}
@@ -123,6 +128,7 @@ static void closeDrive (dvd_input_plugin_t *this) {
close (this->raw_fd);
this->dvd_fd = -1;
+
}
/*
@@ -206,20 +212,16 @@ static int dvd_plugin_open (input_plugin_t *this_gen, char *mrl) {
return 1 ;
}
-/*
- *
- */
static off_t dvd_plugin_read (input_plugin_t *this_gen,
char *buf, off_t nlen) {
+
dvd_input_plugin_t *this = (dvd_input_plugin_t *) this_gen;
if (nlen != DVD_VIDEO_LB_LEN) {
- /*
- * Hide the error reporting now, demuxer try to read 6 bytes
- * at STAGE_BY_CONTENT probe stage
- */
- fprintf (stderr, "ERROR in input_dvd plugin read: %Ld bytes "
- "is not a sector!\n", nlen);
+
+ printf ("input_dvd: error read: %Ld bytes is not a sector!\n",
+ nlen);
+
return 0;
}
@@ -249,9 +251,6 @@ static void pool_release_buffer (void *arg) {
}
-/*
- *
- */
static buf_element_t *dvd_plugin_read_block (input_plugin_t *this_gen,
fifo_buffer_t *fifo, off_t nlen) {
dvd_input_plugin_t *this = (dvd_input_plugin_t *) this_gen;
@@ -263,38 +262,34 @@ static buf_element_t *dvd_plugin_read_block (input_plugin_t *this_gen,
* at STAGE_BY_CONTENT probe stage
*/
if(nlen != DVD_VIDEO_LB_LEN)
- fprintf (stderr, "ERROR in input_dvd plugin read: %Ld bytes "
+ printf ("input_dvd: error in input_dvd plugin read: %Ld bytes "
"is not a sector!\n", nlen);
return NULL;
}
- buf = fifo->buffer_pool_alloc (fifo);
-
- pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
- pthread_cleanup_push( pool_release_buffer, buf );
-
- buf->content = buf->mem;
+ if ((buf = read_cache_read_block (this->read_cache, this->file_lbcur*DVD_VIDEO_LB_LEN))) {
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
+ pthread_cleanup_push( pool_release_buffer, buf );
+
+ pthread_testcancel();
- pthread_testcancel();
- if ((buf->size = dvd_plugin_read (this_gen, buf->mem, DVD_VIDEO_LB_LEN)) > 0) {
+ buf->type = BUF_DEMUX_BLOCK;
+
this->file_lbcur++;
this->file_size_left -= DVD_VIDEO_LB_LEN;
buf->type = BUF_DEMUX_BLOCK;
+
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
+ pthread_cleanup_pop(0);
} else {
- buf->free_buffer (buf);
- buf = NULL;
- fprintf (stderr, "read error in input_dvd plugin\n");
+ printf ("input_dvd: read error in input_dvd plugin\n");
}
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
- pthread_cleanup_pop(0);
return buf;
}
-/*
- *
- */
+
static off_t dvd_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) {
dvd_input_plugin_t *this = (dvd_input_plugin_t *) this_gen;
@@ -320,8 +315,7 @@ static off_t dvd_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin
break;
default:
- fprintf (stderr, "error in input dvd plugin seek: %d is an unknown "
- "origin\n", origin);
+ printf ("input_dvd: seek: %d is an unknown origin\n", origin);
}
return lseek (this->raw_fd,
@@ -329,35 +323,27 @@ static off_t dvd_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin
- this->file_lbstart * (off_t) DVD_VIDEO_LB_LEN;
}
-/*
- *
- */
+
static off_t dvd_plugin_get_current_pos (input_plugin_t *this_gen){
dvd_input_plugin_t *this = (dvd_input_plugin_t *) this_gen;
return ((this->file_lbcur - this->file_lbstart) * DVD_VIDEO_LB_LEN);
}
-/*
- *
- */
+
static off_t dvd_plugin_get_length (input_plugin_t *this_gen) {
dvd_input_plugin_t *this = (dvd_input_plugin_t *) this_gen;
return this->file_size;
}
-/*
- *
- */
+
static uint32_t dvd_plugin_get_blocksize (input_plugin_t *this_gen) {
return DVD_VIDEO_LB_LEN;
}
-/*
- *
- */
+
static int dvd_plugin_eject_media (input_plugin_t *this_gen) {
dvd_input_plugin_t *this = (dvd_input_plugin_t *) this_gen;
int ret, status;
@@ -413,41 +399,31 @@ static int dvd_plugin_eject_media (input_plugin_t *this_gen) {
return 1;
}
-/*
- *
- */
+
static void dvd_plugin_close (input_plugin_t *this_gen) {
dvd_input_plugin_t *this = (dvd_input_plugin_t *) this_gen;
closeDrive (this);
}
-/*
- *
- */
+
static void dvd_plugin_stop (input_plugin_t *this_gen) {
dvd_plugin_close(this_gen);
}
-/*
- *
- */
+
static char *dvd_plugin_get_description (input_plugin_t *this_gen) {
return "dvd device input plugin as shipped with xine";
}
-/*
- *
- */
+
static char *dvd_plugin_get_identifier (input_plugin_t *this_gen) {
return "DVD";
}
-/*
- *
- */
+
static mrl_t **dvd_plugin_get_dir (input_plugin_t *this_gen,
char *filename, int *nEntries) {
dvd_input_plugin_t *this = (dvd_input_plugin_t *) this_gen;
@@ -537,9 +513,7 @@ static mrl_t **dvd_plugin_get_dir (input_plugin_t *this_gen,
return this->mrls;
}
-/*
- *
- */
+
static char **dvd_plugin_get_autoplay_list (input_plugin_t *this_gen,
int *nFiles) {
dvd_input_plugin_t *this = (dvd_input_plugin_t *) this_gen;
@@ -583,9 +557,7 @@ static char **dvd_plugin_get_autoplay_list (input_plugin_t *this_gen,
return this->filelist2;
}
-/*
- *
- */
+
static char* dvd_plugin_get_mrl (input_plugin_t *this_gen) {
dvd_input_plugin_t *this = (dvd_input_plugin_t *) this_gen;
@@ -613,9 +585,7 @@ static int dvd_plugin_get_optional_data (input_plugin_t *this_gen,
return INPUT_OPTIONAL_UNSUPPORTED;
}
-/*
- *
- */
+
input_plugin_t *init_input_plugin (int iface, config_values_t *config) {
dvd_input_plugin_t *this;
@@ -671,6 +641,8 @@ input_plugin_t *init_input_plugin (int iface, config_values_t *config) {
this->config = config;
this->dvd_fd = -1;
this->raw_fd = -1;
+
+ this->read_cache = read_cache_new ();
return (input_plugin_t *) this;
}
diff --git a/src/input/read_cache.c b/src/input/read_cache.c
new file mode 100644
index 000000000..60a139d53
--- /dev/null
+++ b/src/input/read_cache.c
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: read_cache.c,v 1.1 2001/09/11 00:57:11 guenter Exp $
+ */
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <xine/utils.h>
+
+#include "read_cache.h"
+
+#define NUM_BUFFERS 512
+#define NUM_MACRO_BUFFERS 32
+
+typedef struct macro_buf_s macro_buf_t;
+
+struct macro_buf_s {
+
+ macro_buf_t *next;
+
+ int ref;
+ off_t adr;
+
+ uint8_t *data;
+ read_cache_t *source;
+};
+
+struct read_cache_s {
+
+ int fd;
+
+ macro_buf_t *mbuf_pool_top;
+ char *multi_base;
+ buf_element_t *buf_pool_top;
+
+ macro_buf_t *cur_mbuf;
+
+ pthread_mutex_t lock;
+ pthread_cond_t buf_pool_not_empty;
+ pthread_cond_t mbuf_pool_not_empty;
+};
+
+/*
+ * helper function to release buffer pool lock
+ * in case demux thread is cancelled
+ */
+
+static void cache_release_lock (void *arg) {
+
+ pthread_mutex_t *mutex = (pthread_mutex_t *) arg;
+
+ /* printf ("pool release lock\n"); */
+
+ pthread_mutex_unlock (mutex);
+
+}
+
+static void buf_free (buf_element_t *buf) {
+
+ macro_buf_t *mbuf = (macro_buf_t *) buf->source;
+ read_cache_t *this = mbuf->source;
+
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
+
+ pthread_cleanup_push( cache_release_lock, &this->lock);
+
+ pthread_mutex_lock (&this->lock);
+
+ /* free buffer */
+
+ buf->next = this->buf_pool_top;
+ this->buf_pool_top = buf;
+
+ pthread_cond_signal (&this->buf_pool_not_empty);
+
+ /* maybe free mbuf too */
+
+ mbuf->ref--;
+
+ if (!mbuf->ref && (mbuf != this->cur_mbuf)) {
+
+ mbuf->next = this->mbuf_pool_top;
+ this->mbuf_pool_top = mbuf;
+
+ pthread_cond_signal (&this->mbuf_pool_not_empty);
+ }
+
+ pthread_cleanup_pop (0);
+ pthread_mutex_unlock (&this->lock);
+ /* needed because cancellation points defined by POSIX
+ (eg. 'read') would leak allocated buffers */
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
+}
+
+read_cache_t *read_cache_new () {
+
+ read_cache_t *this;
+ int i;
+ char *multi_buffer = NULL;
+ int buf_size;
+
+ this = (read_cache_t *) xmalloc (sizeof (read_cache_t));
+
+ pthread_mutex_init (&this->lock, NULL);
+ pthread_cond_init (&this->buf_pool_not_empty, NULL);
+ pthread_cond_init (&this->mbuf_pool_not_empty, NULL);
+
+ /* init buffer pool */
+
+ this->buf_pool_top = NULL;
+ for (i = 0; i<NUM_BUFFERS; i++) {
+ buf_element_t *buf;
+
+ buf = xmalloc (sizeof (buf_element_t));
+
+ buf->max_size = 2048;
+ buf->free_buffer = buf_free;
+
+ buf->next = this->buf_pool_top;
+ this->buf_pool_top = buf;
+ }
+
+ /* init macro buffer pool */
+
+ buf_size = NUM_MACRO_BUFFERS * 2048 * 16;
+ buf_size += 2048; /* alignment space */
+ this->multi_base = xmalloc (buf_size);
+ multi_buffer = this->multi_base;
+ while ((int) multi_buffer % 2048)
+ multi_buffer++;
+
+ this->mbuf_pool_top = NULL;
+ for (i = 0; i<NUM_MACRO_BUFFERS; i++) {
+ macro_buf_t *mbuf;
+
+ mbuf = xmalloc (sizeof (macro_buf_t));
+
+ mbuf->data = multi_buffer;
+ multi_buffer += 2048*16;
+ mbuf->source = this;
+
+ mbuf->next = this->mbuf_pool_top;
+ this->mbuf_pool_top = mbuf;
+ }
+
+ return this;
+}
+
+void read_cache_set_fd (read_cache_t *this, int fd) {
+ this->fd = fd;
+}
+
+
+buf_element_t *read_cache_read_block (read_cache_t *this,
+ off_t pos) {
+
+ macro_buf_t *mbuf;
+ buf_element_t *buf;
+ off_t madr;
+ int badr;
+
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
+
+ pthread_cleanup_push( cache_release_lock, &this->lock);
+
+ pthread_mutex_lock (&this->lock);
+
+ /* address calculations */
+
+ madr = pos & (~ (off_t) 0x7FFF);
+ badr = pos & ((off_t) 0x7FFF);
+
+ /* find or create macroblock that contains this block */
+
+ if ( !this->cur_mbuf || (this->cur_mbuf->adr != madr) ) {
+
+ if (this->cur_mbuf && (!this->cur_mbuf->ref)) {
+
+ mbuf = this->cur_mbuf;
+
+ } else {
+
+ while (this->mbuf_pool_top==NULL) {
+ pthread_cond_wait (&this->mbuf_pool_not_empty, &this->lock);
+ }
+
+ mbuf = this->mbuf_pool_top;
+
+ this->mbuf_pool_top = this->mbuf_pool_top->next;
+ }
+
+ mbuf->adr = madr;
+ mbuf->ref = 0;
+
+ /* FIXME: error checking */
+ lseek (this->fd, madr, SEEK_SET) ;
+ read ( this->fd, mbuf->data, 2048*16);
+
+ this->cur_mbuf = mbuf;
+
+ } else {
+ mbuf = this->cur_mbuf;
+ }
+
+
+ /* create buf */
+
+ while (this->buf_pool_top==NULL) {
+ pthread_cond_wait (&this->buf_pool_not_empty, &this->lock);
+ }
+
+ buf = this->buf_pool_top;
+
+ this->buf_pool_top = this->buf_pool_top->next;
+
+ buf->mem = mbuf->data + badr;
+ buf->content = buf->mem;
+ buf->source = mbuf;
+
+ mbuf->ref++;
+
+ pthread_cleanup_pop (0);
+ pthread_mutex_unlock (&this->lock);
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
+
+ return buf;
+}
+
+void read_cache_free (read_cache_t *this) {
+
+ buf_element_t *buf;
+ macro_buf_t *mbuf;
+
+ buf = this->buf_pool_top;
+ while (buf) {
+ buf_element_t *next = buf->next;
+
+ free(buf);
+ buf = next;
+ }
+
+ mbuf = this->mbuf_pool_top;
+ while (mbuf) {
+ macro_buf_t *mnext = mbuf->next;
+
+ free (mbuf);
+ mbuf = mnext;
+ }
+
+ free (this->multi_base);
+
+ free (this);
+}
+
diff --git a/src/input/read_cache.h b/src/input/read_cache.h
new file mode 100644
index 000000000..7cd3da4ac
--- /dev/null
+++ b/src/input/read_cache.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: read_cache.h,v 1.1 2001/09/11 00:57:11 guenter Exp $
+ */
+
+#ifndef HAVE_READ_CACHE_H
+#define HAVE_READ_CACHE_H
+
+#include <inttypes.h>
+#include <sys/types.h>
+#include <xine/buffer.h>
+
+typedef struct read_cache_s read_cache_t;
+
+read_cache_t *read_cache_new ();
+
+void read_cache_set_fd (read_cache_t *this, int fd);
+
+buf_element_t *read_cache_read_block (read_cache_t *this,
+ off_t pos);
+
+void read_cache_free (read_cache_t *this);
+
+#endif