summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/xine-engine/audio_out.c104
-rw-r--r--src/xine-engine/audio_out.h11
-rw-r--r--src/xine-engine/video_decoder.c4
-rw-r--r--src/xine-engine/video_out.c57
-rw-r--r--src/xine-engine/video_out.h3
-rw-r--r--src/xine-engine/xine.c24
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);
}