From 7e99ab9333bd1ba8573e78f09c3eb1d01a9ccde3 Mon Sep 17 00:00:00 2001 From: Michael Roitzsch Date: Tue, 16 Mar 2004 12:25:05 +0000 Subject: 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 --- src/xine-engine/audio_out.c | 38 +++++++++++++++++++++++++++++------- src/xine-engine/video_out.c | 47 ++++++++++++++++++++++++++++++++++----------- 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 @@ -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); } -- cgit v1.2.3