summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Roitzsch <mroi@users.sourceforge.net>2004-03-16 12:25:05 +0000
committerMichael Roitzsch <mroi@users.sourceforge.net>2004-03-16 12:25:05 +0000
commit7e99ab9333bd1ba8573e78f09c3eb1d01a9ccde3 (patch)
tree7432dde37585891bae818ad2675acd9b16feb77e
parent50a26e7dabcb36c002f8527c8364c67439adbb11 (diff)
downloadxine-lib-7e99ab9333bd1ba8573e78f09c3eb1d01a9ccde3.tar.gz
xine-lib-7e99ab9333bd1ba8573e78f09c3eb1d01a9ccde3.tar.bz2
while hanging in get_frame or get_buffer, we have to check for ticket
renewal regularly to fulfill the ticket contract, which says: "assure to release or renew revocable tickets after a finite time" this patch also includes a small change to video out's flushing logic: we set last_delivery_pts into the future to avoid flushing again when the decoder does not react (stopped streams are otherwise being flushed all the time) CVS patchset: 6270 CVS date: 2004/03/16 12:25:05
-rw-r--r--src/xine-engine/audio_out.c38
-rw-r--r--src/xine-engine/video_out.c47
2 files changed, 67 insertions, 18 deletions
diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c
index 1897e3710..884980281 100644
--- a/src/xine-engine/audio_out.c
+++ b/src/xine-engine/audio_out.c
@@ -17,7 +17,7 @@
* along with self program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: audio_out.c,v 1.168 2004/03/14 23:07:25 valtri Exp $
+ * $Id: audio_out.c,v 1.169 2004/03/16 12:25:05 mroi Exp $
*
* 22-8-2001 James imported some useful AC3 sections from the previous alsa driver.
* (c) 2001 Andy Lo A Foe <andy@alsaplayer.org>
@@ -330,12 +330,22 @@ static void fifo_append (audio_fifo_t *fifo,
pthread_mutex_unlock (&fifo->mutex);
}
-static audio_buffer_t *fifo_remove_int (audio_fifo_t *fifo) {
+static audio_buffer_t *fifo_remove_int (audio_fifo_t *fifo, int blocking) {
audio_buffer_t *buf;
while (!fifo->first) {
pthread_cond_signal (&fifo->empty);
- pthread_cond_wait (&fifo->not_empty, &fifo->mutex);
+ if (blocking)
+ pthread_cond_wait (&fifo->not_empty, &fifo->mutex);
+ else {
+ struct timeval tv;
+ struct timespec ts;
+ gettimeofday(&tv, NULL);
+ ts.tv_sec = tv.tv_sec + 1;
+ ts.tv_nsec = tv.tv_usec * 1000;
+ if (pthread_cond_timedwait (&fifo->not_empty, &fifo->mutex, &ts) != 0)
+ return NULL;
+ }
}
buf = fifo->first;
@@ -363,7 +373,18 @@ static audio_buffer_t *fifo_remove (audio_fifo_t *fifo) {
audio_buffer_t *buf;
pthread_mutex_lock (&fifo->mutex);
- buf = fifo_remove_int(fifo);
+ buf = fifo_remove_int(fifo, 1);
+ pthread_mutex_unlock (&fifo->mutex);
+
+ return buf;
+}
+
+static audio_buffer_t *fifo_remove_nonblock (audio_fifo_t *fifo) {
+
+ audio_buffer_t *buf;
+
+ pthread_mutex_lock (&fifo->mutex);
+ buf = fifo_remove_int(fifo, 0);
pthread_mutex_unlock (&fifo->mutex);
return buf;
@@ -1157,7 +1178,7 @@ int xine_get_next_audio_frame (xine_audio_port_t *this_gen,
}
}
- in_buf = fifo_remove_int (this->out_fifo);
+ in_buf = fifo_remove_int (this->out_fifo, 1);
pthread_mutex_unlock(&this->out_fifo->mutex);
out_buf = prepare_samples (this, in_buf);
@@ -1340,7 +1361,10 @@ static audio_buffer_t *ao_get_buffer (xine_audio_port_t *this_gen) {
aos_t *this = (aos_t *) this_gen;
audio_buffer_t *buf;
- buf = fifo_remove (this->free_fifo);
+ while (!(buf = fifo_remove_nonblock (this->free_fifo)))
+ if (this->xine->port_ticket->ticket_revoked)
+ this->xine->port_ticket->renew(this->xine->port_ticket, 1);
+
_x_extra_info_reset( buf->extra_info );
return buf;
@@ -1654,7 +1678,7 @@ static int ao_set_property (xine_audio_port_t *this_gen, int property, int value
while ((buf = this->out_fifo->first)) {
lprintf ("flushing out frame\n");
- buf = fifo_remove_int (this->out_fifo);
+ buf = fifo_remove_int (this->out_fifo, 1);
fifo_append (this->free_fifo, buf);
}
pthread_mutex_unlock (&this->out_fifo->mutex);
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index 8e45389a4..2c4e99130 100644
--- a/src/xine-engine/video_out.c
+++ b/src/xine-engine/video_out.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: video_out.c,v 1.187 2004/03/03 20:09:17 mroi Exp $
+ * $Id: video_out.c,v 1.188 2004/03/16 12:25:05 mroi Exp $
*
* frame allocation / queuing / scheduling / output functions
*/
@@ -167,11 +167,21 @@ static void vo_append_to_img_buf_queue (img_buf_fifo_t *queue,
pthread_mutex_unlock (&queue->mutex);
}
-static vo_frame_t *vo_remove_from_img_buf_queue_int (img_buf_fifo_t *queue) {
+static vo_frame_t *vo_remove_from_img_buf_queue_int (img_buf_fifo_t *queue, int blocking) {
vo_frame_t *img;
while (!queue->first || queue->locked_for_read) {
- pthread_cond_wait (&queue->not_empty, &queue->mutex);
+ if (blocking)
+ pthread_cond_wait (&queue->not_empty, &queue->mutex);
+ else {
+ struct timeval tv;
+ struct timespec ts;
+ gettimeofday(&tv, NULL);
+ ts.tv_sec = tv.tv_sec + 1;
+ ts.tv_nsec = tv.tv_usec * 1000;
+ if (pthread_cond_timedwait (&queue->not_empty, &queue->mutex, &ts) != 0)
+ return NULL;
+ }
}
img = queue->first;
@@ -195,7 +205,17 @@ static vo_frame_t *vo_remove_from_img_buf_queue (img_buf_fifo_t *queue) {
vo_frame_t *img;
pthread_mutex_lock (&queue->mutex);
- img = vo_remove_from_img_buf_queue_int(queue);
+ img = vo_remove_from_img_buf_queue_int(queue, 1);
+ pthread_mutex_unlock (&queue->mutex);
+
+ return img;
+}
+
+static vo_frame_t *vo_remove_from_img_buf_queue_nonblock (img_buf_fifo_t *queue) {
+ vo_frame_t *img;
+
+ pthread_mutex_lock (&queue->mutex);
+ img = vo_remove_from_img_buf_queue_int(queue, 0);
pthread_mutex_unlock (&queue->mutex);
return img;
@@ -284,7 +304,9 @@ static vo_frame_t *vo_get_frame (xine_video_port_t *this_gen,
lprintf ("get_frame (%d x %d)\n", width, height);
- img = vo_remove_from_img_buf_queue (this->free_img_buf_queue);
+ while (!(img = vo_remove_from_img_buf_queue_nonblock (this->free_img_buf_queue)))
+ if (this->xine->port_ticket->ticket_revoked)
+ this->xine->port_ticket->renew(this->xine->port_ticket, 1);
lprintf ("got a frame -> pthread_mutex_lock (&img->mutex)\n");
@@ -635,7 +657,7 @@ static void expire_frames (vos_t *this, int64_t cur_vpts) {
this->num_frames_discarded++;
}
- img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue);
+ img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1);
if (img->stream) {
pthread_mutex_lock( &img->stream->current_extra_info_lock );
@@ -774,7 +796,7 @@ static vo_frame_t *get_next_frame (vos_t *this, int64_t cur_vpts) {
* remove frame from display queue and show it
*/
- img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue);
+ img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1);
pthread_mutex_unlock(&this->display_img_buf_queue->mutex);
return img;
@@ -987,7 +1009,10 @@ static void *video_out_loop (void *this_gen) {
}
pthread_mutex_unlock(&this->streams_lock);
- this->last_delivery_pts = vpts;
+ /* set one minute into the future to avoid flushing over and over again;
+ * if the decoder actually reacts to the flush by sending a frame,
+ * vo_frame_draw() will set last_delivery_pts anyway */
+ this->last_delivery_pts = vpts + 90000 * 60;
}
/*
@@ -1032,7 +1057,7 @@ static void *video_out_loop (void *this_gen) {
img = this->display_img_buf_queue->first;
while (img) {
- img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue);
+ img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1);
vo_frame_dec_lock( img );
img = this->display_img_buf_queue->first;
@@ -1089,7 +1114,7 @@ int xine_get_next_video_frame (xine_video_port_t *this_gen,
* remove frame from display queue and show it
*/
- img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue);
+ img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1);
pthread_mutex_unlock(&this->display_img_buf_queue->mutex);
frame->vpts = img->vpts;
@@ -1232,7 +1257,7 @@ static int vo_set_property (xine_video_port_t *this_gen, int property, int value
lprintf ("flushing out frame\n");
- img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue);
+ img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1);
vo_frame_dec_lock (img);
}