summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/post/goom/xine_goom.c4
-rw-r--r--src/post/visualizations/fftgraph.c4
-rw-r--r--src/post/visualizations/fftscope.c4
-rw-r--r--src/post/visualizations/fooviz.c4
-rw-r--r--src/post/visualizations/oscope.c4
-rw-r--r--src/xine-engine/audio_decoder.c104
-rw-r--r--src/xine-engine/buffer.c54
-rw-r--r--src/xine-engine/buffer.h3
-rw-r--r--src/xine-engine/demux.c96
-rw-r--r--src/xine-engine/info_helper.h6
-rw-r--r--src/xine-engine/io_helper.c1
-rw-r--r--src/xine-engine/metronom.c96
-rw-r--r--src/xine-engine/metronom.h7
-rw-r--r--src/xine-engine/video_decoder.c101
-rw-r--r--src/xine-engine/xine.c82
15 files changed, 331 insertions, 239 deletions
diff --git a/src/post/goom/xine_goom.c b/src/post/goom/xine_goom.c
index a1b99afa1..53348c994 100644
--- a/src/post/goom/xine_goom.c
+++ b/src/post/goom/xine_goom.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: xine_goom.c,v 1.41 2003/11/16 12:18:59 mroi Exp $
+ * $Id: xine_goom.c,v 1.42 2003/11/20 00:42:14 tmattern Exp $
*
* GOOM post plugin.
*
@@ -259,7 +259,7 @@ static post_plugin_t *goom_open_plugin(post_class_t *class_gen, int inputs,
this->class = class;
class->ip = this;
- this->metronom = _x_metronom_init(0, class->xine);
+ this->metronom = _x_metronom_init(0, 1, class->xine);
lprintf("goom: goom_open_plugin\n");
diff --git a/src/post/visualizations/fftgraph.c b/src/post/visualizations/fftgraph.c
index 11cd0c180..50d4293e4 100644
--- a/src/post/visualizations/fftgraph.c
+++ b/src/post/visualizations/fftgraph.c
@@ -20,7 +20,7 @@
* FftGraph Visualization Post Plugin For xine
* by Thibaut Mattern (tmattern@noos.fr)
*
- * $Id: fftgraph.c,v 1.5 2003/11/16 12:18:59 mroi Exp $
+ * $Id: fftgraph.c,v 1.6 2003/11/20 00:42:14 tmattern Exp $
*
*/
@@ -467,7 +467,7 @@ static post_plugin_t *fftgraph_open_plugin(post_class_t *class_gen, int inputs,
return NULL;
}
- this->metronom = _x_metronom_init(0, class->xine);
+ this->metronom = _x_metronom_init(0, 1,class->xine);
this->sample_counter = 0;
this->stream = NULL;
diff --git a/src/post/visualizations/fftscope.c b/src/post/visualizations/fftscope.c
index 607f70a29..58e9c5e1f 100644
--- a/src/post/visualizations/fftscope.c
+++ b/src/post/visualizations/fftscope.c
@@ -22,7 +22,7 @@
*
* FFT code by Steve Haehnichen, originally licensed under GPL v1
*
- * $Id: fftscope.c,v 1.19 2003/11/16 12:18:59 mroi Exp $
+ * $Id: fftscope.c,v 1.20 2003/11/20 00:42:14 tmattern Exp $
*
*/
@@ -506,7 +506,7 @@ static post_plugin_t *fftscope_open_plugin(post_class_t *class_gen, int inputs,
return NULL;
}
- this->metronom = _x_metronom_init(0, class->xine);
+ this->metronom = _x_metronom_init(0, 1, class->xine);
this->sample_counter = 0;
this->stream = NULL;
diff --git a/src/post/visualizations/fooviz.c b/src/post/visualizations/fooviz.c
index fccb6d72f..f9485a6d9 100644
--- a/src/post/visualizations/fooviz.c
+++ b/src/post/visualizations/fooviz.c
@@ -23,7 +23,7 @@
* process. It simply paints the screen a solid color and rotates through
* colors on each iteration.
*
- * $Id: fooviz.c,v 1.14 2003/11/16 12:18:59 mroi Exp $
+ * $Id: fooviz.c,v 1.15 2003/11/20 00:42:14 tmattern Exp $
*
*/
@@ -303,7 +303,7 @@ static post_plugin_t *fooviz_open_plugin(post_class_t *class_gen, int inputs,
return NULL;
}
- this->metronom = _x_metronom_init(0, class->xine);
+ this->metronom = _x_metronom_init(0, 1, class->xine);
this->sample_counter = 0;
this->stream = NULL;
diff --git a/src/post/visualizations/oscope.c b/src/post/visualizations/oscope.c
index 553ea5519..2c28e7de3 100644
--- a/src/post/visualizations/oscope.c
+++ b/src/post/visualizations/oscope.c
@@ -20,7 +20,7 @@
* Basic Oscilloscope Visualization Post Plugin For xine
* by Mike Melanson (melanson@pcisys.net)
*
- * $Id: oscope.c,v 1.12 2003/11/16 12:18:59 mroi Exp $
+ * $Id: oscope.c,v 1.13 2003/11/20 00:42:14 tmattern Exp $
*
*/
@@ -373,7 +373,7 @@ static post_plugin_t *oscope_open_plugin(post_class_t *class_gen, int inputs,
return NULL;
}
- this->metronom = _x_metronom_init(0, class->xine);
+ this->metronom = _x_metronom_init(0, 1, class->xine);
this->sample_counter = 0;
this->stream = NULL;
diff --git a/src/xine-engine/audio_decoder.c b/src/xine-engine/audio_decoder.c
index eecc30f61..5f020fa00 100644
--- a/src/xine-engine/audio_decoder.c
+++ b/src/xine-engine/audio_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: audio_decoder.c,v 1.112 2003/11/17 10:22:57 f1rmb Exp $
+ * $Id: audio_decoder.c,v 1.113 2003/11/20 00:42:14 tmattern Exp $
*
*
* functions that implement audio decoding
@@ -123,32 +123,36 @@ static void *audio_decoder_loop (void *stream_gen) {
case BUF_CONTROL_END:
/* wait for video to reach this marker, if necessary */
-
pthread_mutex_lock (&stream->counter_lock);
stream->finished_count_audio++;
-
+
#ifdef LOG
printf ("audio_decoder: reached end marker # %d\n",
- stream->finished_count_audio);
+ stream->finished_count_audio);
#endif
pthread_cond_broadcast (&stream->counter_changed);
- while (stream->finished_count_video < stream->finished_count_audio) {
- struct timeval tv;
- struct timespec ts;
- gettimeofday(&tv, NULL);
- ts.tv_sec = tv.tv_sec + 1;
- ts.tv_nsec = tv.tv_usec * 1000;
- /* use timedwait to workaround buggy pthread broadcast implementations */
- pthread_cond_timedwait (&stream->counter_changed, &stream->counter_lock, &ts);
+ if (stream->video_thread) {
+ while (stream->finished_count_video < stream->finished_count_audio) {
+ struct timeval tv;
+ struct timespec ts;
+ gettimeofday(&tv, NULL);
+ ts.tv_sec = tv.tv_sec + 1;
+ ts.tv_nsec = tv.tv_usec * 1000;
+ /* use timedwait to workaround buggy pthread broadcast implementations */
+ pthread_cond_timedwait (&stream->counter_changed, &stream->counter_lock, &ts);
+ }
}
-
pthread_mutex_unlock (&stream->counter_lock);
-
stream->audio_channel_auto = -1;
+ if (!stream->video_thread) {
+ /* set engine status, send frontend notification event */
+ _x_handle_stream_end (stream, buf->decoder_flags & BUF_FLAG_END_STREAM);
+ }
+
break;
case BUF_CONTROL_QUIT:
@@ -358,41 +362,42 @@ void _x_audio_decoder_init (xine_stream_t *stream) {
int err;
if (stream->audio_out == NULL) {
- stream->audio_fifo = NULL;
+ stream->audio_fifo = _x_dummy_fifo_buffer_new (5, 8192);
return;
- }
+ } else {
- /* The fifo size is based on dvd playback where buffers are filled
- * with 2k of data. With 230 buffers and a typical audio data rate
- * of 1.8 Mbit/s (four ac3 streams), the fifo can hold about 2 seconds
- * of audio, wich should be enough to compensate for drive delays.
- * We provide buffers of 8k size instead of 2k for demuxers sending
- * larger chunks.
- */
- stream->audio_fifo = _x_fifo_buffer_new (230, 8192);
- stream->audio_channel_user = -1;
- stream->audio_channel_auto = -1;
- stream->audio_track_map_entries = 0;
- stream->audio_type = 0;
-
- /* future magic - coming soon
- stream->audio_temp = lrb_new (100, stream->audio_fifo);
- */
-
- pthread_attr_init(&pth_attrs);
- pthread_attr_getschedparam(&pth_attrs, &pth_params);
- pth_params.sched_priority = sched_get_priority_min(SCHED_OTHER);
- pthread_attr_setschedparam(&pth_attrs, &pth_params);
- pthread_attr_setscope(&pth_attrs, PTHREAD_SCOPE_SYSTEM);
+ /* The fifo size is based on dvd playback where buffers are filled
+ * with 2k of data. With 230 buffers and a typical audio data rate
+ * of 1.8 Mbit/s (four ac3 streams), the fifo can hold about 2 seconds
+ * of audio, wich should be enough to compensate for drive delays.
+ * We provide buffers of 8k size instead of 2k for demuxers sending
+ * larger chunks.
+ */
+ stream->audio_fifo = _x_fifo_buffer_new (230, 8192);
+ stream->audio_channel_user = -1;
+ stream->audio_channel_auto = -1;
+ stream->audio_track_map_entries = 0;
+ stream->audio_type = 0;
+
+ /* future magic - coming soon
+ * stream->audio_temp = lrb_new (100, stream->audio_fifo);
+ */
+
+ pthread_attr_init(&pth_attrs);
+ pthread_attr_getschedparam(&pth_attrs, &pth_params);
+ pth_params.sched_priority = sched_get_priority_min(SCHED_OTHER);
+ pthread_attr_setschedparam(&pth_attrs, &pth_params);
+ pthread_attr_setscope(&pth_attrs, PTHREAD_SCOPE_SYSTEM);
- if ((err = pthread_create (&stream->audio_thread,
- &pth_attrs, audio_decoder_loop, stream)) != 0) {
- fprintf (stderr, "audio_decoder: can't create new thread (%s)\n",
- strerror(err));
- abort();
- }
+ if ((err = pthread_create (&stream->audio_thread,
+ &pth_attrs, audio_decoder_loop, stream)) != 0) {
+ fprintf (stderr, "audio_decoder: can't create new thread (%s)\n",
+ strerror(err));
+ abort();
+ }
- pthread_attr_destroy(&pth_attrs);
+ pthread_attr_destroy(&pth_attrs);
+ }
}
void _x_audio_decoder_shutdown (xine_stream_t *stream) {
@@ -400,7 +405,7 @@ void _x_audio_decoder_shutdown (xine_stream_t *stream) {
buf_element_t *buf;
void *p;
- if (stream->audio_fifo) {
+ if (stream->audio_thread) {
/* stream->audio_fifo->clear(stream->audio_fifo); */
buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
@@ -408,10 +413,10 @@ void _x_audio_decoder_shutdown (xine_stream_t *stream) {
stream->audio_fifo->put (stream->audio_fifo, buf);
pthread_join (stream->audio_thread, &p);
-
- stream->audio_fifo->dispose (stream->audio_fifo);
- stream->audio_fifo = NULL;
}
+
+ stream->audio_fifo->dispose (stream->audio_fifo);
+ stream->audio_fifo = NULL;
/* wakeup any rewire operations */
pthread_cond_broadcast(&stream->next_audio_port_wired);
@@ -421,4 +426,3 @@ int _x_get_audio_channel (xine_stream_t *stream) {
return stream->audio_type & 0xFFFF;
}
-
diff --git a/src/xine-engine/buffer.c b/src/xine-engine/buffer.c
index 154634a35..a6e92060a 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.32 2003/11/11 18:45:00 f1rmb Exp $
+ * $Id: buffer.c,v 1.33 2003/11/20 00:42:14 tmattern Exp $
*
*
* contents:
@@ -37,10 +37,18 @@
#include <stdio.h>
#include <stdlib.h>
+#include <assert.h>
+
+/********** logging **********/
+#define LOG_MODULE "buffer"
+#define LOG_VERBOSE
+/*
+#define LOG
+*/
+
#include "buffer.h"
#include "xineutils.h"
#include "xine_internal.h"
-#include <assert.h>
/*
* put a previously allocated buffer element back into the buffer pool
@@ -168,6 +176,22 @@ static void fifo_buffer_put (fifo_buffer_t *fifo, buf_element_t *element) {
}
/*
+ * append buffer element to fifo buffer
+ */
+static void dummy_fifo_buffer_put (fifo_buffer_t *fifo, buf_element_t *element) {
+ int i;
+
+ pthread_mutex_lock (&fifo->mutex);
+
+ for(i = 0; fifo->put_cb[i]; i++)
+ fifo->put_cb[i](fifo, element, fifo->put_cb_data[i]);
+
+ pthread_mutex_unlock (&fifo->mutex);
+
+ element->free_buffer(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) {
@@ -188,13 +212,19 @@ static void fifo_buffer_insert (fifo_buffer_t *fifo, buf_element_t *element) {
pthread_mutex_unlock (&fifo->mutex);
}
+/*
+ * insert buffer element to fifo buffer (demuxers MUST NOT call this one)
+ */
+static void dummy_fifo_buffer_insert (fifo_buffer_t *fifo, buf_element_t *element) {
+
+ element->free_buffer(element);
+}
/*
* get element from fifo buffer
*/
static buf_element_t *fifo_buffer_get (fifo_buffer_t *fifo) {
int i;
-
buf_element_t *buf;
pthread_mutex_lock (&fifo->mutex);
@@ -347,6 +377,7 @@ static void fifo_register_alloc_cb (fifo_buffer_t *this,
void *data_cb),
void *data_cb) {
int i;
+
pthread_mutex_lock(&this->mutex);
for(i = 0; this->alloc_cb[i]; i++)
;
@@ -367,6 +398,7 @@ static void fifo_register_put_cb (fifo_buffer_t *this,
void *data_cb),
void *data_cb) {
int i;
+
pthread_mutex_lock(&this->mutex);
for(i = 0; this->put_cb[i]; i++)
;
@@ -387,6 +419,7 @@ static void fifo_register_get_cb (fifo_buffer_t *this,
void *data_cb),
void *data_cb) {
int i;
+
pthread_mutex_lock(&this->mutex);
for(i = 0; this->get_cb[i]; i++)
;
@@ -405,6 +438,7 @@ static void fifo_unregister_alloc_cb (fifo_buffer_t *this,
void (*cb)(fifo_buffer_t *this,
void *data_cb) ) {
int i,j;
+
pthread_mutex_lock(&this->mutex);
for(i = 0; this->alloc_cb[i]; i++) {
if( this->alloc_cb[i] == cb ) {
@@ -425,6 +459,7 @@ static void fifo_unregister_put_cb (fifo_buffer_t *this,
buf_element_t *buf,
void *data_cb) ) {
int i,j;
+
pthread_mutex_lock(&this->mutex);
for(i = 0; this->put_cb[i]; i++) {
if( this->put_cb[i] == cb ) {
@@ -445,6 +480,7 @@ static void fifo_unregister_get_cb (fifo_buffer_t *this,
buf_element_t *buf,
void *data_cb) ) {
int i,j;
+
pthread_mutex_lock(&this->mutex);
for(i = 0; this->get_cb[i]; i++) {
if( this->get_cb[i] == cb ) {
@@ -539,3 +575,15 @@ fifo_buffer_t *_x_fifo_buffer_new (int num_buffers, uint32_t buf_size) {
return this;
}
+/*
+ * allocate and initialize new (empty) fifo buffer
+ */
+fifo_buffer_t *_x_dummy_fifo_buffer_new (int num_buffers, uint32_t buf_size) {
+
+ fifo_buffer_t *this;
+
+ this = _x_fifo_buffer_new(num_buffers, buf_size);
+ this->put = dummy_fifo_buffer_put;
+ this->insert = dummy_fifo_buffer_insert;
+ return this;
+}
diff --git a/src/xine-engine/buffer.h b/src/xine-engine/buffer.h
index da6d522df..009037c70 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.125 2003/11/16 14:29:29 tmmm Exp $
+ * $Id: buffer.h,v 1.126 2003/11/20 00:42:14 tmattern Exp $
*
*
* contents:
@@ -509,6 +509,7 @@ struct fifo_buffer_s
*/
fifo_buffer_t *_x_fifo_buffer_new (int num_buffers, uint32_t buf_size);
+fifo_buffer_t *_x_dummy_fifo_buffer_new (int num_buffers, uint32_t buf_size);
/* return BUF_VIDEO_xxx given the fourcc
diff --git a/src/xine-engine/demux.c b/src/xine-engine/demux.c
index 6a4039e16..f17ef910c 100644
--- a/src/xine-engine/demux.c
+++ b/src/xine-engine/demux.c
@@ -20,7 +20,7 @@
* Demuxer helper functions
* hide some xine engine details from demuxers and reduce code duplication
*
- * $Id: demux.c,v 1.40 2003/11/16 15:41:15 mroi Exp $
+ * $Id: demux.c,v 1.41 2003/11/20 00:42:14 tmattern Exp $
*/
@@ -71,21 +71,17 @@ void _x_demux_flush_engine (xine_stream_t *stream) {
if (stream->audio_out) {
stream->audio_out->set_property(stream->audio_out, AO_PROP_DISCARD_BUFFERS, 1);
}
+
stream->video_fifo->clear(stream->video_fifo);
-
- if( stream->audio_fifo )
- stream->audio_fifo->clear(stream->audio_fifo);
+ stream->audio_fifo->clear(stream->audio_fifo);
buf = stream->video_fifo->buffer_pool_alloc (stream->video_fifo);
- buf->type = BUF_CONTROL_RESET_DECODER;
+ buf->type = BUF_CONTROL_RESET_DECODER;
stream->video_fifo->put (stream->video_fifo, buf);
-
- if(stream->audio_fifo) {
- buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
- buf->type = BUF_CONTROL_RESET_DECODER;
- stream->audio_fifo->put (stream->audio_fifo, buf);
- }
-
+
+ buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
+ buf->type = BUF_CONTROL_RESET_DECODER;
+ stream->audio_fifo->put (stream->audio_fifo, buf);
/* on seeking we must wait decoder fifos to process before doing flush.
* otherwise we flush too early (before the old data has left decoders)
@@ -114,13 +110,11 @@ void _x_demux_control_newpts( xine_stream_t *stream, int64_t pts, uint32_t flags
buf->disc_off = pts;
stream->video_fifo->put (stream->video_fifo, buf);
- if (stream->audio_fifo) {
- buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
- buf->type = BUF_CONTROL_NEWPTS;
- buf->decoder_flags = flags;
- buf->disc_off = pts;
- stream->audio_fifo->put (stream->audio_fifo, buf);
- }
+ buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
+ buf->type = BUF_CONTROL_NEWPTS;
+ buf->decoder_flags = flags;
+ buf->disc_off = pts;
+ stream->audio_fifo->put (stream->audio_fifo, buf);
}
/* sync with decoder fifos, making sure everything gets processed */
@@ -131,29 +125,35 @@ void _x_demux_control_headers_done (xine_stream_t *stream) {
buf_element_t *buf;
pthread_mutex_lock (&stream->counter_lock);
- if (stream->audio_fifo)
+
+ if (stream->video_thread) {
+ header_count_video = stream->header_count_video + 1;
+ } else {
+ header_count_video = 0;
+ }
+
+ if (stream->audio_thread) {
header_count_audio = stream->header_count_audio + 1;
- else
+ } else {
header_count_audio = 0;
-
- header_count_video = stream->header_count_video + 1;
+ }
buf = stream->video_fifo->buffer_pool_alloc (stream->video_fifo);
buf->type = BUF_CONTROL_HEADERS_DONE;
stream->video_fifo->put (stream->video_fifo, buf);
- if (stream->audio_fifo) {
- buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
- buf->type = BUF_CONTROL_HEADERS_DONE;
- stream->audio_fifo->put (stream->audio_fifo, buf);
- }
+ buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
+ buf->type = BUF_CONTROL_HEADERS_DONE;
+ stream->audio_fifo->put (stream->audio_fifo, buf);
while ((stream->header_count_audio<header_count_audio) ||
(stream->header_count_video<header_count_video)) {
struct timeval tv;
struct timespec ts;
#ifdef LOG
- printf ("xine: waiting for headers.\n");
+ printf ("xine: waiting for headers. v:%d %d a:%d %d\n",
+ stream->header_count_video, header_count_video,
+ stream->header_count_audio, header_count_audio);
#endif
gettimeofday(&tv, NULL);
ts.tv_sec = tv.tv_sec + 1;
@@ -175,11 +175,9 @@ void _x_demux_control_start( xine_stream_t *stream ) {
buf->type = BUF_CONTROL_START;
stream->video_fifo->put (stream->video_fifo, buf);
- if (stream->audio_fifo) {
- buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
- buf->type = BUF_CONTROL_START;
- stream->audio_fifo->put (stream->audio_fifo, buf);
- }
+ buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
+ buf->type = BUF_CONTROL_START;
+ stream->audio_fifo->put (stream->audio_fifo, buf);
}
void _x_demux_control_end( xine_stream_t *stream, uint32_t flags ) {
@@ -191,12 +189,10 @@ void _x_demux_control_end( xine_stream_t *stream, uint32_t flags ) {
buf->decoder_flags = flags;
stream->video_fifo->put (stream->video_fifo, buf);
- if (stream->audio_fifo) {
- buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
- buf->type = BUF_CONTROL_END;
- buf->decoder_flags = flags;
- stream->audio_fifo->put (stream->audio_fifo, buf);
- }
+ buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
+ buf->type = BUF_CONTROL_END;
+ buf->decoder_flags = flags;
+ stream->audio_fifo->put (stream->audio_fifo, buf);
}
void _x_demux_control_nop( xine_stream_t *stream, uint32_t flags ) {
@@ -207,13 +203,11 @@ void _x_demux_control_nop( xine_stream_t *stream, uint32_t flags ) {
buf->type = BUF_CONTROL_NOP;
buf->decoder_flags = flags;
stream->video_fifo->put (stream->video_fifo, buf);
-
- if (stream->audio_fifo) {
- buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
- buf->type = BUF_CONTROL_NOP;
- buf->decoder_flags = flags;
- stream->audio_fifo->put (stream->audio_fifo, buf);
- }
+
+ buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
+ buf->type = BUF_CONTROL_NOP;
+ buf->decoder_flags = flags;
+ stream->audio_fifo->put (stream->audio_fifo, buf);
}
static void *demux_loop (void *stream_gen) {
@@ -258,9 +252,8 @@ static void *demux_loop (void *stream_gen) {
/* wait before sending end buffers: user might want to do a new seek */
while(stream->demux_thread_running &&
- ((!stream->video_fifo || stream->video_fifo->size(stream->video_fifo)) ||
- (stream->audio_out
- && (!stream->audio_fifo || stream->audio_fifo->size(stream->audio_fifo)))) &&
+ ((stream->video_fifo->size(stream->video_fifo)) ||
+ (stream->audio_fifo->size(stream->audio_fifo))) &&
status == DEMUX_FINISHED ){
pthread_mutex_unlock( &stream->demux_lock );
xine_usec_sleep(100000);
@@ -281,6 +274,9 @@ static void *demux_loop (void *stream_gen) {
_x_demux_control_end(stream, BUF_FLAG_END_USER);
}
+#ifdef LOG
+ printf ("demux: loop finished, end buffer sent\n");
+#endif
stream->demux_thread_running = 0;
pthread_mutex_unlock( &stream->demux_lock );
diff --git a/src/xine-engine/info_helper.h b/src/xine-engine/info_helper.h
index a163823a5..6e7052390 100644
--- a/src/xine-engine/info_helper.h
+++ b/src/xine-engine/info_helper.h
@@ -31,7 +31,7 @@
/*
* set a stream info
*
- * params :
+ * params:
* *stream the xine stream
* info stream info id (see xine.h, XINE_STREAM_INFO_*)
* value the value to assign
@@ -82,7 +82,7 @@ uint32_t _x_stream_info_get_public(xine_stream_t *stream, int info);
/*
* set a stream meta info
*
- * params :
+ * params:
* *stream the xine stream
* info meta info id (see xine.h, XINE_META_INFO_*)
* *str null-terminated string
@@ -93,7 +93,7 @@ void _x_meta_info_set(xine_stream_t *stream, int info, const char *str);
/*
* set a stream meta info
*
- * params :
+ * params:
* *stream the xine stream
* info meta info id (see xine.h, XINE_META_INFO_*)
* *buf char buffer (not a null-terminated string)
diff --git a/src/xine-engine/io_helper.c b/src/xine-engine/io_helper.c
index 45ab04748..9798c0378 100644
--- a/src/xine-engine/io_helper.c
+++ b/src/xine-engine/io_helper.c
@@ -211,6 +211,7 @@ int _x_io_select (xine_stream_t *stream, int fd, int state, int timeout_msec) {
rset = (state & XIO_READ_READY) ? &fdset : NULL;
wset = (state & XIO_WRITE_READY) ? &fdset : NULL;
ret = select (fd + 1, rset, wset, NULL, &select_timeout);
+
if (ret == -1) {
/* select error */
return XIO_ERROR;
diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c
index f349f588b..374f616e0 100644
--- a/src/xine-engine/metronom.c
+++ b/src/xine-engine/metronom.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: metronom.c,v 1.128 2003/11/16 15:44:03 mroi Exp $
+ * $Id: metronom.c,v 1.129 2003/11/20 00:42:14 tmattern Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -34,6 +34,10 @@
#include <errno.h>
#define LOG_MODULE "metronom"
+/*
+#define LOG
+#define LOG_AUDIO
+*/
#define METRONOM_INTERNAL
@@ -54,11 +58,6 @@
i guess llabs may not be available everywhere */
#define abs(x) ( ((x)<0) ? -(x) : (x) )
-/*
-#define LOG
-#define LOG_AUDIO
-*/
-
/*
* ****************************************
@@ -298,35 +297,10 @@ static int64_t metronom_got_spu_packet (metronom_t *this, int64_t pts) {
return vpts;
}
-static void metronom_handle_video_discontinuity (metronom_t *this, int type,
- int64_t disc_off) {
+static void metronom_handle_discontinuity (metronom_t *this, int type,
+ int64_t disc_off) {
int64_t cur_time;
- pthread_mutex_lock (&this->lock);
-
- if (this->master) {
- /* slaves are currently not allowed to set discontinuities */
- pthread_mutex_unlock(&this->lock);
- return;
- }
-
- this->video_discontinuity_count++;
- pthread_cond_signal (&this->video_discontinuity_reached);
-
- xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video discontinuity #%d, type is %d, disc_off is %lld\n",
- this->video_discontinuity_count, type, disc_off);
-
- if (this->have_audio) {
- while (this->audio_discontinuity_count <
- this->video_discontinuity_count) {
-
- xprintf(this->xine, XINE_VERBOSITY_DEBUG, "waiting for audio discontinuity #%d\n",
- this->video_discontinuity_count);
-
- pthread_cond_wait (&this->audio_discontinuity_reached, &this->lock);
- }
- }
-
/* video_vpts and audio_vpts adjustements */
cur_time = this->xine->clock->get_current_time(this->xine->clock);
@@ -397,6 +371,38 @@ static void metronom_handle_video_discontinuity (metronom_t *this, int type,
this->last_video_pts = 0;
this->last_audio_pts = 0;
+}
+
+static void metronom_handle_video_discontinuity (metronom_t *this, int type,
+ int64_t disc_off) {
+
+ pthread_mutex_lock (&this->lock);
+
+ if (this->master) {
+ /* slaves are currently not allowed to set discontinuities */
+ pthread_mutex_unlock(&this->lock);
+ return;
+ }
+
+ this->video_discontinuity_count++;
+ pthread_cond_signal (&this->video_discontinuity_reached);
+
+ xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video discontinuity #%d, type is %d, disc_off %lld\n",
+ this->video_discontinuity_count, type, disc_off);
+
+ if (this->have_audio) {
+ while (this->audio_discontinuity_count <
+ this->video_discontinuity_count) {
+
+ xprintf(this->xine, XINE_VERBOSITY_DEBUG, "waiting for audio discontinuity #%d\n",
+ this->video_discontinuity_count);
+
+ pthread_cond_wait (&this->audio_discontinuity_reached, &this->lock);
+ }
+ }
+
+ metronom_handle_discontinuity(this, type, disc_off);
+
this->discontinuity_handled_count++;
pthread_cond_signal (&this->video_discontinuity_reached);
@@ -523,15 +529,20 @@ static void metronom_handle_audio_discontinuity (metronom_t *this, int type,
xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio discontinuity #%d, type is %d, disc_off %lld\n",
this->audio_discontinuity_count, type, disc_off);
-
- /* next_vpts_offset, in_discontinuity is handled in expect_video_discontinuity */
- while ( this->audio_discontinuity_count >
- this->discontinuity_handled_count ) {
- xprintf(this->xine, XINE_VERBOSITY_DEBUG, "waiting for in_discontinuity update #%d\n",
- this->audio_discontinuity_count);
-
- pthread_cond_wait (&this->video_discontinuity_reached, &this->lock);
+ if (this->have_video) {
+
+ /* next_vpts_offset, in_discontinuity is handled in expect_video_discontinuity */
+ while ( this->audio_discontinuity_count >
+ this->discontinuity_handled_count ) {
+
+ xprintf(this->xine, XINE_VERBOSITY_DEBUG, "waiting for in_discontinuity update #%d\n",
+ this->audio_discontinuity_count);
+
+ pthread_cond_wait (&this->video_discontinuity_reached, &this->lock);
+ }
+ } else {
+ metronom_handle_discontinuity(this, type, disc_off);
}
this->audio_samples = 0;
@@ -841,7 +852,7 @@ static void metronom_clock_exit (metronom_clock_t *this) {
}
-metronom_t * _x_metronom_init (int have_audio, xine_t *xine) {
+metronom_t * _x_metronom_init (int have_video, int have_audio, xine_t *xine) {
metronom_t *this = xine_xmalloc (sizeof (metronom_t));
@@ -882,6 +893,7 @@ metronom_t * _x_metronom_init (int have_audio, xine_t *xine) {
/* initialize audio stuff */
+ this->have_video = have_video;
this->have_audio = have_audio;
this->audio_vpts = this->prebuffer;
this->audio_discontinuity_count = 0;
diff --git a/src/xine-engine/metronom.h b/src/xine-engine/metronom.h
index 325aed6e4..2f14f0388 100644
--- a/src/xine-engine/metronom.h
+++ b/src/xine-engine/metronom.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2002 the xine project
+ * Copyright (C) 2000-2003 the xine project
*
* This file is part of xine, a free video player.
*
@@ -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: metronom.h,v 1.55 2003/11/16 15:44:03 mroi Exp $
+ * $Id: metronom.h,v 1.56 2003/11/20 00:42:14 tmattern Exp $
*
* metronom: general pts => virtual calculation/assoc
*
@@ -204,6 +204,7 @@ struct metronom_s {
pthread_mutex_t lock;
+ int have_video;
int have_audio;
int video_discontinuity_count;
int audio_discontinuity_count;
@@ -234,7 +235,7 @@ struct metronom_s {
#define METRONOM_VPTS_OFFSET 6
#define METRONOM_PREBUFFER 7
-metronom_t *_x_metronom_init (int have_audio, xine_t *xine);
+metronom_t *_x_metronom_init (int have_video, int have_audio, xine_t *xine);
struct metronom_clock_s {
diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c
index 724683a23..493716fbc 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.139 2003/11/16 23:33:48 f1rmb Exp $
+ * $Id: video_decoder.c,v 1.140 2003/11/20 00:42:14 tmattern Exp $
*
*/
@@ -166,7 +166,7 @@ static void *video_decoder_loop (void *stream_gen) {
pthread_cond_broadcast (&stream->counter_changed);
- if (stream->audio_fifo) {
+ if (stream->audio_thread) {
while (stream->finished_count_video > stream->finished_count_audio) {
struct timeval tv;
@@ -191,7 +191,6 @@ static void *video_decoder_loop (void *stream_gen) {
pthread_cond_broadcast(&stream->first_frame_reached);
}
pthread_mutex_unlock (&stream->first_frame_lock);
-
break;
case BUF_CONTROL_QUIT:
@@ -392,43 +391,48 @@ static void *video_decoder_loop (void *stream_gen) {
void _x_video_decoder_init (xine_stream_t *stream) {
- pthread_attr_t pth_attrs;
- struct sched_param pth_params;
- int err, num_buffers;
-
- /* The fifo size is based on dvd playback where buffers are filled
- * with 2k of data. With 500 buffers and a typical video data rate
- * of 8 Mbit/s, the fifo can hold about 1 second of video, wich
- * should be enough to compensate for drive delays.
- * We provide buffers of 8k size instead of 2k for demuxers sending
- * larger chunks.
- */
-
- num_buffers = stream->xine->config->register_num (stream->xine->config,
- "video.num_buffers",
- 500,
- "number of video buffers to allocate (higher values mean smoother playback but higher latency)",
- NULL, 20,
- NULL, NULL);
-
-
- stream->video_fifo = _x_fifo_buffer_new (num_buffers, 8192);
- stream->spu_track_map_entries = 0;
-
- pthread_attr_init(&pth_attrs);
- pthread_attr_getschedparam(&pth_attrs, &pth_params);
- pth_params.sched_priority = sched_get_priority_min(SCHED_OTHER);
- pthread_attr_setschedparam(&pth_attrs, &pth_params);
- pthread_attr_setscope(&pth_attrs, PTHREAD_SCOPE_SYSTEM);
+ if (stream->video_out == NULL) {
+ stream->video_fifo = _x_dummy_fifo_buffer_new (5, 8192);
+ stream->spu_track_map_entries = 0;
+ return;
+ } else {
+
+ pthread_attr_t pth_attrs;
+ struct sched_param pth_params;
+ int err, num_buffers;
+ /* The fifo size is based on dvd playback where buffers are filled
+ * with 2k of data. With 500 buffers and a typical video data rate
+ * of 8 Mbit/s, the fifo can hold about 1 second of video, wich
+ * should be enough to compensate for drive delays.
+ * We provide buffers of 8k size instead of 2k for demuxers sending
+ * larger chunks.
+ */
- if ((err = pthread_create (&stream->video_thread,
- &pth_attrs, video_decoder_loop, stream)) != 0) {
- fprintf (stderr, "video_decoder: can't create new thread (%s)\n",
- strerror(err));
- abort();
- }
+ num_buffers = stream->xine->config->register_num (stream->xine->config,
+ "video.num_buffers",
+ 500,
+ "number of video buffers to allocate (higher values mean smoother playback but higher latency)",
+ NULL, 20,
+ NULL, NULL);
+
+ stream->video_fifo = _x_fifo_buffer_new (num_buffers, 8192);
+ stream->spu_track_map_entries = 0;
- pthread_attr_destroy(&pth_attrs);
+ pthread_attr_init(&pth_attrs);
+ pthread_attr_getschedparam(&pth_attrs, &pth_params);
+ pth_params.sched_priority = sched_get_priority_min(SCHED_OTHER);
+ pthread_attr_setschedparam(&pth_attrs, &pth_params);
+ pthread_attr_setscope(&pth_attrs, PTHREAD_SCOPE_SYSTEM);
+
+ if ((err = pthread_create (&stream->video_thread,
+ &pth_attrs, video_decoder_loop, stream)) != 0) {
+ fprintf (stderr, "video_decoder: can't create new thread (%s)\n",
+ strerror(err));
+ abort();
+ }
+
+ pthread_attr_destroy(&pth_attrs);
+ }
}
void _x_video_decoder_shutdown (xine_stream_t *stream) {
@@ -440,24 +444,29 @@ void _x_video_decoder_shutdown (xine_stream_t *stream) {
printf ("video_decoder: shutdown...\n");
#endif
- /* stream->video_fifo->clear(stream->video_fifo); */
+ if (stream->video_thread) {
+
+ /* stream->video_fifo->clear(stream->video_fifo); */
- buf = stream->video_fifo->buffer_pool_alloc (stream->video_fifo);
+ buf = stream->video_fifo->buffer_pool_alloc (stream->video_fifo);
#ifdef LOG
- printf ("video_decoder: shutdown...2\n");
+ printf ("video_decoder: shutdown...2\n");
#endif
- buf->type = BUF_CONTROL_QUIT;
- stream->video_fifo->put (stream->video_fifo, buf);
+ buf->type = BUF_CONTROL_QUIT;
+ stream->video_fifo->put (stream->video_fifo, buf);
#ifdef LOG
printf ("video_decoder: shutdown...3\n");
#endif
- pthread_join (stream->video_thread, &p);
+ pthread_join (stream->video_thread, &p);
#ifdef LOG
- printf ("video_decoder: shutdown...4\n");
+ printf ("video_decoder: shutdown...4\n");
#endif
+ }
+
+ stream->video_fifo->dispose (stream->video_fifo);
+ stream->video_fifo = NULL;
/* wakeup any rewire operations */
pthread_cond_broadcast(&stream->next_video_port_wired);
}
-
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
index 0a163833d..68993354b 100644
--- a/src/xine-engine/xine.c
+++ b/src/xine-engine/xine.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: xine.c,v 1.267 2003/11/16 23:33:48 f1rmb Exp $
+ * $Id: xine.c,v 1.268 2003/11/20 00:42:14 tmattern Exp $
*/
/*
@@ -172,12 +172,16 @@ static void __stop_internal (xine_stream_t *stream) {
*/
pthread_mutex_lock (&stream->counter_lock);
- if (stream->audio_fifo)
+ if (stream->audio_thread)
finished_count_audio = stream->finished_count_audio + 1;
else
finished_count_audio = 0;
- finished_count_video = stream->finished_count_video + 1;
+ if (stream->video_thread)
+ finished_count_video = stream->finished_count_video + 1;
+ else
+ finished_count_video = 0;
+
pthread_mutex_unlock (&stream->counter_lock);
lprintf ("stopping demux\n");
@@ -295,20 +299,22 @@ static int __stream_rewire_audio(xine_post_out_t *output, void *data)
xine_stream_t *stream = (xine_stream_t *)output->data;
xine_audio_port_t *new_port = (xine_audio_port_t *)data;
buf_element_t *buf;
-
+
if (!data)
return 0;
pthread_mutex_lock(&stream->next_audio_port_lock);
stream->next_audio_port = new_port;
- if (stream->audio_fifo &&
- (buf = stream->audio_fifo->buffer_pool_try_alloc(stream->audio_fifo))) {
- /* wake up audio decoder thread */
- buf->type = BUF_CONTROL_NOP;
- stream->audio_fifo->insert(stream->audio_fifo, buf);
+ if (stream->audio_thread) {
+ buf = stream->audio_fifo->buffer_pool_try_alloc(stream->audio_fifo);
+ if (buf) {
+ /* wake up audio decoder thread */
+ buf->type = BUF_CONTROL_NOP;
+ stream->audio_fifo->insert(stream->audio_fifo, buf);
+ }
+ /* wait till rewiring is finished */
+ pthread_cond_wait(&stream->next_audio_port_wired, &stream->next_audio_port_lock);
}
- /* wait till rewiring is finished */
- pthread_cond_wait(&stream->next_audio_port_wired, &stream->next_audio_port_lock);
pthread_mutex_unlock(&stream->next_audio_port_lock);
return 1;
@@ -325,14 +331,16 @@ static int __stream_rewire_video(xine_post_out_t *output, void *data)
pthread_mutex_lock(&stream->next_video_port_lock);
stream->next_video_port = new_port;
- if (stream->video_fifo &&
- (buf = stream->video_fifo->buffer_pool_try_alloc(stream->video_fifo))) {
- /* wake up video decoder thread */
- buf->type = BUF_CONTROL_NOP;
- stream->video_fifo->insert(stream->video_fifo, buf);
+ if (stream->video_thread) {
+ buf = stream->video_fifo->buffer_pool_try_alloc(stream->video_fifo);
+ if (buf) {
+ /* wake up video decoder thread */
+ buf->type = BUF_CONTROL_NOP;
+ stream->video_fifo->insert(stream->video_fifo, buf);
+ }
+ /* wait till rewiring is finished */
+ pthread_cond_wait(&stream->next_video_port_wired, &stream->next_video_port_lock);
}
- /* wait till rewiring is finished */
- pthread_cond_wait(&stream->next_video_port_wired, &stream->next_video_port_lock);
pthread_mutex_unlock(&stream->next_video_port_lock);
return 1;
@@ -376,8 +384,13 @@ xine_stream_t *xine_stream_new (xine_t *this,
stream->spu_channel_pan_scan = -1;
stream->spu_channel_user = -1;
stream->spu_channel = -1;
+
stream->video_out = vo;
- stream->video_driver = vo->driver;
+ if (vo)
+ stream->video_driver = vo->driver;
+ else
+ stream->video_driver = NULL;
+
stream->video_channel = 0;
stream->video_decoder_plugin = NULL;
stream->video_decoder_streamtype = -1;
@@ -437,7 +450,7 @@ xine_stream_t *xine_stream_new (xine_t *this,
* create a metronom
*/
- stream->metronom = _x_metronom_init ( (ao != NULL), this);
+ stream->metronom = _x_metronom_init ( (vo != NULL), (ao != NULL), this);
/*
* alloc fifos, init and start decoder threads
@@ -450,8 +463,11 @@ xine_stream_t *xine_stream_new (xine_t *this,
/*
* osd
*/
-
- stream->osd_renderer = _x_osd_renderer_init (stream->video_out->get_overlay_manager (stream->video_out), stream->xine->config );
+ if (vo)
+ stream->osd_renderer = _x_osd_renderer_init (stream->video_out->get_overlay_manager (stream->video_out),
+ stream->xine->config );
+ else
+ stream->osd_renderer = NULL;
/*
* register stream
@@ -927,6 +943,7 @@ static int __play_internal (xine_stream_t *stream, int start_pos, int start_time
double share ;
off_t pos, len;
int demux_status;
+ int demux_thread_running;
xprintf (stream->xine, XINE_VERBOSITY_DEBUG, "xine_play\n");
@@ -953,6 +970,7 @@ static int __play_internal (xine_stream_t *stream, int start_pos, int start_time
pthread_mutex_lock( &stream->demux_lock );
/* demux_lock taken. now demuxer is suspended */
+ stream->demux_action_pending = 0;
/* set normal speed again (now that demuxer/input pair is suspended)
* some input plugin may have changed speed by itself, we must ensure
@@ -980,8 +998,6 @@ static int __play_internal (xine_stream_t *stream, int start_pos, int start_time
pos, start_time,
stream->demux_thread_running);
- stream->demux_action_pending = 0;
-
if (stream->audio_out)
stream->audio_out->set_property(stream->audio_out, AO_PROP_DISCARD_BUFFERS, 0);
if (stream->video_out)
@@ -997,6 +1013,8 @@ static int __play_internal (xine_stream_t *stream, int start_pos, int start_time
_x_extra_info_reset( stream->current_extra_info );
pthread_mutex_unlock( &stream->current_extra_info_lock );
+ demux_thread_running = stream->demux_thread_running;
+
/* now resume demuxer thread if it is running already */
pthread_mutex_unlock( &stream->demux_lock );
@@ -1009,8 +1027,10 @@ static int __play_internal (xine_stream_t *stream, int start_pos, int start_time
return 0;
} else {
- _x_demux_start_thread( stream );
- stream->status = XINE_STATUS_PLAY;
+ if (!demux_thread_running) {
+ _x_demux_start_thread( stream );
+ stream->status = XINE_STATUS_PLAY;
+ }
}
@@ -1078,7 +1098,7 @@ void xine_dispose (xine_stream_t *stream) {
stream->status = XINE_STATUS_QUIT;
xine_close(stream);
-
+
if( stream->master != stream ) {
stream->master->slave = NULL;
}
@@ -1091,12 +1111,12 @@ void xine_dispose (xine_stream_t *stream) {
xprintf (stream->xine, XINE_VERBOSITY_DEBUG, "shutdown audio\n");
_x_audio_decoder_shutdown (stream);
-
+
xprintf (stream->xine, XINE_VERBOSITY_DEBUG, "shutdown video\n");
+ if (stream->osd_renderer)
+ stream->osd_renderer->close( stream->osd_renderer );
+
_x_video_decoder_shutdown (stream);
-
- stream->osd_renderer->close( stream->osd_renderer );
- stream->video_fifo->dispose (stream->video_fifo);
pthread_mutex_destroy (&stream->info_mutex);
pthread_mutex_destroy (&stream->meta_mutex);