summaryrefslogtreecommitdiff
path: root/src/input
diff options
context:
space:
mode:
Diffstat (limited to 'src/input')
-rw-r--r--src/input/net_buf_ctrl.c124
1 files changed, 88 insertions, 36 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;
}