summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel Freitas <miguelfreitas@users.sourceforge.net>2005-10-30 02:18:35 +0000
committerMiguel Freitas <miguelfreitas@users.sourceforge.net>2005-10-30 02:18:35 +0000
commit5fd98dc3451215272aadbe93dbb7e43805050fc3 (patch)
tree14768677bdde796f8b26e4ff9dd60643bf96d5d9
parentf32c34a198bb2f407b6ceb1157e7239d1c2f6d79 (diff)
downloadxine-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--ChangeLog1
-rw-r--r--configure.ac6
-rw-r--r--include/xine.h.in4
-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
10 files changed, 72 insertions, 37 deletions
diff --git a/ChangeLog b/ChangeLog
index 7893580dd..cd438afb5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
};