From a10da707671a3ea66aab994762c463db58037e00 Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Fri, 10 May 2002 13:10:04 +0000 Subject: fix seeking problem after demuxer finished. patch by Thibaut Mattern and me. some more testing needed, then other demuxers should be updated to do the same. note that (for other demuxers) the new this->thread_running should make the "starting" variable useless. demuxers also need some cleanup/fixes about API: either start/seek must provide a return value or get_status must use thread_running instead of status. this will fix the problem of displaying demux error messages for very small streams. CVS patchset: 1867 CVS date: 2002/05/10 13:10:04 --- src/demuxers/demux_mpeg.c | 57 ++++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/demuxers/demux_mpeg.c b/src/demuxers/demux_mpeg.c index 6a014f094..f1572219e 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.59 2002/04/29 23:31:59 jcdutton Exp $ + * $Id: demux_mpeg.c,v 1.60 2002/05/10 13:10:04 miguelfreitas Exp $ * * demultiplexer for mpeg 1/2 program streams * reads streams of variable blocksizes @@ -66,6 +66,7 @@ typedef struct demux_mpeg_s { input_plugin_t *input; pthread_t thread; + int thread_running; pthread_mutex_t mutex; unsigned char dummy_space[100000]; @@ -76,7 +77,7 @@ typedef struct demux_mpeg_s { int rate; int send_end_buffers; - + int64_t last_pts[2]; int send_newpts; @@ -671,21 +672,30 @@ static void *demux_mpeg_loop (void *this_gen) { buf_element_t *buf; uint32_t w=0; - while(1) { - - pthread_mutex_lock( &this->mutex ); - - if( this->status != DEMUX_OK) - break; - - w = parse_pack (this); + 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 ); + pthread_mutex_lock( &this->mutex ); + } - if (w != 0x000001ba) - demux_mpeg_resync (this, w); + /* 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 ); + } - pthread_mutex_unlock( &this->mutex ); - - } + } while( this->status == DEMUX_OK ); if (this->send_end_buffers) { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); @@ -701,9 +711,10 @@ static void *demux_mpeg_loop (void *this_gen) { } } - printf ("demux_mpeg: demux loop finished (status: %d, buf:%x)\n", + 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); @@ -719,7 +730,7 @@ static void demux_mpeg_stop (demux_plugin_t *this_gen) { pthread_mutex_lock( &this->mutex ); - if (this->status != DEMUX_OK) { + if (!this->thread_running) { printf ("demux_mpeg: stop...ignored\n"); pthread_mutex_unlock( &this->mutex ); return; @@ -763,7 +774,7 @@ static void demux_mpeg_start (demux_plugin_t *this_gen, pthread_mutex_lock( &this->mutex ); - if( this->status != DEMUX_OK ) { + if( !this->thread_running ) { this->video_fifo = video_fifo; this->audio_fifo = audio_fifo; @@ -798,14 +809,13 @@ static void demux_mpeg_start (demux_plugin_t *this_gen, w = parse_pack_preview (this, &num_buffers); if (w != 0x000001ba) - demux_mpeg_resync (this, w); + demux_mpeg_resync (this, w); num_buffers --; } while ( (this->status == DEMUX_OK) && (num_buffers>0)) ; /* printf ("demux_mpeg: rate %d\n", this->rate); */ - this->status = DEMUX_FINISHED; } } @@ -823,11 +833,12 @@ static void demux_mpeg_start (demux_plugin_t *this_gen, read_bytes(this, 4); this->send_newpts = 1; - - if( this->status != DEMUX_OK ) { + this->status = DEMUX_OK ; + + if( !this->thread_running ) { this->preview_mode = 0; this->send_end_buffers = 1; - this->status = DEMUX_OK ; + this->thread_running = 1; if ((err = pthread_create (&this->thread, NULL, demux_mpeg_loop, this)) != 0) { -- cgit v1.2.3