Index: xine-engine/buffer.h =================================================================== RCS file: /cvsroot/xine/xine-lib/src/xine-engine/buffer.h,v retrieving revision 1.124 diff -u -r1.124 buffer.h --- xine-engine/buffer.h 15 Nov 2003 14:54:31 -0000 1.124 +++ xine-engine/buffer.h 16 Nov 2003 17:58:28 -0000 @@ -508,6 +508,7 @@ */ 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 Index: xine-engine/info_helper.h =================================================================== RCS file: /cvsroot/xine/xine-lib/src/xine-engine/info_helper.h,v retrieving revision 1.3 diff -u -r1.3 info_helper.h --- xine-engine/info_helper.h 15 Nov 2003 13:01:01 -0000 1.3 +++ xine-engine/info_helper.h 16 Nov 2003 17:58:28 -0000 @@ -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 @@ -42,7 +42,7 @@ /* * 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 @@ -53,7 +53,7 @@ /* * 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) Index: xine-engine/metronom.h =================================================================== RCS file: /cvsroot/xine/xine-lib/src/xine-engine/metronom.h,v retrieving revision 1.54 diff -u -r1.54 metronom.h --- xine-engine/metronom.h 16 Nov 2003 12:15:21 -0000 1.54 +++ xine-engine/metronom.h 16 Nov 2003 17:58:28 -0000 @@ -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. * @@ -205,6 +205,7 @@ pthread_mutex_t lock; + int have_video; int have_audio; int video_discontinuity_count; int audio_discontinuity_count; @@ -235,7 +236,7 @@ #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 { Index: xine-engine/audio_decoder.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/xine-engine/audio_decoder.c,v retrieving revision 1.109 diff -u -r1.109 audio_decoder.c --- xine-engine/audio_decoder.c 11 Nov 2003 18:45:00 -0000 1.109 +++ xine-engine/audio_decoder.c 16 Nov 2003 17:58:29 -0000 @@ -121,32 +121,36 @@ 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: @@ -357,41 +361,42 @@ 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) { @@ -399,7 +404,7 @@ 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); @@ -407,10 +412,10 @@ 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); @@ -420,4 +425,3 @@ return stream->audio_type & 0xFFFF; } - Index: xine-engine/buffer.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/xine-engine/buffer.c,v retrieving revision 1.32 diff -u -r1.32 buffer.c --- xine-engine/buffer.c 11 Nov 2003 18:45:00 -0000 1.32 +++ xine-engine/buffer.c 16 Nov 2003 17:58:36 -0000 @@ -37,10 +37,18 @@ #include #include +#include + +/********** logging **********/ +#define LOG_MODULE "buffer" +#define LOG_VERBOSE +/* +#define LOG +*/ + #include "buffer.h" #include "xineutils.h" #include "xine_internal.h" -#include /* * put a previously allocated buffer element back into the buffer pool @@ -49,12 +57,13 @@ fifo_buffer_t *this = (fifo_buffer_t *) element->source; + lprintf("\n"); pthread_mutex_lock (&this->buffer_pool_mutex); element->next = this->buffer_pool_top; this->buffer_pool_top = element; - this->buffer_pool_num_free++; + this->buffer_pool_num_free++; if (this->buffer_pool_num_free > this->buffer_pool_capacity) { printf("xine-lib:buffer: Their has been a fatal error: TOO MANY FREE's\n"); assert(0); @@ -74,6 +83,7 @@ buf_element_t *buf; int i; + lprintf("\n"); pthread_mutex_lock (&this->buffer_pool_mutex); for(i = 0; this->alloc_cb[i]; i++) @@ -111,6 +121,7 @@ buf_element_t *buf; + lprintf("\n"); pthread_mutex_lock (&this->buffer_pool_mutex); if (this->buffer_pool_top) { @@ -147,6 +158,7 @@ static void fifo_buffer_put (fifo_buffer_t *fifo, buf_element_t *element) { int i; + lprintf("\n"); pthread_mutex_lock (&fifo->mutex); for(i = 0; fifo->put_cb[i]; i++) @@ -168,10 +180,28 @@ } /* + * append buffer element to fifo buffer + */ +static void dummy_fifo_buffer_put (fifo_buffer_t *fifo, buf_element_t *element) { + int i; + + lprintf("\n"); + 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) { + lprintf("\n"); pthread_mutex_lock (&fifo->mutex); element->next = fifo->first; @@ -188,15 +218,23 @@ 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) { + + lprintf("\n"); + 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; + lprintf("\n"); pthread_mutex_lock (&fifo->mutex); while (fifo->first==NULL) { @@ -227,6 +265,7 @@ buf_element_t *buf, *next, *prev; + lprintf("\n"); pthread_mutex_lock (&fifo->mutex); buf = fifo->first; @@ -267,6 +306,7 @@ static int fifo_buffer_size (fifo_buffer_t *this) { int size; + lprintf("\n"); pthread_mutex_lock(&this->mutex); size = this->fifo_size; pthread_mutex_unlock(&this->mutex); @@ -280,6 +320,7 @@ static uint32_t fifo_buffer_data_size (fifo_buffer_t *this) { uint32_t data_size; + lprintf("\n"); pthread_mutex_lock(&this->mutex); data_size = this->fifo_data_size; pthread_mutex_unlock(&this->mutex); @@ -293,6 +334,7 @@ static int fifo_buffer_num_free (fifo_buffer_t *this) { int buffer_pool_num_free; + lprintf("\n"); pthread_mutex_lock(&this->mutex); buffer_pool_num_free = this->buffer_pool_num_free; pthread_mutex_unlock(&this->mutex); @@ -308,6 +350,7 @@ buf_element_t *buf, *next; int received = 0; + lprintf("\n"); this->clear( this ); buf = this->buffer_pool_top; @@ -347,6 +390,8 @@ void *data_cb), void *data_cb) { int i; + + lprintf("\n"); pthread_mutex_lock(&this->mutex); for(i = 0; this->alloc_cb[i]; i++) ; @@ -367,6 +412,8 @@ void *data_cb), void *data_cb) { int i; + + lprintf("\n"); pthread_mutex_lock(&this->mutex); for(i = 0; this->put_cb[i]; i++) ; @@ -387,6 +434,8 @@ void *data_cb), void *data_cb) { int i; + + lprintf("\n"); pthread_mutex_lock(&this->mutex); for(i = 0; this->get_cb[i]; i++) ; @@ -405,6 +454,8 @@ void (*cb)(fifo_buffer_t *this, void *data_cb) ) { int i,j; + + lprintf("\n"); pthread_mutex_lock(&this->mutex); for(i = 0; this->alloc_cb[i]; i++) { if( this->alloc_cb[i] == cb ) { @@ -425,6 +476,8 @@ buf_element_t *buf, void *data_cb) ) { int i,j; + + lprintf("\n"); pthread_mutex_lock(&this->mutex); for(i = 0; this->put_cb[i]; i++) { if( this->put_cb[i] == cb ) { @@ -445,6 +498,8 @@ buf_element_t *buf, void *data_cb) ) { int i,j; + + lprintf("\n"); pthread_mutex_lock(&this->mutex); for(i = 0; this->get_cb[i]; i++) { if( this->get_cb[i] == cb ) { @@ -467,6 +522,7 @@ int alignment = 2048; char *multi_buffer = NULL; + lprintf("\n"); this = xine_xmalloc (sizeof (fifo_buffer_t)); this->first = NULL; @@ -539,3 +595,16 @@ 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; + + lprintf("\n"); + this = _x_fifo_buffer_new(num_buffers, buf_size); + this->put = dummy_fifo_buffer_put; + this->insert = dummy_fifo_buffer_insert; + return this; +} Index: xine-engine/demux.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/xine-engine/demux.c,v retrieving revision 1.39 diff -u -r1.39 demux.c --- xine-engine/demux.c 15 Nov 2003 14:54:31 -0000 1.39 +++ xine-engine/demux.c 16 Nov 2003 17:58:36 -0000 @@ -68,21 +68,17 @@ 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) @@ -111,13 +107,11 @@ 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 */ @@ -128,29 +122,35 @@ 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_audioheader_count_videoheader_count_video, header_count_video, + stream->header_count_audio, header_count_audio); #endif gettimeofday(&tv, NULL); ts.tv_sec = tv.tv_sec + 1; @@ -172,11 +172,9 @@ 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 ) { @@ -188,12 +186,10 @@ 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 ) { @@ -204,13 +200,11 @@ 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) { @@ -255,9 +249,8 @@ /* 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); @@ -278,6 +271,9 @@ _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 ); Index: xine-engine/io_helper.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/xine-engine/io_helper.c,v retrieving revision 1.6 diff -u -r1.6 io_helper.c --- xine-engine/io_helper.c 11 Nov 2003 18:45:00 -0000 1.6 +++ xine-engine/io_helper.c 16 Nov 2003 17:58:36 -0000 @@ -208,6 +208,7 @@ 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; Index: xine-engine/metronom.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/xine-engine/metronom.c,v retrieving revision 1.127 diff -u -r1.127 metronom.c --- xine-engine/metronom.c 16 Nov 2003 12:15:21 -0000 1.127 +++ xine-engine/metronom.c 16 Nov 2003 17:58:36 -0000 @@ -296,35 +296,10 @@ 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); @@ -395,6 +370,38 @@ 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); @@ -521,15 +528,20 @@ 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; @@ -839,7 +851,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) { metronom_t *this = xine_xmalloc (sizeof (metronom_t)); @@ -880,6 +892,7 @@ /* initialize audio stuff */ + this->have_video = have_video; this->have_audio = have_audio; this->audio_vpts = this->prebuffer; this->audio_discontinuity_count = 0; Index: xine-engine/video_decoder.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/xine-engine/video_decoder.c,v retrieving revision 1.137 diff -u -r1.137 video_decoder.c --- xine-engine/video_decoder.c 11 Nov 2003 18:45:01 -0000 1.137 +++ xine-engine/video_decoder.c 16 Nov 2003 17:58:36 -0000 @@ -164,7 +164,7 @@ 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; @@ -189,7 +189,6 @@ pthread_cond_broadcast(&stream->first_frame_reached); } pthread_mutex_unlock (&stream->first_frame_lock); - break; case BUF_CONTROL_QUIT: @@ -392,43 +391,48 @@ 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 @@ 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); } - Index: xine-engine/xine.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/xine-engine/xine.c,v retrieving revision 1.265 diff -u -r1.265 xine.c --- xine-engine/xine.c 15 Nov 2003 20:43:11 -0000 1.265 +++ xine-engine/xine.c 16 Nov 2003 17:58:36 -0000 @@ -170,12 +170,16 @@ */ 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"); @@ -297,14 +301,16 @@ 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; @@ -321,14 +327,16 @@ 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; @@ -375,8 +383,13 @@ 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; @@ -423,7 +436,7 @@ * 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 @@ -436,8 +449,11 @@ /* * 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 @@ -913,6 +929,7 @@ double share ; off_t pos, len; int demux_status; + int demux_thread_running; xprintf (stream->xine, XINE_VERBOSITY_DEBUG, "xine_play\n"); @@ -939,6 +956,7 @@ 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 @@ -966,8 +984,6 @@ 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) @@ -983,6 +999,8 @@ _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 ); @@ -995,8 +1013,10 @@ 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; + } } @@ -1064,7 +1084,7 @@ stream->status = XINE_STATUS_QUIT; xine_close(stream); - + if( stream->master != stream ) { stream->master->slave = NULL; } @@ -1077,12 +1097,12 @@ 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->frontend_lock); pthread_mutex_destroy (&stream->counter_lock); Index: post/goom/xine_goom.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/post/goom/xine_goom.c,v retrieving revision 1.41 diff -u -r1.41 xine_goom.c --- post/goom/xine_goom.c 16 Nov 2003 12:18:59 -0000 1.41 +++ post/goom/xine_goom.c 16 Nov 2003 17:58:36 -0000 @@ -259,7 +259,7 @@ 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"); Index: post/visualizations/fftgraph.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/post/visualizations/fftgraph.c,v retrieving revision 1.5 diff -u -r1.5 fftgraph.c --- post/visualizations/fftgraph.c 16 Nov 2003 12:18:59 -0000 1.5 +++ post/visualizations/fftgraph.c 16 Nov 2003 17:58:37 -0000 @@ -467,7 +467,7 @@ 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; Index: post/visualizations/fftscope.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/post/visualizations/fftscope.c,v retrieving revision 1.19 diff -u -r1.19 fftscope.c --- post/visualizations/fftscope.c 16 Nov 2003 12:18:59 -0000 1.19 +++ post/visualizations/fftscope.c 16 Nov 2003 17:58:37 -0000 @@ -506,7 +506,7 @@ 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; Index: post/visualizations/fooviz.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/post/visualizations/fooviz.c,v retrieving revision 1.14 diff -u -r1.14 fooviz.c --- post/visualizations/fooviz.c 16 Nov 2003 12:18:59 -0000 1.14 +++ post/visualizations/fooviz.c 16 Nov 2003 17:58:37 -0000 @@ -303,7 +303,7 @@ 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; Index: post/visualizations/oscope.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/post/visualizations/oscope.c,v retrieving revision 1.12 diff -u -r1.12 oscope.c --- post/visualizations/oscope.c 16 Nov 2003 12:18:59 -0000 1.12 +++ post/visualizations/oscope.c 16 Nov 2003 17:58:37 -0000 @@ -373,7 +373,7 @@ 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;