From 7505ad157b1bc5b912430537e4aba444c1c23662 Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Mon, 28 Oct 2002 03:24:42 +0000 Subject: hey, i want to join xine breakage party! (what do you wanna break today? tm) - time to cleanup demuxer mess... no more pthread stuff on any demuxer. of course i haven't tested all demuxers, but they at least compile. (sorry Mike, we will need to move a few variables around to make most of your demuxers work again - not big deal i think) - make api more consistent by providing xine_open/xine_close and xine_start/xine_stop. CVS patchset: 3058 CVS date: 2002/10/28 03:24:42 --- src/demuxers/Makefile.am | 2 +- src/demuxers/demux.h | 39 +-- src/demuxers/demux_aiff.c | 207 ++++------------ src/demuxers/demux_asf.c | 182 +++----------- src/demuxers/demux_avi.c | 134 +---------- src/demuxers/demux_cda.c | 130 +--------- src/demuxers/demux_elem.c | 121 +--------- src/demuxers/demux_film.c | 512 ++++++++++++++++------------------------ src/demuxers/demux_fli.c | 214 +++++------------ src/demuxers/demux_idcin.c | 337 +++++++++----------------- src/demuxers/demux_mpeg.c | 123 +--------- src/demuxers/demux_mpeg_block.c | 128 +--------- src/demuxers/demux_mpgaudio.c | 157 ++---------- src/demuxers/demux_ogg.c | 150 +----------- src/demuxers/demux_qt.c | 369 ++++++++++------------------- src/demuxers/demux_real.c | 217 +++++------------ src/demuxers/demux_realaudio.c | 206 ++++------------ src/demuxers/demux_roq.c | 309 +++++++++--------------- src/demuxers/demux_smjpeg.c | 266 +++++++-------------- src/demuxers/demux_snd.c | 210 ++++------------ src/demuxers/demux_voc.c | 210 ++++------------ src/demuxers/demux_vqa.c | 261 +++++++------------- src/demuxers/demux_wav.c | 207 ++++------------ src/demuxers/demux_wc3movie.c | 379 +++++++++++------------------ src/demuxers/demux_yuv4mpeg2.c | 213 +++++------------ src/xine-engine/demux.c | 123 ++++++++++ src/xine-engine/xine.c | 73 ++++-- src/xine-engine/xine_internal.h | 9 +- 28 files changed, 1576 insertions(+), 3912 deletions(-) (limited to 'src') diff --git a/src/demuxers/Makefile.am b/src/demuxers/Makefile.am index 57ebba430..825ea8f20 100644 --- a/src/demuxers/Makefile.am +++ b/src/demuxers/Makefile.am @@ -56,7 +56,7 @@ lib_LTLIBRARIES = $(ogg_module) $(asf_module) xineplug_dmx_avi.la\ xineplug_dmx_yuv4mpeg2.la \ xineplug_dmx_real.la \ xineplug_dmx_realaudio.la - + xineplug_dmx_ogg_la_SOURCES = demux_ogg.c xineplug_dmx_ogg_la_LIBADD = $(OGG_LIBS) $(VORBIS_LIBS)\ $(top_builddir)/src/xine-engine/libxine.la diff --git a/src/demuxers/demux.h b/src/demuxers/demux.h index c5c74896e..952b1d502 100644 --- a/src/demuxers/demux.h +++ b/src/demuxers/demux.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: demux.h,v 1.21 2002/10/17 17:43:42 mroi Exp $ + * $Id: demux.h,v 1.22 2002/10/28 03:24:43 miguelfreitas Exp $ */ #ifndef HAVE_DEMUX_H @@ -31,7 +31,7 @@ #include "input_plugin.h" #endif -#define DEMUXER_PLUGIN_IFACE_VERSION 14 +#define DEMUXER_PLUGIN_IFACE_VERSION 15 #define DEMUX_OK 0 #define DEMUX_FINISHED 1 @@ -99,24 +99,7 @@ struct demux_plugin_s { void (*send_headers) (demux_plugin_t *this); /* - * start demux thread - * - * for seekable streams, a start position can be specified - * - * start_pos : position in input source - * start_time : position measured in seconds from stream start - * - * if both parameters are !=0 start_pos will be used - * for non-seekable streams both values will be ignored - * - * returns the demux status (like get_status, but immediately after - * starting the demuxer) - */ - - int (*start) (demux_plugin_t *this, off_t start_pos, int start_time); - - /* - * ask running demux thread to seek + * ask demux to seek * * for seekable streams, a start position can be specified * @@ -132,17 +115,21 @@ struct demux_plugin_s { int (*seek) (demux_plugin_t *this, off_t start_pos, int start_time); - + /* - * stop & kill demux thread + * send a chunk of data down to decoder fifos * - * keep plugin ready for restart + * the meaning of "chunk" is specific to every demux, usually + * it involves parsing one unit of data from stream. + * + * this function will be called from demux loop and should return + * the demux current status */ - void (*stop) (demux_plugin_t *this) ; - + int (*send_chunk) (demux_plugin_t *this); + /* - * stop & kill demux thread, free resources + * free resources */ void (*dispose) (demux_plugin_t *this) ; diff --git a/src/demuxers/demux_aiff.c b/src/demuxers/demux_aiff.c index e1881e437..9a8ae2ad6 100644 --- a/src/demuxers/demux_aiff.c +++ b/src/demuxers/demux_aiff.c @@ -19,7 +19,7 @@ * * AIFF File Demuxer by Mike Melanson (melanson@pcisys.net) * - * $Id: demux_aiff.c,v 1.13 2002/10/27 16:14:22 tmmm Exp $ + * $Id: demux_aiff.c,v 1.14 2002/10/28 03:24:43 miguelfreitas Exp $ * */ @@ -30,8 +30,6 @@ #include #include #include -#include -#include #include #include #include @@ -71,10 +69,6 @@ typedef struct { input_plugin_t *input; - pthread_t thread; - int thread_running; - pthread_mutex_t mutex; - int send_end_buffers; int status; unsigned int audio_type; @@ -138,7 +132,6 @@ static int open_aiff_file(demux_aiff_t *this) { if (this->input->read(this->input, preamble, PREAMBLE_SIZE) != PREAMBLE_SIZE) { this->status = DEMUX_FINISHED; - pthread_mutex_lock(&this->mutex); return DEMUX_CANNOT_HANDLE; } chunk_type = BE_32(&preamble[0]); @@ -148,7 +141,6 @@ static int open_aiff_file(demux_aiff_t *this) { if (this->input->read(this->input, buffer, chunk_size) != chunk_size) { this->status = DEMUX_FINISHED; - pthread_mutex_lock(&this->mutex); return DEMUX_CANNOT_HANDLE; } @@ -187,7 +179,7 @@ static int open_aiff_file(demux_aiff_t *this) { return 1; } -static void *demux_aiff_loop (void *this_gen) { +static int demux_aiff_send_chunk (demux_plugin_t *this_gen) { demux_aiff_t *this = (demux_aiff_t *) this_gen; buf_element_t *buf = NULL; @@ -195,89 +187,49 @@ static void *demux_aiff_loop (void *this_gen) { off_t current_file_pos; int64_t current_pts; - pthread_mutex_lock( &this->mutex ); - this->seek_flag = 1; + /* just load data chunks from wherever the stream happens to be + * pointing; issue a DEMUX_FINISHED status if EOF is reached */ + remaining_sample_bytes = this->audio_block_align; + current_file_pos = + this->input->get_current_pos(this->input) - this->data_start; - /* do-while needed to seek after demux finished */ - do { - /* main demuxer loop */ - while (this->status == DEMUX_OK) { - - /* someone may want to interrupt us */ - pthread_mutex_unlock( &this->mutex ); - /* give demux_*_stop a chance to interrupt us */ - sched_yield(); - pthread_mutex_lock( &this->mutex ); - - /* just load data chunks from wherever the stream happens to be - * pointing; issue a DEMUX_FINISHED status if EOF is reached */ - remaining_sample_bytes = this->audio_block_align; - current_file_pos = - this->input->get_current_pos(this->input) - this->data_start; - - current_pts = current_file_pos; - current_pts *= 90000; - current_pts /= this->audio_bytes_per_second; - - if (this->seek_flag) { - xine_demux_control_newpts(this->stream, current_pts, 0); - this->seek_flag = 0; - } + current_pts = current_file_pos; + current_pts *= 90000; + current_pts /= this->audio_bytes_per_second; - while (remaining_sample_bytes) { - buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); - buf->type = this->audio_type; - buf->input_pos = current_file_pos; - buf->input_length = this->data_size; - buf->input_time = current_pts / 90000; - buf->pts = current_pts; - - if (remaining_sample_bytes > buf->max_size) - buf->size = buf->max_size; - else - buf->size = remaining_sample_bytes; - remaining_sample_bytes -= buf->size; - - if (this->input->read(this->input, buf->content, buf->size) != - buf->size) { - buf->free_buffer(buf); - this->status = DEMUX_FINISHED; - break; - } - - if (!remaining_sample_bytes) - buf->decoder_flags |= BUF_FLAG_FRAME_END; - - this->audio_fifo->put (this->audio_fifo, buf); - } - } + if (this->seek_flag) { + xine_demux_control_newpts(this->stream, current_pts, 0); + this->seek_flag = 0; + } - /* wait before sending end buffers: user might want to do a new seek */ - while(this->send_end_buffers && this->audio_fifo->size(this->audio_fifo) && - this->status != DEMUX_OK){ - pthread_mutex_unlock( &this->mutex ); - xine_usec_sleep(100000); - pthread_mutex_lock( &this->mutex ); + while (remaining_sample_bytes) { + buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); + buf->type = this->audio_type; + buf->input_pos = current_file_pos; + buf->input_length = this->data_size; + buf->input_time = current_pts / 90000; + buf->pts = current_pts; + + if (remaining_sample_bytes > buf->max_size) + buf->size = buf->max_size; + else + buf->size = remaining_sample_bytes; + remaining_sample_bytes -= buf->size; + + if (this->input->read(this->input, buf->content, buf->size) != + buf->size) { + buf->free_buffer(buf); + this->status = DEMUX_FINISHED; + break; } - } while (this->status == DEMUX_OK); - - printf ("demux_aiff: demux loop finished (status: %d)\n", - this->status); - - /* seek back to the beginning of the data in preparation for another - * start */ - this->input->seek(this->input, this->data_start, SEEK_SET); - - this->status = DEMUX_FINISHED; + if (!remaining_sample_bytes) + buf->decoder_flags |= BUF_FLAG_FRAME_END; - if (this->send_end_buffers) { - xine_demux_control_end(this->stream, BUF_FLAG_END_STREAM); + this->audio_fifo->put (this->audio_fifo, buf); } - - this->thread_running = 0; - pthread_mutex_unlock(&this->mutex); - return NULL; + + return this->status; } static void demux_aiff_send_headers(demux_plugin_t *this_gen) { @@ -285,8 +237,6 @@ static void demux_aiff_send_headers(demux_plugin_t *this_gen) { demux_aiff_t *this = (demux_aiff_t *) this_gen; buf_element_t *buf; - pthread_mutex_lock(&this->mutex); - this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; @@ -319,57 +269,19 @@ static void demux_aiff_send_headers(demux_plugin_t *this_gen) { } xine_demux_control_headers_done (this->stream); - - pthread_mutex_unlock (&this->mutex); -} - -static int demux_aiff_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time); - -static int demux_aiff_start (demux_plugin_t *this_gen, - off_t start_pos, int start_time) { - - demux_aiff_t *this = (demux_aiff_t *) this_gen; - int err; - - demux_aiff_seek(this_gen, start_pos, start_time); - - pthread_mutex_lock(&this->mutex); - - /* if thread is not running, initialize demuxer */ - if (!this->thread_running) { - - this->status = DEMUX_OK; - this->send_end_buffers = 1; - this->thread_running = 1; - - if ((err = pthread_create (&this->thread, NULL, demux_aiff_loop, this)) != 0) { - printf ("demux_aiff: can't create new thread (%s)\n", strerror(err)); - abort(); - } - } - - pthread_mutex_unlock(&this->mutex); - - return DEMUX_OK; } static int demux_aiff_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time) { demux_aiff_t *this = (demux_aiff_t *) this_gen; - int status; - - pthread_mutex_lock(&this->mutex); /* check the boundary offsets */ if (start_pos < 0) this->input->seek(this->input, this->data_start, SEEK_SET); else if (start_pos >= this->data_size) { this->status = DEMUX_FINISHED; - status = this->status; - pthread_mutex_unlock(&this->mutex); - return status; + return this->status; } else { /* This function must seek along the block alignment. The start_pos * is in reference to the start of the data. Divide the start_pos by @@ -384,46 +296,15 @@ static int demux_aiff_seek (demux_plugin_t *this_gen, } this->seek_flag = 1; - status = this->status = DEMUX_OK; + this->status = DEMUX_OK; xine_demux_flush_engine (this->stream); - pthread_mutex_unlock(&this->mutex); - - return status; -} - -static void demux_aiff_stop (demux_plugin_t *this_gen) { - demux_aiff_t *this = (demux_aiff_t *) this_gen; - void *p; - - pthread_mutex_lock( &this->mutex ); - - if (!this->thread_running) { - pthread_mutex_unlock( &this->mutex ); - return; - } - - /* seek back to the beginning of the data in preparation for another - * start */ - this->input->seek(this->input, this->data_start, SEEK_SET); - - this->send_end_buffers = 0; - this->status = DEMUX_FINISHED; - - pthread_mutex_unlock( &this->mutex ); - pthread_join (this->thread, &p); - - xine_demux_flush_engine(this->stream); - - xine_demux_control_end(this->stream, BUF_FLAG_END_USER); + return this->status; } static void demux_aiff_dispose (demux_plugin_t *this_gen) { demux_aiff_t *this = (demux_aiff_t *) this_gen; - demux_aiff_stop(this_gen); - - pthread_mutex_destroy (&this->mutex); free(this); } @@ -457,16 +338,14 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->input = input; this->demux_plugin.send_headers = demux_aiff_send_headers; - this->demux_plugin.start = demux_aiff_start; + this->demux_plugin.send_chunk = demux_aiff_send_chunk; this->demux_plugin.seek = demux_aiff_seek; - this->demux_plugin.stop = demux_aiff_stop; this->demux_plugin.dispose = demux_aiff_dispose; this->demux_plugin.get_status = demux_aiff_get_status; this->demux_plugin.get_stream_length = demux_aiff_get_stream_length; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; - pthread_mutex_init (&this->mutex, NULL); switch (stream->content_detection_method) { @@ -574,6 +453,6 @@ static void *init_plugin (xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 14, "aiff", XINE_VERSION_CODE, NULL, init_plugin }, + { PLUGIN_DEMUX, 15, "aiff", XINE_VERSION_CODE, NULL, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/demuxers/demux_asf.c b/src/demuxers/demux_asf.c index 7e436c270..8deb0090d 100644 --- a/src/demuxers/demux_asf.c +++ b/src/demuxers/demux_asf.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: demux_asf.c,v 1.72 2002/10/27 23:01:40 guenter Exp $ + * $Id: demux_asf.c,v 1.73 2002/10/28 03:24:43 miguelfreitas Exp $ * * demultiplexer for asf streams * @@ -33,8 +33,6 @@ #include #include #include -#include -#include #include #include @@ -124,14 +122,8 @@ typedef struct demux_asf_s { int segtype; int frame; - pthread_t thread; - int thread_running; - pthread_mutex_t mutex; - int status; - int send_end_buffers; - int send_discontinuity; /* byte reordering from audio streams */ @@ -1116,98 +1108,28 @@ static void asf_read_packet(demux_asf_t *this) { * xine specific functions start here */ -static void *demux_asf_loop (void *this_gen) { - - demux_asf_t *this = (demux_asf_t *) this_gen; - - printf ("demux_asf: demux loop starting...\n"); - - pthread_mutex_lock( &this->mutex ); - /* do-while needed to seek after demux finished */ - do { - - /* main demuxer loop */ - while(this->status == DEMUX_OK) { - - asf_read_packet (this); - - /* someone may want to interrupt us */ - pthread_mutex_unlock( &this->mutex ); - /* give demux_*_stop a chance to interrupt us */ - sched_yield(); - pthread_mutex_lock( &this->mutex ); - } - - /* wait before sending end buffers: user might want to do a new seek */ - while(this->send_end_buffers && this->video_fifo->size(this->video_fifo) && - this->status != DEMUX_OK){ - pthread_mutex_unlock( &this->mutex ); - xine_usec_sleep(100000); - pthread_mutex_lock( &this->mutex ); - } - - } while( this->status == DEMUX_OK ); - - - /* - printf ("demux_asf: demux loop finished (status: %d)\n", - this->status); - */ - - this->status = DEMUX_FINISHED; +static int demux_asf_send_chunk (demux_plugin_t *this_gen) { - if (this->send_end_buffers) { - xine_demux_control_end(this->stream, BUF_FLAG_END_STREAM); - } - - this->thread_running = 0; - pthread_mutex_unlock( &this->mutex ); + demux_asf_t *this = (demux_asf_t *) this_gen; - pthread_exit(NULL); + asf_read_packet (this); - return NULL; + return this->status; } -static void demux_asf_stop (demux_plugin_t *this_gen) { +static void demux_asf_dispose (demux_plugin_t *this_gen) { demux_asf_t *this = (demux_asf_t *) this_gen; int i; - void *p; - - pthread_mutex_lock( &this->mutex ); - - if (!this->thread_running) { - printf ("demux_asf: stop...ignored\n"); - pthread_mutex_unlock( &this->mutex ); - return; - } - - this->send_end_buffers = 0; - this->status = DEMUX_FINISHED; - - pthread_mutex_unlock( &this->mutex ); - pthread_join (this->thread, &p); - - xine_demux_flush_engine(this->stream); - - xine_demux_control_end(this->stream, BUF_FLAG_END_USER); - + for (i=0; inum_streams; i++) { if( this->streams[i].buffer ) { free( this->streams[i].buffer ); this->streams[i].buffer = NULL; } } -} - -static void demux_asf_dispose (demux_plugin_t *this_gen) { - - demux_asf_t *this = (demux_asf_t *) this_gen; - - demux_asf_stop (this_gen); free (this); - } static int demux_asf_get_status (demux_plugin_t *this_gen) { @@ -1224,8 +1146,6 @@ static void demux_asf_send_headers (demux_plugin_t *this_gen) { uint32_t buf_type, max_vrate, max_arate, sum_rate; uint32_t bitrate = 0; - pthread_mutex_lock (&this->mutex); - this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; @@ -1258,7 +1178,6 @@ static void demux_asf_send_headers (demux_plugin_t *this_gen) { printf ("demux_asf: asf_read_header failed.\n"); this->status = DEMUX_FINISHED; - pthread_mutex_unlock (&this->mutex); return; } else { @@ -1323,87 +1242,48 @@ static void demux_asf_send_headers (demux_plugin_t *this_gen) { } xine_demux_control_headers_done (this->stream); - - pthread_mutex_unlock (&this->mutex); } -static int demux_asf_start (demux_plugin_t *this_gen, +static int demux_asf_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time) { demux_asf_t *this = (demux_asf_t *) this_gen; - int err; - int status; - - pthread_mutex_lock( &this->mutex ); this->status = DEMUX_OK; - if (!this->thread_running) { - xine_demux_flush_engine(this->stream); - } - - if( this->status == DEMUX_OK ) { - /* - * seek to start position - */ - this->send_discontinuity = 2; - this->last_video_pts = 0; - this->keyframe_found = (this->num_video_streams==0); - - if (this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) { + xine_demux_flush_engine(this->stream); - if ( (!start_pos) && (start_time)) - start_pos = start_time * this->rate; + /* + * seek to start position + */ + this->send_discontinuity = 2; + this->last_video_pts = 0; + this->keyframe_found = (this->num_video_streams==0); - if (start_pos < this->header_size) - start_pos = this->header_size; + if (this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) { - this->input->seek (this->input, start_pos, SEEK_SET); - } + if ( (!start_pos) && (start_time)) + start_pos = start_time * this->rate; - /* - * now start demuxing - */ + if (start_pos < this->header_size) + start_pos = this->header_size; - if( !this->thread_running ) { - this->send_end_buffers = 1; - this->thread_running = 1; - this->buf_flag_seek = 0; - if ((err = pthread_create (&this->thread, - NULL, demux_asf_loop, this)) != 0) { - printf ("demux_asf: can't create new thread (%s)\n", - strerror(err)); - abort(); - } - } else { - this->buf_flag_seek = 1; - } + this->input->seek (this->input, start_pos, SEEK_SET); } - /* this->status is saved because we can be interrupted between - * pthread_mutex_unlock and return + /* + * now start demuxing */ - status = this->status; - pthread_mutex_unlock( &this->mutex ); - return status; -/* - if( !starting && this->status != DEMUX_OK ) { - void *p; - pthread_join (this->thread, &p); + if( !this->stream->demux_thread_running ) { + this->buf_flag_seek = 0; + } else { + this->buf_flag_seek = 1; } -*/ - -} -static int demux_asf_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time) { - /* demux_asf_t *this = (demux_asf_t *) this_gen; */ - - return demux_asf_start (this_gen, start_pos, start_time); + return this->status; } - static int demux_asf_get_stream_length (demux_plugin_t *this_gen) { demux_asf_t *this = (demux_asf_t *) this_gen; @@ -1480,16 +1360,14 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, this->input = input; this->demux_plugin.send_headers = demux_asf_send_headers; - this->demux_plugin.start = demux_asf_start; + this->demux_plugin.send_chunk = demux_asf_send_chunk; this->demux_plugin.seek = demux_asf_seek; - this->demux_plugin.stop = demux_asf_stop; this->demux_plugin.dispose = demux_asf_dispose; this->demux_plugin.get_status = demux_asf_get_status; this->demux_plugin.get_stream_length = demux_asf_get_stream_length; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; - pthread_mutex_init( &this->mutex, NULL ); return &this->demux_plugin; } @@ -1543,6 +1421,6 @@ static void *init_class (xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 14, "asf", XINE_VERSION_CODE, NULL, init_class }, + { PLUGIN_DEMUX, 15, "asf", XINE_VERSION_CODE, NULL, init_class }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/demuxers/demux_avi.c b/src/demuxers/demux_avi.c index 24e3d8be0..10f762aaa 100644 --- a/src/demuxers/demux_avi.c +++ b/src/demuxers/demux_avi.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: demux_avi.c,v 1.129 2002/10/26 22:50:52 guenter Exp $ + * $Id: demux_avi.c,v 1.130 2002/10/28 03:24:43 miguelfreitas Exp $ * * demultiplexer for avi streams * @@ -55,8 +55,6 @@ #include #include #include -#include -#include #include #include @@ -182,10 +180,6 @@ typedef struct demux_avi_s { avi_t *avi; - pthread_t thread; - int thread_running; - pthread_mutex_t mutex; - int status; int no_audio; @@ -194,8 +188,6 @@ typedef struct demux_avi_s { uint32_t video_step; uint32_t AVI_errno; - int send_end_buffers; - char last_mrl[1024]; idx_grow_t idx_grow; @@ -395,8 +387,6 @@ static long start_time_stopper(demux_avi_t *this, void *data) return -1; } -static void demux_avi_stop (demux_plugin_t *this_gen); - /* This is called periodically to check if there's more file now than * there was before. If there is, we constuct the index for (just) the * new part, and append it to the index we've got so far. We stop @@ -1150,84 +1140,20 @@ static int demux_avi_next (demux_avi_t *this, int decoder_flags) { } } -static void *demux_avi_loop (void *this_gen) { - demux_avi_t *this = (demux_avi_t *) this_gen; - - pthread_mutex_lock( &this->mutex ); - /* do-while needed to seek after demux finished */ - do { - - /* main demuxer loop */ - while(this->status == DEMUX_OK) { - - if (!demux_avi_next (this, 0)) { - this->status = DEMUX_FINISHED; - } - - /* someone may want to interrupt us */ - pthread_mutex_unlock( &this->mutex ); - /* give demux_*_stop a chance to interrupt us */ - sched_yield(); - pthread_mutex_lock( &this->mutex ); - } - - /* wait before sending end buffers: user might want to do a new seek */ - while(this->send_end_buffers && this->video_fifo->size(this->video_fifo) && - this->status != DEMUX_OK){ - pthread_mutex_unlock( &this->mutex ); - xine_usec_sleep(100000); - pthread_mutex_lock( &this->mutex ); - } - - } while( this->status == DEMUX_OK ); - - if (this->send_end_buffers) { - xine_demux_control_end (this->stream, BUF_FLAG_END_STREAM); - } - - printf ("demux_avi: demux loop finished.\n"); - - this->thread_running = 0; - pthread_mutex_unlock (&this->mutex); - - pthread_exit(NULL); - - return NULL; -} - -static void demux_avi_stop (demux_plugin_t *this_gen) { +static int demux_avi_send_chunk (demux_plugin_t *this_gen) { demux_avi_t *this = (demux_avi_t *) this_gen; - void *p; - - pthread_mutex_lock (&this->mutex); - if (!this->thread_running) { - printf ("demux_avi: stop...ignored\n"); - pthread_mutex_unlock (&this->mutex); - return; + if (!demux_avi_next (this, 0)) { + this->status = DEMUX_FINISHED; } - this->send_end_buffers = 0; - this->status = DEMUX_FINISHED; - - pthread_mutex_unlock (&this->mutex); - pthread_join (this->thread, &p); - - xine_demux_flush_engine (this->stream); - /* - AVI_close (this->avi); - this->avi = NULL; - */ - - xine_demux_control_end (this->stream, BUF_FLAG_END_USER); + return this->status; } static void demux_avi_dispose (demux_plugin_t *this_gen) { demux_avi_t *this = (demux_avi_t *) this_gen; - demux_avi_stop(this_gen); - if (this->avi) AVI_close (this->avi); @@ -1245,8 +1171,6 @@ static void demux_avi_send_headers (demux_plugin_t *this_gen) { demux_avi_t *this = (demux_avi_t *) this_gen; int i; - pthread_mutex_lock (&this->mutex); - this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; @@ -1281,7 +1205,7 @@ static void demux_avi_send_headers (demux_plugin_t *this_gen) { * send start/header buffers */ - if (!this->thread_running) { + if (!this->stream->demux_thread_running) { buf_element_t *buf; int i; @@ -1368,8 +1292,6 @@ static void demux_avi_send_headers (demux_plugin_t *this_gen) { } else this->have_spu = 0; - - this->send_end_buffers = 1; } /* @@ -1386,22 +1308,16 @@ static void demux_avi_send_headers (demux_plugin_t *this_gen) { } xine_demux_control_headers_done (this->stream); - - pthread_mutex_unlock (&this->mutex); } -static int demux_avi_start (demux_plugin_t *this_gen, +static int demux_avi_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time) { demux_avi_t *this = (demux_avi_t *) this_gen; int64_t video_pts = 0, max_pos, min_pos = 0, cur_pos; - int err; video_index_entry_t *vie = NULL; - int status; int64_t audio_pts; - pthread_mutex_lock( &this->mutex ); - AVI_seek_start (this->avi); /* @@ -1535,36 +1451,12 @@ static int demux_avi_start (demux_plugin_t *this_gen, } } - if (this->thread_running) - xine_demux_flush_engine (this->stream); + xine_demux_flush_engine (this->stream); if (this->status == DEMUX_OK) xine_demux_control_newpts (this->stream, video_pts, BUF_FLAG_SEEK); - if (!this->thread_running) { - - this->thread_running = 1; - if ((err = pthread_create (&this->thread, NULL, demux_avi_loop, this)) != 0) { - printf ("demux_avi: can't create new thread (%s)\n", - strerror(err)); - abort(); - } - } - - /* this->status is saved because we can be interrupted between - * pthread_mutex_unlock and return - */ - status = this->status; - pthread_mutex_unlock( &this->mutex ); - return status; -} - - -static int demux_avi_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time) { - /* demux_avi_t *this = (demux_avi_t *) this_gen; */ - - return demux_avi_start (this_gen, start_pos, start_time); + return this->status; } static int demux_avi_get_stream_length (demux_plugin_t *this_gen) { @@ -1594,17 +1486,15 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->input = input; this->demux_plugin.send_headers = demux_avi_send_headers; - this->demux_plugin.start = demux_avi_start; + this->demux_plugin.send_chunk = demux_avi_send_chunk; this->demux_plugin.seek = demux_avi_seek; - this->demux_plugin.stop = demux_avi_stop; this->demux_plugin.dispose = demux_avi_dispose; this->demux_plugin.get_status = demux_avi_get_status; this->demux_plugin.get_stream_length = demux_avi_get_stream_length; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; - pthread_mutex_init (&this->mutex, NULL); - + switch (stream->content_detection_method) { case METHOD_BY_CONTENT: @@ -1719,6 +1609,6 @@ static void *init_class (xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 14, "avi", XINE_VERSION_CODE, NULL, init_class }, + { PLUGIN_DEMUX, 15, "avi", XINE_VERSION_CODE, NULL, init_class }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/demuxers/demux_cda.c b/src/demuxers/demux_cda.c index 35c28fe21..655f51371 100644 --- a/src/demuxers/demux_cda.c +++ b/src/demuxers/demux_cda.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: demux_cda.c,v 1.29 2002/10/27 16:14:22 tmmm Exp $ + * $Id: demux_cda.c,v 1.30 2002/10/28 03:24:43 miguelfreitas Exp $ */ #ifdef HAVE_CONFIG_H @@ -27,8 +27,6 @@ #include #include #include -#include -#include #include #include @@ -50,14 +48,9 @@ typedef struct { input_plugin_t *input; - pthread_t thread; - int thread_running; - pthread_mutex_t mutex; - off_t start; int status; - int send_end_buffers; int blocksize; char last_mrl[1024]; @@ -98,127 +91,34 @@ static int demux_cda_next (demux_cda_t *this) { /* * */ -static void *demux_cda_loop (void *this_gen) { +static int demux_cda_send_chunk (demux_plugin_t *this_gen) { demux_cda_t *this = (demux_cda_t *) this_gen; - pthread_mutex_lock( &this->mutex ); - /* do-while needed to seek after demux finished */ - do { - - /* main demuxer loop */ - while(this->status == DEMUX_OK) { - - xine_usec_sleep(100000); - if (!demux_cda_next(this)) - this->status = DEMUX_FINISHED; - - /* someone may want to interrupt us */ - pthread_mutex_unlock( &this->mutex ); - /* give demux_*_stop a chance to interrupt us */ - sched_yield(); - pthread_mutex_lock( &this->mutex ); - } - - /* wait before sending end buffers: user might want to do a new seek */ - while(this->send_end_buffers && this->audio_fifo->size(this->audio_fifo) && - this->status != DEMUX_OK){ - pthread_mutex_unlock( &this->mutex ); - xine_usec_sleep(100000); - pthread_mutex_lock( &this->mutex ); - } - - } while( this->status == DEMUX_OK ); - - this->status = DEMUX_FINISHED; - - if (this->send_end_buffers) { - xine_demux_control_end(this->stream, BUF_FLAG_END_STREAM); - } - - this->thread_running = 0; - pthread_mutex_unlock( &this->mutex ); + if (!demux_cda_next(this)) + this->status = DEMUX_FINISHED; - pthread_exit(NULL); -} - -/* - * - */ -static void demux_cda_stop (demux_plugin_t *this_gen) { - demux_cda_t *this = (demux_cda_t *) this_gen; - void *p; - - pthread_mutex_lock( &this->mutex ); - - if (!this->thread_running) { - printf ("demux_cda: stop...ignored\n"); - return; - } - - /* Force stop */ -/* this->input->stop(this->input);*/ - - this->send_end_buffers = 0; - this->status = DEMUX_FINISHED; - - pthread_mutex_unlock( &this->mutex ); - pthread_join (this->thread, &p); - - xine_demux_flush_engine(this->stream); - - xine_demux_control_end(this->stream, BUF_FLAG_END_USER); + return this->status; } /* * */ -static int demux_cda_start (demux_plugin_t *this_gen, +static int demux_cda_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time) { demux_cda_t *this = (demux_cda_t *) this_gen; - int err; - int status; - - pthread_mutex_lock( &this->mutex ); this->start = start_pos; this->blocksize = this->input->get_blocksize(this->input); - if( !this->thread_running ) { - xine_demux_control_start(this->stream); - } - /* * now start demuxing */ this->input->seek(this->input, this->start, SEEK_SET); - if( !this->thread_running ) { - - this->status = DEMUX_OK; - this->send_end_buffers = 1; - this->thread_running = 1; - if ((err = pthread_create (&this->thread, - NULL, demux_cda_loop, this)) != 0) { - printf ("demux_cda: can't create new thread (%s)\n", strerror(err)); - abort(); - } - } - - /* this->status is saved because we can be interrupted between - * pthread_mutex_unlock and return - */ - status = this->status; - pthread_mutex_unlock( &this->mutex ); - return status; -} - - -static int demux_cda_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time) { - - return demux_cda_start (this_gen, - start_pos, start_time); + this->status = DEMUX_OK; + + return this->status; } /* @@ -228,12 +128,12 @@ static void demux_cda_send_headers(demux_plugin_t *this_gen) { demux_cda_t *this = (demux_cda_t *) this_gen; - pthread_mutex_lock(&this->mutex); - this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; + + xine_demux_control_start(this->stream); /* hardwired stream information */ this->stream->stream_info[XINE_STREAM_INFO_HAS_VIDEO] = 0; @@ -243,8 +143,6 @@ static void demux_cda_send_headers(demux_plugin_t *this_gen) { this->stream->stream_info[XINE_STREAM_INFO_AUDIO_BITS] = 16; xine_demux_control_headers_done (this->stream); - - pthread_mutex_unlock (&this->mutex); } /* @@ -287,16 +185,14 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->input = input; this->demux_plugin.send_headers = demux_cda_send_headers; - this->demux_plugin.start = demux_cda_start; + this->demux_plugin.send_chunk = demux_cda_send_chunk; this->demux_plugin.seek = demux_cda_seek; - this->demux_plugin.stop = demux_cda_stop; this->demux_plugin.dispose = demux_cda_dispose; this->demux_plugin.get_status = demux_cda_get_status; this->demux_plugin.get_stream_length = demux_cda_get_stream_length; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; - pthread_mutex_init (&this->mutex, NULL); switch (stream->content_detection_method) { @@ -378,6 +274,6 @@ static void *init_plugin (xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 14, "cda", XINE_VERSION_CODE, NULL, init_plugin }, + { PLUGIN_DEMUX, 15, "cda", XINE_VERSION_CODE, NULL, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/demuxers/demux_elem.c b/src/demuxers/demux_elem.c index 179148190..7f1b29ea6 100644 --- a/src/demuxers/demux_elem.c +++ b/src/demuxers/demux_elem.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: demux_elem.c,v 1.55 2002/10/27 04:14:27 tmmm Exp $ + * $Id: demux_elem.c,v 1.56 2002/10/28 03:24:43 miguelfreitas Exp $ * * demultiplexer for elementary mpeg streams * @@ -31,8 +31,6 @@ #include #include #include -#include -#include #include #include "xine_internal.h" @@ -55,15 +53,9 @@ typedef struct { input_plugin_t *input; - pthread_t thread; - int thread_running; - pthread_mutex_t mutex; - int blocksize; int status; - int send_end_buffers; - uint8_t scratch[4096]; char last_mrl[1024]; @@ -103,70 +95,13 @@ static int demux_mpeg_elem_next (demux_mpeg_elem_t *this, int preview_mode) { return (buf->size == this->blocksize); } -static void *demux_mpeg_elem_loop (void *this_gen) { - demux_mpeg_elem_t *this = (demux_mpeg_elem_t *) this_gen; - - pthread_mutex_lock( &this->mutex ); - /* do-while needed to seek after demux finished */ - do { - - /* main demuxer loop */ - while(this->status == DEMUX_OK) { - - if (!demux_mpeg_elem_next(this, 0)) - this->status = DEMUX_FINISHED; - - /* someone may want to interrupt us */ - pthread_mutex_unlock( &this->mutex ); - /* give demux_*_stop a chance to interrupt us */ - sched_yield(); - pthread_mutex_lock( &this->mutex ); - } - - /* wait before sending end buffers: user might want to do a new seek */ - while(this->send_end_buffers && this->video_fifo->size(this->video_fifo) && - this->status != DEMUX_OK){ - pthread_mutex_unlock( &this->mutex ); - xine_usec_sleep(100000); - pthread_mutex_lock( &this->mutex ); - } - - } while( this->status == DEMUX_OK ); - - this->status = DEMUX_FINISHED; - - if (this->send_end_buffers) { - xine_demux_control_end(this->stream, BUF_FLAG_END_STREAM); - } - - this->thread_running = 0; - pthread_mutex_unlock( &this->mutex ); - - pthread_exit(NULL); -} - -static void demux_mpeg_elem_stop (demux_plugin_t *this_gen) { +static int demux_mpeg_elem_send_chunk (demux_plugin_t *this_gen) { demux_mpeg_elem_t *this = (demux_mpeg_elem_t *) this_gen; - void *p; - - pthread_mutex_lock( &this->mutex ); - - if (!this->thread_running) { - printf ("demux_elem: stop...ignored\n"); - pthread_mutex_unlock( &this->mutex ); - return; - } - this->send_end_buffers = 0; - this->status = DEMUX_FINISHED; - - pthread_mutex_unlock( &this->mutex ); - pthread_join (this->thread, &p); - - xine_demux_flush_engine(this->stream); - - xine_demux_control_end(this->stream, BUF_FLAG_END_USER); + if (!demux_mpeg_elem_next(this, 0)) + this->status = DEMUX_FINISHED; + return this->status; } static int demux_mpeg_elem_get_status (demux_plugin_t *this_gen) { @@ -180,8 +115,6 @@ static void demux_mpeg_elem_send_headers (demux_plugin_t *this_gen) { demux_mpeg_elem_t *this = (demux_mpeg_elem_t *) this_gen; - pthread_mutex_lock (&this->mutex); - this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; @@ -204,24 +137,17 @@ static void demux_mpeg_elem_send_headers (demux_plugin_t *this_gen) { } xine_demux_control_headers_done (this->stream); - - pthread_mutex_unlock (&this->mutex); } -static int demux_mpeg_elem_start (demux_plugin_t *this_gen, +static int demux_mpeg_elem_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time) { demux_mpeg_elem_t *this = (demux_mpeg_elem_t *) this_gen; - int err; - int status; - - pthread_mutex_lock( &this->mutex ); - + this->status = DEMUX_OK; - if (this->thread_running) + if (this->stream->demux_thread_running) xine_demux_flush_engine(this->stream); - if ((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) { @@ -235,34 +161,11 @@ static int demux_mpeg_elem_start (demux_plugin_t *this_gen, */ this->status = DEMUX_OK; - if( !this->thread_running ) { - - this->send_end_buffers = 1; - this->thread_running = 1; - if ((err = pthread_create (&this->thread, - NULL, demux_mpeg_elem_loop, this)) != 0) { - printf ("demux_mpeg_elem: can't create new thread (%s)\n", - strerror(err)); - abort(); - } - } - /* this->status is saved because we can be interrupted between - * pthread_mutex_unlock and return - */ - status = this->status; - pthread_mutex_unlock( &this->mutex ); - return status; -} - -static int demux_mpeg_elem_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time) { - return demux_mpeg_elem_start (this_gen, start_pos, start_time); + return this->status; } static void demux_mpeg_elem_dispose (demux_plugin_t *this) { - demux_mpeg_elem_stop(this); - free (this); } @@ -286,16 +189,14 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->input = input; this->demux_plugin.send_headers = demux_mpeg_elem_send_headers; - this->demux_plugin.start = demux_mpeg_elem_start; + this->demux_plugin.send_chunk = demux_mpeg_elem_send_chunk; this->demux_plugin.seek = demux_mpeg_elem_seek; - this->demux_plugin.stop = demux_mpeg_elem_stop; this->demux_plugin.dispose = demux_mpeg_elem_dispose; this->demux_plugin.get_status = demux_mpeg_elem_get_status; this->demux_plugin.get_stream_length = demux_mpeg_elem_get_stream_length; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; - pthread_mutex_init (&this->mutex, NULL); switch (stream->content_detection_method) { @@ -413,6 +314,6 @@ static void *init_plugin (xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 14, "elem", XINE_VERSION_CODE, NULL, init_plugin }, + { PLUGIN_DEMUX, 15, "elem", XINE_VERSION_CODE, NULL, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/demuxers/demux_film.c b/src/demuxers/demux_film.c index 7ad7b2063..4994cac8e 100644 --- a/src/demuxers/demux_film.c +++ b/src/demuxers/demux_film.c @@ -21,7 +21,7 @@ * For more information on the FILM file format, visit: * http://www.pcisys.net/~melanson/codecs/ * - * $Id: demux_film.c,v 1.40 2002/10/27 18:48:40 tmmm Exp $ + * $Id: demux_film.c,v 1.41 2002/10/28 03:24:43 miguelfreitas Exp $ */ #ifdef HAVE_CONFIG_H @@ -31,8 +31,6 @@ #include #include #include -#include -#include #include #include @@ -72,11 +70,6 @@ typedef struct { input_plugin_t *input; - pthread_t thread; - int thread_running; - pthread_mutex_t mutex; - int send_end_buffers; - off_t data_start; off_t data_size; int status; @@ -275,7 +268,7 @@ static int open_film_file(demux_film_t *film) { return 1; } -static void *demux_film_loop (void *this_gen) { +static int demux_film_send_chunk(demux_plugin_t *this_gen) { demux_film_t *this = (demux_film_t *) this_gen; buf_element_t *buf = NULL; @@ -285,254 +278,219 @@ static void *demux_film_loop (void *this_gen) { unsigned int remaining_sample_bytes; int64_t frame_duration; - pthread_mutex_lock( &this->mutex ); - - /* do-while needed to seek after demux finished */ - do { - /* main demuxer loop */ - while (this->status == DEMUX_OK) { + i = this->current_sample; - /* someone may want to interrupt us */ - pthread_mutex_unlock( &this->mutex ); - /* give demux_*_stop a chance to interrupt us */ - sched_yield(); - pthread_mutex_lock( &this->mutex ); + /* if there is an incongruency between last and current sample, it + * must be time to send a new pts */ + if (this->last_sample + 1 != this->current_sample) { + /* send new pts */ + xine_demux_control_newpts(this->stream, this->sample_table[i].pts, + (this->sample_table[i].pts) ? BUF_FLAG_SEEK : 0); + } - i = this->current_sample; + this->last_sample = this->current_sample; + this->current_sample++; - /* if there is an incongruency between last and current sample, it - * must be time to send a new pts */ - if (this->last_sample + 1 != this->current_sample) { - /* send new pts */ - xine_demux_control_newpts(this->stream, this->sample_table[i].pts, - (this->sample_table[i].pts) ? BUF_FLAG_SEEK : 0); - } + /* check if all the samples have been sent */ + if (i >= this->sample_count) { + this->status = DEMUX_FINISHED; + return this->status; + } - this->last_sample = this->current_sample; - this->current_sample++; + /* check if we're only sending audio samples until the next keyframe */ + if ((this->waiting_for_keyframe) && + (this->sample_table[i].syncinfo1 != 0xFFFFFFFF)) { + if ((this->sample_table[i].syncinfo1 & 0x80000000) == 0) { + this->waiting_for_keyframe = 0; + } else { + /* move on to the next sample */ + return this->status; + } + } - /* check if all the samples have been sent */ - if (i >= this->sample_count) { - this->status = DEMUX_FINISHED; + if ((this->sample_table[i].syncinfo1 != 0xFFFFFFFF) && + (this->video_type == BUF_VIDEO_CINEPAK)) { + /* do a special song and dance when loading CVID data */ + if (this->version[0]) + cvid_chunk_size = this->sample_table[i].sample_size - 2; + else + cvid_chunk_size = this->sample_table[i].sample_size - 6; + + /* reset flag */ + fixed_cvid_header = 0; + + remaining_sample_bytes = cvid_chunk_size; + this->input->seek(this->input, this->sample_table[i].sample_offset, + SEEK_SET); + + /* frame duration is the pts diff between this video frame and + * the next video frame (so search for the next video frame) */ + frame_duration = 0; + j = i; + while (++j < this->sample_count) { + if (this->sample_table[j].syncinfo1 != 0xFFFFFFFF) { + frame_duration = + this->sample_table[j].pts - this->sample_table[i].pts; break; } + } - /* check if we're only sending audio samples until the next keyframe */ - if ((this->waiting_for_keyframe) && - (this->sample_table[i].syncinfo1 != 0xFFFFFFFF)) { - if ((this->sample_table[i].syncinfo1 & 0x80000000) == 0) { - this->waiting_for_keyframe = 0; - } else { - /* move on to the next sample */ - continue; - } - } + while (remaining_sample_bytes) { + buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); + buf->type = this->video_type; + buf->input_pos = + this->sample_table[i].sample_offset - this->data_start; + buf->input_length = this->data_size; + buf->input_time = this->sample_table[i].pts / 90000; + buf->pts = this->sample_table[i].pts; + + /* set the frame duration */ + buf->decoder_flags |= BUF_FLAG_FRAMERATE; + buf->decoder_info[0] = frame_duration; + + if (remaining_sample_bytes > buf->max_size) + buf->size = buf->max_size; + else + buf->size = remaining_sample_bytes; + remaining_sample_bytes -= buf->size; - if ((this->sample_table[i].syncinfo1 != 0xFFFFFFFF) && - (this->video_type == BUF_VIDEO_CINEPAK)) { - /* do a special song and dance when loading CVID data */ - if (this->version[0]) - cvid_chunk_size = this->sample_table[i].sample_size - 2; - else - cvid_chunk_size = this->sample_table[i].sample_size - 6; - - /* reset flag */ - fixed_cvid_header = 0; - - remaining_sample_bytes = cvid_chunk_size; - this->input->seek(this->input, this->sample_table[i].sample_offset, - SEEK_SET); - - /* frame duration is the pts diff between this video frame and - * the next video frame (so search for the next video frame) */ - frame_duration = 0; - j = i; - while (++j < this->sample_count) { - if (this->sample_table[j].syncinfo1 != 0xFFFFFFFF) { - frame_duration = - this->sample_table[j].pts - this->sample_table[i].pts; - break; - } + if (!fixed_cvid_header) { + if (this->input->read(this->input, buf->content, 10) != 10) { + this->status = DEMUX_FINISHED; + break; } - while (remaining_sample_bytes) { - buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); - buf->type = this->video_type; - buf->input_pos = - this->sample_table[i].sample_offset - this->data_start; - buf->input_length = this->data_size; - buf->input_time = this->sample_table[i].pts / 90000; - buf->pts = this->sample_table[i].pts; - - /* set the frame duration */ - buf->decoder_flags |= BUF_FLAG_FRAMERATE; - buf->decoder_info[0] = frame_duration; - - if (remaining_sample_bytes > buf->max_size) - buf->size = buf->max_size; - else - buf->size = remaining_sample_bytes; - remaining_sample_bytes -= buf->size; - - if (!fixed_cvid_header) { - if (this->input->read(this->input, buf->content, 10) != 10) { - this->status = DEMUX_FINISHED; - break; - } - - /* skip over the extra non-spec CVID bytes */ - this->input->seek(this->input, - this->sample_table[i].sample_size - cvid_chunk_size, SEEK_CUR); - - /* load the rest of the chunk */ - if (this->input->read(this->input, buf->content + 10, - buf->size - 10) != buf->size - 10) { - this->status = DEMUX_FINISHED; - break; - } - - /* adjust the length in the CVID data chunk */ - buf->content[1] = (cvid_chunk_size >> 16) & 0xFF; - buf->content[2] = (cvid_chunk_size >> 8) & 0xFF; - buf->content[3] = (cvid_chunk_size >> 0) & 0xFF; - - fixed_cvid_header = 1; - } else { - if (this->input->read(this->input, buf->content, buf->size) != - buf->size) { - this->status = DEMUX_FINISHED; - break; - } - } - - if ((this->sample_table[i].syncinfo1 & 0x80000000) == 0) - buf->decoder_flags |= BUF_FLAG_KEYFRAME; - if (!remaining_sample_bytes) - buf->decoder_flags |= BUF_FLAG_FRAME_END; - this->video_fifo->put(this->video_fifo, buf); - } + /* skip over the extra non-spec CVID bytes */ + this->input->seek(this->input, + this->sample_table[i].sample_size - cvid_chunk_size, SEEK_CUR); - } else if (this->sample_table[i].syncinfo1 != 0xFFFFFFFF) { - - /* load a non-cvid video chunk */ - remaining_sample_bytes = this->sample_table[i].sample_size; - this->input->seek(this->input, this->sample_table[i].sample_offset, - SEEK_SET); - - /* frame duration is the pts diff between this video frame and - * the next video frame (so search for the next video frame) */ - frame_duration = 0; - j = i; - while (++j < this->sample_count) { - if (this->sample_table[j].syncinfo1 != 0xFFFFFFFF) { - frame_duration = - this->sample_table[j].pts - this->sample_table[i].pts; - break; - } + /* load the rest of the chunk */ + if (this->input->read(this->input, buf->content + 10, + buf->size - 10) != buf->size - 10) { + this->status = DEMUX_FINISHED; + break; } - while (remaining_sample_bytes) { - buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); - buf->type = this->video_type; - buf->input_pos = - this->sample_table[i].sample_offset - this->data_start; - buf->input_length = this->data_size; - buf->input_time = this->sample_table[i].pts / 90000; - buf->pts = this->sample_table[i].pts; - - /* set the frame duration */ - buf->decoder_flags |= BUF_FLAG_FRAMERATE; - buf->decoder_info[0] = frame_duration; - - if (remaining_sample_bytes > buf->max_size) - buf->size = buf->max_size; - else - buf->size = remaining_sample_bytes; - remaining_sample_bytes -= buf->size; - - if (this->input->read(this->input, buf->content, buf->size) != - buf->size) { - this->status = DEMUX_FINISHED; - break; - } - - if ((this->sample_table[i].syncinfo1 & 0x80000000) == 0) - buf->decoder_flags |= BUF_FLAG_KEYFRAME; - if (!remaining_sample_bytes) - buf->decoder_flags |= BUF_FLAG_FRAME_END; - this->video_fifo->put(this->video_fifo, buf); - } - } else if( this->audio_fifo ) { - /* load an audio sample and packetize it */ - remaining_sample_bytes = this->sample_table[i].sample_size; - this->input->seek(this->input, this->sample_table[i].sample_offset, - SEEK_SET); - - while (remaining_sample_bytes) { - buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); - buf->type = this->audio_type; - buf->input_pos = - this->sample_table[i].sample_offset - this->data_start; - buf->input_length = this->data_size; - buf->input_time = this->sample_table[i].pts / 90000; - buf->pts = this->sample_table[i].pts; - - if (remaining_sample_bytes > buf->max_size) - buf->size = buf->max_size; - else - buf->size = remaining_sample_bytes; - remaining_sample_bytes -= buf->size; - - if (this->input->read(this->input, buf->content, buf->size) != - buf->size) { - this->status = DEMUX_FINISHED; - break; - } - - if (this->video_type == BUF_VIDEO_SEGA) { - /* if the file uses the SEGA video codec, assume this is - * sign/magnitude audio */ - for (j = 0; j < buf->size; j++) - if (buf->content[j] < 0x80) - buf->content[j] += 0x80; - else - buf->content[j] = -(buf->content[j] & 0x7F) + 0x80; - } else if (this->audio_bits == 8) { - /* convert 8-bit data from signed -> unsigned */ - for (j = 0; j < buf->size; j++) - buf->content[j] += 0x80; - } - - if (!remaining_sample_bytes) - buf->decoder_flags |= BUF_FLAG_FRAME_END; - - this->audio_fifo->put(this->audio_fifo, buf); + /* adjust the length in the CVID data chunk */ + buf->content[1] = (cvid_chunk_size >> 16) & 0xFF; + buf->content[2] = (cvid_chunk_size >> 8) & 0xFF; + buf->content[3] = (cvid_chunk_size >> 0) & 0xFF; + + fixed_cvid_header = 1; + } else { + if (this->input->read(this->input, buf->content, buf->size) != + buf->size) { + this->status = DEMUX_FINISHED; + break; } } + + if ((this->sample_table[i].syncinfo1 & 0x80000000) == 0) + buf->decoder_flags |= BUF_FLAG_KEYFRAME; + if (!remaining_sample_bytes) + buf->decoder_flags |= BUF_FLAG_FRAME_END; + this->video_fifo->put(this->video_fifo, buf); } - /* wait before sending end buffers: user might want to do a new seek */ - while(this->send_end_buffers && this->video_fifo->size(this->video_fifo) && - this->status != DEMUX_OK){ - pthread_mutex_unlock( &this->mutex ); - xine_usec_sleep(100000); - pthread_mutex_lock( &this->mutex ); + } else if (this->sample_table[i].syncinfo1 != 0xFFFFFFFF) { + + /* load a non-cvid video chunk */ + remaining_sample_bytes = this->sample_table[i].sample_size; + this->input->seek(this->input, this->sample_table[i].sample_offset, + SEEK_SET); + + /* frame duration is the pts diff between this video frame and + * the next video frame (so search for the next video frame) */ + frame_duration = 0; + j = i; + while (++j < this->sample_count) { + if (this->sample_table[j].syncinfo1 != 0xFFFFFFFF) { + frame_duration = + this->sample_table[j].pts - this->sample_table[i].pts; + break; + } } - } while (this->status == DEMUX_OK); + while (remaining_sample_bytes) { + buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); + buf->type = this->video_type; + buf->input_pos = + this->sample_table[i].sample_offset - this->data_start; + buf->input_length = this->data_size; + buf->input_time = this->sample_table[i].pts / 90000; + buf->pts = this->sample_table[i].pts; + + /* set the frame duration */ + buf->decoder_flags |= BUF_FLAG_FRAMERATE; + buf->decoder_info[0] = frame_duration; + + if (remaining_sample_bytes > buf->max_size) + buf->size = buf->max_size; + else + buf->size = remaining_sample_bytes; + remaining_sample_bytes -= buf->size; - this->current_sample = this->last_sample = 0; + if (this->input->read(this->input, buf->content, buf->size) != + buf->size) { + this->status = DEMUX_FINISHED; + break; + } - this->status = DEMUX_FINISHED; + if ((this->sample_table[i].syncinfo1 & 0x80000000) == 0) + buf->decoder_flags |= BUF_FLAG_KEYFRAME; + if (!remaining_sample_bytes) + buf->decoder_flags |= BUF_FLAG_FRAME_END; + this->video_fifo->put(this->video_fifo, buf); + } + } else if( this->audio_fifo ) { + /* load an audio sample and packetize it */ + remaining_sample_bytes = this->sample_table[i].sample_size; + this->input->seek(this->input, this->sample_table[i].sample_offset, + SEEK_SET); + + while (remaining_sample_bytes) { + buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); + buf->type = this->audio_type; + buf->input_pos = + this->sample_table[i].sample_offset - this->data_start; + buf->input_length = this->data_size; + buf->input_time = this->sample_table[i].pts / 90000; + buf->pts = this->sample_table[i].pts; + + if (remaining_sample_bytes > buf->max_size) + buf->size = buf->max_size; + else + buf->size = remaining_sample_bytes; + remaining_sample_bytes -= buf->size; - if (this->send_end_buffers) { - xine_demux_control_end(this->stream, BUF_FLAG_END_STREAM); - } + if (this->input->read(this->input, buf->content, buf->size) != + buf->size) { + this->status = DEMUX_FINISHED; + break; + } - this->thread_running = 0; - pthread_mutex_unlock( &this->mutex ); + if (this->video_type == BUF_VIDEO_SEGA) { + /* if the file uses the SEGA video codec, assume this is + * sign/magnitude audio */ + for (j = 0; j < buf->size; j++) + if (buf->content[j] < 0x80) + buf->content[j] += 0x80; + else + buf->content[j] = -(buf->content[j] & 0x7F) + 0x80; + } else if (this->audio_bits == 8) { + /* convert 8-bit data from signed -> unsigned */ + for (j = 0; j < buf->size; j++) + buf->content[j] += 0x80; + } - return NULL; + if (!remaining_sample_bytes) + buf->decoder_flags |= BUF_FLAG_FRAME_END; + + this->audio_fifo->put(this->audio_fifo, buf); + } + } + + return this->status; } static void demux_film_send_headers(demux_plugin_t *this_gen) { @@ -540,8 +498,6 @@ static void demux_film_send_headers(demux_plugin_t *this_gen) { demux_film_t *this = (demux_film_t *) this_gen; buf_element_t *buf; - pthread_mutex_lock(&this->mutex); - this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; @@ -588,42 +544,6 @@ static void demux_film_send_headers(demux_plugin_t *this_gen) { } xine_demux_control_headers_done (this->stream); - - pthread_mutex_unlock (&this->mutex); -} - -static int demux_film_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time); - -static int demux_film_start (demux_plugin_t *this_gen, - off_t start_pos, int start_time) { - - demux_film_t *this = (demux_film_t *) this_gen; - int err; - - demux_film_seek(this_gen, start_pos, start_time); - - pthread_mutex_lock(&this->mutex); - - /* if thread is not running, initialize demuxer */ - if (!this->thread_running) { - - this->status = DEMUX_OK; - this->send_end_buffers = 1; - this->thread_running = 1; - this->waiting_for_keyframe = 0; - - this->last_sample = 0; - - if ((err = pthread_create (&this->thread, NULL, demux_film_loop, this)) != 0) { - printf ("demux_film: can't create new thread (%s)\n", strerror(err)); - abort(); - } - } - - pthread_mutex_unlock(&this->mutex); - - return DEMUX_OK; } static int demux_film_seek (demux_plugin_t *this_gen, @@ -633,9 +553,6 @@ static int demux_film_seek (demux_plugin_t *this_gen, int left, middle, right; int found; int64_t keyframe_pts; - int status; - - pthread_mutex_lock( &this->mutex ); this->waiting_for_keyframe = 0; @@ -644,9 +561,8 @@ static int demux_film_seek (demux_plugin_t *this_gen, if (start_pos <= 0) best_index = 0; else if (start_pos >= this->data_size) { - status = this->status = DEMUX_FINISHED; - pthread_mutex_unlock( &this->mutex ); - return status; + this->status = DEMUX_FINISHED; + return this->status; } else { start_pos += this->data_start; left = 0; @@ -691,45 +607,21 @@ static int demux_film_seek (demux_plugin_t *this_gen, } this->current_sample = best_index; - status = this->status = DEMUX_OK; + this->status = DEMUX_OK; xine_demux_flush_engine(this->stream); - pthread_mutex_unlock( &this->mutex ); - - return status; -} - -static void demux_film_stop (demux_plugin_t *this_gen) { - - demux_film_t *this = (demux_film_t *) this_gen; - void *p; - - pthread_mutex_lock( &this->mutex ); + + if( !this->stream->demux_thread_running ) { + this->waiting_for_keyframe = 0; - if (!this->thread_running) { - pthread_mutex_unlock( &this->mutex ); - return; + this->last_sample = 0; } - - this->send_end_buffers = 0; - this->status = DEMUX_FINISHED; - - pthread_mutex_unlock( &this->mutex ); - pthread_join (this->thread, &p); - - this->current_sample = this->last_sample = 0; - - xine_demux_flush_engine(this->stream); - - xine_demux_control_end(this->stream, BUF_FLAG_END_USER); + + return this->status; } static void demux_film_dispose (demux_plugin_t *this_gen) { demux_film_t *this = (demux_film_t *) this_gen; - demux_film_stop(this_gen); - - pthread_mutex_destroy (&this->mutex); - if (this->sample_table) free(this->sample_table); free(this); @@ -763,16 +655,14 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->input = input; this->demux_plugin.send_headers = demux_film_send_headers; - this->demux_plugin.start = demux_film_start; + this->demux_plugin.send_chunk = demux_film_send_chunk; this->demux_plugin.seek = demux_film_seek; - this->demux_plugin.stop = demux_film_stop; this->demux_plugin.dispose = demux_film_dispose; this->demux_plugin.get_status = demux_film_get_status; this->demux_plugin.get_stream_length = demux_film_get_stream_length; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; - pthread_mutex_init (&this->mutex, NULL); switch (stream->content_detection_method) { @@ -897,6 +787,6 @@ static void *init_plugin (xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 14, "film", XINE_VERSION_CODE, NULL, init_plugin }, + { PLUGIN_DEMUX, 15, "film", XINE_VERSION_CODE, NULL, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/demuxers/demux_fli.c b/src/demuxers/demux_fli.c index 4a8427721..1c2fc0842 100644 --- a/src/demuxers/demux_fli.c +++ b/src/demuxers/demux_fli.c @@ -22,7 +22,7 @@ * avoid while programming a FLI decoder, visit: * http://www.pcisys.net/~melanson/codecs/ * - * $Id: demux_fli.c,v 1.22 2002/10/27 16:14:23 tmmm Exp $ + * $Id: demux_fli.c,v 1.23 2002/10/28 03:24:43 miguelfreitas Exp $ */ #ifdef HAVE_CONFIG_H @@ -32,8 +32,6 @@ #include #include #include -#include -#include #include #include @@ -61,11 +59,6 @@ typedef struct { input_plugin_t *input; - pthread_t thread; - int thread_running; - pthread_mutex_t mutex; - int send_end_buffers; - off_t start; int status; @@ -81,6 +74,8 @@ typedef struct { unsigned int frame_count; char last_mrl[1024]; + + off_t stream_len; } demux_fli_t; typedef struct { @@ -139,7 +134,7 @@ static int open_fli_file(demux_fli_t *this) { return 1; } -static void *demux_fli_loop (void *this_gen) { +static int demux_fli_send_chunk(demux_plugin_t *this_gen) { demux_fli_t *this = (demux_fli_t *) this_gen; buf_element_t *buf = NULL; @@ -149,95 +144,59 @@ static void *demux_fli_loop (void *this_gen) { unsigned int chunk_magic; int64_t pts_counter = 0; off_t current_file_pos; - off_t stream_len; - - /* make sure to start just after the header */ - this->input->seek(this->input, FLI_HEADER_SIZE, SEEK_SET); - - stream_len = this->input->get_length(this->input); - - /* do-while needed to seek after demux finished */ - do { - /* main demuxer loop */ - while (this->status == DEMUX_OK) { - /* check if all the frames have been sent */ - if (i >= this->frame_count) { - this->status = DEMUX_FINISHED; - break; - } - - current_file_pos = this->input->get_current_pos(this->input); - - /* get the chunk size nd magic number */ - if (this->input->read(this->input, fli_buf, 6) != 6) { + /* check if all the frames have been sent */ + if (i >= this->frame_count) { + this->status = DEMUX_FINISHED; + return this->status; + } + + current_file_pos = this->input->get_current_pos(this->input); + + /* get the chunk size nd magic number */ + if (this->input->read(this->input, fli_buf, 6) != 6) { + this->status = DEMUX_FINISHED; + return this->status; + } + chunk_size = LE_32(&fli_buf[0]); + chunk_magic = LE_16(&fli_buf[4]); + + /* rewind over the size and packetize the chunk */ + this->input->seek(this->input, -6, SEEK_CUR); + + if ((chunk_magic == FLI_CHUNK_MAGIC_1) || + (chunk_magic == FLI_CHUNK_MAGIC_2)) { + while (chunk_size) { + buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); + buf->type = BUF_VIDEO_FLI; + buf->input_pos = current_file_pos; + buf->input_time = pts_counter / 90000; + buf->input_length = this->stream_len; + buf->pts = pts_counter; + + if (chunk_size > buf->max_size) + buf->size = buf->max_size; + else + buf->size = chunk_size; + chunk_size -= buf->size; + + if (this->input->read(this->input, buf->content, buf->size) != + buf->size) { this->status = DEMUX_FINISHED; break; } - chunk_size = LE_32(&fli_buf[0]); - chunk_magic = LE_16(&fli_buf[4]); - - /* rewind over the size and packetize the chunk */ - this->input->seek(this->input, -6, SEEK_CUR); - - if ((chunk_magic == FLI_CHUNK_MAGIC_1) || - (chunk_magic == FLI_CHUNK_MAGIC_2)) { - while (chunk_size) { - buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); - buf->type = BUF_VIDEO_FLI; - buf->input_pos = current_file_pos; - buf->input_time = pts_counter / 90000; - buf->input_length = stream_len; - buf->pts = pts_counter; - - if (chunk_size > buf->max_size) - buf->size = buf->max_size; - else - buf->size = chunk_size; - chunk_size -= buf->size; - - if (this->input->read(this->input, buf->content, buf->size) != - buf->size) { - this->status = DEMUX_FINISHED; - break; - } - - if (!chunk_size) - buf->decoder_flags |= BUF_FLAG_FRAME_END; - this->video_fifo->put(this->video_fifo, buf); - } - pts_counter += this->frame_pts_inc; - } else - this->input->seek(this->input, chunk_size, SEEK_CUR); - - i++; - - /* someone may want to interrupt us */ - pthread_mutex_unlock( &this->mutex ); - /* give demux_*_stop a chance to interrupt us */ - sched_yield(); - pthread_mutex_lock( &this->mutex ); + + if (!chunk_size) + buf->decoder_flags |= BUF_FLAG_FRAME_END; + this->video_fifo->put(this->video_fifo, buf); } - - /* wait before sending end buffers: user might want to do a new seek */ - while(this->send_end_buffers && this->video_fifo->size(this->video_fifo) && - this->status != DEMUX_OK){ - pthread_mutex_unlock( &this->mutex ); - xine_usec_sleep(100000); - pthread_mutex_lock( &this->mutex ); - } - } while (this->status == DEMUX_OK); - - this->status = DEMUX_FINISHED; - - if (this->send_end_buffers) { - xine_demux_control_end(this->stream, BUF_FLAG_END_STREAM); - } - - this->thread_running = 0; - pthread_mutex_unlock( &this->mutex ); - - return NULL; + pts_counter += this->frame_pts_inc; + } else + this->input->seek(this->input, chunk_size, SEEK_CUR); + + i++; + + return this->status; } static void demux_fli_send_headers(demux_plugin_t *this_gen) { @@ -245,8 +204,6 @@ static void demux_fli_send_headers(demux_plugin_t *this_gen) { demux_fli_t *this = (demux_fli_t *) this_gen; buf_element_t *buf; - pthread_mutex_lock(&this->mutex); - this->video_fifo = this->stream->video_fifo; /* video-only format, don't worry about audio_fifo */ @@ -273,78 +230,31 @@ static void demux_fli_send_headers(demux_plugin_t *this_gen) { this->video_fifo->put (this->video_fifo, buf); xine_demux_control_headers_done (this->stream); - - pthread_mutex_unlock (&this->mutex); } -static int demux_fli_start (demux_plugin_t *this_gen, +static int demux_fli_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time) { demux_fli_t *this = (demux_fli_t *) this_gen; - int err; - - pthread_mutex_lock(&this->mutex); /* if thread is not running, initialize demuxer */ - if (!this->thread_running) { + if( !this->stream->demux_thread_running ) { /* send new pts */ xine_demux_control_newpts(this->stream, 0, 0); this->status = DEMUX_OK; - this->send_end_buffers = 1; - this->thread_running = 1; - - /* kick off the demux thread */ - if ((err = pthread_create (&this->thread, NULL, demux_fli_loop, this)) != 0) { - printf ("demux_fli: can't create new thread (%s)\n", strerror(err)); - abort(); - } - } - - pthread_mutex_unlock(&this->mutex); - - return DEMUX_OK; -} - -static int demux_fli_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time) { - - /* FLI files are not meant to be seekable; don't even bother */ - - return 0; -} - -static void demux_fli_stop (demux_plugin_t *this_gen) { - - demux_fli_t *this = (demux_fli_t *) this_gen; - void *p; - - pthread_mutex_lock( &this->mutex ); - - if (!this->thread_running) { - pthread_mutex_unlock( &this->mutex ); - return; + + /* make sure to start just after the header */ + this->input->seek(this->input, FLI_HEADER_SIZE, SEEK_SET); + this->stream_len = this->input->get_length(this->input); } - - /* seek to the start of the data in case there's another start command */ - this->input->seek(this->input, FLI_HEADER_SIZE, SEEK_SET); - - this->send_end_buffers = 0; - this->status = DEMUX_FINISHED; - - pthread_mutex_unlock( &this->mutex ); - pthread_join (this->thread, &p); - - xine_demux_flush_engine(this->stream); - - xine_demux_control_end(this->stream, BUF_FLAG_END_USER); + + return this->status; } static void demux_fli_dispose (demux_plugin_t *this) { - demux_fli_stop(this); - free(this); } @@ -375,16 +285,14 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->input = input; this->demux_plugin.send_headers = demux_fli_send_headers; - this->demux_plugin.start = demux_fli_start; + this->demux_plugin.send_chunk = demux_fli_send_chunk; this->demux_plugin.seek = demux_fli_seek; - this->demux_plugin.stop = demux_fli_stop; this->demux_plugin.dispose = demux_fli_dispose; this->demux_plugin.get_status = demux_fli_get_status; this->demux_plugin.get_stream_length = demux_fli_get_stream_length; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; - pthread_mutex_init (&this->mutex, NULL); switch (stream->content_detection_method) { diff --git a/src/demuxers/demux_idcin.c b/src/demuxers/demux_idcin.c index 76563f885..163caf8a3 100644 --- a/src/demuxers/demux_idcin.c +++ b/src/demuxers/demux_idcin.c @@ -63,7 +63,7 @@ * - if any bytes exceed 63, do not shift the bytes at all before * transmitting them to the video decoder * - * $Id: demux_idcin.c,v 1.22 2002/10/27 16:14:26 tmmm Exp $ + * $Id: demux_idcin.c,v 1.23 2002/10/28 03:24:43 miguelfreitas Exp $ */ #ifdef HAVE_CONFIG_H @@ -73,8 +73,6 @@ #include #include #include -#include -#include #include #include @@ -102,11 +100,6 @@ typedef struct { input_plugin_t *input; - pthread_t thread; - int thread_running; - pthread_mutex_t mutex; - int send_end_buffers; - off_t start; off_t filesize; int status; @@ -135,7 +128,7 @@ typedef struct { config_values_t *config; } demux_idcin_class_t; -static void *demux_idcin_loop (void *this_gen) { +static int demux_idcin_send_chunk(demux_plugin_t *this_gen) { demux_idcin_t *this = (demux_idcin_t *) this_gen; buf_element_t *buf = NULL; @@ -150,175 +143,134 @@ static void *demux_idcin_loop (void *this_gen) { int current_audio_chunk = 1; int scale_bits; - pthread_mutex_lock( &this->mutex ); - - /* reposition stream past the Huffman tables */ - this->input->seek(this->input, 0x14 + 0x10000, SEEK_SET); - - /* do-while needed to seek after demux finished */ - do { - /* main demuxer loop */ - while (this->status == DEMUX_OK) { - - /* someone may want to interrupt us */ - pthread_mutex_unlock( &this->mutex ); - /* give demux_*_stop a chance to interrupt us */ - sched_yield(); - pthread_mutex_lock( &this->mutex ); + current_file_pos = this->input->get_current_pos(this->input); - current_file_pos = this->input->get_current_pos(this->input); - - /* figure out what the next data is */ - if (this->input->read(this->input, (unsigned char *)&command, 4) != 4) { - this->status = DEMUX_FINISHED; - pthread_mutex_unlock(&this->mutex); - break; - } + /* figure out what the next data is */ + if (this->input->read(this->input, (unsigned char *)&command, 4) != 4) { + this->status = DEMUX_FINISHED; + return this->status; + } - command = le2me_32(command); - if (command == 2) { + command = le2me_32(command); + if (command == 2) { + this->status = DEMUX_FINISHED; + return this->status; + } else { + if (command == 1) { + /* load a 768-byte palette and pass it to the demuxer */ + if (this->input->read(this->input, disk_palette, PALETTE_SIZE * 3) != + PALETTE_SIZE * 3) { this->status = DEMUX_FINISHED; - break; - } else { - if (command == 1) { - /* load a 768-byte palette and pass it to the demuxer */ - if (this->input->read(this->input, disk_palette, PALETTE_SIZE * 3) != - PALETTE_SIZE * 3) { - this->status = DEMUX_FINISHED; - pthread_mutex_unlock(&this->mutex); - break; - } - - /* scan the palette to figure out if it's 6- or 8-bit; - * assume 6-bit palette until a value > 63 is seen */ - scale_bits = 2; - for (i = 0; i < PALETTE_SIZE * 3; i++) - if (disk_palette[i] > 63) { - scale_bits = 0; - break; - } - - /* convert palette to internal structure */ - for (i = 0; i < PALETTE_SIZE; i++) { - /* these are VGA color DAC values, which means they only range - * from 0..63; adjust as appropriate */ - palette[i].r = disk_palette[i * 3 + 0] << scale_bits; - palette[i].g = disk_palette[i * 3 + 1] << scale_bits; - palette[i].b = disk_palette[i * 3 + 2] << scale_bits; - } - - buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); - buf->decoder_flags = BUF_FLAG_SPECIAL; - buf->decoder_info[1] = BUF_SPECIAL_PALETTE; - buf->decoder_info[2] = PALETTE_SIZE; - buf->decoder_info[3] = (unsigned int)&palette; - buf->size = 0; - buf->type = BUF_VIDEO_IDCIN; - this->video_fifo->put (this->video_fifo, buf); - } + return this->status; } - /* load the video frame */ - if (this->input->read(this->input, preamble, 8) != 8) { - this->status = DEMUX_FINISHED; - pthread_mutex_unlock(&this->mutex); - break; - } - remaining_sample_bytes = LE_32(&preamble[0]) - 4; - - while (remaining_sample_bytes) { - buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); - buf->type = BUF_VIDEO_IDCIN; - buf->input_pos = this->input->get_current_pos(this->input); - buf->input_length = this->filesize; - buf->input_time = pts_counter / 90000; - buf->pts = pts_counter; - - if (remaining_sample_bytes > buf->max_size) - buf->size = buf->max_size; - else - buf->size = remaining_sample_bytes; - remaining_sample_bytes -= buf->size; - - if (this->input->read(this->input, buf->content, buf->size) != - buf->size) { - buf->free_buffer(buf); - this->status = DEMUX_FINISHED; + /* scan the palette to figure out if it's 6- or 8-bit; + * assume 6-bit palette until a value > 63 is seen */ + scale_bits = 2; + for (i = 0; i < PALETTE_SIZE * 3; i++) + if (disk_palette[i] > 63) { + scale_bits = 0; break; } - /* all frames are intra-coded */ - buf->decoder_flags |= BUF_FLAG_KEYFRAME; - if (!remaining_sample_bytes) - buf->decoder_flags |= BUF_FLAG_FRAME_END; - - this->video_fifo->put(this->video_fifo, buf); + /* convert palette to internal structure */ + for (i = 0; i < PALETTE_SIZE; i++) { + /* these are VGA color DAC values, which means they only range + * from 0..63; adjust as appropriate */ + palette[i].r = disk_palette[i * 3 + 0] << scale_bits; + palette[i].g = disk_palette[i * 3 + 1] << scale_bits; + palette[i].b = disk_palette[i * 3 + 2] << scale_bits; } - /* load the audio frame */ - if (this->audio_fifo && this->audio_sample_rate) { + buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); + buf->decoder_flags = BUF_FLAG_SPECIAL; + buf->decoder_info[1] = BUF_SPECIAL_PALETTE; + buf->decoder_info[2] = PALETTE_SIZE; + buf->decoder_info[3] = (unsigned int)&palette; + buf->size = 0; + buf->type = BUF_VIDEO_IDCIN; + this->video_fifo->put (this->video_fifo, buf); + } + } + + /* load the video frame */ + if (this->input->read(this->input, preamble, 8) != 8) { + this->status = DEMUX_FINISHED; + return this->status; + } + remaining_sample_bytes = LE_32(&preamble[0]) - 4; + + while (remaining_sample_bytes) { + buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); + buf->type = BUF_VIDEO_IDCIN; + buf->input_pos = this->input->get_current_pos(this->input); + buf->input_length = this->filesize; + buf->input_time = pts_counter / 90000; + buf->pts = pts_counter; + + if (remaining_sample_bytes > buf->max_size) + buf->size = buf->max_size; + else + buf->size = remaining_sample_bytes; + remaining_sample_bytes -= buf->size; + + if (this->input->read(this->input, buf->content, buf->size) != + buf->size) { + buf->free_buffer(buf); + this->status = DEMUX_FINISHED; + break; + } - if (current_audio_chunk == 1) { - remaining_sample_bytes = this->audio_chunk_size1; - current_audio_chunk = 2; - } else { - remaining_sample_bytes = this->audio_chunk_size2; - current_audio_chunk = 1; - } + /* all frames are intra-coded */ + buf->decoder_flags |= BUF_FLAG_KEYFRAME; + if (!remaining_sample_bytes) + buf->decoder_flags |= BUF_FLAG_FRAME_END; - while (remaining_sample_bytes) { - buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); - buf->type = BUF_AUDIO_LPCM_LE; - buf->input_pos = this->input->get_current_pos(this->input); - buf->input_length = this->filesize; - buf->input_time = pts_counter / 90000; - buf->pts = pts_counter; - - if (remaining_sample_bytes > buf->max_size) - buf->size = buf->max_size; - else - buf->size = remaining_sample_bytes; - remaining_sample_bytes -= buf->size; - - if (this->input->read(this->input, buf->content, buf->size) != - buf->size) { - buf->free_buffer(buf); - this->status = DEMUX_FINISHED; - break; - } - - if (!remaining_sample_bytes) - buf->decoder_flags |= BUF_FLAG_FRAME_END; - - this->audio_fifo->put(this->audio_fifo, buf); - } - } + this->video_fifo->put(this->video_fifo, buf); + } - pts_counter += IDCIN_FRAME_PTS_INC; - } + /* load the audio frame */ + if (this->audio_fifo && this->audio_sample_rate) { - /* wait before sending end buffers: user might want to do a new seek */ - while(this->send_end_buffers && this->video_fifo->size(this->video_fifo) && - this->status != DEMUX_OK){ - pthread_mutex_unlock( &this->mutex ); - xine_usec_sleep(100000); - pthread_mutex_lock( &this->mutex ); + if (current_audio_chunk == 1) { + remaining_sample_bytes = this->audio_chunk_size1; + current_audio_chunk = 2; + } else { + remaining_sample_bytes = this->audio_chunk_size2; + current_audio_chunk = 1; } - } while (this->status == DEMUX_OK); - - printf ("demux_idcin: demux loop finished (status: %d)\n", - this->status); + while (remaining_sample_bytes) { + buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); + buf->type = BUF_AUDIO_LPCM_LE; + buf->input_pos = this->input->get_current_pos(this->input); + buf->input_length = this->filesize; + buf->input_time = pts_counter / 90000; + buf->pts = pts_counter; + + if (remaining_sample_bytes > buf->max_size) + buf->size = buf->max_size; + else + buf->size = remaining_sample_bytes; + remaining_sample_bytes -= buf->size; + + if (this->input->read(this->input, buf->content, buf->size) != + buf->size) { + buf->free_buffer(buf); + this->status = DEMUX_FINISHED; + break; + } - this->status = DEMUX_FINISHED; + if (!remaining_sample_bytes) + buf->decoder_flags |= BUF_FLAG_FRAME_END; - if (this->send_end_buffers) { - xine_demux_control_end(this->stream, BUF_FLAG_END_STREAM); + this->audio_fifo->put(this->audio_fifo, buf); + } } - this->thread_running = 0; - pthread_mutex_unlock(&this->mutex); - return NULL; + pts_counter += IDCIN_FRAME_PTS_INC; + + return this->status; } /* returns 1 if the CIN file was opened successfully, 0 otherwise */ @@ -366,8 +318,6 @@ static void demux_idcin_send_headers(demux_plugin_t *this_gen) { demux_idcin_t *this = (demux_idcin_t *) this_gen; buf_element_t *buf; - pthread_mutex_lock(&this->mutex); - this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; @@ -425,80 +375,31 @@ static void demux_idcin_send_headers(demux_plugin_t *this_gen) { } xine_demux_control_headers_done (this->stream); - - pthread_mutex_unlock (&this->mutex); } -static int demux_idcin_start (demux_plugin_t *this_gen, +static int demux_idcin_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time) { demux_idcin_t *this = (demux_idcin_t *) this_gen; - int err; - - pthread_mutex_lock(&this->mutex); /* if thread is not running, initialize demuxer */ - if (!this->thread_running) { + if( !this->stream->demux_thread_running ) { /* send new pts */ xine_demux_control_newpts(this->stream, 0, 0); this->status = DEMUX_OK; - this->send_end_buffers = 1; - this->thread_running = 1; - - if ((err = pthread_create (&this->thread, NULL, demux_idcin_loop, this)) != 0) { - printf ("demux_idcin: can't create new thread (%s)\n", strerror(err)); - abort(); - } - - this->status = DEMUX_OK; - } - - pthread_mutex_unlock(&this->mutex); - - return DEMUX_OK; -} - -static int demux_idcin_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time) { - - /* Id CIN files are not meant to be seekable; don't even bother */ - - return 0; -} - -static void demux_idcin_stop (demux_plugin_t *this_gen) { - - demux_idcin_t *this = (demux_idcin_t *) this_gen; - void *p; + + /* reposition stream past the Huffman tables */ + this->input->seek(this->input, 0x14 + 0x10000, SEEK_SET); - pthread_mutex_lock( &this->mutex ); - - if (!this->thread_running) { - pthread_mutex_unlock( &this->mutex ); - return; } - /* seek to the start of the data in case there's another start command */ - this->input->seek(this->input, IDCIN_HEADER_SIZE + HUFFMAN_TABLE_SIZE, - SEEK_SET); - - this->send_end_buffers = 0; - this->status = DEMUX_FINISHED; - - pthread_mutex_unlock( &this->mutex ); - pthread_join (this->thread, &p); - - xine_demux_flush_engine(this->stream); - - xine_demux_control_end(this->stream, BUF_FLAG_END_USER); + return this->status; } static void demux_idcin_dispose (demux_plugin_t *this) { - demux_idcin_stop(this); - free(this); } @@ -531,16 +432,14 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->input = input; this->demux_plugin.send_headers = demux_idcin_send_headers; - this->demux_plugin.start = demux_idcin_start; + this->demux_plugin.send_chunk = demux_idcin_send_chunk; this->demux_plugin.seek = demux_idcin_seek; - this->demux_plugin.stop = demux_idcin_stop; this->demux_plugin.dispose = demux_idcin_dispose; this->demux_plugin.get_status = demux_idcin_get_status; this->demux_plugin.get_stream_length = demux_idcin_get_stream_length; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; - pthread_mutex_init (&this->mutex, NULL); switch (stream->content_detection_method) { @@ -701,6 +600,6 @@ static void *init_plugin (xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 14, "idcin", XINE_VERSION_CODE, NULL, init_plugin }, + { PLUGIN_DEMUX, 15, "idcin", XINE_VERSION_CODE, NULL, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/demuxers/demux_mpeg.c b/src/demuxers/demux_mpeg.c index 5ce7cc26a..53a796464 100644 --- a/src/demuxers/demux_mpeg.c +++ b/src/demuxers/demux_mpeg.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: demux_mpeg.c,v 1.91 2002/10/27 00:01:13 guenter Exp $ + * $Id: demux_mpeg.c,v 1.92 2002/10/28 03:24:43 miguelfreitas Exp $ * * demultiplexer for mpeg 1/2 program streams * reads streams of variable blocksizes @@ -34,8 +34,6 @@ #include #include #include -#include -#include #include #include @@ -60,10 +58,6 @@ typedef struct demux_mpeg_s { xine_stream_t *stream; input_plugin_t *input; - pthread_t thread; - int thread_running; - pthread_mutex_t mutex; - unsigned char dummy_space[100000]; int status; @@ -71,8 +65,6 @@ typedef struct demux_mpeg_s { int rate; - int send_end_buffers; - int64_t last_pts[2]; int send_newpts; int buf_flag_seek; @@ -777,75 +769,17 @@ static void demux_mpeg_resync (demux_mpeg_t *this, uint32_t buf) { } } -static void *demux_mpeg_loop (void *this_gen) { - - demux_mpeg_t *this = (demux_mpeg_t *) this_gen; - uint32_t w=0; - - pthread_mutex_lock( &this->mutex ); - /* do-while needed to seek after demux finished */ - do { - - /* main demuxer loop */ - while(this->status == DEMUX_OK) { - w = parse_pack (this); - if (w != 0x000001ba) - demux_mpeg_resync (this, w); - - /* someone may want to interrupt us */ - pthread_mutex_unlock( &this->mutex ); - /* give demux_*_stop a chance to interrupt us */ - sched_yield(); - pthread_mutex_lock( &this->mutex ); - } - - /* wait before sending end buffers: user might want to do a new seek */ - while(this->send_end_buffers && this->video_fifo->size(this->video_fifo) && - this->status != DEMUX_OK){ - pthread_mutex_unlock( &this->mutex ); - xine_usec_sleep(100000); - pthread_mutex_lock( &this->mutex ); - } - - } while( this->status == DEMUX_OK ); - - if (this->send_end_buffers) { - xine_demux_control_end(this->stream, BUF_FLAG_END_STREAM); - } - - printf ("demux_mpeg: demux thread finished (status: %d, buf:%x)\n", - this->status, w); - - this->thread_running = 0; - pthread_mutex_unlock( &this->mutex ); - - pthread_exit(NULL); - - return NULL; -} - -static void demux_mpeg_stop (demux_plugin_t *this_gen) { +static int demux_mpeg_send_chunk (demux_plugin_t *this_gen) { demux_mpeg_t *this = (demux_mpeg_t *) this_gen; - void *p; - pthread_mutex_lock( &this->mutex ); - - if (!this->thread_running) { - printf ("demux_mpeg: stop...ignored\n"); - pthread_mutex_unlock( &this->mutex ); - return; - } - - this->send_end_buffers = 0; - this->status = DEMUX_FINISHED; - - pthread_mutex_unlock( &this->mutex ); - pthread_join (this->thread, &p); + uint32_t w=0; - xine_demux_flush_engine(this->stream); + w = parse_pack (this); + if (w != 0x000001ba) + demux_mpeg_resync (this, w); - xine_demux_control_end(this->stream, BUF_FLAG_END_USER); + return this->status; } static int demux_mpeg_get_status (demux_plugin_t *this_gen) { @@ -860,8 +794,6 @@ static void demux_mpeg_send_headers (demux_plugin_t *this_gen) { uint32_t w; int num_buffers = NUM_PREVIEW_BUFFERS; - pthread_mutex_lock( &this->mutex ); - this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; @@ -900,18 +832,12 @@ static void demux_mpeg_send_headers (demux_plugin_t *this_gen) { this->stream->stream_info[XINE_STREAM_INFO_BITRATE] = this->rate * 50 * 8; xine_demux_control_headers_done (this->stream); - - pthread_mutex_unlock (&this->mutex); } -static int demux_mpeg_start (demux_plugin_t *this_gen, +static int demux_mpeg_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time) { demux_mpeg_t *this = (demux_mpeg_t *) this_gen; - int err; - int status; - - pthread_mutex_lock( &this->mutex ); if ((this->input->get_capabilities (this->input) & INPUT_CAP_SEEKABLE) != 0 ) { @@ -929,43 +855,20 @@ static int demux_mpeg_start (demux_plugin_t *this_gen, this->send_newpts = 1; this->status = DEMUX_OK ; - if( !this->thread_running ) { + if( !this->stream->demux_thread_running ) { this->preview_mode = 0; - this->send_end_buffers = 1; - this->thread_running = 1; this->buf_flag_seek = 0; - - if ((err = pthread_create (&this->thread, - NULL, demux_mpeg_loop, this)) != 0) { - printf ("demux_mpeg: can't create new thread (%s)\n", - strerror(err)); - abort(); - } } else { this->buf_flag_seek = 1; xine_demux_flush_engine(this->stream); } - /* this->status is saved because we can be interrupted between - * pthread_mutex_unlock and return - */ - status = this->status; - pthread_mutex_unlock( &this->mutex ); - return status; -} - -static int demux_mpeg_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time) { - /* demux_mpeg_t *this = (demux_mpeg_t *) this_gen; */ - - return demux_mpeg_start (this_gen, start_pos, start_time); + return this->status; } static void demux_mpeg_dispose (demux_plugin_t *this_gen) { - demux_mpeg_stop (this_gen); - free (this_gen); } @@ -989,9 +892,8 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->input = input; this->demux_plugin.send_headers = demux_mpeg_send_headers; - this->demux_plugin.start = demux_mpeg_start; + this->demux_plugin.send_chunk = demux_mpeg_send_chunk; this->demux_plugin.seek = demux_mpeg_seek; - this->demux_plugin.stop = demux_mpeg_stop; this->demux_plugin.dispose = demux_mpeg_dispose; this->demux_plugin.get_status = demux_mpeg_get_status; this->demux_plugin.get_stream_length = demux_mpeg_get_stream_length; @@ -1000,9 +902,6 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->status = DEMUX_FINISHED; this->has_pts = 0; - pthread_mutex_init( &this->mutex, NULL ); - - switch (stream->content_detection_method) { case METHOD_BY_CONTENT: { diff --git a/src/demuxers/demux_mpeg_block.c b/src/demuxers/demux_mpeg_block.c index 33e0ff9e9..6507aa0fc 100644 --- a/src/demuxers/demux_mpeg_block.c +++ b/src/demuxers/demux_mpeg_block.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: demux_mpeg_block.c,v 1.133 2002/10/27 22:56:08 guenter Exp $ + * $Id: demux_mpeg_block.c,v 1.134 2002/10/28 03:24:43 miguelfreitas Exp $ * * demultiplexer for mpeg 1/2 program streams * @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -64,16 +63,11 @@ typedef struct demux_mpeg_block_s { input_plugin_t *input; - pthread_t thread; - int thread_running; - pthread_mutex_t mutex; - int status; int blocksize; int rate; - int send_end_buffers; int warned; /* encryption warning */ char cur_mrl[256]; @@ -628,55 +622,13 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m } -static void *demux_mpeg_block_loop (void *this_gen) { +static int demux_mpeg_block_send_chunk (demux_plugin_t *this_gen) { demux_mpeg_block_t *this = (demux_mpeg_block_t *) this_gen; - /* printf ("demux_mpeg_block: demux loop starting...\n"); */ - pthread_mutex_lock( &this->mutex ); - - /* do-while needed to seek after demux finished */ - do { - - /* main demuxer loop */ - while(this->status == DEMUX_OK) { - - demux_mpeg_block_parse_pack(this, 0); - - /* someone may want to interrupt us */ - pthread_mutex_unlock( &this->mutex ); - /* give demux_*_stop a chance to interrupt us */ - sched_yield(); - pthread_mutex_lock( &this->mutex ); - } - - /* wait before sending end buffers: user might want to do a new seek */ - while(this->send_end_buffers && this->video_fifo->size(this->video_fifo) && - this->status != DEMUX_OK){ - pthread_mutex_unlock( &this->mutex ); - xine_usec_sleep(100000); - pthread_mutex_lock( &this->mutex ); - } - - } while( this->status == DEMUX_OK ); - - /* - printf ("demux_mpeg_block: demux loop finished (status: %d)\n", - this->status); - */ - - this->status = DEMUX_FINISHED; - - if (this->send_end_buffers) { - xine_demux_control_end(this->stream, BUF_FLAG_END_STREAM); - } + demux_mpeg_block_parse_pack(this, 0); - this->thread_running = 0; - pthread_mutex_unlock( &this->mutex ); - - pthread_exit(NULL); - - return NULL; + return this->status; } /* estimate bitrate */ @@ -818,37 +770,12 @@ static int demux_mpeg_block_estimate_rate (demux_mpeg_block_t *this) { } -static void demux_mpeg_block_stop (demux_plugin_t *this_gen) { - - demux_mpeg_block_t *this = (demux_mpeg_block_t *) this_gen; - void *p; - - pthread_mutex_lock( &this->mutex ); - - if (!this->thread_running) { - printf ("demux_mpeg_block: stop...ignored\n"); - pthread_mutex_unlock( &this->mutex ); - return; - } - - this->send_end_buffers = 0; - this->status = DEMUX_FINISHED; - - pthread_mutex_unlock( &this->mutex ); - pthread_join (this->thread, &p); - - xine_demux_flush_engine(this->stream); - - xine_demux_control_end(this->stream, BUF_FLAG_END_USER); -} - static void demux_mpeg_block_dispose (demux_plugin_t *this_gen) { demux_mpeg_block_t *this = (demux_mpeg_block_t *) this_gen; - demux_mpeg_block_stop(this_gen); + free (this->scratch_base); free (this); - } static int demux_mpeg_block_get_status (demux_plugin_t *this_gen) { @@ -882,7 +809,6 @@ static int demux_mpeg_detect_blocksize(demux_mpeg_block_t *this, static void demux_mpeg_block_send_headers (demux_plugin_t *this_gen) { demux_mpeg_block_t *this = (demux_mpeg_block_t *) this_gen; - pthread_mutex_lock (&this->mutex); this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; @@ -925,21 +851,13 @@ static void demux_mpeg_block_send_headers (demux_plugin_t *this_gen) { this->stream->stream_info[XINE_STREAM_INFO_BITRATE] = this->rate * 50 * 8; xine_demux_control_headers_done (this->stream); - - pthread_mutex_unlock (&this->mutex); - - return; } -static int demux_mpeg_block_start (demux_plugin_t *this_gen, +static int demux_mpeg_block_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time) { demux_mpeg_block_t *this = (demux_mpeg_block_t *) this_gen; - int err; - int status; - - pthread_mutex_lock( &this->mutex ); if((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) { @@ -962,41 +880,20 @@ static int demux_mpeg_block_start (demux_plugin_t *this_gen, * now start demuxing */ this->send_newpts = 1; - if( !this->thread_running ) { + if( !this->stream->demux_thread_running ) { this->buf_flag_seek = 0; this->nav_last_end_pts = this->nav_last_start_pts = 0; this->status = DEMUX_OK ; this->last_pts[0] = 0; this->last_pts[1] = 0; - - this->send_end_buffers = 1; - this->thread_running = 1; - if ((err = pthread_create (&this->thread, - NULL, demux_mpeg_block_loop, this)) != 0) { - printf ("demux_mpeg_block: can't create new thread (%s)\n", - strerror(err)); - abort(); - } } else { this->buf_flag_seek = 1; this->nav_last_end_pts = this->nav_last_start_pts = 0; xine_demux_flush_engine(this->stream); } - /* this->status is saved because we can be interrupted between - * pthread_mutex_unlock and return - */ - status = this->status; - pthread_mutex_unlock( &this->mutex ); - return status; -} - -static int demux_mpeg_block_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time) { - /* demux_mpeg_block_t *this = (demux_mpeg_block_t *) this_gen; */ - - return demux_mpeg_block_start (this_gen, start_pos, start_time); + return this->status; } @@ -1051,20 +948,17 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this = xine_xmalloc (sizeof (demux_mpeg_block_t)); this->stream = stream; this->input = input; - + this->demux_plugin.send_headers = demux_mpeg_block_send_headers; - this->demux_plugin.start = demux_mpeg_block_start; + this->demux_plugin.send_chunk = demux_mpeg_block_send_chunk; this->demux_plugin.seek = demux_mpeg_block_seek; - this->demux_plugin.stop = demux_mpeg_block_stop; this->demux_plugin.dispose = demux_mpeg_block_dispose; this->demux_plugin.get_status = demux_mpeg_block_get_status; this->demux_plugin.get_stream_length = demux_mpeg_block_get_stream_length; this->demux_plugin.demux_class = class_gen; - this->scratch = xine_xmalloc_aligned (512, 4096, (void**) &this->scratch_base); this->status = DEMUX_FINISHED; - pthread_mutex_init( &this->mutex, NULL ); #ifdef LOG printf ("demux_mpeg_block:open_plugin:detection_method=%d\n", @@ -1203,6 +1097,6 @@ static void *init_plugin (xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 14, "mpeg_block", XINE_VERSION_CODE, NULL, init_plugin }, + { PLUGIN_DEMUX, 15, "mpeg_block", XINE_VERSION_CODE, NULL, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/demuxers/demux_mpgaudio.c b/src/demuxers/demux_mpgaudio.c index 27fb1849e..f6f6da1a6 100644 --- a/src/demuxers/demux_mpgaudio.c +++ b/src/demuxers/demux_mpgaudio.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: demux_mpgaudio.c,v 1.72 2002/10/27 00:27:26 guenter Exp $ + * $Id: demux_mpgaudio.c,v 1.73 2002/10/28 03:24:43 miguelfreitas Exp $ * * demultiplexer for mpeg audio (i.e. mp3) streams * @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -66,14 +65,8 @@ typedef struct { input_plugin_t *input; - pthread_t thread; - int thread_running; - pthread_mutex_t mutex; - int status; - int send_end_buffers; - int stream_length; long bitrate; int64_t last_pts; @@ -323,74 +316,14 @@ static int demux_mpgaudio_next (demux_mpgaudio_t *this, int decoder_flags) { return worked; } -static void *demux_mpgaudio_loop (void *this_gen) { - - demux_mpgaudio_t *this = (demux_mpgaudio_t *) this_gen; - - pthread_mutex_lock( &this->mutex ); - - /* do-while needed to seek after demux finished */ - do { - - /* main demuxer loop */ - while(this->status == DEMUX_OK) { - - if (!demux_mpgaudio_next (this, 0)) - this->status = DEMUX_FINISHED; - - /* someone may want to interrupt us */ - pthread_mutex_unlock( &this->mutex ); - /* give demux_*_stop a chance to interrupt us */ - sched_yield(); - pthread_mutex_lock( &this->mutex ); - } - - /* wait before sending end buffers: user might want to do a new seek */ - while(this->send_end_buffers && this->audio_fifo->size(this->audio_fifo) && - this->status != DEMUX_OK){ - pthread_mutex_unlock( &this->mutex ); - xine_usec_sleep(100000); - pthread_mutex_lock( &this->mutex ); - } - - } while( this->status == DEMUX_OK ); - - this->status = DEMUX_FINISHED; - - if (this->send_end_buffers) { - xine_demux_control_end(this->stream, BUF_FLAG_END_STREAM); - } - printf ("demux_mpgaudio: demux loop finished.\n"); - - this->thread_running = 0; - pthread_mutex_unlock( &this->mutex ); - pthread_exit(NULL); - - return NULL; -} - -static void demux_mpgaudio_stop (demux_plugin_t *this_gen) { +static int demux_mpgaudio_send_chunk (demux_plugin_t *this_gen) { demux_mpgaudio_t *this = (demux_mpgaudio_t *) this_gen; - void *p; - - pthread_mutex_lock( &this->mutex ); - - if (!this->thread_running) { - printf ("demux_mpgaudio_block: stop...ignored\n"); - pthread_mutex_unlock( &this->mutex ); - return; - } - - this->send_end_buffers = 0; - this->status = DEMUX_FINISHED; - - pthread_mutex_unlock( &this->mutex ); - pthread_join (this->thread, &p); - xine_demux_flush_engine(this->stream); + if (!demux_mpgaudio_next (this, 0)) + this->status = DEMUX_FINISHED; - xine_demux_control_end(this->stream, BUF_FLAG_END_USER); + return this->status; } static int demux_mpgaudio_get_status (demux_plugin_t *this_gen) { @@ -442,8 +375,7 @@ static uint32_t demux_mpgaudio_read_head(input_plugin_t *input) { static void demux_mpgaudio_send_headers (demux_plugin_t *this_gen) { demux_mpgaudio_t *this = (demux_mpgaudio_t *) this_gen; - - pthread_mutex_lock (&this->mutex); + int i; this->stream_length = 0; this->bitrate = 0; @@ -456,51 +388,36 @@ static void demux_mpgaudio_send_headers (demux_plugin_t *this_gen) { if ((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) { uint32_t head; - if (!this->thread_running) { - - head = demux_mpgaudio_read_head(this->input); - - if (mpg123_head_check(head)) - mpg123_decode_header(this,head); + + head = demux_mpgaudio_read_head(this->input); - read_id3_tags (this); + if (mpg123_head_check(head)) + mpg123_decode_header(this,head); - } + read_id3_tags (this); } /* * send preview buffers */ - - if (!this->thread_running) { - int i; + xine_demux_control_start (this->stream); - xine_demux_control_start (this->stream); - - if ((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) - this->input->seek (this->input, 0, SEEK_SET); + if ((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) + this->input->seek (this->input, 0, SEEK_SET); - for (i=0; istream); - - - pthread_mutex_unlock (&this->mutex); } -static int demux_mpgaudio_start (demux_plugin_t *this_gen, +static int demux_mpgaudio_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time) { demux_mpgaudio_t *this = (demux_mpgaudio_t *) this_gen; - int err; - int status; - - pthread_mutex_lock( &this->mutex ); if ((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) { @@ -514,44 +431,19 @@ static int demux_mpgaudio_start (demux_plugin_t *this_gen, this->status = DEMUX_OK; this->send_newpts = 1; - if( !this->thread_running ) { - /* - * now start demuxing - */ - - this->send_end_buffers = 1; - this->thread_running = 1; + if( !this->stream->demux_thread_running ) { this->buf_flag_seek = 0; - if ((err = pthread_create (&this->thread, - NULL, demux_mpgaudio_loop, this)) != 0) { - printf ("demux_mpgaudio: can't create new thread (%s)\n", - strerror(err)); - abort(); - } } else { this->buf_flag_seek = 1; xine_demux_flush_engine(this->stream); } - /* this->status is saved because we can be interrupted between - * pthread_mutex_unlock and return - */ - status = this->status; - pthread_mutex_unlock( &this->mutex ); - return status; -} - -static int demux_mpgaudio_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time) { - /* demux_mpgaudio_t *this = (demux_mpgaudio_t *) this_gen; */ - - return demux_mpgaudio_start (this_gen, start_pos, start_time); + + return this->status; } static void demux_mpgaudio_dispose (demux_plugin_t *this) { - demux_mpgaudio_stop (this); - free (this); } @@ -661,9 +553,8 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this = xine_xmalloc (sizeof (demux_mpgaudio_t)); this->demux_plugin.send_headers = demux_mpgaudio_send_headers; - this->demux_plugin.start = demux_mpgaudio_start; + this->demux_plugin.send_chunk = demux_mpgaudio_send_chunk; this->demux_plugin.seek = demux_mpgaudio_seek; - this->demux_plugin.stop = demux_mpgaudio_stop; this->demux_plugin.dispose = demux_mpgaudio_dispose; this->demux_plugin.get_status = demux_mpgaudio_get_status; this->demux_plugin.get_stream_length = demux_mpgaudio_get_stream_length; @@ -673,8 +564,6 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->audio_fifo = stream->audio_fifo; this->status = DEMUX_FINISHED; this->stream = stream; - - pthread_mutex_init( &this->mutex, NULL ); return &this->demux_plugin; } @@ -736,6 +625,6 @@ static void *init_class (xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 14, "mp3", XINE_VERSION_CODE, NULL, init_class }, + { PLUGIN_DEMUX, 15, "mp3", XINE_VERSION_CODE, NULL, init_class }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/demuxers/demux_ogg.c b/src/demuxers/demux_ogg.c index 42a7bc03b..4f996eb17 100644 --- a/src/demuxers/demux_ogg.c +++ b/src/demuxers/demux_ogg.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: demux_ogg.c,v 1.48 2002/10/27 01:52:15 guenter Exp $ + * $Id: demux_ogg.c,v 1.49 2002/10/28 03:24:43 miguelfreitas Exp $ * * demultiplexer for ogg streams * @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -105,14 +104,8 @@ typedef struct demux_ogg_s { input_plugin_t *input; - pthread_t thread; - int thread_running; - pthread_mutex_t mutex; - int status; - int send_end_buffers; - int frame_duration; ogg_sync_state oy; @@ -813,105 +806,22 @@ static void demux_ogg_send_content (demux_ogg_t *this) { } } -static void *demux_ogg_loop (void *this_gen) { - - demux_ogg_t *this = (demux_ogg_t *) this_gen; -#ifdef LOG - printf ("demux_ogg: demux loop starting...\n"); -#endif - - pthread_mutex_lock( &this->mutex ); - /* do-while needed to seek after demux finished */ - do { - - /* main demuxer loop */ - while(this->status == DEMUX_OK) { - - demux_ogg_send_content (this); - - /* someone may want to interrupt us */ - pthread_mutex_unlock( &this->mutex ); - /* give demux_*_stop a chance to interrupt us */ - sched_yield(); - pthread_mutex_lock( &this->mutex ); - } - - /* wait before sending end buffers: user might want to do a new seek */ - while (this->send_end_buffers - && (this->audio_fifo && this->audio_fifo->size(this->audio_fifo)) - && (this->status != DEMUX_OK) ) { - pthread_mutex_unlock( &this->mutex ); - xine_usec_sleep(100000); - pthread_mutex_lock( &this->mutex ); - } - - } while( this->status == DEMUX_OK ); - -#ifdef LOG - printf ("demux_ogg: demux loop finished (status: %d)\n", - this->status); -#endif +static int demux_ogg_send_chunk (demux_plugin_t *this_gen) { - this->status = DEMUX_FINISHED; - - if (this->send_end_buffers) { -#ifdef LOG - printf ("demux_ogg: sending end buffers\n"); -#endif - xine_demux_control_end(this->stream, BUF_FLAG_END_STREAM); - } else { -#ifdef LOG - printf ("demux_ogg: not sending end buffers\n"); -#endif - } - - this->thread_running = 0; - pthread_mutex_unlock( &this->mutex ); - -#ifdef LOG - printf ("demux_ogg: thread ends\n"); -#endif + demux_ogg_t *this = (demux_ogg_t *) this_gen; - pthread_exit(NULL); + demux_ogg_send_content (this); - return NULL; + return this->status; } static void demux_ogg_dispose (demux_plugin_t *this_gen) { demux_ogg_t *this = (demux_ogg_t *) this_gen; - demux_ogg_stop (this_gen); - free (this); } -static void demux_ogg_stop (demux_plugin_t *this_gen) { - - demux_ogg_t *this = (demux_ogg_t *) this_gen; - void *p; - - pthread_mutex_lock( &this->mutex ); - - printf ("demux_ogg: demux_ogg_stop\n"); - - if (!this->thread_running) { - printf ("demux_ogg: stop...ignored\n"); - pthread_mutex_unlock( &this->mutex ); - return; - } - - this->send_end_buffers = 0; - this->status = DEMUX_FINISHED; - - pthread_mutex_unlock( &this->mutex ); - pthread_join (this->thread, &p); - - xine_demux_flush_engine(this->stream); - - xine_demux_control_end(this->stream, BUF_FLAG_END_USER); -} - static int demux_ogg_get_status (demux_plugin_t *this_gen) { demux_ogg_t *this = (demux_ogg_t *) this_gen; @@ -922,8 +832,6 @@ static void demux_ogg_send_headers (demux_plugin_t *this_gen) { demux_ogg_t *this = (demux_ogg_t *) this_gen; - pthread_mutex_lock( &this->mutex ); - this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; @@ -963,19 +871,13 @@ static void demux_ogg_send_headers (demux_plugin_t *this_gen) { this->stream->stream_info[XINE_STREAM_INFO_HAS_AUDIO] = this->num_audio_streams>0; xine_demux_control_headers_done (this->stream); - - pthread_mutex_unlock (&this->mutex); } -static int demux_ogg_start (demux_plugin_t *this_gen, +static int demux_ogg_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time) { demux_ogg_t *this = (demux_ogg_t *) this_gen; - int err; - - pthread_mutex_lock( &this->mutex ); - err = 1; - + /* * seek to start position */ @@ -996,43 +898,17 @@ static int demux_ogg_start (demux_plugin_t *this_gen, this->send_newpts = 1; - if( !this->thread_running ) { - /* - * now start demuxing - */ - + if( !this->stream->demux_thread_running ) { + this->status = DEMUX_OK; - this->send_end_buffers = 1; - this->thread_running = 1; this->buf_flag_seek = 0; -#ifdef LOG - printf ("demux_ogg: creating thread (send_end_buffers=%d)\n", - this->send_end_buffers); -#endif - - if ((err = pthread_create (&this->thread, - NULL, demux_ogg_loop, this)) != 0) { - printf ("demux_ogg: can't create new thread (%s)\n", - strerror(err)); - abort(); - } } else { this->buf_flag_seek = 1; xine_demux_flush_engine(this->stream); - err = 0; } - pthread_mutex_unlock( &this->mutex ); - - return err ? DEMUX_FINISHED : DEMUX_OK; -} - -static int demux_ogg_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time) { - /* demux_ogg_t *this = (demux_ogg_t *) this_gen; */ - - return demux_ogg_start (this_gen, start_pos, start_time); + return this->status; } static int demux_ogg_get_stream_length (demux_plugin_t *this_gen) { @@ -1116,16 +992,14 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, this->input = input; this->demux_plugin.send_headers = demux_ogg_send_headers; - this->demux_plugin.start = demux_ogg_start; + this->demux_plugin.send_chunk = demux_ogg_send_chunk; this->demux_plugin.seek = demux_ogg_seek; - this->demux_plugin.stop = demux_ogg_stop; this->demux_plugin.dispose = demux_ogg_dispose; this->demux_plugin.get_status = demux_ogg_get_status; this->demux_plugin.get_stream_length = demux_ogg_get_stream_length; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; - pthread_mutex_init( &this->mutex, NULL ); return &this->demux_plugin; } @@ -1183,6 +1057,6 @@ static void *init_class (xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 14, "ogg", XINE_VERSION_CODE, NULL, init_class }, + { PLUGIN_DEMUX, 15, "ogg", XINE_VERSION_CODE, NULL, init_class }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c index 45da0b0ba..66220274f 100644 --- a/src/demuxers/demux_qt.c +++ b/src/demuxers/demux_qt.c @@ -30,7 +30,7 @@ * build_frame_table * free_qt_info * - * $Id: demux_qt.c,v 1.105 2002/10/27 17:28:24 tmmm Exp $ + * $Id: demux_qt.c,v 1.106 2002/10/28 03:24:43 miguelfreitas Exp $ * */ @@ -41,8 +41,6 @@ #include #include #include -#include -#include #include #include #include @@ -274,11 +272,6 @@ typedef struct { input_plugin_t *input; - pthread_t thread; - int thread_running; - pthread_mutex_t mutex; - int send_end_buffers; - int status; /* when this flag is set, demuxer only dispatches audio samples until it @@ -1429,7 +1422,7 @@ static qt_error open_qt_file(qt_info *info, input_plugin_t *input) { * xine demuxer functions **********************************************************************/ -static void *demux_qt_loop (void *this_gen) { +static int demux_qt_send_chunk(demux_plugin_t *this_gen) { demux_qt_t *this = (demux_qt_t *) this_gen; buf_element_t *buf = NULL; @@ -1438,191 +1431,155 @@ static void *demux_qt_loop (void *this_gen) { int edit_list_compensation = 0; int frame_duration; - pthread_mutex_lock( &this->mutex ); + i = this->current_frame; - /* do-while needed to seek after demux finished */ - do { - /* main demuxer loop */ - while (this->status == DEMUX_OK) { - - /* someone may want to interrupt us */ - pthread_mutex_unlock( &this->mutex ); - /* give demux_*_stop a chance to interrupt us */ - sched_yield(); - pthread_mutex_lock( &this->mutex ); - - i = this->current_frame; - - /* if there is an incongruency between last and current sample, it - * must be time to send a new pts */ - if (this->last_frame + 1 != this->current_frame) { - /* send new pts */ - xine_demux_control_newpts(this->stream, this->qt->frames[i].pts, - this->qt->frames[i].pts ? BUF_FLAG_SEEK : 0); - } + /* if there is an incongruency between last and current sample, it + * must be time to send a new pts */ + if (this->last_frame + 1 != this->current_frame) { + /* send new pts */ + xine_demux_control_newpts(this->stream, this->qt->frames[i].pts, + this->qt->frames[i].pts ? BUF_FLAG_SEEK : 0); + } - this->last_frame = this->current_frame; - this->current_frame++; + this->last_frame = this->current_frame; + this->current_frame++; - /* check if all the samples have been sent */ - if (i >= this->qt->frame_count) { - this->status = DEMUX_FINISHED; - break; - } + /* check if all the samples have been sent */ + if (i >= this->qt->frame_count) { + this->status = DEMUX_FINISHED; + return this->status; + } - /* check if we're only sending audio samples until the next keyframe */ - if ((this->waiting_for_keyframe) && - (this->qt->frames[i].type == MEDIA_VIDEO)) { - if (this->qt->frames[i].keyframe) { - this->waiting_for_keyframe = 0; - } else { - /* move on to the next sample */ - continue; - } - } + /* check if we're only sending audio samples until the next keyframe */ + if ((this->waiting_for_keyframe) && + (this->qt->frames[i].type == MEDIA_VIDEO)) { + if (this->qt->frames[i].keyframe) { + this->waiting_for_keyframe = 0; + } else { + /* move on to the next sample */ + return this->status; + } + } - if (this->qt->frames[i].type == MEDIA_VIDEO) { - remaining_sample_bytes = this->qt->frames[i].size; - this->input->seek(this->input, this->qt->frames[i].offset, - SEEK_SET); - - /* frame duration is the pts diff between this video frame and - * the next video frame (so search for the next video frame) */ - frame_duration = 0; - j = i; - while (++j < this->qt->frame_count) { - if (this->qt->frames[j].type == MEDIA_VIDEO) { - frame_duration = - this->qt->frames[j].pts - this->qt->frames[i].pts; - break; - } - } + if (this->qt->frames[i].type == MEDIA_VIDEO) { + remaining_sample_bytes = this->qt->frames[i].size; + this->input->seek(this->input, this->qt->frames[i].offset, + SEEK_SET); + + /* frame duration is the pts diff between this video frame and + * the next video frame (so search for the next video frame) */ + frame_duration = 0; + j = i; + while (++j < this->qt->frame_count) { + if (this->qt->frames[j].type == MEDIA_VIDEO) { + frame_duration = + this->qt->frames[j].pts - this->qt->frames[i].pts; + break; + } + } - /* Due to the edit lists, some successive frames have the same pts - * which would ordinarily cause frame_duration to be 0 which can - * cause DIV-by-0 errors in the engine. Perform this little trick - * to compensate. */ - if (!frame_duration) { - frame_duration = 1; - edit_list_compensation++; - } else { - frame_duration -= edit_list_compensation; - edit_list_compensation = 0; - } + /* Due to the edit lists, some successive frames have the same pts + * which would ordinarily cause frame_duration to be 0 which can + * cause DIV-by-0 errors in the engine. Perform this little trick + * to compensate. */ + if (!frame_duration) { + frame_duration = 1; + edit_list_compensation++; + } else { + frame_duration -= edit_list_compensation; + edit_list_compensation = 0; + } /* printf ("%d) video frame, size %d, pts %lld, duration %d\n", - i, - this->qt->frames[i].size, - this->qt->frames[i].pts, - frame_duration); +i, +this->qt->frames[i].size, +this->qt->frames[i].pts, +frame_duration); */ - while (remaining_sample_bytes) { - buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); - buf->type = this->qt->video_type; - buf->input_pos = this->qt->frames[i].offset - this->data_start; - buf->input_length = this->data_size; - buf->input_time = this->qt->frames[i].pts / 90000; - buf->pts = this->qt->frames[i].pts; + while (remaining_sample_bytes) { + buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); + buf->type = this->qt->video_type; + buf->input_pos = this->qt->frames[i].offset - this->data_start; + buf->input_length = this->data_size; + buf->input_time = this->qt->frames[i].pts / 90000; + buf->pts = this->qt->frames[i].pts; - buf->decoder_flags |= BUF_FLAG_FRAMERATE; - buf->decoder_info[0] = frame_duration; + buf->decoder_flags |= BUF_FLAG_FRAMERATE; + buf->decoder_info[0] = frame_duration; - if (remaining_sample_bytes > buf->max_size) - buf->size = buf->max_size; - else - buf->size = remaining_sample_bytes; - remaining_sample_bytes -= buf->size; - - if (this->input->read(this->input, buf->content, buf->size) != - buf->size) { - buf->free_buffer(buf); - this->status = DEMUX_FINISHED; - break; - } + if (remaining_sample_bytes > buf->max_size) + buf->size = buf->max_size; + else + buf->size = remaining_sample_bytes; + remaining_sample_bytes -= buf->size; - if (this->qt->frames[i].keyframe) - buf->decoder_flags |= BUF_FLAG_KEYFRAME; - if (!remaining_sample_bytes) - buf->decoder_flags |= BUF_FLAG_FRAME_END; + if (this->input->read(this->input, buf->content, buf->size) != + buf->size) { + buf->free_buffer(buf); + this->status = DEMUX_FINISHED; + break; + } - this->video_fifo->put(this->video_fifo, buf); - } + if (this->qt->frames[i].keyframe) + buf->decoder_flags |= BUF_FLAG_KEYFRAME; + if (!remaining_sample_bytes) + buf->decoder_flags |= BUF_FLAG_FRAME_END; - } else if ((this->qt->frames[i].type == MEDIA_AUDIO) && - this->audio_fifo && this->qt->audio_type) { - /* load an audio sample and packetize it */ - remaining_sample_bytes = this->qt->frames[i].size; - this->input->seek(this->input, this->qt->frames[i].offset, - SEEK_SET); + this->video_fifo->put(this->video_fifo, buf); + } + + } else if ((this->qt->frames[i].type == MEDIA_AUDIO) && + this->audio_fifo && this->qt->audio_type) { + /* load an audio sample and packetize it */ + remaining_sample_bytes = this->qt->frames[i].size; + this->input->seek(this->input, this->qt->frames[i].offset, + SEEK_SET); /* printf ("%d) audio frame, size %d, pts %lld\n", - i, - this->qt->frames[i].size, - this->qt->frames[i].pts); +i, +this->qt->frames[i].size, +this->qt->frames[i].pts); */ - while (remaining_sample_bytes) { - buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); - buf->type = this->qt->audio_type; - buf->input_pos = this->qt->frames[i].offset - this->data_start; - buf->input_length = this->data_size; - buf->input_time = this->qt->frames[i].pts / 90000; - buf->pts = this->qt->frames[i].pts; + while (remaining_sample_bytes) { + buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); + buf->type = this->qt->audio_type; + buf->input_pos = this->qt->frames[i].offset - this->data_start; + buf->input_length = this->data_size; + buf->input_time = this->qt->frames[i].pts / 90000; + buf->pts = this->qt->frames[i].pts; - if (remaining_sample_bytes > buf->max_size) - buf->size = buf->max_size; - else - buf->size = remaining_sample_bytes; - remaining_sample_bytes -= buf->size; - - if (this->input->read(this->input, buf->content, buf->size) != - buf->size) { - buf->free_buffer(buf); - this->status = DEMUX_FINISHED; - break; - } + if (remaining_sample_bytes > buf->max_size) + buf->size = buf->max_size; + else + buf->size = remaining_sample_bytes; + remaining_sample_bytes -= buf->size; - if (!remaining_sample_bytes) { - buf->decoder_flags |= BUF_FLAG_FRAME_END; + if (this->input->read(this->input, buf->content, buf->size) != + buf->size) { + buf->free_buffer(buf); + this->status = DEMUX_FINISHED; + break; + } - if( this->qt->audio_sample_size_table ) { - buf->decoder_flags |= BUF_FLAG_SPECIAL; - buf->decoder_info[1] = BUF_SPECIAL_SAMPLE_SIZE_TABLE; - buf->decoder_info[3] = (uint32_t) - &this->qt->audio_sample_size_table[this->qt->frames[i].official_byte_count]; - } - } + if (!remaining_sample_bytes) { + buf->decoder_flags |= BUF_FLAG_FRAME_END; - this->audio_fifo->put(this->audio_fifo, buf); + if( this->qt->audio_sample_size_table ) { + buf->decoder_flags |= BUF_FLAG_SPECIAL; + buf->decoder_info[1] = BUF_SPECIAL_SAMPLE_SIZE_TABLE; + buf->decoder_info[3] = (uint32_t) + &this->qt->audio_sample_size_table[this->qt->frames[i].official_byte_count]; } } - } - /* wait before sending end buffers: user might want to do a new seek */ - while(this->send_end_buffers && this->video_fifo->size(this->video_fifo) && - this->status != DEMUX_OK){ - pthread_mutex_unlock( &this->mutex ); - xine_usec_sleep(100000); - pthread_mutex_lock( &this->mutex ); + this->audio_fifo->put(this->audio_fifo, buf); } - - } while (this->status == DEMUX_OK); - - printf ("demux_qt: demux loop finished (status: %d)\n", - this->status); - - this->status = DEMUX_FINISHED; - - if (this->send_end_buffers) { - xine_demux_control_end(this->stream, BUF_FLAG_END_STREAM); } - - this->thread_running = 0; - pthread_mutex_unlock(&this->mutex); - return NULL; + return this->status; } static void demux_qt_send_headers(demux_plugin_t *this_gen) { @@ -1631,7 +1588,6 @@ static void demux_qt_send_headers(demux_plugin_t *this_gen) { buf_element_t *buf; printf ("sending qt headers\n"); - pthread_mutex_lock(&this->mutex); this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; @@ -1739,41 +1695,6 @@ printf ("sending qt headers\n"); } xine_demux_control_headers_done (this->stream); - - pthread_mutex_unlock (&this->mutex); -} - -static int demux_qt_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time); - -static int demux_qt_start (demux_plugin_t *this_gen, - off_t start_pos, int start_time) { - demux_qt_t *this = (demux_qt_t *) this_gen; - int err; - - /* perform a seek with the start_pos before starting the demuxer */ - demux_qt_seek(this_gen, start_pos, start_time); - - pthread_mutex_lock(&this->mutex); - - /* if thread is not running, initialize demuxer */ - if (!this->thread_running) { - - this->status = DEMUX_OK; - this->send_end_buffers = 1; - this->thread_running = 1; - - this->last_frame = 0; - - if ((err = pthread_create (&this->thread, NULL, demux_qt_loop, this)) != 0) { - printf ("demux_qt: can't create new thread (%s)\n", strerror(err)); - abort(); - } - } - - pthread_mutex_unlock(&this->mutex); - - return DEMUX_OK; } static int demux_qt_seek (demux_plugin_t *this_gen, @@ -1784,9 +1705,6 @@ static int demux_qt_seek (demux_plugin_t *this_gen, int left, middle, right; int found; int64_t keyframe_pts; - int status; - - pthread_mutex_lock(&this->mutex); this->waiting_for_keyframe = 0; @@ -1795,9 +1713,8 @@ static int demux_qt_seek (demux_plugin_t *this_gen, if (start_pos <= this->qt->frames[0].offset) best_index = 0; else if (start_pos >= this->qt->frames[this->qt->frame_count - 1].offset) { - status = this->status = DEMUX_FINISHED; - pthread_mutex_unlock( &this->mutex ); - return status; + this->status = DEMUX_FINISHED; + return this->status; } else { left = 0; right = this->qt->frame_count - 1; @@ -1844,44 +1761,18 @@ static int demux_qt_seek (demux_plugin_t *this_gen, this->status = DEMUX_OK; xine_demux_flush_engine(this->stream); - - pthread_mutex_unlock( &this->mutex ); - - return DEMUX_OK; -} - -static void demux_qt_stop (demux_plugin_t *this_gen) { - - demux_qt_t *this = (demux_qt_t *) this_gen; - void *p; - - pthread_mutex_lock( &this->mutex ); - - if (!this->thread_running) { - pthread_mutex_unlock( &this->mutex ); - return; + + if( !this->stream->demux_thread_running ) { + this->last_frame = 0; } - this->send_end_buffers = 0; - this->status = DEMUX_FINISHED; - - xine_demux_flush_engine(this->stream); - - pthread_mutex_unlock( &this->mutex ); - pthread_join (this->thread, &p); - - this->current_frame = this->last_frame = 0; - - xine_demux_control_end(this->stream, BUF_FLAG_END_USER); + return this->status; } static void demux_qt_dispose (demux_plugin_t *this_gen) { demux_qt_t *this = (demux_qt_t *) this_gen; - demux_qt_stop(this_gen); - free_qt_info(this->qt); - pthread_mutex_destroy (&this->mutex); free(this); } @@ -1919,16 +1810,14 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->input = input; this->demux_plugin.send_headers = demux_qt_send_headers; - this->demux_plugin.start = demux_qt_start; + this->demux_plugin.send_chunk = demux_qt_send_chunk; this->demux_plugin.seek = demux_qt_seek; - this->demux_plugin.stop = demux_qt_stop; this->demux_plugin.dispose = demux_qt_dispose; this->demux_plugin.get_status = demux_qt_get_status; this->demux_plugin.get_stream_length = demux_qt_get_stream_length; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; - pthread_mutex_init (&this->mutex, NULL); switch (stream->content_detection_method) { @@ -2070,6 +1959,6 @@ static void *init_plugin (xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 14, "quicktime", XINE_VERSION_CODE, NULL, init_plugin }, + { PLUGIN_DEMUX, 15, "quicktime", XINE_VERSION_CODE, NULL, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/demuxers/demux_real.c b/src/demuxers/demux_real.c index fdaeacbfa..c6ba422a1 100644 --- a/src/demuxers/demux_real.c +++ b/src/demuxers/demux_real.c @@ -21,7 +21,7 @@ * For more information regarding the Real file format, visit: * http://www.pcisys.net/~melanson/codecs/ * - * $Id: demux_real.c,v 1.5 2002/10/27 03:18:11 tmmm Exp $ + * $Id: demux_real.c,v 1.6 2002/10/28 03:24:43 miguelfreitas Exp $ */ #ifdef HAVE_CONFIG_H @@ -31,8 +31,6 @@ #include #include #include -#include -#include #include #include @@ -83,11 +81,6 @@ typedef struct { input_plugin_t *input; - pthread_t thread; - int thread_running; - pthread_mutex_t mutex; - int send_end_buffers; - off_t data_start; off_t data_size; int status; @@ -254,7 +247,7 @@ static int open_real_file(demux_real_t *this) { return 1; } -static void *demux_real_loop (void *this_gen) { +static int demux_real_send_chunk(demux_plugin_t *this_gen) { demux_real_t *this = (demux_real_t *) this_gen; buf_element_t *buf = NULL; @@ -262,113 +255,71 @@ static void *demux_real_loop (void *this_gen) { unsigned char data_chunk_header[DATA_CHUNK_HEADER_SIZE]; char header[DATA_PACKET_HEADER_SIZE]; - pthread_mutex_lock( &this->mutex ); - - /* do-while needed to seek after demux finished */ - do { - /* main demuxer loop */ - while (this->status == DEMUX_OK) { - - /* someone may want to interrupt us */ - pthread_mutex_unlock( &this->mutex ); - /* give demux_*_stop a chance to interrupt us */ - sched_yield(); - pthread_mutex_lock( &this->mutex ); - - /* load a header from wherever the stream happens to be pointing */ - if (this->input->read(this->input, header, DATA_PACKET_HEADER_SIZE) != - DATA_PACKET_HEADER_SIZE) { - this->status = DEMUX_FINISHED; - break; - } + /* load a header from wherever the stream happens to be pointing */ + if (this->input->read(this->input, header, DATA_PACKET_HEADER_SIZE) != + DATA_PACKET_HEADER_SIZE) { + this->status = DEMUX_FINISHED; + return this->status; + } - /* log the packet information */ - this->packets[this->current_packet].stream = BE_16(&header[4]); - this->packets[this->current_packet].offset = - this->input->get_current_pos(this->input); - this->packets[this->current_packet].size = - BE_16(&header[2]) - DATA_PACKET_HEADER_SIZE; - this->packets[this->current_packet].pts = - BE_32(&header[6]); - this->packets[this->current_packet].pts *= 90; - this->packets[this->current_packet].keyframe = - (header[11] & PN_KEYFRAME_FLAG); + /* log the packet information */ + this->packets[this->current_packet].stream = BE_16(&header[4]); + this->packets[this->current_packet].offset = + this->input->get_current_pos(this->input); + this->packets[this->current_packet].size = + BE_16(&header[2]) - DATA_PACKET_HEADER_SIZE; + this->packets[this->current_packet].pts = + BE_32(&header[6]); + this->packets[this->current_packet].pts *= 90; + this->packets[this->current_packet].keyframe = + (header[11] & PN_KEYFRAME_FLAG); printf ("packet %d: stream %d, 0x%X bytes @ %llX, pts = %lld%s\n", - this->current_packet, - this->packets[this->current_packet].stream, - this->packets[this->current_packet].size, - this->packets[this->current_packet].offset, - this->packets[this->current_packet].pts, - (this->packets[this->current_packet].keyframe) ? ", keyframe" : ""); +this->current_packet, +this->packets[this->current_packet].stream, +this->packets[this->current_packet].size, +this->packets[this->current_packet].offset, +this->packets[this->current_packet].pts, +(this->packets[this->current_packet].keyframe) ? ", keyframe" : ""); this->input->seek(this->input, this->packets[this->current_packet].size, - SEEK_CUR); - - this->current_packet++; - this->current_data_chunk_packet_count--; - - /* check if it's time to reload */ - if (!this->current_data_chunk_packet_count && - this->next_data_chunk_offset) { - - /* seek to the next DATA chunk offset */ - this->input->seek(this->input, this->next_data_chunk_offset, SEEK_SET); - - /* load the DATA chunk preamble */ - if (this->input->read(this->input, preamble, PREAMBLE_SIZE) != - PREAMBLE_SIZE) { - this->status = DEMUX_FINISHED; - break; - } - - /* load the rest of the DATA chunk header */ - if (this->input->read(this->input, data_chunk_header, - DATA_CHUNK_HEADER_SIZE) != DATA_CHUNK_HEADER_SIZE) { - this->status = DEMUX_FINISHED; - break; - } -printf ("**** found next DATA tag\n"); - this->current_data_chunk_packet_count = BE_32(&data_chunk_header[2]); - this->next_data_chunk_offset = BE_32(&data_chunk_header[6]); - } +SEEK_CUR); -if (!this->current_data_chunk_packet_count) { - this->status = DEMUX_FINISHED; - break; -} - } + this->current_packet++; + this->current_data_chunk_packet_count--; - /* wait before sending end buffers: user might want to do a new seek */ - while(this->send_end_buffers && this->audio_fifo->size(this->audio_fifo) && - this->status != DEMUX_OK){ - pthread_mutex_unlock( &this->mutex ); - xine_usec_sleep(100000); - pthread_mutex_lock( &this->mutex ); - } + /* check if it's time to reload */ + if (!this->current_data_chunk_packet_count && + this->next_data_chunk_offset) { - } while (this->status == DEMUX_OK); + /* seek to the next DATA chunk offset */ + this->input->seek(this->input, this->next_data_chunk_offset, SEEK_SET); - printf ("demux_real: demux loop finished (status: %d)\n", - this->status); - - /* seek back to the beginning of the data in preparation for another - * start */ - this->input->seek(this->input, this->data_start, SEEK_SET); - - this->status = DEMUX_FINISHED; + /* load the DATA chunk preamble */ + if (this->input->read(this->input, preamble, PREAMBLE_SIZE) != + PREAMBLE_SIZE) { + this->status = DEMUX_FINISHED; + return this->status; + } - if (this->send_end_buffers) { - xine_demux_control_end(this->stream, BUF_FLAG_END_STREAM); + /* load the rest of the DATA chunk header */ + if (this->input->read(this->input, data_chunk_header, + DATA_CHUNK_HEADER_SIZE) != DATA_CHUNK_HEADER_SIZE) { + this->status = DEMUX_FINISHED; + return this->status; + } +printf ("**** found next DATA tag\n"); + this->current_data_chunk_packet_count = BE_32(&data_chunk_header[2]); + this->next_data_chunk_offset = BE_32(&data_chunk_header[6]); } - this->thread_running = 0; - - pthread_mutex_unlock( &this->mutex ); - - return NULL; + if (!this->current_data_chunk_packet_count) { + this->status = DEMUX_FINISHED; + return this->status; + } + return this->status; } static void demux_real_send_headers(demux_plugin_t *this_gen) { @@ -376,8 +327,6 @@ static void demux_real_send_headers(demux_plugin_t *this_gen) { demux_real_t *this = (demux_real_t *) this_gen; buf_element_t *buf; - pthread_mutex_lock( &this->mutex ); - this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; @@ -391,80 +340,30 @@ static void demux_real_send_headers(demux_plugin_t *this_gen) { xine_demux_control_headers_done (this->stream); - - pthread_mutex_unlock( &this->mutex ); } static int demux_real_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time); - -static int demux_real_start (demux_plugin_t *this_gen, off_t start_pos, int start_time) { demux_real_t *this = (demux_real_t *) this_gen; - int err; - - pthread_mutex_lock(&this->mutex); - - demux_real_seek(this_gen, start_pos, start_time); /* if thread is not running, initialize demuxer */ - if (!this->thread_running) { + if( !this->stream->demux_thread_running ) { /* send new pts */ /* xine_demux_control_newpts(this->stream, 0, 0); */ this->status = DEMUX_OK; - this->send_end_buffers = 1; - this->thread_running = 1; - - if ((err = pthread_create (&this->thread, NULL, demux_real_loop, this)) != 0) { - printf ("demux_real: can't create new thread (%s)\n", strerror(err)); - abort(); - } } - pthread_mutex_unlock(&this->mutex); - - return DEMUX_OK; -} - -static int demux_real_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time) { - - return 0; -} - -static void demux_real_stop (demux_plugin_t *this_gen) { - - demux_real_t *this = (demux_real_t *) this_gen; - void *p; - - pthread_mutex_lock( &this->mutex ); - - if (!this->thread_running) { - pthread_mutex_unlock( &this->mutex ); - return; - } - - this->send_end_buffers = 0; - this->status = DEMUX_FINISHED; - - pthread_mutex_unlock( &this->mutex ); - pthread_join (this->thread, &p); - - xine_demux_flush_engine(this->stream); - - xine_demux_control_end(this->stream, BUF_FLAG_END_USER); + return this->status; } static void demux_real_dispose (demux_plugin_t *this_gen) { demux_real_t *this = (demux_real_t *) this_gen; - demux_real_stop(this_gen); - free(this->packets); free(this); } @@ -499,16 +398,14 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->input = input; this->demux_plugin.send_headers = demux_real_send_headers; - this->demux_plugin.start = demux_real_start; + this->demux_plugin.send_chunk = demux_real_send_chunk; this->demux_plugin.seek = demux_real_seek; - this->demux_plugin.stop = demux_real_stop; this->demux_plugin.dispose = demux_real_dispose; this->demux_plugin.get_status = demux_real_get_status; this->demux_plugin.get_stream_length = demux_real_get_stream_length; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; - pthread_mutex_init (&this->mutex, NULL); switch (stream->content_detection_method) { @@ -610,6 +507,6 @@ static void *init_plugin (xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 14, "real", XINE_VERSION_CODE, NULL, init_plugin }, + { PLUGIN_DEMUX, 15, "real", XINE_VERSION_CODE, NULL, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/demuxers/demux_realaudio.c b/src/demuxers/demux_realaudio.c index 570ae9851..d3a4eb453 100644 --- a/src/demuxers/demux_realaudio.c +++ b/src/demuxers/demux_realaudio.c @@ -19,7 +19,7 @@ * * RealAudio File Demuxer by Mike Melanson (melanson@pcisys.net) * - * $Id: demux_realaudio.c,v 1.1 2002/10/27 18:00:30 tmmm Exp $ + * $Id: demux_realaudio.c,v 1.2 2002/10/28 03:24:43 miguelfreitas Exp $ * */ @@ -30,8 +30,6 @@ #include #include #include -#include -#include #include #include #include @@ -58,10 +56,6 @@ typedef struct { input_plugin_t *input; - pthread_t thread; - int thread_running; - pthread_mutex_t mutex; - int send_end_buffers; int status; xine_waveformatex wave; @@ -121,7 +115,7 @@ static int open_ra_file(demux_ra_t *this) { return 1; } -static void *demux_ra_loop (void *this_gen) { +static int demux_ra_send_chunk(demux_plugin_t *this_gen) { demux_ra_t *this = (demux_ra_t *) this_gen; buf_element_t *buf = NULL; @@ -129,91 +123,50 @@ static void *demux_ra_loop (void *this_gen) { off_t current_file_pos; int64_t current_pts; - pthread_mutex_lock( &this->mutex ); - this->seek_flag = 1; - - /* do-while needed to seek after demux finished */ - do { - /* main demuxer loop */ - while (this->status == DEMUX_OK) { - - /* someone may want to interrupt us */ - pthread_mutex_unlock( &this->mutex ); - /* give demux_*_stop a chance to interrupt us */ - sched_yield(); - pthread_mutex_lock( &this->mutex ); - - /* just load data chunks from wherever the stream happens to be - * pointing; issue a DEMUX_FINISHED status if EOF is reached */ - remaining_sample_bytes = this->wave.nBlockAlign; - current_file_pos = - this->input->get_current_pos(this->input) - this->data_start; - - - - current_pts = 0; /* let the engine sort out the pts for now */ - + /* just load data chunks from wherever the stream happens to be + * pointing; issue a DEMUX_FINISHED status if EOF is reached */ + remaining_sample_bytes = this->wave.nBlockAlign; + current_file_pos = + this->input->get_current_pos(this->input) - this->data_start; - if (this->seek_flag) { - xine_demux_control_newpts(this->stream, current_pts, 0); - this->seek_flag = 0; - } - while (remaining_sample_bytes) { - buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); - buf->type = this->audio_type; - buf->input_pos = current_file_pos; - buf->input_length = this->data_size; - buf->input_time = current_pts / 90000; - buf->pts = current_pts; + current_pts = 0; /* let the engine sort out the pts for now */ - if (remaining_sample_bytes > buf->max_size) - buf->size = buf->max_size; - else - buf->size = remaining_sample_bytes; - remaining_sample_bytes -= buf->size; - if (this->input->read(this->input, buf->content, buf->size) != - buf->size) { - buf->free_buffer(buf); - this->status = DEMUX_FINISHED; - break; - } - if (!remaining_sample_bytes) - buf->decoder_flags |= BUF_FLAG_FRAME_END; - - this->audio_fifo->put (this->audio_fifo, buf); - } - } + if (this->seek_flag) { + xine_demux_control_newpts(this->stream, current_pts, 0); + this->seek_flag = 0; + } - /* wait before sending end buffers: user might want to do a new seek */ - while(this->send_end_buffers && this->audio_fifo->size(this->audio_fifo) && - this->status != DEMUX_OK){ - pthread_mutex_unlock( &this->mutex ); - xine_usec_sleep(100000); - pthread_mutex_lock( &this->mutex ); + while (remaining_sample_bytes) { + buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); + buf->type = this->audio_type; + buf->input_pos = current_file_pos; + buf->input_length = this->data_size; + buf->input_time = current_pts / 90000; + buf->pts = current_pts; + + if (remaining_sample_bytes > buf->max_size) + buf->size = buf->max_size; + else + buf->size = remaining_sample_bytes; + remaining_sample_bytes -= buf->size; + + if (this->input->read(this->input, buf->content, buf->size) != + buf->size) { + buf->free_buffer(buf); + this->status = DEMUX_FINISHED; + break; } - } while (this->status == DEMUX_OK); - - printf ("demux_ra: demux loop finished (status: %d)\n", - this->status); - - /* seek back to the beginning of the data in preparation for another - * start */ - this->input->seek(this->input, this->data_start, SEEK_SET); + if (!remaining_sample_bytes) + buf->decoder_flags |= BUF_FLAG_FRAME_END; - this->status = DEMUX_FINISHED; - - if (this->send_end_buffers) { - xine_demux_control_end(this->stream, BUF_FLAG_END_STREAM); + this->audio_fifo->put (this->audio_fifo, buf); } - - this->thread_running = 0; - pthread_mutex_unlock(&this->mutex); - return NULL; + return this->status; } static void demux_ra_send_headers(demux_plugin_t *this_gen) { @@ -221,8 +174,6 @@ static void demux_ra_send_headers(demux_plugin_t *this_gen) { demux_ra_t *this = (demux_ra_t *) this_gen; buf_element_t *buf; - pthread_mutex_lock(&this->mutex); - this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; @@ -256,58 +207,19 @@ static void demux_ra_send_headers(demux_plugin_t *this_gen) { } xine_demux_control_headers_done (this->stream); - - pthread_mutex_unlock (&this->mutex); -} - -static int demux_ra_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time); - - -static int demux_ra_start (demux_plugin_t *this_gen, - off_t start_pos, int start_time) { - - demux_ra_t *this = (demux_ra_t *) this_gen; - int err; - - demux_ra_seek(this_gen, start_pos, start_time); - - pthread_mutex_lock(&this->mutex); - - /* if thread is not running, initialize demuxer */ - if (!this->thread_running) { - - this->status = DEMUX_OK; - this->send_end_buffers = 1; - this->thread_running = 1; - - if ((err = pthread_create (&this->thread, NULL, demux_ra_loop, this)) != 0) - { - printf ("demux_ra: can't create new thread (%s)\n", strerror(err)); - abort(); - } - } - - pthread_mutex_unlock(&this->mutex); - - return DEMUX_OK; } static int demux_ra_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time) { demux_ra_t *this = (demux_ra_t *) this_gen; - int status; - - pthread_mutex_lock(&this->mutex); /* check the boundary offsets */ if (start_pos <= 0) this->input->seek(this->input, this->data_start, SEEK_SET); else if (start_pos >= this->data_size) { - status = this->status = DEMUX_FINISHED; - pthread_mutex_unlock(&this->mutex); - return status; + this->status = DEMUX_FINISHED; + return this->status; } else { /* This function must seek along the block alignment. The start_pos * is in reference to the start of the data. Divide the start_pos by @@ -322,46 +234,22 @@ static int demux_ra_seek (demux_plugin_t *this_gen, } this->seek_flag = 1; - status = this->status = DEMUX_OK; + this->status = DEMUX_OK; xine_demux_flush_engine (this->stream); - pthread_mutex_unlock(&this->mutex); - - return status; -} - -static void demux_ra_stop (demux_plugin_t *this_gen) { - - demux_ra_t *this = (demux_ra_t *) this_gen; - void *p; - - pthread_mutex_lock( &this->mutex ); + + /* if thread is not running, initialize demuxer */ + if( !this->stream->demux_thread_running ) { - if (!this->thread_running) { - pthread_mutex_unlock( &this->mutex ); - return; + this->status = DEMUX_OK; } - /* seek back to the beginning of the data in preparation for another - * start */ - this->input->seek(this->input, this->data_start, SEEK_SET); - - this->send_end_buffers = 0; - this->status = DEMUX_FINISHED; - - pthread_mutex_unlock( &this->mutex ); - pthread_join (this->thread, &p); - - xine_demux_flush_engine(this->stream); - - xine_demux_control_end(this->stream, BUF_FLAG_END_USER); + return this->status; } + static void demux_ra_dispose (demux_plugin_t *this_gen) { demux_ra_t *this = (demux_ra_t *) this_gen; - demux_ra_stop(this_gen); - - pthread_mutex_destroy (&this->mutex); free(this); } @@ -395,16 +283,14 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->input = input; this->demux_plugin.send_headers = demux_ra_send_headers; - this->demux_plugin.start = demux_ra_start; + this->demux_plugin.send_chunk = demux_ra_send_chunk; this->demux_plugin.seek = demux_ra_seek; - this->demux_plugin.stop = demux_ra_stop; this->demux_plugin.dispose = demux_ra_dispose; this->demux_plugin.get_status = demux_ra_get_status; this->demux_plugin.get_stream_length = demux_ra_get_stream_length; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; - pthread_mutex_init (&this->mutex, NULL); switch (stream->content_detection_method) { @@ -511,7 +397,7 @@ static void *init_plugin (xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 14, "realaudio", XINE_VERSION_CODE, NULL, init_plugin }, + { PLUGIN_DEMUX, 15, "realaudio", XINE_VERSION_CODE, NULL, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/demuxers/demux_roq.c b/src/demuxers/demux_roq.c index 381da363d..fc7212a8f 100644 --- a/src/demuxers/demux_roq.c +++ b/src/demuxers/demux_roq.c @@ -21,7 +21,7 @@ * For more information regarding the RoQ file format, visit: * http://www.csse.monash.edu.au/~timf/ * - * $Id: demux_roq.c,v 1.25 2002/10/27 16:14:28 tmmm Exp $ + * $Id: demux_roq.c,v 1.26 2002/10/28 03:24:43 miguelfreitas Exp $ */ #ifdef HAVE_CONFIG_H @@ -31,8 +31,6 @@ #include #include #include -#include -#include #include #include @@ -65,11 +63,6 @@ typedef struct { input_plugin_t *input; - pthread_t thread; - int thread_running; - pthread_mutex_t mutex; - int send_end_buffers; - off_t start; int status; @@ -178,7 +171,7 @@ static int open_roq_file(demux_roq_t *this) { return 1; } -static void *demux_roq_loop (void *this_gen) { +static int demux_roq_send_chunk(demux_plugin_t *this_gen) { demux_roq_t *this = (demux_roq_t *) this_gen; buf_element_t *buf = NULL; @@ -190,154 +183,116 @@ static void *demux_roq_loop (void *this_gen) { unsigned int audio_byte_count = 0; off_t current_file_pos; - pthread_mutex_lock( &this->mutex ); + /* fetch the next preamble */ + if (this->input->read(this->input, preamble, RoQ_CHUNK_PREAMBLE_SIZE) != + RoQ_CHUNK_PREAMBLE_SIZE) { + this->status = DEMUX_FINISHED; + return this->status; + } + chunk_type = LE_16(&preamble[0]); + chunk_size = LE_32(&preamble[2]); + + /* if the chunk is an audio chunk, route it to the audio fifo */ + if ((chunk_type == RoQ_SOUND_MONO) || (chunk_type == RoQ_SOUND_STEREO)) { + /* rewind over the preamble */ + this->input->seek(this->input, -RoQ_CHUNK_PREAMBLE_SIZE, SEEK_CUR); - /* start after the signature chunk */ - this->input->seek(this->input, RoQ_CHUNK_PREAMBLE_SIZE, SEEK_SET); + /* adjust the chunk size */ + chunk_size += RoQ_CHUNK_PREAMBLE_SIZE; - /* do-while needed to seek after demux finished */ - do { - /* main demuxer loop */ - while (this->status == DEMUX_OK) { + if( this->audio_fifo ) { + + /* do this calculation carefully because I can't trust the + * 64-bit numerical manipulation */ + audio_pts = audio_byte_count; + audio_pts *= 90000; + audio_pts /= (RoQ_AUDIO_SAMPLE_RATE * this->audio_channels); + audio_byte_count += chunk_size - 8; /* do not count the preamble */ + + current_file_pos = this->input->get_current_pos(this->input); + + /* packetize the audio */ + while (chunk_size) { + buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); + buf->type = BUF_AUDIO_ROQ; + buf->input_pos = current_file_pos; + buf->pts = audio_pts; + + if (chunk_size > buf->max_size) + buf->size = buf->max_size; + else + buf->size = chunk_size; + chunk_size -= buf->size; + + if (this->input->read(this->input, buf->content, buf->size) != + buf->size) { + this->status = DEMUX_FINISHED; + break; + } - /* fetch the next preamble */ + if (!chunk_size) + buf->decoder_flags |= BUF_FLAG_FRAME_END; + this->audio_fifo->put(this->audio_fifo, buf); + } + } else { + /* no audio -> skip chunk */ + this->input->seek(this->input, chunk_size, SEEK_CUR); + } + } else if (chunk_type == RoQ_INFO) { + /* skip 8 bytes */ + this->input->seek(this->input, 8, SEEK_CUR); + } else if ((chunk_type == RoQ_QUAD_CODEBOOK) || + (chunk_type == RoQ_QUAD_VQ)) { + + current_file_pos = this->input->get_current_pos(this->input) - + RoQ_CHUNK_PREAMBLE_SIZE; + + /* if the chunk is video, check if it is a codebook */ + if (chunk_type == RoQ_QUAD_CODEBOOK) { + /* if it is, figure in the size of the next VQ chunk, too */ + this->input->seek(this->input, chunk_size, SEEK_CUR); if (this->input->read(this->input, preamble, RoQ_CHUNK_PREAMBLE_SIZE) != RoQ_CHUNK_PREAMBLE_SIZE) { this->status = DEMUX_FINISHED; - break; + return this->status; } - chunk_type = LE_16(&preamble[0]); - chunk_size = LE_32(&preamble[2]); - /* if the chunk is an audio chunk, route it to the audio fifo */ - if ((chunk_type == RoQ_SOUND_MONO) || (chunk_type == RoQ_SOUND_STEREO)) { - /* rewind over the preamble */ - this->input->seek(this->input, -RoQ_CHUNK_PREAMBLE_SIZE, SEEK_CUR); + /* rewind to the start of the codebook chunk */ + this->input->seek(this->input, current_file_pos, SEEK_SET); - /* adjust the chunk size */ - chunk_size += RoQ_CHUNK_PREAMBLE_SIZE; - - if( this->audio_fifo ) { - - /* do this calculation carefully because I can't trust the - * 64-bit numerical manipulation */ - audio_pts = audio_byte_count; - audio_pts *= 90000; - audio_pts /= (RoQ_AUDIO_SAMPLE_RATE * this->audio_channels); - audio_byte_count += chunk_size - 8; /* do not count the preamble */ - - current_file_pos = this->input->get_current_pos(this->input); - - /* packetize the audio */ - while (chunk_size) { - buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); - buf->type = BUF_AUDIO_ROQ; - buf->input_pos = current_file_pos; - buf->pts = audio_pts; - - if (chunk_size > buf->max_size) - buf->size = buf->max_size; - else - buf->size = chunk_size; - chunk_size -= buf->size; - - if (this->input->read(this->input, buf->content, buf->size) != - buf->size) { - this->status = DEMUX_FINISHED; - break; - } - - if (!chunk_size) - buf->decoder_flags |= BUF_FLAG_FRAME_END; - this->audio_fifo->put(this->audio_fifo, buf); - } - } else { - /* no audio -> skip chunk */ - this->input->seek(this->input, chunk_size, SEEK_CUR); - } - } else if (chunk_type == RoQ_INFO) { - /* skip 8 bytes */ - this->input->seek(this->input, 8, SEEK_CUR); - } else if ((chunk_type == RoQ_QUAD_CODEBOOK) || - (chunk_type == RoQ_QUAD_VQ)) { - - current_file_pos = this->input->get_current_pos(this->input) - - RoQ_CHUNK_PREAMBLE_SIZE; - - /* if the chunk is video, check if it is a codebook */ - if (chunk_type == RoQ_QUAD_CODEBOOK) { - /* if it is, figure in the size of the next VQ chunk, too */ - this->input->seek(this->input, chunk_size, SEEK_CUR); - if (this->input->read(this->input, preamble, RoQ_CHUNK_PREAMBLE_SIZE) != - RoQ_CHUNK_PREAMBLE_SIZE) { - this->status = DEMUX_FINISHED; - break; - } - - /* rewind to the start of the codebook chunk */ - this->input->seek(this->input, current_file_pos, SEEK_SET); - - /* figure out the total video chunk size */ - chunk_size += (2 * RoQ_CHUNK_PREAMBLE_SIZE) + LE_32(&preamble[2]); - } + /* figure out the total video chunk size */ + chunk_size += (2 * RoQ_CHUNK_PREAMBLE_SIZE) + LE_32(&preamble[2]); + } - /* packetize the video chunk and route it to the video fifo */ - while (chunk_size) { - buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); - buf->type = BUF_VIDEO_ROQ; - buf->input_pos = current_file_pos; - buf->pts = video_pts_counter; - - if (chunk_size > buf->max_size) - buf->size = buf->max_size; - else - buf->size = chunk_size; - chunk_size -= buf->size; - - if (this->input->read(this->input, buf->content, buf->size) != - buf->size) { - this->status = DEMUX_FINISHED; - break; - } - - if (!chunk_size) - buf->decoder_flags |= BUF_FLAG_FRAME_END; - this->video_fifo->put(this->video_fifo, buf); - } - video_pts_counter += this->frame_pts_inc; - } else { - printf ("demux_roq: encountered bad chunk type: %d\n", chunk_type); + /* packetize the video chunk and route it to the video fifo */ + while (chunk_size) { + buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); + buf->type = BUF_VIDEO_ROQ; + buf->input_pos = current_file_pos; + buf->pts = video_pts_counter; + + if (chunk_size > buf->max_size) + buf->size = buf->max_size; + else + buf->size = chunk_size; + chunk_size -= buf->size; + + if (this->input->read(this->input, buf->content, buf->size) != + buf->size) { + this->status = DEMUX_FINISHED; + break; } - /* someone may want to interrupt us */ - pthread_mutex_unlock(&this->mutex); - /* give demux_*_stop a chance to interrupt us */ - sched_yield(); - pthread_mutex_lock(&this->mutex); - } - - /* wait before sending end buffers: user might want to do a new seek */ - while(this->send_end_buffers && this->video_fifo->size(this->video_fifo) && - this->status != DEMUX_OK){ - pthread_mutex_unlock( &this->mutex ); - xine_usec_sleep(100000); - pthread_mutex_lock( &this->mutex ); + if (!chunk_size) + buf->decoder_flags |= BUF_FLAG_FRAME_END; + this->video_fifo->put(this->video_fifo, buf); } - } while (this->status == DEMUX_OK); - - printf ("demux_roq: demux loop finished (status: %d)\n", - this->status); - - this->status = DEMUX_FINISHED; - - if (this->send_end_buffers) { - xine_demux_control_end(this->stream, BUF_FLAG_END_STREAM); + video_pts_counter += this->frame_pts_inc; + } else { + printf ("demux_roq: encountered bad chunk type: %d\n", chunk_type); } - this->thread_running = 0; - pthread_mutex_unlock( &this->mutex ); - - return NULL; + return this->status; } static void demux_roq_send_headers(demux_plugin_t *this_gen) { @@ -345,8 +300,6 @@ static void demux_roq_send_headers(demux_plugin_t *this_gen) { demux_roq_t *this = (demux_roq_t *) this_gen; buf_element_t *buf; - pthread_mutex_lock(&this->mutex); - this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; @@ -394,76 +347,32 @@ static void demux_roq_send_headers(demux_plugin_t *this_gen) { } xine_demux_control_headers_done (this->stream); - - pthread_mutex_unlock (&this->mutex); } -static int demux_roq_start (demux_plugin_t *this_gen, +static int demux_roq_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time) { demux_roq_t *this = (demux_roq_t *) this_gen; - int err; - - pthread_mutex_lock(&this->mutex); /* if thread is not running, initialize demuxer */ - if (!this->thread_running) { + if( !this->stream->demux_thread_running ) { /* send new pts */ xine_demux_control_newpts(this->stream, 0, 0); this->status = DEMUX_OK; - this->send_end_buffers = 1; - this->thread_running = 1; - - if ((err = pthread_create (&this->thread, NULL, demux_roq_loop, this)) != 0) { - printf ("demux_roq: can't create new thread (%s)\n", strerror(err)); - abort(); - } - + + /* start after the signature chunk */ + this->input->seek(this->input, RoQ_CHUNK_PREAMBLE_SIZE, SEEK_SET); + this->status = DEMUX_OK; } - - pthread_mutex_unlock(&this->mutex); - - return DEMUX_OK; -} - -static int demux_roq_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time) { - - /* RoQ files are not meant to be seekable; don't even bother */ - - return 0; -} - -static void demux_roq_stop (demux_plugin_t *this_gen) { - - demux_roq_t *this = (demux_roq_t *) this_gen; - void *p; - - pthread_mutex_lock( &this->mutex ); - - if (!this->thread_running) { - pthread_mutex_unlock( &this->mutex ); - return; - } - - this->send_end_buffers = 0; - this->status = DEMUX_FINISHED; - - pthread_mutex_unlock( &this->mutex ); - pthread_join (this->thread, &p); - - xine_demux_flush_engine(this->stream); - - xine_demux_control_end(this->stream, BUF_FLAG_END_USER); + + return this->status; } static void demux_roq_dispose (demux_plugin_t *this) { - demux_roq_stop(this); - free(this); } @@ -495,17 +404,15 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->input = input; this->demux_plugin.send_headers = demux_roq_send_headers; - this->demux_plugin.start = demux_roq_start; + this->demux_plugin.send_chunk = demux_roq_send_chunk; this->demux_plugin.seek = demux_roq_seek; - this->demux_plugin.stop = demux_roq_stop; this->demux_plugin.dispose = demux_roq_dispose; this->demux_plugin.get_status = demux_roq_get_status; this->demux_plugin.get_stream_length = demux_roq_get_stream_length; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; - pthread_mutex_init (&this->mutex, NULL); - + switch (stream->content_detection_method) { case METHOD_BY_CONTENT: @@ -635,6 +542,6 @@ static void *init_plugin (xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 14, "roq", XINE_VERSION_CODE, NULL, init_plugin }, + { PLUGIN_DEMUX, 15, "roq", XINE_VERSION_CODE, NULL, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/demuxers/demux_smjpeg.c b/src/demuxers/demux_smjpeg.c index 145e210bf..66935eada 100644 --- a/src/demuxers/demux_smjpeg.c +++ b/src/demuxers/demux_smjpeg.c @@ -21,7 +21,7 @@ * For more information on the SMJPEG file format, visit: * http://www.lokigames.com/development/smjpeg.php3 * - * $Id: demux_smjpeg.c,v 1.22 2002/10/27 16:14:28 tmmm Exp $ + * $Id: demux_smjpeg.c,v 1.23 2002/10/28 03:24:43 miguelfreitas Exp $ */ #ifdef HAVE_CONFIG_H @@ -31,8 +31,6 @@ #include #include #include -#include -#include #include #include @@ -74,11 +72,6 @@ typedef struct { input_plugin_t *input; - pthread_t thread; - int thread_running; - pthread_mutex_t mutex; - int send_end_buffers; - off_t input_length; int status; @@ -213,7 +206,7 @@ static int open_smjpeg_file(demux_smjpeg_t *this) { return 1; } -static void *demux_smjpeg_loop (void *this_gen) { +static int demux_smjpeg_send_chunk(demux_plugin_t *this_gen) { demux_smjpeg_t *this = (demux_smjpeg_t *) this_gen; buf_element_t *buf = NULL; @@ -225,138 +218,103 @@ static void *demux_smjpeg_loop (void *this_gen) { int64_t last_frame_pts = 0; unsigned int audio_frame_count = 0; - pthread_mutex_lock( &this->mutex ); - - /* do-while needed to seek after demux finished */ - do { - /* main demuxer loop */ - while (this->status == DEMUX_OK) { + /* load the next sample */ + current_file_pos = this->input->get_current_pos(this->input); + if (this->input->read(this->input, preamble, + SMJPEG_CHUNK_PREAMBLE_SIZE) != SMJPEG_CHUNK_PREAMBLE_SIZE) { + this->status = DEMUX_FINISHED; + return this->status; /* skip to next while() iteration to bail out */ + } - /* someone may want to interrupt us */ - pthread_mutex_unlock( &this->mutex ); - /* give demux_*_stop a chance to interrupt us */ - sched_yield(); - pthread_mutex_lock( &this->mutex ); + chunk_tag = BE_32(&preamble[0]); + remaining_sample_bytes = BE_32(&preamble[8]); + + /* + * Each sample has an absolute timestamp in millisecond units: + * + * xine pts timestamp (ms) + * -------- = -------------- + * 90000 1000 + * + * therefore, xine pts = timestamp * 90000 / 1000 => timestamp * 90 + * + * However, millisecond timestamps are not completely accurate + * for the audio samples. These audio chunks usually have 256 bytes, + * or 512 nibbles, which corresponds to 512 samples. + * + * 512 samples * (1 sec / 22050 samples) * (1000 ms / 1 sec) + * = 23.2 ms + * + * where the audio samples claim that each chunk is 23 ms long. + * Therefore, manually compute the pts values for the audio samples. + */ + if (chunk_tag == sndD_TAG) { + pts = audio_frame_count; + pts *= 90000; + pts /= (this->audio_sample_rate * this->audio_channels); + audio_frame_count += ((remaining_sample_bytes - 4) * 2); + } else { + pts = BE_32(&preamble[4]); + pts *= 90; + } - /* load the next sample */ - current_file_pos = this->input->get_current_pos(this->input); - if (this->input->read(this->input, preamble, - SMJPEG_CHUNK_PREAMBLE_SIZE) != SMJPEG_CHUNK_PREAMBLE_SIZE) { - this->status = DEMUX_FINISHED; - continue; /* skip to next while() iteration to bail out */ - } + /* break up the data into packets and dispatch them */ + if (((chunk_tag == sndD_TAG) && this->audio_fifo && this->audio_type) || + (chunk_tag == vidD_TAG)) { - chunk_tag = BE_32(&preamble[0]); - remaining_sample_bytes = BE_32(&preamble[8]); - - /* - * Each sample has an absolute timestamp in millisecond units: - * - * xine pts timestamp (ms) - * -------- = -------------- - * 90000 1000 - * - * therefore, xine pts = timestamp * 90000 / 1000 => timestamp * 90 - * - * However, millisecond timestamps are not completely accurate - * for the audio samples. These audio chunks usually have 256 bytes, - * or 512 nibbles, which corresponds to 512 samples. - * - * 512 samples * (1 sec / 22050 samples) * (1000 ms / 1 sec) - * = 23.2 ms - * - * where the audio samples claim that each chunk is 23 ms long. - * Therefore, manually compute the pts values for the audio samples. - */ + while (remaining_sample_bytes) { if (chunk_tag == sndD_TAG) { - pts = audio_frame_count; - pts *= 90000; - pts /= (this->audio_sample_rate * this->audio_channels); - audio_frame_count += ((remaining_sample_bytes - 4) * 2); + buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); + buf->type = this->audio_type; } else { - pts = BE_32(&preamble[4]); - pts *= 90; + buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); + buf->type = this->video_type; } - /* break up the data into packets and dispatch them */ - if (((chunk_tag == sndD_TAG) && this->audio_fifo && this->audio_type) || - (chunk_tag == vidD_TAG)) { - - while (remaining_sample_bytes) { - if (chunk_tag == sndD_TAG) { - buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); - buf->type = this->audio_type; - } else { - buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); - buf->type = this->video_type; - } - - buf->input_pos = current_file_pos; - buf->input_length = this->input_length; - buf->input_time = pts / 90000; - buf->pts = pts; - - if (last_frame_pts) { - buf->decoder_flags |= BUF_FLAG_FRAMERATE; - buf->decoder_info[0] = buf->pts - last_frame_pts; - } - - if (remaining_sample_bytes > buf->max_size) - buf->size = buf->max_size; - else - buf->size = remaining_sample_bytes; - remaining_sample_bytes -= buf->size; - - if (this->input->read(this->input, buf->content, buf->size) != - buf->size) { - this->status = DEMUX_FINISHED; - break; - } - - /* every frame is a keyframe */ - buf->decoder_flags |= BUF_FLAG_KEYFRAME; - if (!remaining_sample_bytes) - buf->decoder_flags |= BUF_FLAG_FRAME_END; - - if (chunk_tag == sndD_TAG) - this->audio_fifo->put(this->audio_fifo, buf); - else - this->video_fifo->put(this->video_fifo, buf); - } + buf->input_pos = current_file_pos; + buf->input_length = this->input_length; + buf->input_time = pts / 90000; + buf->pts = pts; - } else { + if (last_frame_pts) { + buf->decoder_flags |= BUF_FLAG_FRAMERATE; + buf->decoder_info[0] = buf->pts - last_frame_pts; + } - /* skip the chunk if it can't be handled */ - this->input->seek(this->input, remaining_sample_bytes, SEEK_CUR); + if (remaining_sample_bytes > buf->max_size) + buf->size = buf->max_size; + else + buf->size = remaining_sample_bytes; + remaining_sample_bytes -= buf->size; + if (this->input->read(this->input, buf->content, buf->size) != + buf->size) { + this->status = DEMUX_FINISHED; + break; } - if (chunk_tag == vidD_TAG) - last_frame_pts = buf->pts; - } + /* every frame is a keyframe */ + buf->decoder_flags |= BUF_FLAG_KEYFRAME; + if (!remaining_sample_bytes) + buf->decoder_flags |= BUF_FLAG_FRAME_END; - /* wait before sending end buffers: user might want to do a new seek */ - while(this->send_end_buffers && this->video_fifo->size(this->video_fifo) && - this->status != DEMUX_OK){ - pthread_mutex_unlock( &this->mutex ); - xine_usec_sleep(100000); - pthread_mutex_lock( &this->mutex ); + if (chunk_tag == sndD_TAG) + this->audio_fifo->put(this->audio_fifo, buf); + else + this->video_fifo->put(this->video_fifo, buf); } - } while (this->status == DEMUX_OK); + } else { - printf ("demux_smjpeg: demux loop finished (status: %d)\n", - this->status); + /* skip the chunk if it can't be handled */ + this->input->seek(this->input, remaining_sample_bytes, SEEK_CUR); - this->status = DEMUX_FINISHED; - - if (this->send_end_buffers) { - xine_demux_control_end(this->stream, BUF_FLAG_END_STREAM); } - this->thread_running = 0; - pthread_mutex_unlock(&this->mutex); - return NULL; + if (chunk_tag == vidD_TAG) + last_frame_pts = buf->pts; + + return this->status; } static void demux_smjpeg_send_headers(demux_plugin_t *this_gen) { @@ -364,8 +322,6 @@ static void demux_smjpeg_send_headers(demux_plugin_t *this_gen) { demux_smjpeg_t *this = (demux_smjpeg_t *) this_gen; buf_element_t *buf; - pthread_mutex_lock(&this->mutex); - this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; @@ -409,76 +365,26 @@ static void demux_smjpeg_send_headers(demux_plugin_t *this_gen) { } xine_demux_control_headers_done (this->stream); - - pthread_mutex_unlock (&this->mutex); } -static int demux_smjpeg_start (demux_plugin_t *this_gen, +static int demux_smjpeg_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time) { demux_smjpeg_t *this = (demux_smjpeg_t *) this_gen; - int err; - - pthread_mutex_lock(&this->mutex); /* if thread is not running, initialize demuxer */ - if (!this->thread_running) { + if( !this->stream->demux_thread_running ) { this->status = DEMUX_OK; - this->send_end_buffers = 1; - this->thread_running = 1; - - if ((err = pthread_create (&this->thread, NULL, demux_smjpeg_loop, this)) != 0) { - printf ("demux_smjpeg: can't create new thread (%s)\n", strerror(err)); - abort(); - } } - pthread_mutex_unlock(&this->mutex); - - return DEMUX_OK; -} - -static int demux_smjpeg_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time) { - - /* SMJPEG files consist of a series of keyframes, but there is no - * master index; in order to effectively seek, an index would have to be - * built by traversing the file in advance. Therefore, don't bother - * implementing the seek function. */ - - return 0; + return this->status; } -static void demux_smjpeg_stop (demux_plugin_t *this_gen) { - - demux_smjpeg_t *this = (demux_smjpeg_t *) this_gen; - void *p; - - pthread_mutex_lock( &this->mutex ); - - if (!this->thread_running) { - pthread_mutex_unlock( &this->mutex ); - return; - } - - this->send_end_buffers = 0; - this->status = DEMUX_FINISHED; - - pthread_mutex_unlock( &this->mutex ); - pthread_join (this->thread, &p); - - xine_demux_flush_engine(this->stream); - - xine_demux_control_end(this->stream, BUF_FLAG_END_USER); -} static void demux_smjpeg_dispose (demux_plugin_t *this_gen) { demux_smjpeg_t *this = (demux_smjpeg_t *) this_gen; - demux_smjpeg_stop(this_gen); - - pthread_mutex_destroy (&this->mutex); free(this); } @@ -511,16 +417,14 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->input = input; this->demux_plugin.send_headers = demux_smjpeg_send_headers; - this->demux_plugin.start = demux_smjpeg_start; + this->demux_plugin.send_chunk = demux_smjpeg_send_chunk; this->demux_plugin.seek = demux_smjpeg_seek; - this->demux_plugin.stop = demux_smjpeg_stop; this->demux_plugin.dispose = demux_smjpeg_dispose; this->demux_plugin.get_status = demux_smjpeg_get_status; this->demux_plugin.get_stream_length = demux_smjpeg_get_stream_length; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; - pthread_mutex_init (&this->mutex, NULL); switch (stream->content_detection_method) { @@ -642,6 +546,6 @@ static void *init_plugin (xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 14, "smjpeg", XINE_VERSION_CODE, NULL, init_plugin }, + { PLUGIN_DEMUX, 15, "smjpeg", XINE_VERSION_CODE, NULL, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/demuxers/demux_snd.c b/src/demuxers/demux_snd.c index bc4bdf2dc..c2d40500c 100644 --- a/src/demuxers/demux_snd.c +++ b/src/demuxers/demux_snd.c @@ -19,7 +19,7 @@ * * SND/AU File Demuxer by Mike Melanson (melanson@pcisys.net) * - * $Id: demux_snd.c,v 1.14 2002/10/27 16:14:29 tmmm Exp $ + * $Id: demux_snd.c,v 1.15 2002/10/28 03:24:43 miguelfreitas Exp $ * */ @@ -30,8 +30,6 @@ #include #include #include -#include -#include #include #include #include @@ -60,10 +58,6 @@ typedef struct { input_plugin_t *input; - pthread_t thread; - int thread_running; - pthread_mutex_t mutex; - int send_end_buffers; int status; unsigned int audio_type; @@ -169,7 +163,7 @@ static int open_snd_file(demux_snd_t *this) { return 1; } -static void *demux_snd_loop (void *this_gen) { +static int demux_snd_send_chunk(demux_plugin_t *this_gen) { demux_snd_t *this = (demux_snd_t *) this_gen; buf_element_t *buf = NULL; @@ -177,89 +171,48 @@ static void *demux_snd_loop (void *this_gen) { off_t current_file_pos; int64_t current_pts; - pthread_mutex_lock( &this->mutex ); - this->seek_flag = 1; - - /* do-while needed to seek after demux finished */ - do { - /* main demuxer loop */ - while (this->status == DEMUX_OK) { - - /* someone may want to interrupt us */ - pthread_mutex_unlock( &this->mutex ); - /* give demux_*_stop a chance to interrupt us */ - sched_yield(); - pthread_mutex_lock( &this->mutex ); - - /* just load data chunks from wherever the stream happens to be - * pointing; issue a DEMUX_FINISHED status if EOF is reached */ - remaining_sample_bytes = this->audio_block_align; - current_file_pos = - this->input->get_current_pos(this->input) - this->data_start; - - current_pts = current_file_pos; - current_pts *= 90000; - current_pts /= this->audio_bytes_per_second; - - if (this->seek_flag) { - xine_demux_control_newpts(this->stream, current_pts, 0); - this->seek_flag = 0; - } - - while (remaining_sample_bytes) { - buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); - buf->type = this->audio_type; - buf->input_pos = current_file_pos; - buf->input_length = this->data_size; - buf->input_time = current_pts / 90000; - buf->pts = current_pts; - - if (remaining_sample_bytes > buf->max_size) - buf->size = buf->max_size; - else - buf->size = remaining_sample_bytes; - remaining_sample_bytes -= buf->size; - - if (this->input->read(this->input, buf->content, buf->size) != - buf->size) { - buf->free_buffer(buf); - this->status = DEMUX_FINISHED; - break; - } - - if (!remaining_sample_bytes) - buf->decoder_flags |= BUF_FLAG_FRAME_END; - - this->audio_fifo->put (this->audio_fifo, buf); - } - } + /* just load data chunks from wherever the stream happens to be + * pointing; issue a DEMUX_FINISHED status if EOF is reached */ + remaining_sample_bytes = this->audio_block_align; + current_file_pos = + this->input->get_current_pos(this->input) - this->data_start; - /* wait before sending end buffers: user might want to do a new seek */ - while(this->send_end_buffers && this->audio_fifo->size(this->audio_fifo) && - this->status != DEMUX_OK){ - pthread_mutex_unlock( &this->mutex ); - xine_usec_sleep(100000); - pthread_mutex_lock( &this->mutex ); - } + current_pts = current_file_pos; + current_pts *= 90000; + current_pts /= this->audio_bytes_per_second; - } while (this->status == DEMUX_OK); - - printf ("demux_snd: demux loop finished (status: %d)\n", - this->status); + if (this->seek_flag) { + xine_demux_control_newpts(this->stream, current_pts, 0); + this->seek_flag = 0; + } - /* seek back to the beginning of the data in preparation for another - * start */ - this->input->seek(this->input, this->data_start, SEEK_SET); + while (remaining_sample_bytes) { + buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); + buf->type = this->audio_type; + buf->input_pos = current_file_pos; + buf->input_length = this->data_size; + buf->input_time = current_pts / 90000; + buf->pts = current_pts; + + if (remaining_sample_bytes > buf->max_size) + buf->size = buf->max_size; + else + buf->size = remaining_sample_bytes; + remaining_sample_bytes -= buf->size; + + if (this->input->read(this->input, buf->content, buf->size) != + buf->size) { + buf->free_buffer(buf); + this->status = DEMUX_FINISHED; + break; + } - this->status = DEMUX_FINISHED; + if (!remaining_sample_bytes) + buf->decoder_flags |= BUF_FLAG_FRAME_END; - if (this->send_end_buffers) { - xine_demux_control_end(this->stream, BUF_FLAG_END_STREAM); + this->audio_fifo->put (this->audio_fifo, buf); } - - this->thread_running = 0; - pthread_mutex_unlock(&this->mutex); - return NULL; + return this->status; } static void demux_snd_send_headers(demux_plugin_t *this_gen) { @@ -267,8 +220,6 @@ static void demux_snd_send_headers(demux_plugin_t *this_gen) { demux_snd_t *this = (demux_snd_t *) this_gen; buf_element_t *buf; - pthread_mutex_lock(&this->mutex); - this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; @@ -301,57 +252,19 @@ static void demux_snd_send_headers(demux_plugin_t *this_gen) { } xine_demux_control_headers_done (this->stream); - - pthread_mutex_unlock (&this->mutex); -} - -static int demux_snd_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time); - -static int demux_snd_start (demux_plugin_t *this_gen, - off_t start_pos, int start_time) { - - demux_snd_t *this = (demux_snd_t *) this_gen; - int err; - - demux_snd_seek(this_gen, start_pos, start_time); - - pthread_mutex_lock(&this->mutex); - - /* if thread is not running, initialize demuxer */ - if (!this->thread_running) { - - this->status = DEMUX_OK; - this->send_end_buffers = 1; - this->thread_running = 1; - - if ((err = pthread_create (&this->thread, NULL, demux_snd_loop, this)) != 0) { - printf ("demux_snd: can't create new thread (%s)\n", strerror(err)); - abort(); - } - } - - pthread_mutex_unlock(&this->mutex); - - return DEMUX_OK; } static int demux_snd_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time) { demux_snd_t *this = (demux_snd_t *) this_gen; - int status; - - pthread_mutex_lock(&this->mutex); - + /* check the boundary offsets */ if (start_pos < 0) this->input->seek(this->input, this->data_start, SEEK_SET); else if (start_pos >= this->data_size) { this->status = DEMUX_FINISHED; - status = this->status; - pthread_mutex_unlock(&this->mutex); - return status; + return this->status; } else { /* This function must seek along the block alignment. The start_pos * is in reference to the start of the data. Divide the start_pos by @@ -366,46 +279,15 @@ static int demux_snd_seek (demux_plugin_t *this_gen, } this->seek_flag = 1; - status = this->status = DEMUX_OK; + this->status = DEMUX_OK; xine_demux_flush_engine (this->stream); - pthread_mutex_unlock(&this->mutex); - - return status; -} - -static void demux_snd_stop (demux_plugin_t *this_gen) { - - demux_snd_t *this = (demux_snd_t *) this_gen; - void *p; - - pthread_mutex_lock( &this->mutex ); - - if (!this->thread_running) { - pthread_mutex_unlock( &this->mutex ); - return; - } - - /* seek back to the beginning of the data in preparation for another - * start */ - this->input->seek(this->input, this->data_start, SEEK_SET); - - this->send_end_buffers = 0; - this->status = DEMUX_FINISHED; - - pthread_mutex_unlock( &this->mutex ); - pthread_join (this->thread, &p); - - xine_demux_flush_engine(this->stream); - - xine_demux_control_end(this->stream, BUF_FLAG_END_USER); + + return this->status; } static void demux_snd_dispose (demux_plugin_t *this_gen) { demux_snd_t *this = (demux_snd_t *) this_gen; - demux_snd_stop(this_gen); - - pthread_mutex_destroy (&this->mutex); free(this); } @@ -439,16 +321,14 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->input = input; this->demux_plugin.send_headers = demux_snd_send_headers; - this->demux_plugin.start = demux_snd_start; + this->demux_plugin.send_chunk = demux_snd_send_chunk; this->demux_plugin.seek = demux_snd_seek; - this->demux_plugin.stop = demux_snd_stop; this->demux_plugin.dispose = demux_snd_dispose; this->demux_plugin.get_status = demux_snd_get_status; this->demux_plugin.get_stream_length = demux_snd_get_stream_length; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; - pthread_mutex_init (&this->mutex, NULL); switch (stream->content_detection_method) { @@ -557,6 +437,6 @@ static void *init_plugin (xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 14, "snd", XINE_VERSION_CODE, NULL, init_plugin }, + { PLUGIN_DEMUX, 15, "snd", XINE_VERSION_CODE, NULL, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/demuxers/demux_voc.c b/src/demuxers/demux_voc.c index e87c63d50..fb43ac00e 100644 --- a/src/demuxers/demux_voc.c +++ b/src/demuxers/demux_voc.c @@ -23,7 +23,7 @@ * It will only play that block if it is PCM data. More variations will be * supported as they are encountered. * - * $Id: demux_voc.c,v 1.14 2002/10/27 16:14:29 tmmm Exp $ + * $Id: demux_voc.c,v 1.15 2002/10/28 03:24:43 miguelfreitas Exp $ * */ @@ -34,8 +34,6 @@ #include #include #include -#include -#include #include #include #include @@ -64,10 +62,6 @@ typedef struct { input_plugin_t *input; - pthread_t thread; - int thread_running; - pthread_mutex_t mutex; - int send_end_buffers; int status; unsigned int voc_audio_type; @@ -161,7 +155,7 @@ static int open_voc_file(demux_voc_t *this) { return 1; } -static void *demux_voc_loop (void *this_gen) { +static int demux_voc_send_chunk(demux_plugin_t *this_gen) { demux_voc_t *this = (demux_voc_t *) this_gen; buf_element_t *buf = NULL; @@ -169,90 +163,49 @@ static void *demux_voc_loop (void *this_gen) { off_t current_file_pos; int64_t current_pts; - pthread_mutex_lock( &this->mutex ); - this->seek_flag = 1; - - /* do-while needed to seek after demux finished */ - do { - /* main demuxer loop */ - while (this->status == DEMUX_OK) { - - /* someone may want to interrupt us */ - pthread_mutex_unlock( &this->mutex ); - /* give demux_*_stop a chance to interrupt us */ - sched_yield(); - pthread_mutex_lock( &this->mutex ); - - /* just load data chunks from wherever the stream happens to be - * pointing; issue a DEMUX_FINISHED status if EOF is reached */ - remaining_sample_bytes = PCM_BLOCK_ALIGN; - current_file_pos = - this->input->get_current_pos(this->input) - this->data_start; - - current_pts = current_file_pos; - current_pts *= 90000; - current_pts /= this->audio_sample_rate; - - if (this->seek_flag) { - xine_demux_control_newpts(this->stream, current_pts, 0); - this->seek_flag = 0; - } - - while (remaining_sample_bytes) { - buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); - buf->type = this->audio_type; - buf->input_pos = current_file_pos; - buf->input_length = this->data_size; - buf->input_time = current_pts / 90000; - buf->pts = current_pts; - - if (remaining_sample_bytes > buf->max_size) - buf->size = buf->max_size; - else - buf->size = remaining_sample_bytes; - remaining_sample_bytes -= buf->size; - - if (this->input->read(this->input, buf->content, buf->size) != - buf->size) { - buf->free_buffer(buf); - this->status = DEMUX_FINISHED; - break; - } - - if (!remaining_sample_bytes) - buf->decoder_flags |= BUF_FLAG_FRAME_END; - - this->audio_fifo->put (this->audio_fifo, buf); - } - } + /* just load data chunks from wherever the stream happens to be + * pointing; issue a DEMUX_FINISHED status if EOF is reached */ + remaining_sample_bytes = PCM_BLOCK_ALIGN; + current_file_pos = + this->input->get_current_pos(this->input) - this->data_start; - /* wait before sending end buffers: user might want to do a new seek */ - while(this->send_end_buffers && this->audio_fifo->size(this->audio_fifo) && - this->status != DEMUX_OK){ - pthread_mutex_unlock( &this->mutex ); - xine_usec_sleep(100000); - pthread_mutex_lock( &this->mutex ); - } + current_pts = current_file_pos; + current_pts *= 90000; + current_pts /= this->audio_sample_rate; - } while (this->status == DEMUX_OK); - - printf ("demux_voc: demux loop finished (status: %d)\n", - this->status); + if (this->seek_flag) { + xine_demux_control_newpts(this->stream, current_pts, 0); + this->seek_flag = 0; + } - /* seek back to the beginning of the data in preparation for another - * start */ - this->input->seek(this->input, this->data_start, SEEK_SET); + while (remaining_sample_bytes) { + buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); + buf->type = this->audio_type; + buf->input_pos = current_file_pos; + buf->input_length = this->data_size; + buf->input_time = current_pts / 90000; + buf->pts = current_pts; + + if (remaining_sample_bytes > buf->max_size) + buf->size = buf->max_size; + else + buf->size = remaining_sample_bytes; + remaining_sample_bytes -= buf->size; + + if (this->input->read(this->input, buf->content, buf->size) != + buf->size) { + buf->free_buffer(buf); + this->status = DEMUX_FINISHED; + break; + } - this->status = DEMUX_FINISHED; + if (!remaining_sample_bytes) + buf->decoder_flags |= BUF_FLAG_FRAME_END; - if (this->send_end_buffers) { - xine_demux_control_end(this->stream, BUF_FLAG_END_STREAM); + this->audio_fifo->put (this->audio_fifo, buf); } - this->thread_running = 0; - pthread_mutex_unlock(&this->mutex); - - return NULL; + return this->status; } static void demux_voc_send_headers(demux_plugin_t *this_gen) { @@ -260,8 +213,6 @@ static void demux_voc_send_headers(demux_plugin_t *this_gen) { demux_voc_t *this = (demux_voc_t *) this_gen; buf_element_t *buf; - pthread_mutex_lock(&this->mutex); - this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; @@ -294,56 +245,19 @@ static void demux_voc_send_headers(demux_plugin_t *this_gen) { } xine_demux_control_headers_done (this->stream); - - pthread_mutex_unlock (&this->mutex); -} - -static int demux_voc_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time); - -static int demux_voc_start (demux_plugin_t *this_gen, - off_t start_pos, int start_time) { - - demux_voc_t *this = (demux_voc_t *) this_gen; - int err; - - demux_voc_seek(this_gen, start_pos, start_time); - - pthread_mutex_lock(&this->mutex); - - /* if thread is not running, initialize demuxer */ - if (!this->thread_running) { - - this->status = DEMUX_OK; - this->send_end_buffers = 1; - this->thread_running = 1; - - if ((err = pthread_create (&this->thread, NULL, demux_voc_loop, this)) != 0) { - printf ("demux_voc: can't create new thread (%s)\n", strerror(err)); - abort(); - } - } - - pthread_mutex_unlock(&this->mutex); - - return DEMUX_OK; } static int demux_voc_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time) { demux_voc_t *this = (demux_voc_t *) this_gen; - int status; - - pthread_mutex_lock(&this->mutex); /* check the boundary offsets */ if (start_pos < 0) this->input->seek(this->input, this->data_start, SEEK_SET); else if (start_pos >= this->data_size) { - status = this->status = DEMUX_FINISHED; - pthread_mutex_unlock(&this->mutex); - return status; + this->status = DEMUX_FINISHED; + return this->status; } else { /* This function must seek along the block alignment. The start_pos * is in reference to the start of the data. Divide the start_pos by @@ -358,46 +272,15 @@ static int demux_voc_seek (demux_plugin_t *this_gen, } this->seek_flag = 1; - status = this->status = DEMUX_OK; + this->status = DEMUX_OK; xine_demux_flush_engine (this->stream); - pthread_mutex_unlock(&this->mutex); - - return status; -} - -static void demux_voc_stop (demux_plugin_t *this_gen) { - - demux_voc_t *this = (demux_voc_t *) this_gen; - void *p; - - pthread_mutex_lock( &this->mutex ); - if (!this->thread_running) { - pthread_mutex_unlock( &this->mutex ); - return; - } - - /* seek back to the beginning of the data in preparation for another - * start */ - this->input->seek(this->input, this->data_start, SEEK_SET); - - this->send_end_buffers = 0; - this->status = DEMUX_FINISHED; - - pthread_mutex_unlock( &this->mutex ); - pthread_join (this->thread, &p); - - xine_demux_flush_engine(this->stream); - - xine_demux_control_end(this->stream, BUF_FLAG_END_USER); + return this->status; } static void demux_voc_dispose (demux_plugin_t *this_gen) { demux_voc_t *this = (demux_voc_t *) this_gen; - demux_voc_stop(this_gen); - - pthread_mutex_destroy (&this->mutex); free(this); } @@ -415,9 +298,6 @@ static int demux_voc_get_stream_length (demux_plugin_t *this_gen) { return this->running_time; } - - - static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input_gen) { @@ -434,16 +314,14 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->input = input; this->demux_plugin.send_headers = demux_voc_send_headers; - this->demux_plugin.start = demux_voc_start; + this->demux_plugin.send_chunk = demux_voc_send_chunk; this->demux_plugin.seek = demux_voc_seek; - this->demux_plugin.stop = demux_voc_stop; this->demux_plugin.dispose = demux_voc_dispose; this->demux_plugin.get_status = demux_voc_get_status; this->demux_plugin.get_stream_length = demux_voc_get_stream_length; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; - pthread_mutex_init (&this->mutex, NULL); switch (stream->content_detection_method) { @@ -547,6 +425,6 @@ static void *init_plugin (xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 14, "voc", XINE_VERSION_CODE, NULL, init_plugin }, + { PLUGIN_DEMUX, 15, "voc", XINE_VERSION_CODE, NULL, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/demuxers/demux_vqa.c b/src/demuxers/demux_vqa.c index 2239b0090..c7b3cf761 100644 --- a/src/demuxers/demux_vqa.c +++ b/src/demuxers/demux_vqa.c @@ -27,7 +27,7 @@ * block needs information from the previous audio block in order to be * decoded, thus making random seeking difficult. * - * $Id: demux_vqa.c,v 1.15 2002/10/27 16:14:30 tmmm Exp $ + * $Id: demux_vqa.c,v 1.16 2002/10/28 03:24:43 miguelfreitas Exp $ */ #ifdef HAVE_CONFIG_H @@ -37,8 +37,6 @@ #include #include #include -#include -#include #include #include @@ -80,11 +78,6 @@ typedef struct { input_plugin_t *input; - pthread_t thread; - int thread_running; - pthread_mutex_t mutex; - int send_end_buffers; - off_t filesize; int status; @@ -160,7 +153,7 @@ static int open_vqa_file(demux_vqa_t *this) { return 1; } -static void *demux_vqa_loop (void *this_gen) { +static int demux_vqa_send_chunk(demux_plugin_t *this_gen) { demux_vqa_t *this = (demux_vqa_t *) this_gen; buf_element_t *buf = NULL; @@ -173,129 +166,93 @@ static void *demux_vqa_loop (void *this_gen) { int64_t audio_pts = 0; unsigned int audio_frames = 0; - pthread_mutex_lock( &this->mutex ); + /* load and dispatch the audio portion of the frame */ + if (this->input->read(this->input, preamble, VQA_PREAMBLE_SIZE) != + VQA_PREAMBLE_SIZE) { + this->status = DEMUX_FINISHED; + return this->status; + } - /* do-while needed to seek after demux finished */ - do { - /* main demuxer loop */ - while (this->status == DEMUX_OK) { + current_file_pos = this->input->get_current_pos(this->input); + chunk_size = BE_32(&preamble[4]); + skip_byte = chunk_size & 0x1; + audio_pts = audio_frames; + audio_pts *= 90000; + audio_pts /= this->audio_sample_rate; + audio_frames += (chunk_size * 2 / this->audio_channels); + while (chunk_size) { + buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); + buf->type = BUF_AUDIO_VQA_IMA; + buf->input_pos = current_file_pos; + buf->input_length = this->filesize; + buf->input_time = audio_pts / 90000; + buf->pts = audio_pts; + + if (chunk_size > buf->max_size) + buf->size = buf->max_size; + else + buf->size = chunk_size; + chunk_size -= buf->size; + + if (this->input->read(this->input, buf->content, buf->size) != + buf->size) { + buf->free_buffer(buf); + this->status = DEMUX_FINISHED; + break; + } - /* someone may want to interrupt us */ - pthread_mutex_unlock( &this->mutex ); - /* give demux_*_stop a chance to interrupt us */ - sched_yield(); - pthread_mutex_lock( &this->mutex ); + if (!chunk_size) + buf->decoder_flags |= BUF_FLAG_FRAME_END; - /* load and dispatch the audio portion of the frame */ - if (this->input->read(this->input, preamble, VQA_PREAMBLE_SIZE) != - VQA_PREAMBLE_SIZE) { + this->audio_fifo->put (this->audio_fifo, buf); + } + /* stay on 16-bit alignment */ + if (skip_byte) + this->input->seek(this->input, 1, SEEK_CUR); + + /* load and dispatch the video portion of the frame but only if this + * is not frame #0 */ + if (i > 0) { + if (this->input->read(this->input, preamble, VQA_PREAMBLE_SIZE) != + VQA_PREAMBLE_SIZE) { + this->status = DEMUX_FINISHED; + return this->status; + } + + current_file_pos = this->input->get_current_pos(this->input); + chunk_size = BE_32(&preamble[4]); + while (chunk_size) { + buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); + buf->type = BUF_VIDEO_VQA; + buf->input_pos = current_file_pos; + buf->input_length = this->filesize; + buf->input_time = video_pts / 90000; + buf->pts = video_pts; + + if (chunk_size > buf->max_size) + buf->size = buf->max_size; + else + buf->size = chunk_size; + chunk_size -= buf->size; + + if (this->input->read(this->input, buf->content, buf->size) != + buf->size) { + buf->free_buffer(buf); this->status = DEMUX_FINISHED; break; } - current_file_pos = this->input->get_current_pos(this->input); - chunk_size = BE_32(&preamble[4]); - skip_byte = chunk_size & 0x1; - audio_pts = audio_frames; - audio_pts *= 90000; - audio_pts /= this->audio_sample_rate; - audio_frames += (chunk_size * 2 / this->audio_channels); - while (chunk_size) { - buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); - buf->type = BUF_AUDIO_VQA_IMA; - buf->input_pos = current_file_pos; - buf->input_length = this->filesize; - buf->input_time = audio_pts / 90000; - buf->pts = audio_pts; - - if (chunk_size > buf->max_size) - buf->size = buf->max_size; - else - buf->size = chunk_size; - chunk_size -= buf->size; - - if (this->input->read(this->input, buf->content, buf->size) != - buf->size) { - buf->free_buffer(buf); - this->status = DEMUX_FINISHED; - break; - } - - if (!chunk_size) - buf->decoder_flags |= BUF_FLAG_FRAME_END; - - this->audio_fifo->put (this->audio_fifo, buf); - } - /* stay on 16-bit alignment */ - if (skip_byte) - this->input->seek(this->input, 1, SEEK_CUR); - - /* load and dispatch the video portion of the frame but only if this - * is not frame #0 */ - if (i > 0) { - if (this->input->read(this->input, preamble, VQA_PREAMBLE_SIZE) != - VQA_PREAMBLE_SIZE) { - this->status = DEMUX_FINISHED; - break; - } - - current_file_pos = this->input->get_current_pos(this->input); - chunk_size = BE_32(&preamble[4]); - while (chunk_size) { - buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); - buf->type = BUF_VIDEO_VQA; - buf->input_pos = current_file_pos; - buf->input_length = this->filesize; - buf->input_time = video_pts / 90000; - buf->pts = video_pts; - - if (chunk_size > buf->max_size) - buf->size = buf->max_size; - else - buf->size = chunk_size; - chunk_size -= buf->size; - - if (this->input->read(this->input, buf->content, buf->size) != - buf->size) { - buf->free_buffer(buf); - this->status = DEMUX_FINISHED; - break; - } - - if (!chunk_size) - buf->decoder_flags |= BUF_FLAG_FRAME_END; - - this->video_fifo->put (this->video_fifo, buf); - } - video_pts += VQA_PTS_INC; - } - - i++; - } + if (!chunk_size) + buf->decoder_flags |= BUF_FLAG_FRAME_END; - /* wait before sending end buffers: user might want to do a new seek */ - while(this->send_end_buffers && this->video_fifo->size(this->video_fifo) && - this->status != DEMUX_OK){ - pthread_mutex_unlock( &this->mutex ); - xine_usec_sleep(100000); - pthread_mutex_lock( &this->mutex ); + this->video_fifo->put (this->video_fifo, buf); } - - } while (this->status == DEMUX_OK); - - printf ("demux_vqa: demux loop finished (status: %d)\n", - this->status); - - this->status = DEMUX_FINISHED; - - if (this->send_end_buffers) { - xine_demux_control_end(this->stream, BUF_FLAG_END_STREAM); + video_pts += VQA_PTS_INC; } - this->thread_running = 0; - pthread_mutex_unlock(&this->mutex); + i++; - return NULL; + return this->status; } static void demux_vqa_send_headers(demux_plugin_t *this_gen) { @@ -303,8 +260,6 @@ static void demux_vqa_send_headers(demux_plugin_t *this_gen) { demux_vqa_t *this = (demux_vqa_t *) this_gen; buf_element_t *buf; - pthread_mutex_lock(&this->mutex); - this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; @@ -363,76 +318,26 @@ static void demux_vqa_send_headers(demux_plugin_t *this_gen) { } xine_demux_control_headers_done (this->stream); - - pthread_mutex_unlock (&this->mutex); } -static int demux_vqa_start (demux_plugin_t *this_gen, +static int demux_vqa_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time) { demux_vqa_t *this = (demux_vqa_t *) this_gen; - int err; - - pthread_mutex_lock(&this->mutex); /* if thread is not running, initialize demuxer */ - if (!this->thread_running) { - - this->status = DEMUX_OK; - this->send_end_buffers = 1; - this->thread_running = 1; - - if ((err = pthread_create (&this->thread, NULL, demux_vqa_loop, this)) != 0) { - printf ("demux_vqa: can't create new thread (%s)\n", strerror(err)); - abort(); - } + if( !this->stream->demux_thread_running ) { this->status = DEMUX_OK; } - pthread_mutex_unlock(&this->mutex); - - return DEMUX_OK; -} - -static int demux_vqa_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time) { - - /* despite the presence of a frame index in the header, VQA files are - * not built for seeking; don't even bother */ - - return 0; -} - -static void demux_vqa_stop (demux_plugin_t *this_gen) { - - demux_vqa_t *this = (demux_vqa_t *) this_gen; - void *p; - - pthread_mutex_lock( &this->mutex ); - - if (!this->thread_running) { - pthread_mutex_unlock( &this->mutex ); - return; - } - - this->send_end_buffers = 0; - this->status = DEMUX_FINISHED; - - pthread_mutex_unlock( &this->mutex ); - pthread_join (this->thread, &p); - - xine_demux_flush_engine(this->stream); - - xine_demux_control_end(this->stream, BUF_FLAG_END_USER); + return this->status; } static void demux_vqa_dispose (demux_plugin_t *this_gen) { demux_vqa_t *this = (demux_vqa_t *) this_gen; - demux_vqa_stop(this_gen); - free(this); } @@ -463,16 +368,14 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->input = input; this->demux_plugin.send_headers = demux_vqa_send_headers; - this->demux_plugin.start = demux_vqa_start; + this->demux_plugin.send_chunk = demux_vqa_send_chunk; this->demux_plugin.seek = demux_vqa_seek; - this->demux_plugin.stop = demux_vqa_stop; this->demux_plugin.dispose = demux_vqa_dispose; this->demux_plugin.get_status = demux_vqa_get_status; this->demux_plugin.get_stream_length = demux_vqa_get_stream_length; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; - pthread_mutex_init (&this->mutex, NULL); switch (stream->content_detection_method) { @@ -576,6 +479,6 @@ static void *init_plugin (xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 14, "vqa", XINE_VERSION_CODE, NULL, init_plugin }, + { PLUGIN_DEMUX, 15, "vqa", XINE_VERSION_CODE, NULL, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/demuxers/demux_wav.c b/src/demuxers/demux_wav.c index 04251c1fb..07f2ef6ec 100644 --- a/src/demuxers/demux_wav.c +++ b/src/demuxers/demux_wav.c @@ -20,7 +20,7 @@ * MS WAV File Demuxer by Mike Melanson (melanson@pcisys.net) * based on WAV specs that are available far and wide * - * $Id: demux_wav.c,v 1.22 2002/10/27 16:14:30 tmmm Exp $ + * $Id: demux_wav.c,v 1.23 2002/10/28 03:24:43 miguelfreitas Exp $ * */ @@ -31,8 +31,6 @@ #include #include #include -#include -#include #include #include #include @@ -61,10 +59,6 @@ typedef struct { input_plugin_t *input; - pthread_t thread; - int thread_running; - pthread_mutex_t mutex; - int send_end_buffers; int status; xine_waveformatex *wave; @@ -154,7 +148,7 @@ static int open_wav_file(demux_wav_t *this) { return 1; } -static void *demux_wav_loop (void *this_gen) { +static int demux_wav_send_chunk(demux_plugin_t *this_gen) { demux_wav_t *this = (demux_wav_t *) this_gen; buf_element_t *buf = NULL; @@ -162,89 +156,49 @@ static void *demux_wav_loop (void *this_gen) { off_t current_file_pos; int64_t current_pts; - pthread_mutex_lock( &this->mutex ); - this->seek_flag = 1; - - /* do-while needed to seek after demux finished */ - do { - /* main demuxer loop */ - while (this->status == DEMUX_OK) { - - /* someone may want to interrupt us */ - pthread_mutex_unlock( &this->mutex ); - /* give demux_*_stop a chance to interrupt us */ - sched_yield(); - pthread_mutex_lock( &this->mutex ); - - /* just load data chunks from wherever the stream happens to be - * pointing; issue a DEMUX_FINISHED status if EOF is reached */ - remaining_sample_bytes = this->wave->nBlockAlign; - current_file_pos = - this->input->get_current_pos(this->input) - this->data_start; - - current_pts = current_file_pos; - current_pts *= 90000; - current_pts /= this->wave->nAvgBytesPerSec; - - if (this->seek_flag) { - xine_demux_control_newpts(this->stream, current_pts, 0); - this->seek_flag = 0; - } - - while (remaining_sample_bytes) { - buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); - buf->type = this->audio_type; - buf->input_pos = current_file_pos; - buf->input_length = this->data_size; - buf->input_time = current_pts / 90000; - buf->pts = current_pts; - - if (remaining_sample_bytes > buf->max_size) - buf->size = buf->max_size; - else - buf->size = remaining_sample_bytes; - remaining_sample_bytes -= buf->size; - - if (this->input->read(this->input, buf->content, buf->size) != - buf->size) { - buf->free_buffer(buf); - this->status = DEMUX_FINISHED; - break; - } - - if (!remaining_sample_bytes) - buf->decoder_flags |= BUF_FLAG_FRAME_END; - - this->audio_fifo->put (this->audio_fifo, buf); - } - } + /* just load data chunks from wherever the stream happens to be + * pointing; issue a DEMUX_FINISHED status if EOF is reached */ + remaining_sample_bytes = this->wave->nBlockAlign; + current_file_pos = + this->input->get_current_pos(this->input) - this->data_start; - /* wait before sending end buffers: user might want to do a new seek */ - while(this->send_end_buffers && this->audio_fifo->size(this->audio_fifo) && - this->status != DEMUX_OK){ - pthread_mutex_unlock( &this->mutex ); - xine_usec_sleep(100000); - pthread_mutex_lock( &this->mutex ); - } - - } while (this->status == DEMUX_OK); + current_pts = current_file_pos; + current_pts *= 90000; + current_pts /= this->wave->nAvgBytesPerSec; - printf ("demux_wav: demux loop finished (status: %d)\n", - this->status); + if (this->seek_flag) { + xine_demux_control_newpts(this->stream, current_pts, 0); + this->seek_flag = 0; + } - /* seek back to the beginning of the data in preparation for another - * start */ - this->input->seek(this->input, this->data_start, SEEK_SET); + while (remaining_sample_bytes) { + buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); + buf->type = this->audio_type; + buf->input_pos = current_file_pos; + buf->input_length = this->data_size; + buf->input_time = current_pts / 90000; + buf->pts = current_pts; + + if (remaining_sample_bytes > buf->max_size) + buf->size = buf->max_size; + else + buf->size = remaining_sample_bytes; + remaining_sample_bytes -= buf->size; + + if (this->input->read(this->input, buf->content, buf->size) != + buf->size) { + buf->free_buffer(buf); + this->status = DEMUX_FINISHED; + break; + } - this->status = DEMUX_FINISHED; + if (!remaining_sample_bytes) + buf->decoder_flags |= BUF_FLAG_FRAME_END; - if (this->send_end_buffers) { - xine_demux_control_end(this->stream, BUF_FLAG_END_STREAM); + this->audio_fifo->put (this->audio_fifo, buf); } - this->thread_running = 0; - pthread_mutex_unlock(&this->mutex); - return NULL; + return this->status; } static void demux_wav_send_headers(demux_plugin_t *this_gen) { @@ -252,8 +206,6 @@ static void demux_wav_send_headers(demux_plugin_t *this_gen) { demux_wav_t *this = (demux_wav_t *) this_gen; buf_element_t *buf; - pthread_mutex_lock(&this->mutex); - this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; @@ -288,55 +240,19 @@ static void demux_wav_send_headers(demux_plugin_t *this_gen) { xine_demux_control_headers_done (this->stream); - pthread_mutex_unlock (&this->mutex); -} - -static int demux_wav_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time); - -static int demux_wav_start (demux_plugin_t *this_gen, - off_t start_pos, int start_time) { - - demux_wav_t *this = (demux_wav_t *) this_gen; - int err; - - demux_wav_seek(this_gen, start_pos, start_time); - - pthread_mutex_lock(&this->mutex); - - /* if thread is not running, initialize demuxer */ - if (!this->thread_running) { - - this->status = DEMUX_OK; - this->send_end_buffers = 1; - this->thread_running = 1; - - if ((err = pthread_create (&this->thread, NULL, demux_wav_loop, this)) != 0) { - printf ("demux_wav: can't create new thread (%s)\n", strerror(err)); - abort(); - } - } - - pthread_mutex_unlock(&this->mutex); - - return DEMUX_OK; } static int demux_wav_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time) { demux_wav_t *this = (demux_wav_t *) this_gen; - int status; - - pthread_mutex_lock(&this->mutex); /* check the boundary offsets */ if (start_pos <= 0) this->input->seek(this->input, this->data_start, SEEK_SET); else if (start_pos >= this->data_size) { - status = this->status = DEMUX_FINISHED; - pthread_mutex_unlock(&this->mutex); - return status; + this->status = DEMUX_FINISHED; + return this->status; } else { /* This function must seek along the block alignment. The start_pos * is in reference to the start of the data. Divide the start_pos by @@ -351,46 +267,19 @@ static int demux_wav_seek (demux_plugin_t *this_gen, } this->seek_flag = 1; - status = this->status = DEMUX_OK; + this->status = DEMUX_OK; xine_demux_flush_engine (this->stream); - pthread_mutex_unlock(&this->mutex); - - return status; -} - -static void demux_wav_stop (demux_plugin_t *this_gen) { - - demux_wav_t *this = (demux_wav_t *) this_gen; - void *p; - - pthread_mutex_lock( &this->mutex ); - - if (!this->thread_running) { - pthread_mutex_unlock( &this->mutex ); - return; + + /* if thread is not running, initialize demuxer */ + if( !this->stream->demux_thread_running ) { } - /* seek back to the beginning of the data in preparation for another - * start */ - this->input->seek(this->input, this->data_start, SEEK_SET); - - this->send_end_buffers = 0; - this->status = DEMUX_FINISHED; - - pthread_mutex_unlock( &this->mutex ); - pthread_join (this->thread, &p); - - xine_demux_flush_engine(this->stream); - - xine_demux_control_end(this->stream, BUF_FLAG_END_USER); + return this->status; } static void demux_wav_dispose (demux_plugin_t *this_gen) { demux_wav_t *this = (demux_wav_t *) this_gen; - demux_wav_stop(this_gen); - - pthread_mutex_destroy (&this->mutex); free(this); } @@ -424,16 +313,14 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->input = input; this->demux_plugin.send_headers = demux_wav_send_headers; - this->demux_plugin.start = demux_wav_start; + this->demux_plugin.send_chunk = demux_wav_send_chunk; this->demux_plugin.seek = demux_wav_seek; - this->demux_plugin.stop = demux_wav_stop; this->demux_plugin.dispose = demux_wav_dispose; this->demux_plugin.get_status = demux_wav_get_status; this->demux_plugin.get_stream_length = demux_wav_get_stream_length; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; - pthread_mutex_init (&this->mutex, NULL); switch (stream->content_detection_method) { @@ -552,6 +439,6 @@ static void *init_plugin (xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 14, "wav", XINE_VERSION_CODE, NULL, init_plugin }, + { PLUGIN_DEMUX, 15, "wav", XINE_VERSION_CODE, NULL, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/demuxers/demux_wc3movie.c b/src/demuxers/demux_wc3movie.c index 8c1ec6b24..bf40a1728 100644 --- a/src/demuxers/demux_wc3movie.c +++ b/src/demuxers/demux_wc3movie.c @@ -22,7 +22,7 @@ * For more information on the MVE file format, visit: * http://www.pcisys.net/~melanson/codecs/ * - * $Id: demux_wc3movie.c,v 1.20 2002/10/27 16:14:31 tmmm Exp $ + * $Id: demux_wc3movie.c,v 1.21 2002/10/28 03:24:43 miguelfreitas Exp $ */ #ifdef HAVE_CONFIG_H @@ -32,8 +32,6 @@ #include #include #include -#include -#include #include #include @@ -85,11 +83,6 @@ typedef struct { input_plugin_t *input; - pthread_t thread; - int thread_running; - pthread_mutex_t mutex; - int send_end_buffers; - int status; unsigned int fps; @@ -157,7 +150,7 @@ const unsigned char wc3_pal_lookup[] = { 0xFD, 0xFD, 0xFD }; -static void *demux_mve_loop (void *this_gen) { +static int demux_mve_send_chunk(demux_plugin_t *this_gen) { demux_mve_t *this = (demux_mve_t *) this_gen; buf_element_t *buf = NULL; @@ -170,186 +163,146 @@ static void *demux_mve_loop (void *this_gen) { off_t current_file_pos; unsigned int palette_number; - pthread_mutex_lock( &this->mutex ); - this->seek_flag = 0; + /* compensate for the initial data in the file */ + current_file_pos = this->input->get_current_pos(this->input) - + this->data_start; - /* do-while needed to seek after demux finished */ - do { - /* main demuxer loop */ - while (this->status == DEMUX_OK) { + if (this->input->read(this->input, preamble, PREAMBLE_SIZE) != + PREAMBLE_SIZE) + this->status = DEMUX_FINISHED; + else { + chunk_tag = BE_32(&preamble[0]); + /* round up to the nearest even size */ + chunk_size = (BE_32(&preamble[4]) + 1) & (~1); - /* someone may want to interrupt us */ - pthread_mutex_unlock( &this->mutex ); - /* give demux_*_stop a chance to interrupt us */ - sched_yield(); - pthread_mutex_lock( &this->mutex ); + if (chunk_tag == BRCH_TAG) { - /* compensate for the initial data in the file */ - current_file_pos = this->input->get_current_pos(this->input) - - this->data_start; + /* empty chunk; do nothing */ - if (this->input->read(this->input, preamble, PREAMBLE_SIZE) != - PREAMBLE_SIZE) - this->status = DEMUX_FINISHED; - else { - chunk_tag = BE_32(&preamble[0]); - /* round up to the nearest even size */ - chunk_size = (BE_32(&preamble[4]) + 1) & (~1); + } else if (chunk_tag == SHOT_TAG) { - if (chunk_tag == BRCH_TAG) { - - /* empty chunk; do nothing */ - - } else if (chunk_tag == SHOT_TAG) { - - if (this->seek_flag) { - - /* reset pts */ - video_pts = 0; - xine_demux_control_newpts(this->stream, 0, BUF_FLAG_SEEK); - this->seek_flag = 0; - - } else { - - /* record the offset of the SHOT chunk */ - this->shot_offsets[this->current_shot] = - this->input->get_current_pos(this->input) - PREAMBLE_SIZE; - } - - this->current_shot++; - - /* this is the start of a new shot; send a new palette */ - if (this->input->read(this->input, preamble, 4) != 4) { - this->status = DEMUX_FINISHED; - break; - } - palette_number = LE_32(&preamble[0]); - - if (palette_number >= this->number_of_shots) { - xine_log(this->stream->xine, XINE_LOG_MSG, - _("demux_wc3movie: SHOT chunk referenced invalid palette (%d >= %d)\n"), - palette_number, this->number_of_shots); - this->status = DEMUX_FINISHED; - break; - } - - buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); - buf->decoder_flags = BUF_FLAG_SPECIAL; - buf->decoder_info[1] = BUF_SPECIAL_PALETTE; - buf->decoder_info[2] = PALETTE_SIZE; - buf->decoder_info[3] = - (unsigned int)&this->palettes[PALETTE_SIZE * palette_number]; - buf->size = 0; - buf->type = BUF_VIDEO_WC3; - this->video_fifo->put (this->video_fifo, buf); - - } else if (chunk_tag == AUDI_TAG) { - - audio_pts = video_pts - WC3_PTS_INC; - - while (chunk_size) { - buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); - buf->type = BUF_AUDIO_LPCM_LE; - buf->input_pos = current_file_pos; - buf->input_length = this->data_size; - buf->input_time = audio_pts / 90000; - buf->pts = audio_pts; - - if (chunk_size > buf->max_size) - buf->size = buf->max_size; - else - buf->size = chunk_size; - chunk_size -= buf->size; - - if (this->input->read(this->input, buf->content, buf->size) != - buf->size) { - buf->free_buffer(buf); - this->status = DEMUX_FINISHED; - break; - } - - if (!chunk_size) - buf->decoder_flags |= BUF_FLAG_FRAME_END; - - this->audio_fifo->put (this->audio_fifo, buf); - } - - } else if (chunk_tag == VGA_TAG) { - - while (chunk_size) { - buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); - buf->type = BUF_VIDEO_WC3; - buf->input_pos = current_file_pos; - buf->input_length = this->data_size; - buf->input_time = video_pts / 90000; - buf->pts = video_pts; - - if (chunk_size > buf->max_size) - buf->size = buf->max_size; - else - buf->size = chunk_size; - chunk_size -= buf->size; - - if (this->input->read(this->input, buf->content, buf->size) != - buf->size) { - buf->free_buffer(buf); - this->status = DEMUX_FINISHED; - break; - } - - if (!chunk_size) - buf->decoder_flags |= BUF_FLAG_FRAME_END; - - this->video_fifo->put (this->video_fifo, buf); - } - video_pts += WC3_PTS_INC; - - } else if (chunk_tag == TEXT_TAG) { - - text_pts = video_pts - WC3_PTS_INC; - - /* unhandled thus far */ - this->input->seek(this->input, chunk_size, SEEK_CUR); + if (this->seek_flag) { - } else { + /* reset pts */ + video_pts = 0; + xine_demux_control_newpts(this->stream, 0, BUF_FLAG_SEEK); + this->seek_flag = 0; - /* report an unknown chunk and skip it */ - printf (_("demux_wc3movie: encountered unknown chunk: %c%c%c%c\n"), - (chunk_tag >> 24) & 0xFF, - (chunk_tag >> 16) & 0xFF, - (chunk_tag >> 8) & 0xFF, - (chunk_tag >> 0) & 0xFF); - this->input->seek(this->input, chunk_size, SEEK_CUR); + } else { + + /* record the offset of the SHOT chunk */ + this->shot_offsets[this->current_shot] = + this->input->get_current_pos(this->input) - PREAMBLE_SIZE; + } + + this->current_shot++; + + /* this is the start of a new shot; send a new palette */ + if (this->input->read(this->input, preamble, 4) != 4) { + this->status = DEMUX_FINISHED; + return this->status; + } + palette_number = LE_32(&preamble[0]); + + if (palette_number >= this->number_of_shots) { + xine_log(this->stream->xine, XINE_LOG_MSG, + _("demux_wc3movie: SHOT chunk referenced invalid palette (%d >= %d)\n"), + palette_number, this->number_of_shots); + this->status = DEMUX_FINISHED; + return this->status; + } + + buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); + buf->decoder_flags = BUF_FLAG_SPECIAL; + buf->decoder_info[1] = BUF_SPECIAL_PALETTE; + buf->decoder_info[2] = PALETTE_SIZE; + buf->decoder_info[3] = + (unsigned int)&this->palettes[PALETTE_SIZE * palette_number]; + buf->size = 0; + buf->type = BUF_VIDEO_WC3; + this->video_fifo->put (this->video_fifo, buf); + + } else if (chunk_tag == AUDI_TAG) { + + audio_pts = video_pts - WC3_PTS_INC; + + while (chunk_size) { + buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); + buf->type = BUF_AUDIO_LPCM_LE; + buf->input_pos = current_file_pos; + buf->input_length = this->data_size; + buf->input_time = audio_pts / 90000; + buf->pts = audio_pts; + + if (chunk_size > buf->max_size) + buf->size = buf->max_size; + else + buf->size = chunk_size; + chunk_size -= buf->size; + + if (this->input->read(this->input, buf->content, buf->size) != + buf->size) { + buf->free_buffer(buf); + this->status = DEMUX_FINISHED; + break; } + + if (!chunk_size) + buf->decoder_flags |= BUF_FLAG_FRAME_END; + + this->audio_fifo->put (this->audio_fifo, buf); } - } - /* wait before sending end buffers: user might want to do a new seek */ - while(this->send_end_buffers && this->audio_fifo->size(this->audio_fifo) && - this->status != DEMUX_OK){ - pthread_mutex_unlock( &this->mutex ); - xine_usec_sleep(100000); - pthread_mutex_lock( &this->mutex ); - } + } else if (chunk_tag == VGA_TAG) { + + while (chunk_size) { + buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); + buf->type = BUF_VIDEO_WC3; + buf->input_pos = current_file_pos; + buf->input_length = this->data_size; + buf->input_time = video_pts / 90000; + buf->pts = video_pts; + + if (chunk_size > buf->max_size) + buf->size = buf->max_size; + else + buf->size = chunk_size; + chunk_size -= buf->size; + + if (this->input->read(this->input, buf->content, buf->size) != + buf->size) { + buf->free_buffer(buf); + this->status = DEMUX_FINISHED; + break; + } - } while (this->status == DEMUX_OK); + if (!chunk_size) + buf->decoder_flags |= BUF_FLAG_FRAME_END; - printf ("demux_wc3movie: demux loop finished (status: %d)\n", - this->status); + this->video_fifo->put (this->video_fifo, buf); + } + video_pts += WC3_PTS_INC; - /* seek back to the beginning of the data in preparation for another - * start */ - this->input->seek(this->input, this->data_start, SEEK_SET); + } else if (chunk_tag == TEXT_TAG) { - this->status = DEMUX_FINISHED; + text_pts = video_pts - WC3_PTS_INC; + + /* unhandled thus far */ + this->input->seek(this->input, chunk_size, SEEK_CUR); + + } else { - if (this->send_end_buffers) { - xine_demux_control_end(this->stream, BUF_FLAG_END_STREAM); + /* report an unknown chunk and skip it */ + printf (_("demux_wc3movie: encountered unknown chunk: %c%c%c%c\n"), + (chunk_tag >> 24) & 0xFF, + (chunk_tag >> 16) & 0xFF, + (chunk_tag >> 8) & 0xFF, + (chunk_tag >> 0) & 0xFF); + this->input->seek(this->input, chunk_size, SEEK_CUR); + } } - this->thread_running = 0; - pthread_mutex_unlock(&this->mutex); - return NULL; + return this->status; } static void demux_mve_send_headers(demux_plugin_t *this_gen) { @@ -357,8 +310,6 @@ static void demux_mve_send_headers(demux_plugin_t *this_gen) { demux_mve_t *this = (demux_mve_t *) this_gen; buf_element_t *buf; - pthread_mutex_lock(&this->mutex); - this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; @@ -417,8 +368,6 @@ static void demux_mve_send_headers(demux_plugin_t *this_gen) { } xine_demux_control_headers_done (this->stream); - - pthread_mutex_unlock (&this->mutex); } /* returns 1 if the MVE file was opened successfully, 0 otherwise */ @@ -558,38 +507,6 @@ static int open_mve_file(demux_mve_t *this) { return 1; } -static int demux_mve_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time); - -static int demux_mve_start (demux_plugin_t *this_gen, - off_t start_pos, int start_time) { - - demux_mve_t *this = (demux_mve_t *) this_gen; - int err; - - demux_mve_seek(this_gen, start_pos, start_time); - - /* if thread is not running, initialize demuxer */ - if (!this->thread_running) { - - /* send new pts */ - xine_demux_control_newpts(this->stream, 0, 0); - - this->status = DEMUX_OK; - this->send_end_buffers = 1; - this->thread_running = 1; - - if ((err = pthread_create (&this->thread, NULL, demux_mve_loop, this)) != 0) { - printf ("demux_wc3movie: can't create new thread (%s)\n", strerror(err)); - abort(); - } - } - - pthread_mutex_unlock(&this->mutex); - - return DEMUX_OK; -} - static int demux_mve_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time) { @@ -612,8 +529,6 @@ static int demux_mve_seek (demux_plugin_t *this_gen, unsigned int chunk_size; int new_shot = -1; - pthread_mutex_lock(&this->mutex); - /* make sure the first shot has been recorded */ if (this->shot_offsets[0] == 0) { @@ -622,8 +537,7 @@ static int demux_mve_seek (demux_plugin_t *this_gen, if (this->input->read(this->input, preamble, PREAMBLE_SIZE) != PREAMBLE_SIZE) { this->status = DEMUX_FINISHED; - pthread_mutex_unlock(&this->mutex); - return 1; + return this->status; } chunk_tag = BE_32(&preamble[0]); @@ -655,8 +569,7 @@ static int demux_mve_seek (demux_plugin_t *this_gen, if (this->input->read(this->input, preamble, PREAMBLE_SIZE) != PREAMBLE_SIZE) { this->status = DEMUX_FINISHED; - pthread_mutex_unlock(&this->mutex); - return 1; + return this->status; } chunk_tag = BE_32(&preamble[0]); @@ -698,39 +611,23 @@ static int demux_mve_seek (demux_plugin_t *this_gen, this->status = DEMUX_OK; xine_demux_flush_engine(this->stream); - pthread_mutex_unlock(&this->mutex); - - return 0; -} - -static void demux_mve_stop (demux_plugin_t *this_gen) { - - demux_mve_t *this = (demux_mve_t *) this_gen; - void *p; + + /* if thread is not running, initialize demuxer */ + if( !this->stream->demux_thread_running ) { - pthread_mutex_lock( &this->mutex ); + /* send new pts */ + xine_demux_control_newpts(this->stream, 0, 0); - if (!this->thread_running) { - pthread_mutex_unlock( &this->mutex ); - return; + this->status = DEMUX_OK; + this->seek_flag = 0; } - this->send_end_buffers = 0; - this->status = DEMUX_FINISHED; - - pthread_mutex_unlock( &this->mutex ); - pthread_join (this->thread, &p); - - xine_demux_flush_engine(this->stream); - - xine_demux_control_end(this->stream, BUF_FLAG_END_USER); + return 0; } static void demux_mve_dispose (demux_plugin_t *this_gen) { demux_mve_t *this = (demux_mve_t *) this_gen; - demux_mve_stop(this_gen); - free(this->palettes); free(this); } @@ -763,16 +660,14 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->input = input; this->demux_plugin.send_headers = demux_mve_send_headers; - this->demux_plugin.start = demux_mve_start; + this->demux_plugin.send_chunk = demux_mve_send_chunk; this->demux_plugin.seek = demux_mve_seek; - this->demux_plugin.stop = demux_mve_stop; this->demux_plugin.dispose = demux_mve_dispose; this->demux_plugin.get_status = demux_mve_get_status; this->demux_plugin.get_stream_length = demux_mve_get_stream_length; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; - pthread_mutex_init (&this->mutex, NULL); switch (stream->content_detection_method) { @@ -879,6 +774,6 @@ static void *init_plugin (xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 14, "wc3movie", XINE_VERSION_CODE, NULL, init_plugin }, + { PLUGIN_DEMUX, 15, "wc3movie", XINE_VERSION_CODE, NULL, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/demuxers/demux_yuv4mpeg2.c b/src/demuxers/demux_yuv4mpeg2.c index cf6345806..e89470739 100644 --- a/src/demuxers/demux_yuv4mpeg2.c +++ b/src/demuxers/demux_yuv4mpeg2.c @@ -22,7 +22,7 @@ * tools, visit: * http://mjpeg.sourceforge.net/ * - * $Id: demux_yuv4mpeg2.c,v 1.7 2002/10/27 16:14:31 tmmm Exp $ + * $Id: demux_yuv4mpeg2.c,v 1.8 2002/10/28 03:24:43 miguelfreitas Exp $ */ #ifdef HAVE_CONFIG_H @@ -32,8 +32,6 @@ #include #include #include -#include -#include #include #include @@ -170,7 +168,7 @@ static int open_yuv4mpeg2_file(demux_yuv4mpeg2_t *this) { return 1; } -static void *demux_yuv4mpeg2_loop (void *this_gen) { +static int demux_yuv4mpeg2_send_chunk(demux_plugin_t *this_gen) { demux_yuv4mpeg2_t *this = (demux_yuv4mpeg2_t *) this_gen; buf_element_t *buf = NULL; @@ -179,102 +177,64 @@ static void *demux_yuv4mpeg2_loop (void *this_gen) { off_t current_file_pos; int64_t pts; - pthread_mutex_lock( &this->mutex ); - - /* do-while needed to seek after demux finished */ - do { - /* main demuxer loop */ - while (this->status == DEMUX_OK) { - - /* someone may want to interrupt us */ - pthread_mutex_unlock( &this->mutex ); - /* give demux_*_stop a chance to interrupt us */ - sched_yield(); - pthread_mutex_lock( &this->mutex ); - - /* validate that this is an actual frame boundary */ - if (this->input->read(this->input, preamble, Y4M_FRAME_SIGNATURE_SIZE) != - Y4M_FRAME_SIGNATURE_SIZE) { - this->status = DEMUX_FINISHED; - break; - } - if (memcmp(preamble, Y4M_FRAME_SIGNATURE, Y4M_FRAME_SIGNATURE_SIZE) != - 0) { - this->status = DEMUX_FINISHED; - break; - } - - /* load and dispatch the raw frame */ - bytes_remaining = this->frame_size; - current_file_pos = - this->input->get_current_pos(this->input) - this->data_start; - pts = current_file_pos; - pts /= (this->frame_size + Y4M_FRAME_SIGNATURE_SIZE); - pts *= this->frame_pts_inc; - - /* reset the pts after a seek */ - if (this->seek_flag) { - xine_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK); - this->seek_flag = 0; - } - - while(bytes_remaining) { - buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); - buf->type = BUF_VIDEO_YV12; - buf->input_pos = current_file_pos; - buf->input_length = this->data_size; - buf->pts = pts; - - if (bytes_remaining > buf->max_size) - buf->size = buf->max_size; - else - buf->size = bytes_remaining; - bytes_remaining -= buf->size; - - if (this->input->read(this->input, buf->content, buf->size) != - buf->size) { - this->status = DEMUX_FINISHED; - break; - } - - if (!bytes_remaining) - buf->decoder_flags |= BUF_FLAG_FRAME_END; - this->video_fifo->put(this->video_fifo, buf); - } - } + /* validate that this is an actual frame boundary */ + if (this->input->read(this->input, preamble, Y4M_FRAME_SIGNATURE_SIZE) != + Y4M_FRAME_SIGNATURE_SIZE) { + this->status = DEMUX_FINISHED; + return this->status; + } + if (memcmp(preamble, Y4M_FRAME_SIGNATURE, Y4M_FRAME_SIGNATURE_SIZE) != + 0) { + this->status = DEMUX_FINISHED; + return this->status; + } - /* wait before sending end buffers: user might want to do a new seek */ - while(this->send_end_buffers && this->video_fifo->size(this->video_fifo) && - this->status != DEMUX_OK){ - pthread_mutex_unlock( &this->mutex ); - xine_usec_sleep(100000); - pthread_mutex_lock( &this->mutex ); - } + /* load and dispatch the raw frame */ + bytes_remaining = this->frame_size; + current_file_pos = + this->input->get_current_pos(this->input) - this->data_start; + pts = current_file_pos; + pts /= (this->frame_size + Y4M_FRAME_SIGNATURE_SIZE); + pts *= this->frame_pts_inc; + + /* reset the pts after a seek */ + if (this->seek_flag) { + xine_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK); + this->seek_flag = 0; + } - } while (this->status == DEMUX_OK); + while(bytes_remaining) { + buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); + buf->type = BUF_VIDEO_YV12; + buf->input_pos = current_file_pos; + buf->input_length = this->data_size; + buf->pts = pts; - printf ("demux_yuv4mpeg2: demux loop finished (status: %d)\n", - this->status); + if (bytes_remaining > buf->max_size) + buf->size = buf->max_size; + else + buf->size = bytes_remaining; + bytes_remaining -= buf->size; - this->status = DEMUX_FINISHED; + if (this->input->read(this->input, buf->content, buf->size) != + buf->size) { + this->status = DEMUX_FINISHED; + break; + } - if (this->send_end_buffers) { - xine_demux_control_end(this->stream, BUF_FLAG_END_STREAM); + if (!bytes_remaining) + buf->decoder_flags |= BUF_FLAG_FRAME_END; + this->video_fifo->put(this->video_fifo, buf); } - - this->thread_running = 0; - pthread_mutex_unlock(&this->mutex); - - return NULL; -} + + return this->status; +} static void demux_yuv4mpeg2_send_headers(demux_plugin_t *this_gen) { demux_yuv4mpeg2_t *this = (demux_yuv4mpeg2_t *) this_gen; buf_element_t *buf; - pthread_mutex_lock(&this->mutex); - this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; @@ -300,53 +260,12 @@ static void demux_yuv4mpeg2_send_headers(demux_plugin_t *this_gen) { this->video_fifo->put (this->video_fifo, buf); xine_demux_control_headers_done (this->stream); - - pthread_mutex_unlock (&this->mutex); -} - -static int demux_yuv4mpeg2_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time); - -static int demux_yuv4mpeg2_start (demux_plugin_t *this_gen, - off_t start_pos, int start_time) { - - demux_yuv4mpeg2_t *this = (demux_yuv4mpeg2_t *) this_gen; - int err; - - demux_yuv4mpeg2_seek(this_gen, start_pos, start_time); - - pthread_mutex_lock(&this->mutex); - - /* if thread is not running, initialize demuxer */ - if (!this->thread_running) { - - /* send new pts */ - xine_demux_control_newpts(this->stream, 0, 0); - - this->status = DEMUX_OK; - this->send_end_buffers = 1; - this->thread_running = 1; - - if ((err = pthread_create (&this->thread, NULL, demux_yuv4mpeg2_loop, this)) != 0) { - printf ("demux_yuv4mpeg2: can't create new thread (%s)\n", strerror(err)); - abort(); - } - - this->status = DEMUX_OK; - } - - pthread_mutex_unlock(&this->mutex); - - return DEMUX_OK; } static int demux_yuv4mpeg2_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time) { demux_yuv4mpeg2_t *this = (demux_yuv4mpeg2_t *) this_gen; - int status; - - pthread_mutex_lock(&this->mutex); /* YUV4MPEG2 files are essentially constant bit-rate video. Seek along * the calculated frame boundaries. Divide the requested seek offset @@ -361,41 +280,25 @@ static int demux_yuv4mpeg2_seek (demux_plugin_t *this_gen, this->input->seek(this->input, start_pos, SEEK_SET); this->seek_flag = 1; - status = this->status = DEMUX_OK; + this->status = DEMUX_OK; xine_demux_flush_engine (this->stream); - pthread_mutex_unlock(&this->mutex); - return status; -} - -static void demux_yuv4mpeg2_stop (demux_plugin_t *this_gen) { - - demux_yuv4mpeg2_t *this = (demux_yuv4mpeg2_t *) this_gen; - void *p; + /* if thread is not running, initialize demuxer */ + if( !this->stream->demux_thread_running ) { - pthread_mutex_lock( &this->mutex ); + /* send new pts */ + xine_demux_control_newpts(this->stream, 0, 0); - if (!this->thread_running) { - pthread_mutex_unlock( &this->mutex ); - return; + this->status = DEMUX_OK; } - this->send_end_buffers = 0; - this->status = DEMUX_FINISHED; - - pthread_mutex_unlock( &this->mutex ); - pthread_join (this->thread, &p); - - xine_demux_flush_engine(this->stream); - - xine_demux_control_end(this->stream, BUF_FLAG_END_USER); + return this->status; } static void demux_yuv4mpeg2_dispose (demux_plugin_t *this_gen) { demux_yuv4mpeg2_t *this = (demux_yuv4mpeg2_t *) this_gen; - demux_yuv4mpeg2_stop(this_gen); free(this); } @@ -429,16 +332,14 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->input = input; this->demux_plugin.send_headers = demux_yuv4mpeg2_send_headers; - this->demux_plugin.start = demux_yuv4mpeg2_start; + this->demux_plugin.send_chunk = demux_yuv4mpeg2_send_chunk; this->demux_plugin.seek = demux_yuv4mpeg2_seek; - this->demux_plugin.stop = demux_yuv4mpeg2_stop; this->demux_plugin.dispose = demux_yuv4mpeg2_dispose; this->demux_plugin.get_status = demux_yuv4mpeg2_get_status; this->demux_plugin.get_stream_length = demux_yuv4mpeg2_get_stream_length; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; - pthread_mutex_init (&this->mutex, NULL); switch (stream->content_detection_method) { @@ -540,6 +441,6 @@ static void *init_plugin (xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 14, "yuv4mpeg2", XINE_VERSION_CODE, NULL, init_plugin }, + { PLUGIN_DEMUX, 15, "yuv4mpeg2", XINE_VERSION_CODE, NULL, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/xine-engine/demux.c b/src/xine-engine/demux.c index 59339f0e2..1fb4dac2c 100644 --- a/src/xine-engine/demux.c +++ b/src/xine-engine/demux.c @@ -23,10 +23,16 @@ * $id$ */ +#include +#include +#include #include "xine_internal.h" #include "demuxers/demux.h" #include "buffer.h" +#define LOG + + /* internal use only - called from demuxers on seek/stop * warning: after clearing decoders fifos an absolute discontinuity * indication must be sent. relative discontinuities are likely @@ -121,3 +127,120 @@ void xine_demux_control_end( xine_stream_t *stream, uint32_t flags ) { stream->audio_fifo->put (stream->audio_fifo, buf); } } + +static void *demux_loop (void *stream_gen) { + + xine_stream_t *stream = (xine_stream_t *)stream_gen; + int status; + +#ifdef LOG + printf ("demux: loop starting...\n"); +#endif + + pthread_mutex_lock( &stream->demux_lock ); + + /* do-while needed to seek after demux finished */ + do { + + /* main demuxer loop */ + status = stream->demux_plugin->get_status(stream->demux_plugin); + while(status == DEMUX_OK && stream->demux_thread_running) { + + status = stream->demux_plugin->send_chunk(stream->demux_plugin); + + /* someone may want to interrupt us */ + pthread_mutex_unlock( &stream->demux_lock ); + pthread_mutex_lock( &stream->demux_lock ); + } + +#ifdef LOG + printf ("demux: main demuxer loop finished (status: %d)\n", status); +#endif + /* 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_fifo || stream->audio_fifo->size(stream->audio_fifo)) && + status != DEMUX_OK ){ + pthread_mutex_unlock( &stream->demux_lock ); + xine_usec_sleep(100000); + pthread_mutex_lock( &stream->demux_lock ); + status = stream->demux_plugin->get_status(stream->demux_plugin); + } + + } while( status == DEMUX_OK && stream->demux_thread_running ); + +#ifdef LOG + printf ("demux: loop finished (status: %d)\n", status); +#endif + + /* demux_thread_running is zero is demux loop has being stopped by user */ + if (stream->demux_thread_running) { + xine_demux_control_end(stream, BUF_FLAG_END_STREAM); + } else { + xine_demux_control_end(stream, BUF_FLAG_END_USER); + } + + stream->demux_thread_running = 0; + pthread_mutex_unlock( &stream->demux_lock ); + + pthread_exit(NULL); + + return NULL; +} + +int xine_demux_start_thread (xine_stream_t *stream) { + + int err; + +#ifdef LOG + printf ("demux: start thread called\n"); +#endif + + pthread_mutex_lock( &stream->demux_lock ); + + if( !stream->demux_thread_running ) { + + stream->demux_thread_running = 1; + if ((err = pthread_create (&stream->demux_thread, + NULL, demux_loop, (void *)stream)) != 0) { + printf ("demux: can't create new thread (%s)\n", + strerror(err)); + abort(); + } + } + + pthread_mutex_unlock( &stream->demux_lock ); + return 0; +} + +int xine_demux_stop_thread (xine_stream_t *stream) { + + void *p; + +#ifdef LOG + printf ("demux: stop thread called\n"); +#endif + + pthread_mutex_lock( &stream->demux_lock ); + stream->demux_thread_running = 0; + pthread_mutex_unlock( &stream->demux_lock ); + +#ifdef LOG + printf ("demux: joining thread %d\n", stream->demux_thread ); +#endif + + /* FIXME: counter_lock isn't meant to protect demux_thread update. + however we can't use demux_lock here. should we create a new lock? */ + pthread_mutex_lock (&stream->counter_lock); + + /* must be atomic */ + if( stream->demux_thread ) + pthread_join (stream->demux_thread, &p); + stream->demux_thread = 0; + + pthread_mutex_unlock (&stream->counter_lock); + + xine_demux_flush_engine(stream); + + return 0; +} diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c index a4560e658..8bf736c54 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.177 2002/10/27 01:52:15 guenter Exp $ + * $Id: xine.c,v 1.178 2002/10/28 03:24:43 miguelfreitas Exp $ * * top-level xine functions * @@ -67,6 +67,9 @@ void xine_handle_stream_end (xine_stream_t *stream, int non_user) { if (stream->status == XINE_STATUS_QUIT) return; stream->status = XINE_STATUS_STOP; + + /* join thread if needed to fix resource leaks */ + xine_demux_stop_thread( stream ); if (non_user) { /* frontends will not be interested in receiving this event @@ -160,8 +163,8 @@ static void xine_stop_internal (xine_stream_t *stream) { printf ("xine_stop: stopping demux\n"); #endif if (stream->demux_plugin) { - stream->demux_plugin->dispose (stream->demux_plugin); - stream->demux_plugin = NULL; + + xine_demux_stop_thread( stream ); /* * wait until engine has really stopped @@ -183,15 +186,6 @@ static void xine_stop_internal (xine_stream_t *stream) { printf ("xine_stop: demux stopped\n"); #endif - /* - * close input plugin - */ - - if (stream->input_plugin) { - stream->input_plugin->dispose(stream->input_plugin); - stream->input_plugin = NULL; - } - /* remove buffered samples from the sound device driver */ if (stream->audio_out) stream->audio_out->control (stream->audio_out, AO_CTRL_FLUSH_BUFFERS); @@ -217,6 +211,40 @@ void xine_stop (xine_stream_t *stream) { pthread_mutex_unlock (&stream->frontend_lock); } + +static void xine_close_internal (xine_stream_t *stream) { + + xine_stop_internal( stream ); + +#ifdef LOG + printf ("xine_close: disposing demux\n"); +#endif + if (stream->demux_plugin) { + + stream->demux_plugin->dispose (stream->demux_plugin); + stream->demux_plugin = NULL; + } + + /* + * close input plugin + */ + + if (stream->input_plugin) { + stream->input_plugin->dispose(stream->input_plugin); + stream->input_plugin = NULL; + } +} + +void xine_close (xine_stream_t *stream) { + + pthread_mutex_lock (&stream->frontend_lock); + + xine_close_internal (stream); + + pthread_mutex_unlock (&stream->frontend_lock); +} + + xine_stream_t *xine_stream_new (xine_t *this, xine_ao_driver_t *ao, xine_vo_driver_t *vo) { @@ -270,6 +298,7 @@ xine_stream_t *xine_stream_new (xine_t *this, * init mutexes and conditions */ + pthread_mutex_init (&stream->demux_lock, NULL); pthread_mutex_init (&stream->frontend_lock, NULL); pthread_mutex_init (&stream->event_queues_lock, NULL); pthread_mutex_init (&stream->osd_lock, NULL); @@ -335,7 +364,7 @@ static int xine_open_internal (xine_stream_t *stream, const char *mrl) { * stop engine if necessary */ - xine_stop_internal (stream); + xine_close_internal (stream); #ifdef LOG printf ("xine: engine should be stopped now\n"); @@ -363,8 +392,6 @@ static int xine_open_internal (xine_stream_t *stream, const char *mrl) { if (!(stream->demux_plugin=find_demux_plugin (stream, stream->input_plugin))) { xine_log (stream->xine, XINE_LOG_MSG, _("xine: couldn't find demux for >%s<\n"), mrl); - stream->input_plugin->dispose (stream->input_plugin); - stream->input_plugin = NULL; stream->err = XINE_ERROR_NO_DEMUX_PLUGIN; /* remove buffered samples from the sound device driver */ @@ -483,14 +510,8 @@ static int xine_play_internal (xine_stream_t *stream, int start_pos, int start_t return 0; } - if (stream->status == XINE_STATUS_STOP) { - - demux_status = stream->demux_plugin->start (stream->demux_plugin, - pos, start_time); - } else { - demux_status = stream->demux_plugin->seek (stream->demux_plugin, + demux_status = stream->demux_plugin->seek (stream->demux_plugin, pos, start_time); - } if (demux_status != DEMUX_OK) { xine_log (stream->xine, XINE_LOG_MSG, @@ -498,12 +519,10 @@ static int xine_play_internal (xine_stream_t *stream, int start_pos, int start_t stream->err = XINE_ERROR_DEMUX_FAILED; - if (stream->status == XINE_STATUS_STOP) - stream->input_plugin->dispose(stream->input_plugin); - return 0; } else { + xine_demux_start_thread( stream ); stream->status = XINE_STATUS_PLAY; } @@ -754,9 +773,13 @@ int xine_get_speed (xine_stream_t *stream) { */ static int xine_get_stream_length (xine_stream_t *stream) { + + pthread_mutex_lock( &stream->demux_lock ); if (stream->demux_plugin) return stream->demux_plugin->get_stream_length (stream->demux_plugin); + + pthread_mutex_unlock( &stream->demux_lock ); return 0; } diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h index 74f0a1db2..0f7e8baec 100644 --- a/src/xine-engine/xine_internal.h +++ b/src/xine-engine/xine_internal.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: xine_internal.h,v 1.107 2002/10/27 01:52:15 guenter Exp $ + * $Id: xine_internal.h,v 1.108 2002/10/28 03:24:44 miguelfreitas Exp $ * */ @@ -201,6 +201,11 @@ struct xine_stream_s { /* event mechanism */ xine_list_t *event_queues; pthread_mutex_t event_queues_lock; + + /* demux thread stuff */ + pthread_t demux_thread; + int demux_thread_running; + pthread_mutex_t demux_lock; int err; }; @@ -238,6 +243,8 @@ void xine_demux_control_newpts (xine_stream_t *stream, int64_t pts, uint32 void xine_demux_control_headers_done (xine_stream_t *stream); void xine_demux_control_start (xine_stream_t *stream); void xine_demux_control_end (xine_stream_t *stream, uint32_t flags); +int xine_demux_start_thread (xine_stream_t *stream); +int xine_demux_stop_thread (xine_stream_t *stream); /* * plugin_loader functions -- cgit v1.2.3