[prev in list] [next in list] [prev in thread] [next in thread] 

List:       xine-cvslog
Subject:    [xine-cvs] CVS: xine-lib/src/input net_buf_ctrl.c,1.40,1.41
From:       Thibaut Mattern <tmattern () users ! sourceforge ! net>
Date:       2004-03-28 18:17:36
Message-ID: E1B7eqm-0000xE-O9 () sc8-pr-cvs1 ! sourceforge ! net
[Download RAW message or body]

Update of /cvsroot/xine/xine-lib/src/input
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1131

Modified Files:
	net_buf_ctrl.c 
Log Message:
- new logic evaluate engine latency.
    try to evaluate the amount of data inside decoders, audio decoders tends to keep \
a lot, and that's why the audio fifo keeps empty. This remove the "50%" step with \
                video trailers, and the playback starts earlier.
- fix a potential deadlock at exit.
- increase high watermark if rebuffering

I've tested with asf/mpeg/mov/real streams.



Index: net_buf_ctrl.c
===================================================================
RCS file: /cvsroot/xine/xine-lib/src/input/net_buf_ctrl.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -r1.40 -r1.41
--- net_buf_ctrl.c	26 Mar 2004 12:30:04 -0000	1.40
+++ net_buf_ctrl.c	28 Mar 2004 18:17:34 -0000	1.41
@@ -35,6 +35,7 @@
 #define LOG
 */
 
+
 #include "net_buf_ctrl.h"
 
 #define DEFAULT_LOW_WATER_MARK     1
@@ -59,8 +60,10 @@
   int              audio_fifo_fill;
   int              video_fifo_free;
   int              audio_fifo_free;
-  int64_t          video_fifo_length; /* in ms */
-  int64_t          audio_fifo_length; /* in ms */
+  int64_t          video_fifo_length;     /* in ms */
+  int64_t          audio_fifo_length;     /* in ms */
+  int64_t          video_fifo_length_int; /* in ms */
+  int64_t          audio_fifo_length_int; /* in ms */
 
   int64_t          low_water_mark;
   int64_t          high_water_mark;
@@ -119,7 +122,7 @@
 static void display_stats (nbc_t *this) {
   char *buffering[2] = {"   ", "buf"};
   char *enabled[2]   = {"off", "on "};
-
+  
   printf("net_buf_ctrl: vid %3d%% %4.1fs %4lldkbps %1d, "\
 	 "aud %3d%% %4.1fs %4lldkbps %1d, %s %s\r",
 	 this->video_fifo_fill,
@@ -131,7 +134,8 @@
 	 this->audio_br / 1000,
 	 this->audio_in_disc,
 	 buffering[this->buffering],
-	 enabled[this->enabled]);
+	 enabled[this->enabled]
+	 );
   fflush(stdout);
 }
 
