From dfa0e0d469812068026375e336aa5322cbc2b33e Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Thu, 6 Feb 2003 00:09:19 +0000 Subject: first pass on cleaning up ao/vo properties and flush stuff CVS patchset: 4110 CVS date: 2003/02/06 00:09:19 --- src/xine-engine/audio_out.c | 69 ++++++++++------------- src/xine-engine/audio_out.h | 8 +-- src/xine-engine/post.c | 15 ++++- src/xine-engine/video_out.c | 131 ++++++++++++++++++++++++++++++-------------- src/xine-engine/video_out.h | 13 ++++- src/xine-engine/xine.c | 23 ++++---- 6 files changed, 155 insertions(+), 104 deletions(-) (limited to 'src') diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c index 4679c0630..7ac3af148 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.103 2003/02/02 12:33:23 hadess Exp $ + * $Id: audio_out.c,v 1.104 2003/02/06 00:09:19 miguelfreitas Exp $ * * 22-8-2001 James imported some useful AC3 sections from the previous alsa driver. * (c) 2001 Andy Lo A Foe @@ -148,7 +148,6 @@ 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; @@ -1175,10 +1174,10 @@ static void ao_put_buffer (xine_audio_port_t *this_gen, #ifdef LOG printf ("audio_out: ao_put_buffer, pts=%lld, vpts=%lld, flushmode=%d\n", - pts, buf->vpts, this->flush_mode); + pts, buf->vpts, this->discard_buffers); #endif - if (!this->flush_mode) + if (!this->discard_buffers) fifo_append (this->out_fifo, buf); else fifo_append (this->free_fifo, buf); @@ -1190,37 +1189,6 @@ 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; @@ -1380,8 +1348,31 @@ static int ao_set_property (xine_audio_port_t *this_gen, int property, int value break; case AO_PROP_DISCARD_BUFFERS: - this->discard_buffers = value; + /* recursive discard buffers setting */ + if(value) + this->discard_buffers++; + else + this->discard_buffers--; ret = this->discard_buffers; + + /* discard buffers here because we have no output thread */ + if (this->grab_only && this->discard_buffers) { + audio_buffer_t *buf; + + 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); + } break; case AO_PROP_PAUSED: @@ -1426,7 +1417,7 @@ static void ao_flush (xine_audio_port_t *this_gen) { audio_buffer_t *buf; if( this->audio_loop_running ) { - this->discard_buffers = 1; + this->discard_buffers++; this->flush_audio_driver = 1; buf = fifo_remove (this->free_fifo); @@ -1436,7 +1427,7 @@ static void ao_flush (xine_audio_port_t *this_gen) { /* do not try this in paused mode */ while( this->flush_audio_driver ) xine_usec_sleep (20000); /* pthread_cond_t could be used here */ - this->discard_buffers = 0; + this->discard_buffers--; } } @@ -1491,10 +1482,8 @@ 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 67a841f2e..3d4d836ac 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.50 2003/02/01 19:22:30 guenter Exp $ + * $Id: audio_out.h,v 1.51 2003/02/06 00:09:20 miguelfreitas Exp $ */ #ifndef HAVE_AUDIO_OUT_H #define HAVE_AUDIO_OUT_H @@ -226,12 +226,6 @@ 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/post.c b/src/xine-engine/post.c index a7091c6b7..d060fefb1 100644 --- a/src/xine-engine/post.c +++ b/src/xine-engine/post.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: post.c,v 1.10 2003/01/11 12:51:17 miguelfreitas Exp $ + * $Id: post.c,v 1.11 2003/02/06 00:09:20 miguelfreitas Exp $ */ /* @@ -81,6 +81,17 @@ static int post_video_status(xine_video_port_t *port_gen, xine_stream_t *stream, return port->original_port->status(port->original_port, stream, width, height, img_duration); } +static int post_video_get_property(xine_video_port_t *port_gen, int property) { + post_video_port_t *port = (post_video_port_t *)port_gen; + return port->original_port->get_property(port->original_port, property); +} + +static int post_video_set_property(xine_video_port_t *port_gen, int property, int value) { + post_video_port_t *port = (post_video_port_t *)port_gen; + return port->original_port->set_property(port->original_port, property, value); +} + + post_video_port_t *post_intercept_video_port(post_plugin_t *post, xine_video_port_t *original) { post_video_port_t *post_port = (post_video_port_t *)malloc(sizeof(post_video_port_t)); @@ -97,6 +108,8 @@ post_video_port_t *post_intercept_video_port(post_plugin_t *post, xine_video_por post_port->port.get_overlay_instance = post_video_get_overlay_instance; post_port->port.flush = post_video_flush; post_port->port.status = post_video_status; + post_port->port.get_property = post_video_get_property; + post_port->port.set_property = post_video_set_property; post_port->port.driver = original->driver; post_port->original_port = original; diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c index 78fa2d308..516cf2b74 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.139 2003/02/01 19:22:31 guenter Exp $ + * $Id: video_out.c,v 1.140 2003/02/06 00:09:20 miguelfreitas Exp $ * * frame allocation / queuing / scheduling / output functions */ @@ -54,6 +54,7 @@ typedef struct { xine_video_port_t vo; /* public part */ vo_driver_t *driver; + pthread_mutex_t driver_lock; xine_t *xine; metronom_clock_t *clock; xine_list_t *streams; @@ -65,7 +66,7 @@ typedef struct { vo_frame_t *last_frame; vo_frame_t *img_backup; int redraw_needed; - int flush_frames; + int discard_frames; int video_loop_running; int video_opened; @@ -84,7 +85,6 @@ 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 */ @@ -343,7 +343,7 @@ static int vo_frame_draw (vo_frame_t *img, xine_stream_t *stream) { } else { frames_to_skip = 0; - if (this->flush_mode) { + if (this->discard_frames) { #ifdef LOG printf ("video_out: i'm in flush mode, not appending this frame to queue\n"); #endif @@ -503,13 +503,13 @@ static void expire_frames (vos_t *this, int64_t cur_vpts) { diff = 1000000; /* always enter the while-loop */ - while (img && (diff > img->duration || this->flush_frames)) { + while (img && (diff > img->duration || this->discard_frames)) { pts = img->vpts; diff = cur_vpts - pts; - if (diff > img->duration || this->flush_frames) { + if (diff > img->duration || this->discard_frames) { - if( !this->flush_frames ) { + if( !this->discard_frames ) { xine_log(this->xine, XINE_LOG_MSG, _("video_out: throwing away image with pts %lld because " "it's too old (diff : %lld).\n"), pts, diff); @@ -524,7 +524,7 @@ static void expire_frames (vos_t *this, int64_t cur_vpts) { pthread_mutex_unlock( &img->stream->current_extra_info_lock ); /* when flushing frames, keep the first one as backup */ - if( this->flush_frames ) { + if( this->discard_frames ) { if (!this->img_backup) { this->img_backup = img; @@ -564,7 +564,6 @@ static void expire_frames (vos_t *this, int64_t cur_vpts) { img = this->display_img_buf_queue->first; } } - this->flush_frames = 0; pthread_mutex_unlock(&this->display_img_buf_queue->mutex); } @@ -1049,7 +1048,7 @@ static void vo_open (xine_video_port_t *this_gen, xine_stream_t *stream) { printf("video_out: vo_open\n"); #endif this->video_opened = 1; - this->flush_frames = 0; + this->discard_frames = 0; this->last_delivery_pts = 0; if (!this->overlay_enabled && stream->spu_channel_user > -2) /* enable overlays if our new stream might want to show some */ @@ -1081,6 +1080,73 @@ static void vo_close (xine_video_port_t *this_gen, xine_stream_t *stream) { pthread_mutex_unlock(&this->streams_lock); } + +static int vo_get_property (xine_video_port_t *this_gen, int property) { + vos_t *this = (vos_t *) this_gen; + int ret; + + switch (property) { + case VO_PROP_DISCARD_FRAMES: + ret = this->discard_frames; + break; + + default: + pthread_mutex_lock( &this->driver_lock ); + ret = this->driver->get_property(this->driver, property); + pthread_mutex_unlock( &this->driver_lock ); + } + return ret; +} + +static int vo_set_property (xine_video_port_t *this_gen, int property, int value) { + vos_t *this = (vos_t *) this_gen; + int ret; + + switch (property) { + + case VO_PROP_DISCARD_FRAMES: + /* recursive discard frames setting */ + pthread_mutex_lock(&this->display_img_buf_queue->mutex); + if(value) + this->discard_frames++; + else + this->discard_frames--; + pthread_mutex_unlock(&this->display_img_buf_queue->mutex); + ret = this->discard_frames; + + /* discard buffers here because we have no output thread */ + if (this->grab_only && this->discard_frames) { + vo_frame_t *img; + + 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); + } + break; + + default: + 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; +} + + static int vo_status (xine_video_port_t *this_gen, xine_stream_t *stream, int *width, int *height, int64_t *img_duration) { @@ -1199,48 +1265,29 @@ static void vo_enable_overlay (xine_video_port_t *this_gen, int overlay_enabled) */ static void vo_flush (xine_video_port_t *this_gen) { vos_t *this = (vos_t *) this_gen; + vo_frame_t *img; if( this->video_loop_running ) { pthread_mutex_lock(&this->display_img_buf_queue->mutex); - this->flush_frames = 1; + this->discard_frames++; pthread_mutex_unlock(&this->display_img_buf_queue->mutex); /* do not try this in paused mode */ - while(this->flush_frames) + while(1) { + pthread_mutex_lock(&this->display_img_buf_queue->mutex); + img = this->display_img_buf_queue->first; + pthread_mutex_unlock(&this->display_img_buf_queue->mutex); + if(!img) + break; xine_usec_sleep (20000); /* pthread_cond_t could be used here */ - } -} - -/* - * 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_lock(&this->display_img_buf_queue->mutex); + this->discard_frames--; 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) { @@ -1259,6 +1306,7 @@ xine_video_port_t *vo_new_port (xine_t *xine, vo_driver_t *driver, this->streams = xine_list_new(); pthread_mutex_init(&this->streams_lock, NULL); + pthread_mutex_init(&this->driver_lock, NULL ); this->vo.open = vo_open; this->vo.get_frame = vo_get_frame; @@ -1269,7 +1317,8 @@ 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.get_property = vo_get_property; + this->vo.set_property = vo_set_property; 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 5b96e510c..a0d68c82f 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.81 2003/02/01 19:22:31 guenter Exp $ + * $Id: video_out.h,v 1.82 2003/02/06 00:09:20 miguelfreitas Exp $ * * * xine version of video_out.h @@ -172,8 +172,14 @@ 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); + /* * Get/Set video property + * + * See VO_PROP_* bellow + */ + int (*get_property) (xine_video_port_t *this, int property); + int (*set_property) (xine_video_port_t *this, int property, int value); + /* return true if port is opened for this stream */ int (*status) (xine_video_port_t *this, xine_stream_t *stream, int *width, int *height, int64_t *img_duration); @@ -198,7 +204,8 @@ struct xine_video_port_s { #define VO_PROP_TVMODE 10 #define VO_PROP_MAX_NUM_FRAMES 11 #define VO_PROP_ZOOM_Y 13 -#define VO_NUM_PROPERTIES 14 +#define VO_PROP_DISCARD_FRAMES 14 /* not used by drivers */ +#define VO_NUM_PROPERTIES 15 /* zoom specific constants FIXME: generate this from xine.tmpl.in */ #define VO_ZOOM_STEP 100 diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c index cd573dd4b..afb982ed5 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.227 2003/02/04 21:24:52 f1rmb Exp $ + * $Id: xine.c,v 1.228 2003/02/06 00:09:20 miguelfreitas Exp $ * * top-level xine functions * @@ -213,31 +213,30 @@ 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->set_flush_mode (stream->audio_out, 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_flush_mode) - stream->video_out->set_flush_mode (stream->video_out, 1); + if (stream->video_out) + stream->video_out->set_property(stream->video_out, VO_PROP_DISCARD_FRAMES, 1); xine_stop_internal (stream); - /* - * stream will make output threads discard about everything - */ +/* redundant? (xine_stop_internal calls xine_demux_flush_engine) if (stream->audio_out) stream->audio_out->flush(stream->audio_out); if (stream->video_out) stream->video_out->flush(stream->video_out); +*/ 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->set_flush_mode (stream->video_out, 0); + 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_flush_mode) - stream->audio_out->set_flush_mode (stream->audio_out, 0); + if (stream->audio_out) + stream->audio_out->set_property(stream->audio_out, AO_PROP_DISCARD_BUFFERS, 0); pthread_mutex_unlock (&stream->frontend_lock); } -- cgit v1.2.3