From 0dce44a4e7540ec29ec25d93a90d1f34e8e48b95 Mon Sep 17 00:00:00 2001 From: Thibaut Mattern Date: Sat, 8 Feb 2003 13:52:44 +0000 Subject: 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 --- src/input/net_buf_ctrl.c | 124 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 88 insertions(+), 36 deletions(-) (limited to 'src/input') 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_filllow_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; } -- cgit v1.2.3