summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/xine-engine/buffer.c69
-rw-r--r--src/xine-engine/buffer.h15
-rw-r--r--src/xine-engine/video_decoder.c10
-rw-r--r--src/xine-engine/video_out.c70
4 files changed, 100 insertions, 64 deletions
diff --git a/src/xine-engine/buffer.c b/src/xine-engine/buffer.c
index e4d1c7724..2e93009a1 100644
--- a/src/xine-engine/buffer.c
+++ b/src/xine-engine/buffer.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: buffer.c,v 1.19 2002/12/21 12:56:52 miguelfreitas Exp $
+ * $Id: buffer.c,v 1.20 2002/12/22 15:02:06 miguelfreitas Exp $
*
*
* contents:
@@ -116,6 +116,42 @@ static buf_element_t *buffer_pool_alloc (fifo_buffer_t *this) {
}
/*
+ * allocate a buffer from buffer pool - may fail if none is available
+ */
+
+static buf_element_t *buffer_pool_try_alloc (fifo_buffer_t *this) {
+
+ buf_element_t *buf;
+
+ pthread_mutex_lock (&this->buffer_pool_mutex);
+
+ if (this->buffer_pool_top) {
+
+ buf = this->buffer_pool_top;
+ this->buffer_pool_top = this->buffer_pool_top->next;
+ this->buffer_pool_num_free--;
+
+ } else {
+
+ buf = NULL;
+
+ }
+
+ pthread_mutex_unlock (&this->buffer_pool_mutex);
+
+ /* set sane values to the newly allocated buffer */
+ if( buf ) {
+ buf->content = buf->mem; /* 99% of demuxers will want this */
+ buf->pts = 0;
+ buf->size = 0;
+ buf->decoder_flags = 0;
+ extra_info_reset( buf->extra_info );
+ }
+ return buf;
+}
+
+
+/*
* append buffer element to fifo buffer
*/
static void fifo_buffer_put (fifo_buffer_t *fifo, buf_element_t *element) {
@@ -137,6 +173,27 @@ static void fifo_buffer_put (fifo_buffer_t *fifo, buf_element_t *element) {
}
/*
+ * insert buffer element to fifo buffer (demuxers MUST NOT call this one)
+ */
+static void fifo_buffer_insert (fifo_buffer_t *fifo, buf_element_t *element) {
+
+ pthread_mutex_lock (&fifo->mutex);
+
+ element->next = fifo->first;
+ fifo->first = element;
+
+ if( !fifo->last )
+ fifo->last = element;
+
+ fifo->fifo_size++;
+
+ pthread_cond_signal (&fifo->not_empty);
+
+ pthread_mutex_unlock (&fifo->mutex);
+}
+
+
+/*
* get element from fifo buffer
*/
static buf_element_t *fifo_buffer_get (fifo_buffer_t *fifo) {
@@ -270,6 +327,7 @@ fifo_buffer_t *fifo_buffer_new (int num_buffers, uint32_t buf_size) {
this->last = NULL;
this->fifo_size = 0;
this->put = fifo_buffer_put;
+ this->insert = fifo_buffer_insert;
this->get = fifo_buffer_get;
this->clear = fifo_buffer_clear;
this->size = fifo_buffer_size;
@@ -313,10 +371,11 @@ fifo_buffer_t *fifo_buffer_new (int num_buffers, uint32_t buf_size) {
buffer_pool_free (buf);
}
- this->buffer_pool_num_free = num_buffers;
- this->buffer_pool_capacity = num_buffers;
- this->buffer_pool_buf_size = buf_size;
- this->buffer_pool_alloc = buffer_pool_alloc;
+ this->buffer_pool_num_free = num_buffers;
+ this->buffer_pool_capacity = num_buffers;
+ this->buffer_pool_buf_size = buf_size;
+ this->buffer_pool_alloc = buffer_pool_alloc;
+ this->buffer_pool_try_alloc = buffer_pool_try_alloc;
return this;
}
diff --git a/src/xine-engine/buffer.h b/src/xine-engine/buffer.h
index 3fb3bd397..dad8752ae 100644
--- a/src/xine-engine/buffer.h
+++ b/src/xine-engine/buffer.h
@@ -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: buffer.h,v 1.86 2002/12/21 12:56:52 miguelfreitas Exp $
+ * $Id: buffer.h,v 1.87 2002/12/22 15:02:06 miguelfreitas Exp $
*
*
* contents:
@@ -77,6 +77,7 @@ extern "C" {
#define BUF_CONTROL_NEWPTS 0x01070000
#define BUF_CONTROL_RESET_DECODER 0x01080000
#define BUF_CONTROL_HEADERS_DONE 0x01090000
+#define BUF_CONTROL_FLUSH_DECODER 0x010a0000
/* video buffer types: (please keep in sync with buffer_types.c) */
@@ -404,6 +405,18 @@ struct fifo_buffer_s
*/
buf_element_t *(*buffer_pool_alloc) (fifo_buffer_t *this);
+
+
+ /*
+ * special functions, not used by demuxers
+ */
+
+ /* the same as buffer_pool_alloc but may fail if none is available */
+ buf_element_t *(*buffer_pool_try_alloc) (fifo_buffer_t *this);
+
+ /* the samme as put but insert at the head of the fifo */
+ void (*insert) (fifo_buffer_t *fifo, buf_element_t *buf);
+
/*
* private variables for buffer pool management
diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c
index 7f43b3dd0..218578734 100644
--- a/src/xine-engine/video_decoder.c
+++ b/src/xine-engine/video_decoder.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_decoder.c,v 1.115 2002/12/21 16:13:43 miguelfreitas Exp $
+ * $Id: video_decoder.c,v 1.116 2002/12/22 15:02:06 miguelfreitas Exp $
*
*/
@@ -193,7 +193,13 @@ void *video_decoder_loop (void *stream_gen) {
stream->spu_decoder_plugin->reset (stream->spu_decoder_plugin);
}
break;
-
+
+ case BUF_CONTROL_FLUSH_DECODER:
+ if (stream->video_decoder_plugin) {
+ stream->video_decoder_plugin->flush (stream->video_decoder_plugin);
+ }
+ break;
+
case BUF_CONTROL_DISCONTINUITY:
#ifdef LOG
printf ("video_decoder: discontinuity ahead\n");
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index 027327183..16611629e 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.122 2002/12/21 19:23:01 miguelfreitas Exp $
+ * $Id: video_out.c,v 1.123 2002/12/22 15:02:07 miguelfreitas Exp $
*
* frame allocation / queuing / scheduling / output functions
*/
@@ -609,7 +609,7 @@ static vo_frame_t *get_next_frame (vos_t *this, int64_t cur_vpts) {
*/
pthread_mutex_lock( &this->free_img_buf_queue->mutex );
if (img && !img->next) {
-
+
if (img->stream->stream_info[XINE_STREAM_INFO_VIDEO_HAS_STILL] ||
img->stream->video_fifo->size(img->stream->video_fifo) < 10) {
@@ -737,12 +737,12 @@ static void *video_out_loop (void *this_gen) {
vos_t *this = (vos_t *) this_gen;
int64_t frame_duration, next_frame_vpts;
int64_t usec_to_sleep;
-
+
/*
* here it is - the heart of xine (or rather: one of the hearts
* of xine) : the video output loop
*/
-
+
frame_duration = 1500; /* default */
next_frame_vpts = this->clock->get_current_time (this->clock);
@@ -788,66 +788,24 @@ static void *video_out_loop (void *this_gen) {
if (diff > 30000 && !this->display_img_buf_queue->first) {
xine_stream_t *stream;
-#if XINE_DEADLOCK_ON_QUIT
- /*
- * this flush code often deadlocks when a BUF_CONTROL_QUIT is
- * sent to the video_decoder thread (that is, on xine exit):
- *
- * - we're detecting a "stall" here, this code locks
- * streams_lock, and then video decoder's lock in the
- * ...->flush() call
- *
- * - video_decoder performs actions for BUF_CONTROL_QUIT: it
- * locks and disposes the video_decoder, which calls vo_close()
- * and vo_close() tries to lock the streams_lock.
- */
pthread_mutex_lock(&this->streams_lock);
for (stream = xine_list_first_content(this->streams); stream;
stream = xine_list_next_content(this->streams)) {
- if (stream->video_decoder_plugin) {
-
+ if (stream->video_decoder_plugin && stream->video_fifo) {
+ buf_element_t *buf;
+
#ifdef LOG
- printf ("video_out: flushing current video decoder plugin (%d %d)\n",
- this->display_img_buf_queue->num_buffers,
- this->free_img_buf_queue->num_buffers);
+ printf ("video_out: flushing current video decoder plugin\n");
#endif
-
- stream->video_decoder_plugin->flush(stream->video_decoder_plugin);
+
+ buf = stream->video_fifo->buffer_pool_try_alloc (stream->video_fifo);
+ if( buf ) {
+ buf->type = BUF_CONTROL_FLUSH_DECODER;
+ stream->video_fifo->put(stream->video_fifo, buf);
+ }
}
}
pthread_mutex_unlock(&this->streams_lock);
-#else
- /*
- * Ugly hack to avoid the above mentioned deadlock: try to
- * release the streams_lock as soon as possible, when we know
- * that the current stream is the last one.
- *
- * This hack only works when the stream with video_decorder_plugin
- * is the last one in the streams list!
- */
- pthread_mutex_lock(&this->streams_lock);
- if ((stream = xine_list_first_content(this->streams)) != NULL) {
- xine_stream_t *stream_next;
-
- for (; stream; stream = stream_next) {
- stream_next = xine_list_next_content(this->streams);
- if (!stream_next)
- pthread_mutex_unlock(&this->streams_lock);
-
- if (stream->video_decoder_plugin) {
-
-#ifdef LOG
- printf ("video_out: flushing current video decoder plugin (%d %d)\n",
- this->display_img_buf_queue->num_buffers,
- this->free_img_buf_queue->num_buffers);
-#endif
-
- stream->video_decoder_plugin->flush(stream->video_decoder_plugin);
- }
- }
- } else
- pthread_mutex_unlock(&this->streams_lock);
-#endif
this->last_delivery_pts = vpts;
}