summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/xine-engine/audio_decoder.c9
-rw-r--r--src/xine-engine/audio_out.c5
-rw-r--r--src/xine-engine/demux.c5
-rw-r--r--src/xine-engine/video_decoder.c11
-rw-r--r--src/xine-engine/xine.c46
-rw-r--r--src/xine-engine/xine_interface.c18
-rw-r--r--src/xine-engine/xine_internal.h4
7 files changed, 65 insertions, 33 deletions
diff --git a/src/xine-engine/audio_decoder.c b/src/xine-engine/audio_decoder.c
index f3b09b50b..a380d7af3 100644
--- a/src/xine-engine/audio_decoder.c
+++ b/src/xine-engine/audio_decoder.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: audio_decoder.c,v 1.135 2005/08/25 15:36:30 valtri Exp $
+ * $Id: audio_decoder.c,v 1.136 2005/10/30 02:18:35 miguelfreitas Exp $
*
*
* functions that implement audio decoding
@@ -100,7 +100,8 @@ static void *audio_decoder_loop (void *stream_gen) {
running_ticket->release(running_ticket, 0);
- stream->metronom->handle_audio_discontinuity (stream->metronom, DISC_STREAMSTART, 0);
+ if( !stream->gapless_switch )
+ stream->metronom->handle_audio_discontinuity (stream->metronom, DISC_STREAMSTART, 0);
buftype_unknown = 0;
break;
@@ -119,7 +120,7 @@ static void *audio_decoder_loop (void *stream_gen) {
}
first_header = last_header = NULL;
}
-
+
/*
* wait the output fifos to run dry before sending the notification event
* to the frontend. this test is only valid if there is only a single
@@ -133,7 +134,7 @@ static void *audio_decoder_loop (void *stream_gen) {
num_streams = stream->audio_out->get_property(stream->audio_out, AO_PROP_NUM_STREAMS);
running_ticket->release(running_ticket, 0);
- if( num_bufs > 0 && num_streams == 1 )
+ if( num_bufs > 0 && num_streams == 1 && !stream->early_finish_event)
xine_usec_sleep (10000);
else
break;
diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c
index f7120d919..d7567994c 100644
--- a/src/xine-engine/audio_out.c
+++ b/src/xine-engine/audio_out.c
@@ -17,7 +17,7 @@
* along with self program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: audio_out.c,v 1.193 2005/09/14 23:42:37 miguelfreitas Exp $
+ * $Id: audio_out.c,v 1.194 2005/10/30 02:18:35 miguelfreitas Exp $
*
* 22-8-2001 James imported some useful AC3 sections from the previous alsa driver.
* (c) 2001 Andy Lo A Foe <andy@alsaplayer.org>
@@ -1528,7 +1528,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 (!cur && !this->grab_only) {
+ if (!cur && !this->grab_only && !stream->gapless_switch) {
xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_out: no streams left, closing driver\n");
if (this->audio_loop_running) {
@@ -1786,6 +1786,7 @@ static int ao_set_property (xine_audio_port_t *this_gen, int property, int value
this->discard_buffers++;
else
this->discard_buffers--;
+
ret = this->discard_buffers;
/* discard buffers here because we have no output thread */
diff --git a/src/xine-engine/demux.c b/src/xine-engine/demux.c
index f89fec38f..75928c6e1 100644
--- a/src/xine-engine/demux.c
+++ b/src/xine-engine/demux.c
@@ -20,7 +20,7 @@
* Demuxer helper functions
* hide some xine engine details from demuxers and reduce code duplication
*
- * $Id: demux.c,v 1.59 2005/08/25 15:36:30 valtri Exp $
+ * $Id: demux.c,v 1.60 2005/10/30 02:18:35 miguelfreitas Exp $
*/
@@ -67,6 +67,9 @@ void _x_demux_flush_engine (xine_stream_t *stream) {
buf_element_t *buf;
+ if( stream->gapless_switch )
+ return;
+
stream->xine->port_ticket->acquire(stream->xine->port_ticket, 1);
/* only flush/discard output ports on master streams */
diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c
index edec3a00c..061962d4a 100644
--- a/src/xine-engine/video_decoder.c
+++ b/src/xine-engine/video_decoder.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: video_decoder.c,v 1.159 2005/08/25 15:36:30 valtri Exp $
+ * $Id: video_decoder.c,v 1.160 2005/10/30 02:18:35 miguelfreitas Exp $
*
*/
@@ -153,8 +153,9 @@ static void *video_decoder_loop (void *stream_gen) {
running_ticket->release(running_ticket, 0);
- stream->metronom->handle_video_discontinuity (stream->metronom,
- DISC_STREAMSTART, 0);
+ if( !stream->gapless_switch )
+ stream->metronom->handle_video_discontinuity (stream->metronom,
+ DISC_STREAMSTART, 0);
buftype_unknown = 0;
break;
@@ -189,7 +190,7 @@ static void *video_decoder_loop (void *stream_gen) {
stream->video_decoder_plugin->flush (stream->video_decoder_plugin);
running_ticket->release(running_ticket, 0);
}
-
+
/*
* wait the output fifos to run dry before sending the notification event
* to the frontend. this test is only valid if there is only a single
@@ -203,7 +204,7 @@ static void *video_decoder_loop (void *stream_gen) {
num_streams = stream->video_out->get_property(stream->video_out, VO_PROP_NUM_STREAMS);
running_ticket->release(running_ticket, 0);
- if( num_bufs > 0 && num_streams == 1 )
+ if( num_bufs > 0 && num_streams == 1 && !stream->early_finish_event )
xine_usec_sleep (10000);
else
break;
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
index ce37b289e..2b789bed0 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.318 2005/09/19 16:14:02 valtri Exp $
+ * $Id: xine.c,v 1.319 2005/10/30 02:18:35 miguelfreitas Exp $
*/
/*
@@ -88,7 +88,7 @@ void _x_handle_stream_end (xine_stream_t *stream, int non_user) {
* if they have called xine_stop explicitly, so only send
* it if stream playback finished because of stream end reached
*/
-
+
xine_event_t event;
event.data_length = 0;
@@ -332,24 +332,28 @@ static void close_internal (xine_stream_t *stream) {
}
}
- stream->ignore_speed_change = 1;
- stream->xine->port_ticket->acquire(stream->xine->port_ticket, 1);
-
- if (stream->audio_out)
- stream->audio_out->set_property(stream->audio_out, AO_PROP_DISCARD_BUFFERS, 1);
- if (stream->video_out)
- stream->video_out->set_property(stream->video_out, VO_PROP_DISCARD_FRAMES, 1);
-
+ if( !stream->gapless_switch ) {
+ stream->ignore_speed_change = 1;
+ stream->xine->port_ticket->acquire(stream->xine->port_ticket, 1);
+
+ if (stream->audio_out)
+ stream->audio_out->set_property(stream->audio_out, AO_PROP_DISCARD_BUFFERS, 1);
+ if (stream->video_out)
+ stream->video_out->set_property(stream->video_out, VO_PROP_DISCARD_FRAMES, 1);
+ }
+
stop_internal( stream );
- if (stream->video_out)
- stream->video_out->set_property(stream->video_out, VO_PROP_DISCARD_FRAMES, 0);
- if (stream->audio_out)
- stream->audio_out->set_property(stream->audio_out, AO_PROP_DISCARD_BUFFERS, 0);
-
- stream->xine->port_ticket->release(stream->xine->port_ticket, 1);
- stream->ignore_speed_change = 0;
+ if( !stream->gapless_switch ) {
+ if (stream->video_out)
+ stream->video_out->set_property(stream->video_out, VO_PROP_DISCARD_FRAMES, 0);
+ if (stream->audio_out)
+ stream->audio_out->set_property(stream->audio_out, AO_PROP_DISCARD_BUFFERS, 0);
+ stream->xine->port_ticket->release(stream->xine->port_ticket, 1);
+ stream->ignore_speed_change = 0;
+ }
+
if (stream->demux_plugin) {
_x_free_demux_plugin(stream, stream->demux_plugin);
stream->demux_plugin = NULL;
@@ -486,6 +490,8 @@ xine_stream_t *xine_stream_new (xine_t *this,
stream->spu_channel_pan_scan = -1;
stream->spu_channel_user = -1;
stream->spu_channel = -1;
+ stream->early_finish_event = 0;
+ stream->gapless_switch = 0;
stream->video_out = vo;
if (vo)
@@ -1124,7 +1130,7 @@ static int play_internal (xine_stream_t *stream, int start_pos, int start_time)
stream->xine->port_ticket->acquire(stream->xine->port_ticket, 1);
/* only flush/discard output ports on master streams */
- if( stream->master == stream ) {
+ if( stream->master == stream && !stream->gapless_switch) {
/* discard audio/video buffers to get engine going and take the lock faster */
if (stream->audio_out)
stream->audio_out->set_property(stream->audio_out, AO_PROP_DISCARD_BUFFERS, 1);
@@ -1153,7 +1159,7 @@ static int play_internal (xine_stream_t *stream, int start_pos, int start_time)
stream->demux_thread_running);
/* only flush/discard output ports on master streams */
- if( stream->master == stream ) {
+ if( stream->master == stream && !stream->gapless_switch) {
if (stream->audio_out)
stream->audio_out->set_property(stream->audio_out, AO_PROP_DISCARD_BUFFERS, 0);
if (stream->video_out)
@@ -1211,6 +1217,8 @@ int xine_play (xine_stream_t *stream, int start_pos, int start_time) {
ret = play_internal (stream, start_pos, start_time);
if( stream->slave && (stream->slave_affection & XINE_MASTER_SLAVE_PLAY) )
xine_play (stream->slave, start_pos, start_time);
+
+ stream->gapless_switch = 0;
pthread_mutex_unlock (&stream->frontend_lock);
diff --git a/src/xine-engine/xine_interface.c b/src/xine-engine/xine_interface.c
index 70415c3e8..18c86349b 100644
--- a/src/xine-engine/xine_interface.c
+++ b/src/xine-engine/xine_interface.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_interface.c,v 1.90 2005/07/03 20:31:29 miguelfreitas Exp $
+ * $Id: xine_interface.c,v 1.91 2005/10/30 02:18:35 miguelfreitas Exp $
*
* convenience/abstraction layer, functions to implement
* libxine's public interface
@@ -474,6 +474,14 @@ void xine_set_param (xine_stream_t *stream, int param, int value) {
stream->broadcaster = NULL;
}
break;
+
+ case XINE_PARAM_EARLY_FINISHED_EVENT:
+ stream->early_finish_event = value;
+ break;
+
+ case XINE_PARAM_GAPLESS_SWITCH:
+ stream->gapless_switch = value;
+ break;
default:
xprintf (stream->xine, XINE_VERBOSITY_DEBUG,
@@ -621,6 +629,14 @@ int xine_get_param (xine_stream_t *stream, int param) {
else
ret = 0;
break;
+
+ case XINE_PARAM_EARLY_FINISHED_EVENT:
+ ret = stream->early_finish_event;
+ break;
+
+ case XINE_PARAM_GAPLESS_SWITCH:
+ ret = stream->gapless_switch;
+ break;
default:
xprintf (stream->xine, XINE_VERBOSITY_DEBUG,
diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h
index 94235ad51..718349ea3 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.168 2005/09/25 00:44:04 miguelfreitas Exp $
+ * $Id: xine_internal.h,v 1.169 2005/10/30 02:18:35 miguelfreitas Exp $
*
*/
@@ -336,6 +336,8 @@ struct xine_stream_s {
int emergency_brake; /* something went really wrong and this stream must be
* stopped. usually due some fatal error on output
* layers as they cannot call xine_stop. */
+ int early_finish_event; /* do not wait fifos get empty before sending event */
+ int gapless_switch; /* next stream switch will be gapless */
#endif
};