summaryrefslogtreecommitdiff
path: root/src/xine-engine
diff options
context:
space:
mode:
authorDarren Salt <linux@youmustbejoking.demon.co.uk>2009-02-10 18:25:09 +0000
committerDarren Salt <linux@youmustbejoking.demon.co.uk>2009-02-10 18:25:09 +0000
commit1c19b8e8e3cfb32e341332b751686e86d7389569 (patch)
tree64d9edcf312915b3d9ae524d55b6508b61bf361f /src/xine-engine
parentc62b455944c8c91bd4d9ae5e8000ec33190174c5 (diff)
parent6002a9a87b3f591832c2b91ca1b2b1b67be008f5 (diff)
downloadxine-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.c6
-rw-r--r--src/xine-engine/audio_out.c2
-rw-r--r--src/xine-engine/demux.c53
-rw-r--r--src/xine-engine/video_decoder.c2
-rw-r--r--src/xine-engine/xine.c6
-rw-r--r--src/xine-engine/xine_interface.c3
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: