[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