# HG changeset patch # User richwareham # Date 1022752349 0 # Node ID 1f29402ef2ef45e7a3b1a7e4153a3024dc563b78 # Parent ef2136c4e7b26d1c4ca444793c5429f3df88dca7 'Objectified' the read-ahead cache in preparation to implement a 'proper' threaded cache a-la that recommended in the DVD Demystified book. diff -r ef2136c4e7b2 -r 1f29402ef2ef dvdnav.c --- 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) * diff -r ef2136c4e7b2 -r 1f29402ef2ef dvdnav_internal.h --- 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]; }; diff -r ef2136c4e7b2 -r 1f29402ef2ef read_cache.c --- 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; } diff -r ef2136c4e7b2 -r 1f29402ef2ef read_cache.h --- 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 */