diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/xine-engine/audio_out.c | 104 | ||||
-rw-r--r-- | src/xine-engine/audio_out.h | 11 | ||||
-rw-r--r-- | src/xine-engine/video_decoder.c | 4 | ||||
-rw-r--r-- | src/xine-engine/video_out.c | 57 | ||||
-rw-r--r-- | src/xine-engine/video_out.h | 3 | ||||
-rw-r--r-- | src/xine-engine/xine.c | 24 |
6 files changed, 164 insertions, 39 deletions
diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c index 9712de308..d0b1de0ab 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.101 2003/01/30 20:40:42 miguelfreitas Exp $ + * $Id: audio_out.c,v 1.102 2003/02/01 19:22:30 guenter Exp $ * * 22-8-2001 James imported some useful AC3 sections from the previous alsa driver. * (c) 2001 Andy Lo A Foe <andy@alsaplayer.org> @@ -73,9 +73,9 @@ #include "resample.h" #include "metronom.h" -/* + #define LOG -*/ + #define LOG_RESAMPLE_SYNC #define NUM_AUDIO_BUFFERS 32 @@ -148,6 +148,7 @@ typedef struct { int audio_loop_running; int grab_only; /* => do not start thread, frontend will consume samples */ + int flush_mode; int audio_paused; pthread_t audio_thread; @@ -222,7 +223,6 @@ static void fifo_append_int (audio_fifo_t *fifo, assert (!buf->next); if (!fifo->first) { - fifo->first = buf; fifo->last = buf; fifo->num_buffers = 1; @@ -755,7 +755,7 @@ static void *ao_loop (void *this_gen) { } #ifdef LOG - printf ("audio_out:loop:pause: I feel sleepy.\n"); + printf ("audio_out:loop:pause: I feel sleepy (%d buffers).\n", this->out_fifo->num_buffers); #endif xine_usec_sleep (10000); #ifdef LOG @@ -830,7 +830,7 @@ static void *ao_loop (void *this_gen) { /* drop package */ #ifdef LOG - printf ("audio_out:loop: next fifo\n"); + printf ("audio_out:loop: drop package, next fifo\n"); #endif fifo_append (this->free_fifo, in_buf); @@ -889,6 +889,11 @@ static void *ao_loop (void *this_gen) { } #endif +#ifdef LOG + printf ("audio_out: loop: writing %d samples to sound device\n", + out_buf->num_frames); +#endif + pthread_mutex_lock( &this->driver_lock ); this->driver->write (this->driver, out_buf->mem, out_buf->num_frames ); pthread_mutex_unlock( &this->driver_lock ); @@ -917,7 +922,7 @@ int xine_get_next_audio_frame (xine_audio_port_t *this_gen, xine_audio_frame_t *frame) { aos_t *this = (aos_t *) this_gen; - audio_buffer_t *buf; + audio_buffer_t *in_buf, *out_buf; xine_stream_t *stream; do { @@ -928,49 +933,53 @@ int xine_get_next_audio_frame (xine_audio_port_t *this_gen, pthread_mutex_lock (&this->out_fifo->mutex); - buf = this->out_fifo->first; + in_buf = this->out_fifo->first; /* FIXME: ugly, use conditions and locks instead */ - while (!buf + while (!in_buf && (stream->demux_plugin->get_status (stream->demux_plugin)==DEMUX_OK)) { pthread_mutex_unlock(&this->out_fifo->mutex); xine_usec_sleep (1000); pthread_mutex_lock(&this->out_fifo->mutex); - buf = this->out_fifo->first; + in_buf = this->out_fifo->first; } - if (!buf) { + if (!in_buf) { pthread_mutex_unlock(&this->out_fifo->mutex); return 0; } - buf = fifo_remove_int (this->out_fifo); + in_buf = fifo_remove_int (this->out_fifo); pthread_mutex_unlock(&this->out_fifo->mutex); - frame->vpts = buf->vpts; - frame->num_samples = buf->num_frames; + out_buf = prepare_samples (this, in_buf); + + fifo_append (this->free_fifo, in_buf); + + frame->vpts = out_buf->vpts; + frame->num_samples = out_buf->num_frames; frame->sample_rate = this->input.rate; frame->num_channels = mode_channels (this->input.mode); frame->bits_per_sample = this->input.bits; - frame->pos_stream = buf->extra_info->input_pos; - frame->pos_time = buf->extra_info->input_time; - frame->data = (uint8_t *) buf->mem; - frame->xine_frame = buf; + frame->pos_stream = out_buf->extra_info->input_pos; + frame->pos_time = out_buf->extra_info->input_time; + frame->data = (uint8_t *) out_buf->mem; + frame->xine_frame = out_buf; return 1; } void xine_free_audio_frame (xine_audio_port_t *this_gen, xine_audio_frame_t *frame) { +#if 0 aos_t *this = (aos_t *) this_gen; audio_buffer_t *buf; buf = (audio_buffer_t *) frame->xine_frame; - - fifo_append (this->free_fifo, buf); +#endif } @@ -1165,11 +1174,15 @@ static void ao_put_buffer (xine_audio_port_t *this_gen, buf->extra_info->vpts = buf->vpts; #ifdef LOG - printf ("audio_out: ao_put_buffer, pts=%lld, vpts=%lld\n", - pts, buf->vpts); + printf ("audio_out: ao_put_buffer, pts=%lld, vpts=%lld, flushmode=%d\n", + pts, buf->vpts, this->flush_mode); #endif - fifo_append (this->out_fifo, buf); + if (!this->flush_mode) + fifo_append (this->out_fifo, buf); + else + fifo_append (this->free_fifo, buf); + this->last_audio_vpts = buf->vpts; #ifdef LOG @@ -1177,6 +1190,37 @@ static void ao_put_buffer (xine_audio_port_t *this_gen, #endif } +/* + * set audio_out fifo to flush mode (grab mode only) + */ +static void ao_set_flush_mode (xine_audio_port_t *this_gen, int flush_mode) { + aos_t *this = (aos_t *) this_gen; + audio_buffer_t *buf; + + if (!this->grab_only) + return; + + this->flush_mode = flush_mode; + + if (flush_mode) { + pthread_mutex_lock(&this->out_fifo->mutex); + + while ((buf = this->out_fifo->first)) { + +#ifdef LOG + printf ("audio_out: flushing out frame\n"); +#endif + + buf = fifo_remove_int (this->out_fifo); + + fifo_append (this->free_fifo, buf); + } + pthread_mutex_unlock (&this->out_fifo->mutex); + } +} + + + static void ao_close(xine_audio_port_t *this_gen, xine_stream_t *stream) { aos_t *this = (aos_t *) this_gen; @@ -1346,9 +1390,12 @@ static int ao_set_property (xine_audio_port_t *this_gen, int property, int value break; default: - pthread_mutex_lock( &this->driver_lock ); - ret = this->driver->set_property(this->driver, property, value); - pthread_mutex_unlock( &this->driver_lock ); + if (!this->grab_only) { + pthread_mutex_lock( &this->driver_lock ); + ret = this->driver->set_property(this->driver, property, value); + pthread_mutex_unlock( &this->driver_lock ); + } else + ret = 0; } return ret; @@ -1361,6 +1408,9 @@ static int ao_control (xine_audio_port_t *this_gen, int cmd, ...) { void *arg; int rval; + if (this->grab_only) + return 0; + pthread_mutex_lock( &this->driver_lock ); va_start(args, cmd); arg = va_arg(args, void*); @@ -1441,8 +1491,10 @@ xine_audio_port_t *ao_new_port (xine_t *xine, ao_driver_t *driver, this->ao.control = ao_control; this->ao.flush = ao_flush; this->ao.status = ao_status; + this->ao.set_flush_mode = ao_set_flush_mode; this->audio_loop_running = 0; + this->flush_mode = 0; this->grab_only = grab_only; this->audio_paused = 0; this->flush_audio_driver = 0; diff --git a/src/xine-engine/audio_out.h b/src/xine-engine/audio_out.h index ab7cbd008..67a841f2e 100644 --- a/src/xine-engine/audio_out.h +++ b/src/xine-engine/audio_out.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: audio_out.h,v 1.49 2003/01/11 19:06:52 guenter Exp $ + * $Id: audio_out.h,v 1.50 2003/02/01 19:22:30 guenter Exp $ */ #ifndef HAVE_AUDIO_OUT_H #define HAVE_AUDIO_OUT_H @@ -176,8 +176,7 @@ struct ao_format_s { struct xine_audio_port_s { uint32_t (*get_capabilities) (xine_audio_port_t *this); /* for constants see below */ - /* - * Get/Set audio property + /* * Get/Set audio property * * See AO_PROP_* bellow */ @@ -227,6 +226,12 @@ struct xine_audio_port_s { int (*status) (xine_audio_port_t *this, xine_stream_t *stream, uint32_t *bits, uint32_t *rate, int *mode); + /* + * set flush mode, can be used in grad_mode to free all + * audio buffers automatically while the engine is navigating + */ + + void (*set_flush_mode) (xine_audio_port_t *this, int flush_mode); }; typedef struct audio_driver_class_s audio_driver_class_t; diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c index f51363bc7..d99c55832 100644 --- a/src/xine-engine/video_decoder.c +++ b/src/xine-engine/video_decoder.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000-2002 the xine project + * Copyright (C) 2000-2003 the xine project * * This file is part of xine, a free video player. * @@ -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.124 2003/01/14 00:10:29 miguelfreitas Exp $ + * $Id: video_decoder.c,v 1.125 2003/02/01 19:22:30 guenter Exp $ * */ diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c index 97a5221ec..78fa2d308 100644 --- a/src/xine-engine/video_out.c +++ b/src/xine-engine/video_out.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_out.c,v 1.138 2003/01/26 18:12:39 mroi Exp $ + * $Id: video_out.c,v 1.139 2003/02/01 19:22:31 guenter Exp $ * * frame allocation / queuing / scheduling / output functions */ @@ -84,6 +84,7 @@ typedef struct { /* do we true real-time output or is this a grab only instance ? */ int grab_only; + int flush_mode; extra_info_t *extra_info_base; /* used to free mem chunk */ @@ -339,9 +340,18 @@ static int vo_frame_draw (vo_frame_t *img, xine_stream_t *stream) { if (frames_to_skip<0) frames_to_skip = 0; - } else + } else { frames_to_skip = 0; + if (this->flush_mode) { +#ifdef LOG + printf ("video_out: i'm in flush mode, not appending this frame to queue\n"); +#endif + return 0; + } + } + + #ifdef LOG printf ("video_out: delivery diff : %lld, current vpts is %lld, %d frames to skip\n", diff, cur_vpts, frames_to_skip); @@ -956,14 +966,23 @@ int xine_get_next_video_frame (xine_video_port_t *this_gen, /* FIXME: ugly, use conditions and locks instead */ - while (!img - && (stream->demux_plugin->get_status (stream->demux_plugin)==DEMUX_OK)) { + printf ("video_out: get_next_video_frame demux status = %d, fifo_size=%d\n", + stream->demux_plugin->get_status (stream->demux_plugin), + stream->video_fifo->fifo_size); + + while ( !img && (stream->video_fifo->fifo_size + || (stream->demux_plugin->get_status (stream->demux_plugin)==DEMUX_OK))) { pthread_mutex_unlock(&this->display_img_buf_queue->mutex); xine_usec_sleep (1000); pthread_mutex_lock(&this->display_img_buf_queue->mutex); img = this->display_img_buf_queue->first; + printf ("video_out: get_next_video_frame demux status = %d, fifo_size=%d\n", + stream->demux_plugin->get_status (stream->demux_plugin), + stream->video_fifo->fifo_size); + + } if (!img) { @@ -1192,6 +1211,35 @@ static void vo_flush (xine_video_port_t *this_gen) { } } +/* + * set video_out fifo to flush mode (grab mode only) + */ +static void vo_set_flush_mode (xine_video_port_t *this_gen, int flush_mode) { + vos_t *this = (vos_t *) this_gen; + vo_frame_t *img; + + if (!this->grab_only) + return; + + this->flush_mode = flush_mode; + + if (flush_mode) { + pthread_mutex_lock(&this->display_img_buf_queue->mutex); + + while ((img = this->display_img_buf_queue->first)) { + +#ifdef LOG + printf ("video_out: flushing out frame\n"); +#endif + + img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue); + + vo_frame_dec_lock (img); + } + pthread_mutex_unlock(&this->display_img_buf_queue->mutex); + } +} + xine_video_port_t *vo_new_port (xine_t *xine, vo_driver_t *driver, int grabonly) { @@ -1221,6 +1269,7 @@ xine_video_port_t *vo_new_port (xine_t *xine, vo_driver_t *driver, this->vo.enable_ovl = vo_enable_overlay; this->vo.get_overlay_instance = vo_get_overlay_instance; this->vo.flush = vo_flush; + this->vo.set_flush_mode = vo_set_flush_mode; this->vo.status = vo_status; this->vo.driver = driver; diff --git a/src/xine-engine/video_out.h b/src/xine-engine/video_out.h index c52b9e45c..5b96e510c 100644 --- a/src/xine-engine/video_out.h +++ b/src/xine-engine/video_out.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: video_out.h,v 1.80 2003/01/11 19:06:53 guenter Exp $ + * $Id: video_out.h,v 1.81 2003/02/01 19:22:31 guenter Exp $ * * * xine version of video_out.h @@ -172,6 +172,7 @@ struct xine_video_port_s { /* flush video_out fifo */ void (*flush) (xine_video_port_t *this); + void (*set_flush_mode) (xine_video_port_t *this, int flush_mode); /* return true if port is opened for this stream */ int (*status) (xine_video_port_t *this, xine_stream_t *stream, diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c index e010c3aa8..438593817 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.225 2003/01/27 21:43:18 mroi Exp $ + * $Id: xine.c,v 1.226 2003/02/01 19:22:31 guenter Exp $ * * top-level xine functions * @@ -58,9 +58,9 @@ #include "xineutils.h" #include "compat.h" -/* + #define LOG -*/ + void xine_handle_stream_end (xine_stream_t *stream, int non_user) { @@ -176,7 +176,13 @@ static void xine_stop_internal (xine_stream_t *stream) { if (stream->demux_plugin) { xine_demux_stop_thread( stream ); +#ifdef LOG + printf ("xine_stop: stop thread done\n"); +#endif xine_demux_flush_engine( stream ); +#ifdef LOG + printf ("xine_stop: flush engine done\n"); +#endif /* * wait until engine has really stopped @@ -207,6 +213,12 @@ void xine_stop (xine_stream_t *stream) { pthread_mutex_lock (&stream->frontend_lock); + if (stream->audio_out) + stream->audio_out->set_flush_mode (stream->audio_out, 1); + + if (stream->video_out) + stream->video_out->set_flush_mode (stream->video_out, 1); + xine_stop_internal (stream); /* @@ -220,6 +232,12 @@ void xine_stop (xine_stream_t *stream) { if (stream->slave && (stream->slave_affection & XINE_MASTER_SLAVE_STOP)) xine_stop(stream->slave); + + if (stream->video_out) + stream->video_out->set_flush_mode (stream->video_out, 0); + + if (stream->audio_out) + stream->audio_out->set_flush_mode (stream->audio_out, 0); pthread_mutex_unlock (&stream->frontend_lock); } |