summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/input/net_buf_ctrl.c124
-rw-r--r--src/xine-engine/buffer.c51
-rw-r--r--src/xine-engine/buffer.h34
3 files changed, 141 insertions, 68 deletions
diff --git a/src/input/net_buf_ctrl.c b/src/input/net_buf_ctrl.c
index 27c19d5ff..22dbb4c2b 100644
--- a/src/input/net_buf_ctrl.c
+++ b/src/input/net_buf_ctrl.c
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2000-2002 the xine project
*
* This file is part of xine, a free video player.
@@ -30,8 +30,10 @@
#include "net_buf_ctrl.h"
-#define DEFAULT_LOW_WATER_MARK 2
-#define DEFAULT_HIGH_WATER_MARK 5
+#define DEFAULT_LOW_WATER_MARK 1
+#define DEFAULT_HIGH_WATER_MARK 5000 /* in millisecond */
+#define VIDEO_FIFO_BUFS 499 /* 500 - 1 */
+#define AUDIO_FIFO_BUFS 229 /* 230 - 1 */
/*
#define LOG
@@ -44,6 +46,7 @@ struct nbc_s {
int buffering;
int low_water_mark;
int high_water_mark;
+ int fifo_full;
};
@@ -54,11 +57,11 @@ static void report_progress (xine_stream_t *stream, int p) {
prg.description = _("Buffering...");
prg.percent = (p>100)?100:p;
-
+
event.type = XINE_EVENT_PROGRESS;
event.data = &prg;
event.data_length = sizeof (xine_progress_data_t);
-
+
xine_event_send (stream, &event);
}
@@ -66,46 +69,94 @@ static void report_progress (xine_stream_t *stream, int p) {
void nbc_check_buffers (nbc_t *this) {
- int fifo_fill;
+ int fifo_fill, video_fifo_fill, audio_fifo_fill; /* number of buffers */
+ int data_length, video_data_length, audio_data_length; /* fifo length in second */
+ uint32_t video_data_size, audio_data_size; /* fifo size in bytes */
+ int video_bitrate, audio_bitrate;
+
+ video_fifo_fill = this->stream->video_fifo->size(this->stream->video_fifo);
+ if (this->stream->audio_fifo)
+ audio_fifo_fill = this->stream->audio_fifo->size(this->stream->audio_fifo);
+ else
+ audio_fifo_fill = 0;
+
+ fifo_fill = audio_fifo_fill + video_fifo_fill;
+
+ /* start buffering if fifos are empty */
+ if (fifo_fill == 0) {
+ if (!this->buffering) {
+
+ /* increase/decrease marks to adapt to stream/network needs */
+ if (!this->fifo_full) {
+ this->high_water_mark += this->high_water_mark / 4;
+ /* this->low_water_mark = this->high_water_mark/4; */
+ } else {
+ this->high_water_mark -= this->high_water_mark / 8;
+ }
+ this->buffering = 1;
+ report_progress (this->stream, 0);
- fifo_fill = this->stream->video_fifo->size(this->stream->video_fifo);
- if (this->stream->audio_fifo) {
- fifo_fill += 8*this->stream->audio_fifo->size(this->stream->audio_fifo);
- }
- if (this->buffering) {
+ }
+ /* pause */
+ this->stream->xine->clock->set_speed (this->stream->xine->clock, XINE_SPEED_PAUSE);
+ this->stream->xine->clock->set_option (this->stream->xine->clock, CLOCK_SCR_ADJUSTABLE, 0);
+ if (this->stream->audio_out)
+ this->stream->audio_out->set_property(this->stream->audio_out,AO_PROP_PAUSED,2);
- report_progress (this->stream, fifo_fill*100 / this->high_water_mark);
+ } else {
-#ifdef LOG
- printf ("net_buf_ctl: buffering (%d/%d)...\n",
- fifo_fill, this->high_water_mark);
-#endif
- }
- if (fifo_fill<this->low_water_mark) {
-
- if (!this->buffering) {
+ if (this->buffering) {
- if (this->high_water_mark<150) {
+ /* compute data length in fifos */
+ video_bitrate = this->stream->stream_info[XINE_STREAM_INFO_VIDEO_BITRATE];
+ audio_bitrate = this->stream->stream_info[XINE_STREAM_INFO_AUDIO_BITRATE];
- /* increase marks to adapt to stream/network needs */
+ if (video_bitrate) {
+ video_data_size = this->stream->video_fifo->data_size(this->stream->video_fifo);
+ video_data_length = (8000 * video_data_size) / video_bitrate;
+ } else {
+ video_data_length = 0;
+ }
- this->high_water_mark += 10;
- /* this->low_water_mark = this->high_water_mark/4; */
+ if (this->stream->audio_fifo) {
+ if (audio_bitrate) {
+ audio_data_size = this->stream->audio_fifo->data_size(this->stream->audio_fifo);
+ audio_data_length = (8000 * audio_data_size) / audio_bitrate;
+ } else {
+ audio_data_length = 0;
+ }
+ } else {
+ audio_data_length = 0;
}
- }
- this->stream->xine->clock->set_speed (this->stream->xine->clock, XINE_SPEED_PAUSE);
- this->stream->xine->clock->set_option (this->stream->xine->clock, CLOCK_SCR_ADJUSTABLE, 0);
- if (this->stream->audio_out)
- this->stream->audio_out->set_property(this->stream->audio_out,AO_PROP_PAUSED,2);
- this->buffering = 1;
+ data_length = (video_data_length > audio_data_length) ? video_data_length : audio_data_length;
+
+#ifdef LOG
+ printf("net_buf_ctrl: vff=%d, aff=%d, vdl=%d, adl=%d, dl=%d\n",
+ video_fifo_fill, audio_fifo_fill,
+ video_data_length, audio_data_length, data_length);
+#endif
+ /* stop buffering if fifos are filled enough */
+ if ((data_length >= this->high_water_mark) ||
+ (video_fifo_fill >= VIDEO_FIFO_BUFS) || /* there is 512 video buffers */
+ (audio_fifo_fill >= AUDIO_FIFO_BUFS) ) { /* there is 230 audio buffers */
+ /* unpause */
+
+ this->stream->xine->clock->set_speed (this->stream->xine->clock, XINE_SPEED_NORMAL);
+ this->stream->xine->clock->set_option (this->stream->xine->clock, CLOCK_SCR_ADJUSTABLE, 1);
+ if (this->stream->audio_out)
+ this->stream->audio_out->set_property(this->stream->audio_out,AO_PROP_PAUSED,0);
+
+ report_progress (this->stream, 100);
+ this->buffering = 0;
+ this->fifo_full = (data_length < this->high_water_mark);
+ } else {
+ report_progress (this->stream, (data_length * 100) / this->high_water_mark);
+ }
- } else if ( (fifo_fill>this->high_water_mark) && (this->buffering)) {
- this->stream->xine->clock->set_speed (this->stream->xine->clock, XINE_SPEED_NORMAL);
- this->stream->xine->clock->set_option (this->stream->xine->clock, CLOCK_SCR_ADJUSTABLE, 1);
- if (this->stream->audio_out)
- this->stream->audio_out->set_property(this->stream->audio_out,AO_PROP_PAUSED,0);
- this->buffering = 0;
+ } else {
+ /* fifos are ok */
+ }
}
}
@@ -127,6 +178,7 @@ nbc_t *nbc_init (xine_stream_t *stream) {
return this;
}
+
void nbc_set_high_water_mark(nbc_t *this, int value) {
this->high_water_mark = value;
}
diff --git a/src/xine-engine/buffer.c b/src/xine-engine/buffer.c
index 05b94fdd7..5c7de503f 100644
--- a/src/xine-engine/buffer.c
+++ b/src/xine-engine/buffer.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: buffer.c,v 1.22 2003/01/26 23:36:46 f1rmb Exp $
+ * $Id: buffer.c,v 1.23 2003/02/08 13:52:44 tmattern Exp $
*
*
* contents:
@@ -60,7 +60,7 @@ static void buffer_pool_free (buf_element_t *element) {
pthread_mutex_unlock (&this->buffer_pool_mutex);
}
-/*
+/*
* helper function to release buffer pool lock
* in case demux thread is cancelled
*/
@@ -120,7 +120,7 @@ static buf_element_t *buffer_pool_alloc (fifo_buffer_t *this) {
*/
static buf_element_t *buffer_pool_try_alloc (fifo_buffer_t *this) {
-
+
buf_element_t *buf;
pthread_mutex_lock (&this->buffer_pool_mutex);
@@ -163,9 +163,10 @@ static void fifo_buffer_put (fifo_buffer_t *fifo, buf_element_t *element) {
else
fifo->first = element;
- fifo->last = element;
+ fifo->last = element;
element->next = NULL;
fifo->fifo_size++;
+ fifo->fifo_data_size += element->size;
pthread_cond_signal (&fifo->not_empty);
@@ -186,6 +187,7 @@ static void fifo_buffer_insert (fifo_buffer_t *fifo, buf_element_t *element) {
fifo->last = element;
fifo->fifo_size++;
+ fifo->fifo_data_size += element->size;
pthread_cond_signal (&fifo->not_empty);
@@ -199,7 +201,7 @@ static void fifo_buffer_insert (fifo_buffer_t *fifo, buf_element_t *element) {
static buf_element_t *fifo_buffer_get (fifo_buffer_t *fifo) {
buf_element_t *buf;
-
+
pthread_mutex_lock (&fifo->mutex);
while (fifo->first==NULL) {
@@ -213,6 +215,7 @@ static buf_element_t *fifo_buffer_get (fifo_buffer_t *fifo) {
fifo->last = NULL;
fifo->fifo_size--;
+ fifo->fifo_data_size -= buf->size;
pthread_mutex_unlock (&fifo->mutex);
@@ -223,7 +226,7 @@ static buf_element_t *fifo_buffer_get (fifo_buffer_t *fifo) {
* clear buffer (put all contained buffer elements back into buffer pool)
*/
static void fifo_buffer_clear (fifo_buffer_t *fifo) {
-
+
buf_element_t *buf, *next, *prev;
pthread_mutex_lock (&fifo->mutex);
@@ -242,16 +245,16 @@ static void fifo_buffer_clear (fifo_buffer_t *fifo) {
prev->next = next;
else
fifo->first = next;
-
+
if (!next)
fifo->last = prev;
-
+
fifo->fifo_size--;
buf->free_buffer(buf);
} else
prev = buf;
-
+
buf = next;
}
@@ -273,6 +276,19 @@ static int fifo_buffer_size (fifo_buffer_t *this) {
}
/*
+ * Return the amount of the data in the fifo buffer
+ */
+static uint32_t fifo_buffer_data_size (fifo_buffer_t *this) {
+ uint32_t data_size;
+
+ pthread_mutex_lock(&this->mutex);
+ data_size = this->fifo_data_size;
+ pthread_mutex_unlock(&this->mutex);
+
+ return data_size;
+}
+
+/*
* Destroy the buffer
*/
static void fifo_buffer_dispose (fifo_buffer_t *this) {
@@ -293,11 +309,11 @@ static void fifo_buffer_dispose (fifo_buffer_t *this) {
buf = next;
}
-
+
while (received < this->buffer_pool_capacity) {
-
+
buf = this->get(this);
-
+
free(buf->extra_info);
free(buf);
received++;
@@ -331,13 +347,14 @@ fifo_buffer_t *fifo_buffer_new (int num_buffers, uint32_t buf_size) {
this->get = fifo_buffer_get;
this->clear = fifo_buffer_clear;
this->size = fifo_buffer_size;
+ this->data_size = fifo_buffer_data_size;
this->dispose = fifo_buffer_dispose;
pthread_mutex_init (&this->mutex, NULL);
pthread_cond_init (&this->not_empty, NULL);
/*
- * init buffer pool, allocate nNumBuffers of buf_size bytes each
+ * init buffer pool, allocate nNumBuffers of buf_size bytes each
*/
@@ -345,10 +362,10 @@ fifo_buffer_t *fifo_buffer_new (int num_buffers, uint32_t buf_size) {
buf_size += alignment - (buf_size % alignment);
/*
- printf ("Allocating %d buffers of %ld bytes in one chunk (alignment = %d)\n",
+ printf ("Allocating %d buffers of %ld bytes in one chunk (alignment = %d)\n",
num_buffers, (long int) buf_size, alignment);
*/
- multi_buffer = xine_xmalloc_aligned (alignment, num_buffers * buf_size,
+ multi_buffer = xine_xmalloc_aligned (alignment, num_buffers * buf_size,
&this->buffer_pool_base);
this->buffer_pool_top = NULL;
@@ -360,7 +377,7 @@ fifo_buffer_t *fifo_buffer_new (int num_buffers, uint32_t buf_size) {
buf_element_t *buf;
buf = xine_xmalloc (sizeof (buf_element_t));
-
+
buf->mem = multi_buffer;
multi_buffer += buf_size;
@@ -368,7 +385,7 @@ fifo_buffer_t *fifo_buffer_new (int num_buffers, uint32_t buf_size) {
buf->free_buffer = buffer_pool_free;
buf->source = this;
buf->extra_info = malloc(sizeof(extra_info_t));
-
+
buffer_pool_free (buf);
}
this->buffer_pool_num_free = num_buffers;
diff --git a/src/xine-engine/buffer.h b/src/xine-engine/buffer.h
index 057e3222b..1e180e475 100644
--- a/src/xine-engine/buffer.h
+++ b/src/xine-engine/buffer.h
@@ -7,7 +7,7 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* xine is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: buffer.h,v 1.99 2003/01/31 18:29:47 miguelfreitas Exp $
+ * $Id: buffer.h,v 1.100 2003/02/08 13:52:44 tmattern Exp $
*
*
* contents:
@@ -276,7 +276,7 @@ struct buf_element_s {
/* these are the types of special buffers */
-/*
+/*
* In a BUF_SPECIAL_PALETTE buffer:
* decoder_info[1] = BUF_SPECIAL_PALETTE
* decoder_info[2] = number of entries in palette table
@@ -392,7 +392,10 @@ typedef struct fifo_buffer_s fifo_buffer_t;
struct fifo_buffer_s
{
buf_element_t *first, *last;
+
int fifo_size;
+ uint32_t fifo_data_size;
+ void *fifo_empty_cb_data;
pthread_mutex_t mutex;
pthread_cond_t not_empty;
@@ -402,35 +405,36 @@ struct fifo_buffer_s
*/
void (*put) (fifo_buffer_t *fifo, buf_element_t *buf);
-
+
buf_element_t *(*get) (fifo_buffer_t *fifo);
void (*clear) (fifo_buffer_t *fifo) ;
int (*size) (fifo_buffer_t *fifo);
+ uint32_t (*data_size) (fifo_buffer_t *fifo);
+
void (*dispose) (fifo_buffer_t *fifo);
- /*
- * alloc buffer for this fifo from global buf pool
+ /*
+ * alloc buffer for this fifo from global buf pool
* you don't have to use this function to allocate a buffer,
* an input plugin can decide to implement it's own
* buffer allocation functions
*/
buf_element_t *(*buffer_pool_alloc) (fifo_buffer_t *this);
-
-
+
+
/*
* special functions, not used by demuxers
- */
-
+ */
+
/* the same as buffer_pool_alloc but may fail if none is available */
buf_element_t *(*buffer_pool_try_alloc) (fifo_buffer_t *this);
-
+
/* the samme as put but insert at the head of the fifo */
void (*insert) (fifo_buffer_t *fifo, buf_element_t *buf);
-
/*
* private variables for buffer pool management
@@ -448,7 +452,7 @@ struct fifo_buffer_s
/*
* allocate and initialize new (empty) fifo buffer,
* init buffer pool for it:
- * allocate num_buffers of buf_size bytes each
+ * allocate num_buffers of buf_size bytes each
*/
fifo_buffer_t *fifo_buffer_new (int num_buffers, uint32_t buf_size);
@@ -474,8 +478,8 @@ char * buf_audio_name( uint32_t buf_type );
/* no attribute packed? let's try with pragma pack as a last resort */
#pragma pack(2)
#endif
-/* this is xine version of BITMAPINFOHEADER
- * - should be safe to compile on 64bits machines
+/* this is xine version of BITMAPINFOHEADER
+ * - should be safe to compile on 64bits machines
* - will always use machine endian format, so demuxers reading
* stuff from win32 formats must use the function below.
*/