diff options
author | Thibaut Mattern <tmattern@users.sourceforge.net> | 2003-02-08 13:52:44 +0000 |
---|---|---|
committer | Thibaut Mattern <tmattern@users.sourceforge.net> | 2003-02-08 13:52:44 +0000 |
commit | 0dce44a4e7540ec29ec25d93a90d1f34e8e48b95 (patch) | |
tree | fb0a2bf210b9579b46fc5becb70f4cc2504533e8 /src | |
parent | 2020c00620ef6eea03d928d4c32b57d0aa14cd2d (diff) | |
download | xine-lib-0dce44a4e7540ec29ec25d93a90d1f34e8e48b95.tar.gz xine-lib-0dce44a4e7540ec29ec25d93a90d1f34e8e48b95.tar.bz2 |
New net_buf_ctrl strategy.
see http://sourceforge.net/mailarchive/forum.php?thread_id=1568239&forum_id=7131
CVS patchset: 4116
CVS date: 2003/02/08 13:52:44
Diffstat (limited to 'src')
-rw-r--r-- | src/input/net_buf_ctrl.c | 124 | ||||
-rw-r--r-- | src/xine-engine/buffer.c | 51 | ||||
-rw-r--r-- | src/xine-engine/buffer.h | 34 |
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. */ |