From cc7a2d3287d4bf08a3e85a4bddc41cdfaf55ace7 Mon Sep 17 00:00:00 2001 From: reimar Date: Sun, 23 May 2010 19:49:28 +0000 Subject: Add code to wake up cache process when e.g. a seek is needed. Dramatically reduces seeking times with lavf ogg demuxer. Needs a spearate implementation for the thread-based cache implementation. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31198 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/cache2.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'stream') diff --git a/stream/cache2.c b/stream/cache2.c index 2e2aadc3fe..98268cf46b 100644 --- a/stream/cache2.c +++ b/stream/cache2.c @@ -90,6 +90,14 @@ static int min_fill=0; int cache_fill_status=0; +static void cache_wakeup(stream_t *s) +{ +#if !defined(__MINGW32__) && !defined(PTHREAD_CACHE) && !defined(__OS2__) + // signal process to wake up immediately + kill(s->cache_pid, SIGUSR1); +#endif +} + static void cache_stats(cache_vars_t *s) { int newb=s->max_filepos-s->read_filepos; // new bytes in the buffer @@ -329,6 +337,9 @@ static void exit_sighandler(int x){ exit(0); } +static void dummy_sighandler(int x) { +} + /** * \return 1 on success, 0 if the function was interrupted and -1 on error */ @@ -420,6 +431,7 @@ static void ThreadProc( void *s ){ #endif // cache thread mainloop: signal(SIGTERM,exit_sighandler); // kill + signal(SIGUSR1, dummy_sighandler); // wakeup do { if(!cache_fill(s)){ usec_sleep(FILL_USLEEP_TIME); // idle @@ -470,6 +482,7 @@ int cache_stream_seek_long(stream_t *stream,off_t pos){ newpos=pos/s->sector_size; newpos*=s->sector_size; // align stream->pos=s->read_filepos=newpos; s->eof=0; // !!!!!!! + cache_wakeup(stream); cache_stream_fill_buffer(stream); @@ -514,6 +527,7 @@ int cache_do_control(stream_t *stream, int cmd, void *arg) { default: return STREAM_UNSUPPORTED; } + cache_wakeup(stream); while (s->control != -1) usec_sleep(CONTROL_SLEEP_TIME); switch (cmd) { -- cgit v1.2.3 From 2ced41082c0bc3135063c2e0ef5ac8ea2837bbc0 Mon Sep 17 00:00:00 2001 From: reimar Date: Sun, 23 May 2010 21:53:48 +0000 Subject: Optimize cache behaviour for the many-consecutive-seeks case. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31199 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/cache2.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'stream') diff --git a/stream/cache2.c b/stream/cache2.c index 98268cf46b..48ebe50123 100644 --- a/stream/cache2.c +++ b/stream/cache2.c @@ -23,6 +23,10 @@ // TODO: seeking, data consistency checking #define READ_USLEEP_TIME 10000 +// These defines are used to reduce the cost of many succesive +// seeks (e.g. when a file has no index) by spinning quickly at first. +#define INITIAL_FILL_USLEEP_TIME 1000 +#define INITIAL_FILL_USLEEP_COUNT 10 #define FILL_USLEEP_TIME 50000 #define PREFILL_SLEEP_TIME 200 #define CONTROL_SLEEP_TIME 0 @@ -432,10 +436,17 @@ static void ThreadProc( void *s ){ // cache thread mainloop: signal(SIGTERM,exit_sighandler); // kill signal(SIGUSR1, dummy_sighandler); // wakeup + { + int sleep_count = 0; do { if(!cache_fill(s)){ + if (sleep_count < INITIAL_FILL_USLEEP_COUNT) { + sleep_count++; + usec_sleep(INITIAL_FILL_USLEEP_TIME); + } else usec_sleep(FILL_USLEEP_TIME); // idle - } + } else + sleep_count = 0; // cache_stats(s->cache_data); } while (cache_execute_control(s)); #if defined(__MINGW32__) || defined(__OS2__) @@ -446,6 +457,7 @@ static void ThreadProc( void *s ){ // make sure forked code never leaves this function exit(0); #endif + } } int cache_stream_fill_buffer(stream_t *s){ -- cgit v1.2.3 From 939df8d5a815d72f83a41683611edb738b46e19e Mon Sep 17 00:00:00 2001 From: reimar Date: Sun, 23 May 2010 21:58:50 +0000 Subject: Extract the cache main loop into a separate function. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31201 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/cache2.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'stream') diff --git a/stream/cache2.c b/stream/cache2.c index 48ebe50123..7bdeabd9e3 100644 --- a/stream/cache2.c +++ b/stream/cache2.c @@ -344,6 +344,24 @@ static void exit_sighandler(int x){ static void dummy_sighandler(int x) { } +/** + * Main loop of the cache process or thread. + */ +static void cache_mainloop(cache_vars_t *s) { + int sleep_count = 0; + do { + if (!cache_fill(s)) { + if (sleep_count < INITIAL_FILL_USLEEP_COUNT) { + sleep_count++; + usec_sleep(INITIAL_FILL_USLEEP_TIME); + } else + usec_sleep(FILL_USLEEP_TIME); // idle + } else + sleep_count = 0; +// cache_stats(s->cache_data); + } while (cache_execute_control(s)); +} + /** * \return 1 on success, 0 if the function was interrupted and -1 on error */ @@ -436,19 +454,7 @@ static void ThreadProc( void *s ){ // cache thread mainloop: signal(SIGTERM,exit_sighandler); // kill signal(SIGUSR1, dummy_sighandler); // wakeup - { - int sleep_count = 0; - do { - if(!cache_fill(s)){ - if (sleep_count < INITIAL_FILL_USLEEP_COUNT) { - sleep_count++; - usec_sleep(INITIAL_FILL_USLEEP_TIME); - } else - usec_sleep(FILL_USLEEP_TIME); // idle - } else - sleep_count = 0; -// cache_stats(s->cache_data); - } while (cache_execute_control(s)); + cache_mainloop(s); #if defined(__MINGW32__) || defined(__OS2__) _endthread(); #elif defined(PTHREAD_CACHE) @@ -457,7 +463,6 @@ static void ThreadProc( void *s ){ // make sure forked code never leaves this function exit(0); #endif - } } int cache_stream_fill_buffer(stream_t *s){ -- cgit v1.2.3 From 991b9b9e6d9133daec11f4b3cd39fb81d52fbd9b Mon Sep 17 00:00:00 2001 From: reimar Date: Sun, 23 May 2010 22:04:01 +0000 Subject: Try reducing the #ifdef mess for the different cache variants. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31202 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/cache2.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) (limited to 'stream') diff --git a/stream/cache2.c b/stream/cache2.c index 7bdeabd9e3..e5756e07be 100644 --- a/stream/cache2.c +++ b/stream/cache2.c @@ -439,32 +439,30 @@ err_out: return res; } -#if defined(__MINGW32__) || defined(PTHREAD_CACHE) || defined(__OS2__) -} -#ifdef PTHREAD_CACHE -static void *ThreadProc( void *s ){ -#else -static void ThreadProc( void *s ){ -#endif -#endif - +#if !defined(__MINGW32__) && !defined(PTHREAD_CACHE) && !defined(__OS2__) #ifdef CONFIG_GUI use_gui = 0; // mp_msg may not use gui stuff in forked code #endif -// cache thread mainloop: signal(SIGTERM,exit_sighandler); // kill signal(SIGUSR1, dummy_sighandler); // wakeup cache_mainloop(s); -#if defined(__MINGW32__) || defined(__OS2__) - _endthread(); -#elif defined(PTHREAD_CACHE) - return NULL; -#else // make sure forked code never leaves this function exit(0); #endif } +#ifdef PTHREAD_CACHE +static void *ThreadProc( void *s ){ + cache_mainloop(s); + return NULL; +} +#elif defined(__MINGW32__) || defined(__OS2__) +static void ThreadProc( void *s ){ + cache_mainloop(s); + _endthread(); +} +#endif + int cache_stream_fill_buffer(stream_t *s){ int len; if(s->eof){ s->buf_pos=s->buf_len=0; return 0; } -- cgit v1.2.3 From bc2adc2e4816847bcf4ef33e1f1a1e6fdda115af Mon Sep 17 00:00:00 2001 From: reimar Date: Sun, 23 May 2010 22:09:40 +0000 Subject: Use an extra define to simplify ifdefs git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31203 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/cache2.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) (limited to 'stream') diff --git a/stream/cache2.c b/stream/cache2.c index e5756e07be..9572bda827 100644 --- a/stream/cache2.c +++ b/stream/cache2.c @@ -53,6 +53,10 @@ static void ThreadProc( void *s ); static void *ThreadProc(void *s); #else #include +#define FORKED_CACHE 1 +#endif +#ifndef FORKED_CACHE +#define FORKED_CACHE 0 #endif #include "mp_msg.h" @@ -96,7 +100,7 @@ int cache_fill_status=0; static void cache_wakeup(stream_t *s) { -#if !defined(__MINGW32__) && !defined(PTHREAD_CACHE) && !defined(__OS2__) +#if FORKED_CACHE // signal process to wake up immediately kill(s->cache_pid, SIGUSR1); #endif @@ -277,7 +281,7 @@ static int cache_execute_control(cache_vars_t *s) { static cache_vars_t* cache_init(int size,int sector){ int num; -#if !defined(__MINGW32__) && !defined(PTHREAD_CACHE) && !defined(__OS2__) +#if FORKED_CACHE cache_vars_t* s=shmem_alloc(sizeof(cache_vars_t)); #else cache_vars_t* s=malloc(sizeof(cache_vars_t)); @@ -291,14 +295,14 @@ static cache_vars_t* cache_init(int size,int sector){ }//32kb min_size s->buffer_size=num*sector; s->sector_size=sector; -#if !defined(__MINGW32__) && !defined(PTHREAD_CACHE) && !defined(__OS2__) +#if FORKED_CACHE s->buffer=shmem_alloc(s->buffer_size); #else s->buffer=malloc(s->buffer_size); #endif if(s->buffer == NULL){ -#if !defined(__MINGW32__) && !defined(PTHREAD_CACHE) && !defined(__OS2__) +#if FORKED_CACHE shmem_free(s,sizeof(cache_vars_t)); #else free(s); @@ -314,7 +318,7 @@ static cache_vars_t* cache_init(int size,int sector){ void cache_uninit(stream_t *s) { cache_vars_t* c = s->cache_data; if(s->cache_pid) { -#if defined(__MINGW32__) || defined(PTHREAD_CACHE) || defined(__OS2__) +#if !FORKED_CACHE cache_do_control(s, -2, NULL); #else kill(s->cache_pid,SIGKILL); @@ -323,7 +327,7 @@ void cache_uninit(stream_t *s) { s->cache_pid = 0; } if(!c) return; -#if defined(__MINGW32__) || defined(PTHREAD_CACHE) || defined(__OS2__) +#if !FORKED_CACHE free(c->buffer); c->buffer = NULL; c->stream = NULL; @@ -391,7 +395,7 @@ int stream_enable_cache(stream_t *stream,int size,int min,int seek_limit){ min = s->buffer_size - s->fill_limit; } -#if !defined(__MINGW32__) && !defined(PTHREAD_CACHE) && !defined(__OS2__) +#if FORKED_CACHE if((stream->cache_pid=fork())){ if ((pid_t)stream->cache_pid == -1) stream->cache_pid = 0; @@ -439,7 +443,7 @@ err_out: return res; } -#if !defined(__MINGW32__) && !defined(PTHREAD_CACHE) && !defined(__OS2__) +#if FORKED_CACHE #ifdef CONFIG_GUI use_gui = 0; // mp_msg may not use gui stuff in forked code #endif @@ -451,16 +455,18 @@ err_out: #endif } -#ifdef PTHREAD_CACHE -static void *ThreadProc( void *s ){ - cache_mainloop(s); - return NULL; -} -#elif defined(__MINGW32__) || defined(__OS2__) +#if !FORKED_CACHE +#if defined(__MINGW32__) || defined(__OS2__) static void ThreadProc( void *s ){ cache_mainloop(s); _endthread(); } +#else +static void *ThreadProc( void *s ){ + cache_mainloop(s); + return NULL; +} +#endif #endif int cache_stream_fill_buffer(stream_t *s){ -- cgit v1.2.3 From 8e84b9288cd6e9036e3c151da13a8c654a77a6cf Mon Sep 17 00:00:00 2001 From: reimar Date: Sun, 23 May 2010 22:26:10 +0000 Subject: Slightly reduce number of #ifs git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31204 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/cache2.c | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) (limited to 'stream') diff --git a/stream/cache2.c b/stream/cache2.c index 9572bda827..51989ebd2a 100644 --- a/stream/cache2.c +++ b/stream/cache2.c @@ -279,13 +279,25 @@ static int cache_execute_control(cache_vars_t *s) { return 1; } -static cache_vars_t* cache_init(int size,int sector){ - int num; +static void *shared_alloc(int size) { #if FORKED_CACHE - cache_vars_t* s=shmem_alloc(sizeof(cache_vars_t)); + return shmem_alloc(size); #else - cache_vars_t* s=malloc(sizeof(cache_vars_t)); + return malloc(size); #endif +} + +static void shared_free(void *ptr, int size) { +#if FORKED_CACHE + shmem_free(ptr, size); +#else + free(ptr); +#endif +} + +static cache_vars_t* cache_init(int size,int sector){ + int num; + cache_vars_t* s=shared_alloc(sizeof(cache_vars_t)); if(s==NULL) return NULL; memset(s,0,sizeof(cache_vars_t)); @@ -295,18 +307,10 @@ static cache_vars_t* cache_init(int size,int sector){ }//32kb min_size s->buffer_size=num*sector; s->sector_size=sector; -#if FORKED_CACHE - s->buffer=shmem_alloc(s->buffer_size); -#else - s->buffer=malloc(s->buffer_size); -#endif + s->buffer=shared_alloc(s->buffer_size); if(s->buffer == NULL){ -#if FORKED_CACHE - shmem_free(s,sizeof(cache_vars_t)); -#else - free(s); -#endif + shared_free(s, sizeof(cache_vars_t)); return NULL; } @@ -327,16 +331,10 @@ void cache_uninit(stream_t *s) { s->cache_pid = 0; } if(!c) return; -#if !FORKED_CACHE - free(c->buffer); + shared_free(c->buffer, c->buffer_size); c->buffer = NULL; c->stream = NULL; - free(s->cache_data); -#else - shmem_free(c->buffer,c->buffer_size); - c->buffer = NULL; - shmem_free(s->cache_data,sizeof(cache_vars_t)); -#endif + shared_free(s->cache_data, sizeof(cache_vars_t)); s->cache_data = NULL; } -- cgit v1.2.3