@@ -147,7 +151,7 @@
                                     buf_element_t *buf,
                                     int action) {
   int fifo_free, fifo_fill;
-  int64_t video_br, audio_br;
+  int64_t video_br, audio_br, diff;
   int has_video, has_audio;
 
   has_video = _x_stream_info_get(this->stream, XINE_STREAM_INFO_HAS_VIDEO);
@@ -162,59 +166,82 @@
     this->video_fifo_free = fifo_free;
     this->video_fifo_fill = (100 * fifo_fill) / (fifo_fill + fifo_free - 1);
     this->video_fifo_size = fifo->fifo_data_size;
+    
+    if (buf->pts && (this->video_in_disc == 0)) {
+      if (action == FIFO_PUT) {
+        this->video_last_pts = buf->pts;
+        if (this->video_first_pts == 0) {
+          this->video_first_pts = buf->pts;
+        }
+      } else {
+        /* GET */
+        this->video_first_pts = buf->pts;
+      }
+    }
+    
     if (video_br) {
       this->video_br = video_br;
-      this->video_fifo_length = (8000 * this->video_fifo_size) / this->video_br;
+      this->video_fifo_length_int = (8000 * this->video_fifo_size) / this->video_br;
     } else {
       if (buf->pts && (this->video_in_disc == 0)) {
-        if (action == FIFO_PUT) {
-          this->video_last_pts = buf->pts;
-          if (this->video_first_pts == 0) {
-            this->video_first_pts = buf->pts;
-          }
-        } else {
-          /* GET */
-          this->video_first_pts = buf->pts;
-        }
-        this->video_fifo_length = (this->video_last_pts - this->video_first_pts) / \
90; +        this->video_fifo_length_int = (this->video_last_pts - \
this->video_first_pts) / 90;  if (this->video_fifo_length)
           this->video_br = 8000 * (this->video_fifo_size / this->video_fifo_length);
         else
           this->video_br = 0;
       } else {
         if (this->video_br)
-          this->video_fifo_length = (8000 * this->video_fifo_size) / this->video_br;
+          this->video_fifo_length_int = (8000 * this->video_fifo_size) / \
this->video_br;  }
     }
+
   } else {
     this->audio_fifo_free = fifo_free;
     this->audio_fifo_fill = (100 * fifo_fill) / (fifo_fill + fifo_free - 1);
     this->audio_fifo_size = fifo->fifo_data_size;
+    
+    if (buf->pts && (this->audio_in_disc == 0)) {
+      if (action == FIFO_PUT) {
+        this->audio_last_pts = buf->pts;
+        if (!this->audio_first_pts) {
+          this->audio_first_pts = buf->pts;
+        }
+      } else {
+        /* GET */
+        this->audio_first_pts = buf->pts;
+      }
+    }
+    
     if (audio_br) {
       this->audio_br = audio_br;
-      this->audio_fifo_length = (8000 * this->audio_fifo_size) / this->audio_br;
+      this->audio_fifo_length_int = (8000 * this->audio_fifo_size) / this->audio_br;
     } else {
       if (buf->pts && (this->audio_in_disc == 0)) {
-        if (action == FIFO_PUT) {
-          this->audio_last_pts = buf->pts;
-          if (!this->audio_first_pts) {
-            this->audio_first_pts = buf->pts;
-          }
-        } else {
-          /* GET */
-          this->audio_first_pts = buf->pts;
-        }
-        this->audio_fifo_length = (this->audio_last_pts - this->audio_first_pts) / \
90; +        this->audio_fifo_length_int = (this->audio_last_pts - \
this->audio_first_pts) / 90;  if (this->audio_fifo_length)
           this->audio_br = 8000 * (this->audio_fifo_size / this->audio_fifo_length);
         else
           this->audio_br = 0;
       } else {
         if (this->audio_br)
-          this->audio_fifo_length = (8000 * this->audio_fifo_size) / this->audio_br;
+          this->audio_fifo_length_int = (8000 * this->audio_fifo_size) / \
this->audio_br;  }
     }
   }
+  
+  /* decoder buffer compensation */
+  if (has_audio && has_video) {
+    diff = this->video_first_pts - this->audio_first_pts;
+  } else {
+    diff = 0;
+  }
+  if (diff > 0) {
+    this->video_fifo_length = this->video_fifo_length_int + diff / 90;
+    this->audio_fifo_length = this->audio_fifo_length_int;
+  } else {
+    this->video_fifo_length = this->video_fifo_length_int;
+    this->audio_fifo_length = this->audio_fifo_length_int - diff / 90;
+  }
 }
 
 /* Alloc callback */
@@ -282,6 +309,8 @@
           xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "\nnet_buf_ctrl: \
nbc_put_cb: stops buffering\n");  
           nbc_set_speed_normal(this);
