diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/post/goom/xine_goom.c | 4 | ||||
-rw-r--r-- | src/post/visualizations/fftgraph.c | 4 | ||||
-rw-r--r-- | src/post/visualizations/fftscope.c | 4 | ||||
-rw-r--r-- | src/post/visualizations/fooviz.c | 4 | ||||
-rw-r--r-- | src/post/visualizations/oscope.c | 4 | ||||
-rw-r--r-- | src/xine-engine/audio_decoder.c | 104 | ||||
-rw-r--r-- | src/xine-engine/buffer.c | 54 | ||||
-rw-r--r-- | src/xine-engine/buffer.h | 3 | ||||
-rw-r--r-- | src/xine-engine/demux.c | 96 | ||||
-rw-r--r-- | src/xine-engine/info_helper.h | 6 | ||||
-rw-r--r-- | src/xine-engine/io_helper.c | 1 | ||||
-rw-r--r-- | src/xine-engine/metronom.c | 96 | ||||
-rw-r--r-- | src/xine-engine/metronom.h | 7 | ||||
-rw-r--r-- | src/xine-engine/video_decoder.c | 101 | ||||
-rw-r--r-- | src/xine-engine/xine.c | 82 |
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); |