[MPlayer-dev-eng] [patch] quicker startup with -cache xxx

Eric Lammerts eric at lammerts.org
Fri May 10 23:55:50 CEST 2002


Hi,
When I use the -cache option, it takes a long time (1-2s longer than
without -cache) before mplayer starts playing. When the cache size is
small (16kbyte for example), it takes ages before it starts playing.

I looked into it, and discovered that there's a lot of sleeping going
on (parent waiting for data, child waiting until more data is needed).

Patch below speeds it up by sending USR1 signals when something
happened (child has read some data, or parent wants some more data).
The signal handler is empty, but the signal interrupts the usleep(),
so there's no needless sleeping going on any more.

I measured the effect using "time mplayer -frames 1 -cache 512 -vo
null -ao null some.avi &>/dev/null", and it went from ~1.5s to ~0.4s.

If you dislike the use of signals, I could make a patch that does the
sleeping/signalling with two pipes (or a socketpair) and select().

Cheers,
Eric

p.s. I don't know how portable this stuff is. I use Linux.


Index: libmpdemux/cache2.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/cache2.c,v
retrieving revision 1.13
diff -u -r1.13 cache2.c
--- libmpdemux/cache2.c	5 May 2002 21:43:16 -0000	1.13
+++ libmpdemux/cache2.c	10 May 2002 21:03:36 -0000
@@ -47,6 +47,8 @@
 //  int fifo_flag;  // 1 if we should use FIFO to notice cache about buffer reads.
   // callback
   stream_t* stream;
+  int parent_sleeping:1;
+  int child_sleeping:1;
 } cache_vars_t;

 static int min_fill=0;
@@ -70,8 +72,14 @@
     if(s->read_filepos>=s->max_filepos || s->read_filepos<s->min_filepos){
 	// eof?
 	if(s->eof) break;
+
+	// kick the baby!
+	if(s->child_sleeping) kill(s->stream->cache_pid, SIGUSR1);
+
 	// waiting for buffer fill...
+	s->parent_sleeping = 1;
 	usleep(READ_USLEEP_TIME); // 10ms
+	s->parent_sleeping = 0;
 	continue; // try again...
     }

@@ -188,6 +196,7 @@
   s->fill_limit=8*sector;
   s->back_size=size/2;
   s->prefill=size/20; // default: 5%
+  s->parent_sleeping=s->child_sleeping=0;
   return s;
 }

@@ -196,6 +205,10 @@
   exit(0);
 }

+void sighandler_nothing(int x)
+{
+}
+
 int stream_enable_cache(stream_t *stream,int size,int min,int prefill){
   int ss=(stream->type==STREAMTYPE_VCD)?VCD_SECTOR_DATA:STREAM_BUFFER_SIZE;
   cache_vars_t* s;
@@ -205,6 +218,7 @@
   s->stream=stream; // callback
   s->prefill=size*prefill;

+  signal(SIGUSR1,sighandler_nothing);
   if((stream->cache_pid=fork())){
     // wait until cache is filled at least prefill_init %
     mp_msg(MSGT_CACHE,MSGL_V,"CACHE_PRE_INIT: %d [%d] %d  pre:%d  eof:%d  \n",
@@ -224,8 +238,12 @@
 // cache thread mainloop:
   signal(SIGTERM,exit_sighandler); // kill
   while(1){
-    if(!cache_fill(s)){
+    if(cache_fill(s)){
+	 if(s->parent_sleeping) kill(getppid(), SIGUSR1);
+    } else {
+	 s->child_sleeping = 1;
 	 usleep(FILL_USLEEP_TIME); // idle
+	 s->child_sleeping = 0;
     }
 //	 cache_stats(s->cache_data);
   }





More information about the MPlayer-dev-eng mailing list