diff options
author | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2005-10-30 02:18:35 +0000 |
---|---|---|
committer | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2005-10-30 02:18:35 +0000 |
commit | 5fd98dc3451215272aadbe93dbb7e43805050fc3 (patch) | |
tree | 14768677bdde796f8b26e4ff9dd60643bf96d5d9 | |
parent | f32c34a198bb2f407b6ceb1157e7239d1c2f6d79 (diff) | |
download | xine-lib-5fd98dc3451215272aadbe93dbb7e43805050fc3.tar.gz xine-lib-5fd98dc3451215272aadbe93dbb7e43805050fc3.tar.bz2 |
gapless playback stream switching support
CVS patchset: 7784
CVS date: 2005/10/30 02:18:35
-rw-r--r-- | ChangeLog | 1 | ||||
-rw-r--r-- | configure.ac | 6 | ||||
-rw-r--r-- | include/xine.h.in | 4 | ||||
-rw-r--r-- | src/xine-engine/audio_decoder.c | 9 | ||||
-rw-r--r-- | src/xine-engine/audio_out.c | 5 | ||||
-rw-r--r-- | src/xine-engine/demux.c | 5 | ||||
-rw-r--r-- | src/xine-engine/video_decoder.c | 11 | ||||
-rw-r--r-- | src/xine-engine/xine.c | 46 | ||||
-rw-r--r-- | src/xine-engine/xine_interface.c | 18 | ||||
-rw-r--r-- | src/xine-engine/xine_internal.h | 4 |
10 files changed, 72 insertions, 37 deletions
@@ -18,6 +18,7 @@ xine-lib (1.1.1) * FFmpeg sync (new QDM2 decoder) * imported Duck TrueMotion 2 decoder from FFmpeg * sync libfaad2 to newer version; fixes AAC decoding on x86_64 arch + * support gapless playback while switching streams (requires UI cooperation) xine-lib (1.1.0) * new quality deinterlacer from dscaler: GreedyH (Greedy High Motion) diff --git a/configure.ac b/configure.ac index 98ee87885..06fd5fd53 100644 --- a/configure.ac +++ b/configure.ac @@ -16,7 +16,7 @@ dnl XINE_SUB += 1; continue with XINE_LT_* values below dnl XINE_MAJOR=1 XINE_MINOR=1 -XINE_SUB=0 +XINE_SUB=1 #if test $XINE_SUB -eq 0 ; then # XINE_SUBPART=""; @@ -49,9 +49,9 @@ dnl are platform dependent dnl * in Linux, the library will be named dnl libname.so.(XINE_LT_CURRENT - XINE_LT_AGE).XINE_LT_AGE.XINE_LT_REVISION -XINE_LT_CURRENT=14 +XINE_LT_CURRENT=15 XINE_LT_REVISION=0 -XINE_LT_AGE=13 +XINE_LT_AGE=14 dnl for a release tarball do "rm .cvsversion" before "make dist" if test -f .cvsversion; then diff --git a/include/xine.h.in b/include/xine.h.in index e50830347..25b41a0d9 100644 --- a/include/xine.h.in +++ b/include/xine.h.in @@ -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.h.in,v 1.145 2005/10/07 20:09:12 mroi Exp $ + * $Id: xine.h.in,v 1.146 2005/10/30 02:18:35 miguelfreitas Exp $ * * public xine-lib (libxine) interface and documentation * @@ -338,6 +338,8 @@ int xine_get_param (xine_stream_t *stream, int param); #define XINE_PARAM_AUDIO_CLOSE_DEVICE 28 /* force closing audio device */ #define XINE_PARAM_AUDIO_AMP_MUTE 29 /* 1=>mute, 0=>unmute */ #define XINE_PARAM_FINE_SPEED 30 /* 1.000.000 => normal speed */ +#define XINE_PARAM_EARLY_FINISHED_EVENT 31 /* send event when demux finish*/ +#define XINE_PARAM_GAPLESS_SWITCH 32 /* next stream only gapless swi*/ /* * speed values for XINE_PARAM_SPEED parameter. 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 }; |