diff options
| author | Darren Salt <linux@youmustbejoking.demon.co.uk> | 2009-02-10 18:25:09 +0000 |
|---|---|---|
| committer | Darren Salt <linux@youmustbejoking.demon.co.uk> | 2009-02-10 18:25:09 +0000 |
| commit | 1c19b8e8e3cfb32e341332b751686e86d7389569 (patch) | |
| tree | 64d9edcf312915b3d9ae524d55b6508b61bf361f /src/xine-engine | |
| parent | c62b455944c8c91bd4d9ae5e8000ec33190174c5 (diff) | |
| parent | 6002a9a87b3f591832c2b91ca1b2b1b67be008f5 (diff) | |
| download | xine-lib-1c19b8e8e3cfb32e341332b751686e86d7389569.tar.gz xine-lib-1c19b8e8e3cfb32e341332b751686e86d7389569.tar.bz2 | |
Merge from 1.1.
--HG--
rename : doc/faq/faq.sgml => doc/faq/faq.docbook
rename : src/xine-engine/buffer.h => include/xine/buffer.h
rename : src/xine-engine/xine_internal.h => include/xine/xine_internal.h
Diffstat (limited to 'src/xine-engine')
| -rw-r--r-- | src/xine-engine/audio_decoder.c | 6 | ||||
| -rw-r--r-- | src/xine-engine/audio_out.c | 2 | ||||
| -rw-r--r-- | src/xine-engine/demux.c | 53 | ||||
| -rw-r--r-- | src/xine-engine/video_decoder.c | 2 | ||||
| -rw-r--r-- | src/xine-engine/xine.c | 6 | ||||
| -rw-r--r-- | src/xine-engine/xine_interface.c | 3 |
6 files changed, 52 insertions, 20 deletions
diff --git a/src/xine-engine/audio_decoder.c b/src/xine-engine/audio_decoder.c index 6a0688f0d..483567994 100644 --- a/src/xine-engine/audio_decoder.c +++ b/src/xine-engine/audio_decoder.c @@ -89,16 +89,18 @@ static void *audio_decoder_loop (void *stream_gen) { if (stream->audio_decoder_plugin) { lprintf ("close old decoder\n"); - + + stream->keep_ao_driver_open = !!(buf->decoder_flags & BUF_FLAG_GAPLESS_SW); _x_free_audio_decoder (stream, stream->audio_decoder_plugin); stream->audio_decoder_plugin = NULL; stream->audio_track_map_entries = 0; stream->audio_type = 0; + stream->keep_ao_driver_open = 0; } running_ticket->release(running_ticket, 0); - if( !stream->gapless_switch ) + if( !(buf->decoder_flags & BUF_FLAG_GAPLESS_SW) ) stream->metronom->handle_audio_discontinuity (stream->metronom, DISC_STREAMSTART, 0); buftype_unknown = 0; diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c index f16f482aa..cf202cf8f 100644 --- a/src/xine-engine/audio_out.c +++ b/src/xine-engine/audio_out.c @@ -1611,7 +1611,7 @@ static void ao_close(xine_audio_port_t *this_gen, xine_stream_t *stream) { pthread_mutex_unlock(&this->streams_lock); /* close driver if no streams left */ - if (!ite && !this->grab_only && !stream->gapless_switch) { + if (!ite && !this->grab_only && !stream->keep_ao_driver_open) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_out: no streams left, closing driver\n"); if (this->audio_loop_running) { diff --git a/src/xine-engine/demux.c b/src/xine-engine/demux.c index ed5abb247..449b9f991 100644 --- a/src/xine-engine/demux.c +++ b/src/xine-engine/demux.c @@ -120,6 +120,16 @@ void _x_demux_flush_engine (xine_stream_t *stream) { } +struct timespec _x_compute_interval(unsigned int millisecs) { + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + uint64_t ttimer = (uint64_t)ts.tv_sec*1000 + ts.tv_nsec/1000000 + millisecs; + ts.tv_sec = ttimer/1000; + ts.tv_nsec = (ttimer%1000)*1000000; + return ts; +} + + void _x_demux_control_newpts( xine_stream_t *stream, int64_t pts, uint32_t flags ) { buf_element_t *buf; @@ -147,19 +157,20 @@ void _x_demux_control_newpts( xine_stream_t *stream, int64_t pts, uint32_t flags */ static int demux_unstick_ao_loop (xine_stream_t *stream) { - if (!stream->audio_thread_created) +/* if (!stream->audio_thread_created) return 0; - +*/ int status = xine_get_status (stream); - if (status != XINE_STATUS_QUIT && status != XINE_STATUS_STOP) + if (status != XINE_STATUS_QUIT && status != XINE_STATUS_STOP && stream->demux_plugin->get_status(stream->demux_plugin) != DEMUX_FINISHED) return 0; - +#if 0 /* right, stream is stopped... */ audio_buffer_t *buf = stream->audio_out->get_buffer (stream->audio_out); buf->num_frames = 0; buf->stream = NULL; stream->audio_out->put_buffer (stream->audio_out, buf, stream); - +#endif + lprintf("stuck\n"); return 1; } @@ -200,24 +211,27 @@ void _x_demux_control_headers_done (xine_stream_t *stream) { stream->audio_fifo->put (stream->audio_fifo, buf_audio); pthread_mutex_unlock(&stream->demux_mutex); + unsigned int max_iterations = 0; while ((stream->header_count_audio < header_count_audio) || (stream->header_count_video < header_count_video)) { - struct timeval tv; - struct timespec ts; lprintf ("waiting for headers. v:%d %d a:%d %d\n", stream->header_count_video, header_count_video, stream->header_count_audio, header_count_audio); + + struct timespec ts = _x_compute_interval(1000); + int ret_wait; - gettimeofday(&tv, NULL); - ts.tv_sec = tv.tv_sec + 1; - ts.tv_nsec = tv.tv_usec * 1000; /* use timedwait to workaround buggy pthread broadcast implementations */ - pthread_cond_timedwait (&stream->counter_changed, &stream->counter_lock, &ts); + ret_wait = pthread_cond_timedwait (&stream->counter_changed, &stream->counter_lock, &ts); - if (demux_unstick_ao_loop (stream)) + if (ret_wait == ETIMEDOUT && demux_unstick_ao_loop (stream) && ++max_iterations > 4) { + xine_log(stream->xine, + XINE_LOG_MSG,_("Stuck in _x_demux_control_headers_done(). Taking the emergency exit\n")); + stream->emergency_brake = 1; break; + } } stream->demux_action_pending = 0; @@ -231,15 +245,18 @@ void _x_demux_control_headers_done (xine_stream_t *stream) { void _x_demux_control_start( xine_stream_t *stream ) { buf_element_t *buf; + uint32_t flags = (stream->gapless_switch) ? BUF_FLAG_GAPLESS_SW : 0; pthread_mutex_lock(&stream->demux_mutex); buf = stream->video_fifo->buffer_pool_alloc (stream->video_fifo); buf->type = BUF_CONTROL_START; + buf->decoder_flags = flags; stream->video_fifo->put (stream->video_fifo, buf); buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo); buf->type = BUF_CONTROL_START; + buf->decoder_flags = flags; stream->audio_fifo->put (stream->audio_fifo, buf); pthread_mutex_unlock(&stream->demux_mutex); @@ -371,13 +388,21 @@ static void *demux_loop (void *stream_gen) { pthread_mutex_unlock( &stream->demux_lock ); pthread_mutex_lock (&stream->counter_lock); + struct timespec ts; + unsigned int max_iterations = 0; + int ret_wait; while ((stream->finished_count_audio < finished_count_audio) || (stream->finished_count_video < finished_count_video)) { lprintf ("waiting for finisheds.\n"); - pthread_cond_wait (&stream->counter_changed, &stream->counter_lock); + ts = _x_compute_interval(1000); + ret_wait = pthread_cond_timedwait (&stream->counter_changed, &stream->counter_lock, &ts); - if (demux_unstick_ao_loop (stream)) + if (ret_wait == ETIMEDOUT && demux_unstick_ao_loop (stream) && ++max_iterations > 4) { + xine_log(stream->xine, + XINE_LOG_MSG,_("Stuck in demux_loop(). Taking the emergency exit\n")); + stream->emergency_brake = 1; break; + } } pthread_mutex_unlock (&stream->counter_lock); diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c index 3cc4e37f7..af22ecdd0 100644 --- a/src/xine-engine/video_decoder.c +++ b/src/xine-engine/video_decoder.c @@ -161,7 +161,7 @@ static void *video_decoder_loop (void *stream_gen) { running_ticket->release(running_ticket, 0); - if( !stream->gapless_switch ) + if( !(buf->decoder_flags & BUF_FLAG_GAPLESS_SW) ) stream->metronom->handle_video_discontinuity (stream->metronom, DISC_STREAMSTART, 0); diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c index 722e04679..86b099922 100644 --- a/src/xine-engine/xine.c +++ b/src/xine-engine/xine.c @@ -456,6 +456,7 @@ void xine_stop (xine_stream_t *stream) { static void close_internal (xine_stream_t *stream) { int i ; + int gapless_switch = stream->gapless_switch; if( stream->slave ) { xine_close( stream->slave ); @@ -466,7 +467,7 @@ static void close_internal (xine_stream_t *stream) { } } - if( !stream->gapless_switch ) { + if( !gapless_switch ) { /* make sure that other threads cannot change the speed, especially pauseing the stream */ pthread_mutex_lock(&stream->speed_change_lock); stream->ignore_speed_change = 1; @@ -482,7 +483,7 @@ static void close_internal (xine_stream_t *stream) { stop_internal( stream ); - if( !stream->gapless_switch ) { + if( !gapless_switch ) { if (stream->video_out) stream->video_out->set_property(stream->video_out, VO_PROP_DISCARD_FRAMES, 0); if (stream->audio_out) @@ -637,6 +638,7 @@ xine_stream_t *xine_stream_new (xine_t *this, stream->early_finish_event = 0; stream->delay_finish_event = 0; stream->gapless_switch = 0; + stream->keep_ao_driver_open = 0; stream->video_out = vo; if (vo) diff --git a/src/xine-engine/xine_interface.c b/src/xine-engine/xine_interface.c index 43a40f51c..a2015bb06 100644 --- a/src/xine-engine/xine_interface.c +++ b/src/xine-engine/xine_interface.c @@ -518,6 +518,9 @@ void xine_set_param (xine_stream_t *stream, int param, int value) { case XINE_PARAM_GAPLESS_SWITCH: stream->gapless_switch = !!value; + if( stream->gapless_switch && !stream->early_finish_event ) { + xprintf (stream->xine, XINE_VERBOSITY_DEBUG, "frontend possibly buggy: gapless_switch without early_finish_event\n"); + } break; default: |