+  
+          this->high_water_mark += this->high_water_mark / 2;   
 
         } else {
           /*  compute the buffering progress
@@ -414,29 +443,17 @@
          */
         int has_video = _x_stream_info_get(this->stream, \
                XINE_STREAM_INFO_HAS_VIDEO);
         int has_audio = _x_stream_info_get(this->stream, \
                XINE_STREAM_INFO_HAS_AUDIO);
-        if (fifo->fifo_size == 0 && 
-            (((fifo == this->video_fifo) && has_video) ||
-             ((fifo == this->audio_fifo) && has_audio))) {
-          int other_fifo_free;
+        if (((this->video_fifo_length == 0) && has_video) ||
+            ((this->audio_fifo_length == 0) && has_audio)) {
 
-          if (fifo == this->video_fifo) {
-            other_fifo_free = this->audio_fifo_free;
-          } else {
-            other_fifo_free = this->video_fifo_free;
-          }
-
-          /* Don't pause if the other fifo is full because the next
-             put() will restart the engine */
-          if (other_fifo_free > FULL_FIFO_MARK) {
-            this->buffering = 1;
-            this->progress  = 0;
-            report_progress (this->stream, 0);
-
-            xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, 
-              "\nnet_buf_ctrl: nbc_get_cb: starts buffering, vid: %d, aud: %d\n",
-              this->video_fifo_fill, this->audio_fifo_fill);
-            nbc_set_speed_pause(this);
-          }
+          this->buffering = 1;
+          this->progress  = 0;
+          report_progress (this->stream, 0);
+
+          xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, 
+                  "\nnet_buf_ctrl: nbc_get_cb: starts buffering, vid: %d, aud: \
%d\n", +                  this->video_fifo_fill, this->audio_fifo_fill);
+          nbc_set_speed_pause(this);
         }
       } else {
         nbc_set_speed_pause(this);
@@ -474,7 +491,7 @@
 
 nbc_t *nbc_init (xine_stream_t *stream) {
   
-  nbc_t *this = (nbc_t *) malloc (sizeof (nbc_t));
+  nbc_t *this = (nbc_t *) xine_xmalloc (sizeof (nbc_t));
   fifo_buffer_t *video_fifo = stream->video_fifo;
   fifo_buffer_t *audio_fifo = stream->audio_fifo;
 
@@ -482,29 +499,10 @@
   pthread_mutex_init (&this->mutex, NULL);
 
   this->stream              = stream;
-  this->buffering           = 0;
-  this->enabled             = 0;
   this->low_water_mark      = DEFAULT_LOW_WATER_MARK;
   this->high_water_mark     = DEFAULT_HIGH_WATER_MARK;
-  this->progress            = 0;
   this->video_fifo          = video_fifo;
   this->audio_fifo          = audio_fifo;
-  this->video_fifo_fill     = 0;
-  this->audio_fifo_fill     = 0;
-  this->video_fifo_free     = 0;
-  this->audio_fifo_free     = 0;
-  this->video_fifo_length   = 0;
-  this->audio_fifo_length   = 0;
-  this->video_last_pts      = 0;
-  this->audio_last_pts      = 0;
-  this->video_first_pts     = 0;
-  this->audio_first_pts     = 0;
-  this->video_fifo_size     = 0;
-  this->audio_fifo_size     = 0;
-  this->video_br            = 0;
-  this->audio_br            = 0;
-  this->video_in_disc       = 0;
-  this->audio_in_disc       = 0;
 
   video_fifo->register_alloc_cb(video_fifo, nbc_alloc_cb, this);
   video_fifo->register_put_cb(video_fifo, nbc_put_cb, this);
@@ -523,8 +521,9 @@
   xine_t        *xine       = this->stream->xine;
 
   xprintf(xine, XINE_VERBOSITY_DEBUG, "\nnet_buf_ctrl: nbc_close\n");
-  pthread_mutex_lock(&this->mutex);
 
+  /* unregister all fifo callbacks */
+  /* do not lock the mutex to avoid deadlocks if a decoder calls fifo->get() */
   video_fifo->unregister_alloc_cb(video_fifo, nbc_alloc_cb);
   video_fifo->unregister_put_cb(video_fifo, nbc_put_cb);
   video_fifo->unregister_get_cb(video_fifo, nbc_get_cb);
@@ -533,11 +532,10 @@
   audio_fifo->unregister_put_cb(audio_fifo, nbc_put_cb);
   audio_fifo->unregister_get_cb(audio_fifo, nbc_get_cb);
 
+  /* now we are sure that nobody will call a callback */
   this->stream->xine->clock->set_option (this->stream->xine->clock, \
CLOCK_SCR_ADJUSTABLE, 1);  
-  pthread_mutex_unlock(&this->mutex);
   pthread_mutex_destroy(&this->mutex);
-  
   free (this);
   xprintf(xine, XINE_VERBOSITY_DEBUG, "\nnet_buf_ctrl: nbc_close: done\n");
 }



-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click
_______________________________________________
Xine-cvslog mailing list
Xine-cvslog@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/xine-cvslog


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic