changeset 34:1f29402ef2ef src

'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book.
author richwareham
date Thu, 30 May 2002 09:52:29 +0000
parents ef2136c4e7b2
children fbf85034a242
files dvdnav.c dvdnav_internal.h read_cache.c read_cache.h
diffstat 4 files changed, 104 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/dvdnav.c	Thu May 09 11:57:24 2002 +0000
+++ b/dvdnav.c	Thu May 30 09:52:29 2002 +0000
@@ -141,7 +141,7 @@
   }
   /* clear everything except path, file, vm, mutex, readahead */
 
-  // path
+  /* path */
   if (this->file) DVDCloseFile(this->file);
   this->file = NULL;
   this->open_vtsN = -1;
@@ -156,12 +156,10 @@
   this->stop = 0;
   this->spu_clut_changed = 0;
   this->started=0;
-  // this->use_read_ahead
+  /* this->use_read_ahead */
 
-  this->cache_start_sector = -1;
-  this->cache_block_count = 0;
-  this->cache_valid = 0;
-
+  dvdnav_read_cache_clear(this->cache);
+  
   return S_OK;
 }
 
@@ -206,6 +204,9 @@
     this->started = 1;
   }
 
+  /* Start the read-ahead cache. */
+  this->cache = dvdnav_read_cache_new(this);
+  
   (*dest) = this;
   return S_OK;
 }
@@ -218,6 +219,14 @@
 #ifdef LOG_DEBUG
   fprintf(stderr,"dvdnav:close:called\n");
 #endif
+
+  /* Stop caching */
+
+  if(this->cache) {
+    dvdnav_read_cache_free(this->cache);
+    this->cache = NULL;
+  }
+  
   if (this->file) {
     DVDCloseFile(this->file);
 #ifdef LOG_DEBUG
@@ -610,7 +619,7 @@
     dvdnav_vts_change_event_t vts_event;
     
     if(this->file) {
-      dvdnav_read_cache_clear(this);
+      dvdnav_read_cache_clear(this->cache);
       DVDCloseFile(this->file);
       this->file = NULL;
     }
@@ -641,7 +650,7 @@
     
     this->position_current.vts = this->position_next.vts; 
     this->position_current.domain = this->position_next.domain;
-    dvdnav_read_cache_clear(this);
+    dvdnav_read_cache_clear(this->cache);
     this->file = DVDOpenFile(vm_get_dvd_reader(this->vm), vtsN, domain);
     vts_event.new_vtsN = this->position_next.vts; 
     vts_event.new_domain = this->position_next.domain; 
@@ -758,7 +767,7 @@
      *        This is so RSM resumes to the VOBU level and not just the CELL level.
      *        This should be implemented with a new Public API call.
      */
-    dvdnav_pre_cache_blocks(this, this->vobu.vobu_start+1, this->vobu.vobu_length);
+    dvdnav_pre_cache_blocks(this->cache, this->vobu.vobu_start+1, this->vobu.vobu_length);
     
     /* Successfully got a NAV packet */
     (*event) = DVDNAV_NAV_PACKET;
@@ -774,7 +783,7 @@
     return S_ERR;
   }
 
-  result = dvdnav_read_cache_block(this, this->vobu.vobu_start + this->vobu.blockN, 1, buf);
+  result = dvdnav_read_cache_block(this->cache, this->vobu.vobu_start + this->vobu.blockN, 1, buf);
   if(result <= 0) {
     printerr("Error reading from DVD.");
     pthread_mutex_unlock(&this->vm_lock); 
@@ -928,6 +937,9 @@
 
 /*
  * $Log$
+ * Revision 1.18  2002/05/30 09:52:29  richwareham
+ * 'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book.
+ *
  * Revision 1.17  2002/05/09 11:57:24  richwareham
  * Angles now work (still a few wrinkles though -- e.g. angle does not reset to '1' when returning to menus)
  *
--- a/dvdnav_internal.h	Thu May 09 11:57:24 2002 +0000
+++ b/dvdnav_internal.h	Thu May 30 09:52:29 2002 +0000
@@ -57,6 +57,8 @@
 #define DVD_VIDEO_LB_LEN 2048
 #endif
 
+typedef struct read_cache_s read_cache_t;
+
 /*
  * These are defined here because they are
  * not in ifo_types.h, they maybe one day 
@@ -140,15 +142,13 @@
   pthread_mutex_t vm_lock;
 
   /* Highlight */
-  int hli_state;  /* State of highlight 0 - disabled, 1 - selected,
-		 2 - activated */
-  /* Read-ahead cache. */
-  uint8_t      *cache_buffer;
-  int32_t      cache_start_sector; /* -1 means cache invalid */
-  size_t       cache_block_count;
-  size_t       cache_malloc_size;
-  int          cache_valid;
-  
+  int hli_state;  /* State of highlight: 0 - disabled,
+		                         1 - selected,
+                         		 2 - activated */
+
+  /* Read-ahead cache */
+  read_cache_t *cache;
+
   /* Errors */
   char err_str[MAX_ERR_LEN];
 };
--- a/read_cache.c	Thu May 09 11:57:24 2002 +0000
+++ b/read_cache.c	Thu May 30 09:52:29 2002 +0000
@@ -25,24 +25,74 @@
 #include "config.h"
 #endif
 
+#include "dvdnav.h"
 #include "read_cache.h"
 
+/* Read-ahead cache structure. */
+#if _MULTITHREAD_
+struct read_cache_s {
+  /* Bit of strange cross-linking going on here :) -- Gotta love C :) */
+  dvdnav_t    *dvd_self;
+};
+#else
+struct read_cache_s {
+  /* Read-ahead cache. */
+  uint8_t      *cache_buffer;
+  int32_t      cache_start_sector; /* -1 means cache invalid */
+  size_t       cache_block_count;
+  size_t       cache_malloc_size;
+  int          cache_valid;
+
+  /* Bit of strange cross-linking going on here :) -- Gotta love C :) */
+  dvdnav_t    *dvd_self;
+};
+#endif
+
+read_cache_t *dvdnav_read_cache_new(dvdnav_t* dvd_self) {
+  read_cache_t *me;
+
+  me = (read_cache_t*)malloc(sizeof(struct read_cache_s));
+
+  if(me) {
+    me->dvd_self = dvd_self;
+
+    dvdnav_read_cache_clear(me);
+    me->cache_buffer = NULL;
+  }
+  
+  /* this->cache_start_sector = -1;
+  this->cache_block_count = 0;
+  this->cache_valid = 0; */
+
+  return me;
+}
+
+void dvdnav_read_cache_free(read_cache_t* self) {
+  if(self->cache_buffer) {
+    free(self->cache_buffer);
+    self->cache_buffer = NULL;
+  }
+
+  free(self);
+}
+
 /* This function MUST be called whenever self->file changes. */
-void dvdnav_read_cache_clear(dvdnav_t *self) {
+void dvdnav_read_cache_clear(read_cache_t *self) {
   if(!self)
    return;
   
   self->cache_start_sector = -1;
   self->cache_valid = 0;
 }
+
 /* This function is called just after reading the NAV packet. */
-void dvdnav_pre_cache_blocks(dvdnav_t *self, int sector, size_t block_count) {
+void dvdnav_pre_cache_blocks(read_cache_t *self, int sector, size_t block_count) {
   int result;
  
   if(!self)
    return;
   
-  if(!self->use_read_ahead) {
+  if(!self->dvd_self->use_read_ahead) {
     self->cache_valid = 0;
     self->cache_start_sector = -1;
     return;
@@ -59,18 +109,18 @@
   }
   self->cache_start_sector = sector;
   self->cache_block_count = block_count;
-  result = DVDReadBlocks( self->file, sector, block_count, self->cache_buffer);
+  result = DVDReadBlocks( self->dvd_self->file, sector, block_count, self->cache_buffer);
   self->cache_valid = 1;
 }
 
 /* This function will do the cache read once implemented */
-int dvdnav_read_cache_block( dvdnav_t *self, int sector, size_t block_count, uint8_t *buf) {
+int dvdnav_read_cache_block( read_cache_t *self, int sector, size_t block_count, uint8_t *buf) {
   int result;
  
   if(!self)
    return 0;
 
-  if(self->cache_valid && self->use_read_ahead) {
+  if(self->cache_valid && self->dvd_self->use_read_ahead) {
     if (self->cache_start_sector != -1 ) {
       if ((sector >= self->cache_start_sector) && 
 	  (sector < self->cache_start_sector + self->cache_block_count)) {
@@ -79,12 +129,12 @@
       }
     }
   } else {
-    result = DVDReadBlocks( self->file, sector, block_count, buf);
+    result = DVDReadBlocks( self->dvd_self->file, sector, block_count, buf);
     return result;
   }
   
   fprintf(stderr,"DVD read cache miss! sector=%d, start=%d\n", sector, self->cache_start_sector); 
-  result = DVDReadBlocks( self->file, sector, block_count, buf);
+  result = DVDReadBlocks( self->dvd_self->file, sector, block_count, buf);
   return result;
 }
 
--- a/read_cache.h	Thu May 09 11:57:24 2002 +0000
+++ b/read_cache.h	Thu May 30 09:52:29 2002 +0000
@@ -26,11 +26,23 @@
 
 #include "dvdnav_internal.h"
 
+/* Opaque cache type -- defined in dvdnav_internal.h */
+/* typedef struct read_cache_s read_cache_t; */
+
+/* EXPERIMENTAL: Setting the following to 1 will use an experimental multi-threaded
+ *               read-ahead cache. 
+ */
+#define _MULTITHREAD_ 0
+
+/* Constructor/destructors */
+read_cache_t *dvdnav_read_cache_new(dvdnav_t* dvd_self);
+void dvdnav_read_cache_free(read_cache_t* self);
+
 /* This function MUST be called whenever self->file changes. */
-void dvdnav_read_cache_clear(dvdnav_t *self);
+void dvdnav_read_cache_clear(read_cache_t *self);
 /* This function is called just after reading the NAV packet. */
-void dvdnav_pre_cache_blocks(dvdnav_t *self, int sector, size_t block_count);
+void dvdnav_pre_cache_blocks(read_cache_t *self, int sector, size_t block_count);
 /* This function will do the cache read */
-int dvdnav_read_cache_block(dvdnav_t *self, int sector, size_t block_count, uint8_t *buf);
+int dvdnav_read_cache_block(read_cache_t *self, int sector, size_t block_count, uint8_t *buf);
 
 #endif /* __DVDNAV_READ_CACHE_H */