From 891fb0a646780b715e4f8d53b49e4615917a13e8 Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Thu, 21 Mar 2002 16:21:01 +0000 Subject: - only draw still frame/logo if needed - fix syncfb driver CVS patchset: 1605 CVS date: 2002/03/21 16:21:01 --- src/video_out/video_out_syncfb.c | 53 ++++++++++++++++++++-------------- src/video_out/video_out_xshm.c | 47 +++++++++++++++++++++++++----- src/video_out/video_out_xv.c | 62 +++++++++++++++++++++++----------------- src/xine-engine/video_out.c | 42 ++++++++++++++++++--------- src/xine-engine/video_out.h | 12 ++++++-- src/xine-engine/video_overlay.c | 21 ++++++++++++-- 6 files changed, 163 insertions(+), 74 deletions(-) (limited to 'src') diff --git a/src/video_out/video_out_syncfb.c b/src/video_out/video_out_syncfb.c index 5c18312e1..79505c8a5 100644 --- a/src/video_out/video_out_syncfb.c +++ b/src/video_out/video_out_syncfb.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_syncfb.c,v 1.56 2002/03/18 11:01:07 richwareham Exp $ + * $Id: video_out_syncfb.c,v 1.57 2002/03/21 16:21:01 miguelfreitas Exp $ * * video_out_syncfb.c, SyncFB (for Matrox G200/G400 cards) interface for xine * @@ -746,6 +746,32 @@ static void syncfb_flush_recent_frames (syncfb_driver_t *this) { } #endif +static int syncfb_redraw_needed (vo_driver_t *this_gen) { + syncfb_driver_t *this = (syncfb_driver_t *) this_gen; + int gui_x, gui_y, gui_width, gui_height; + int ret = 0; + + this->frame_output_cb (this->user_data, + this->ideal_width, this->ideal_height, + &gui_x, &gui_y, &gui_width, &gui_height); + + if ( (gui_x != this->gui_x) || (gui_y != this->gui_y) + || (gui_width != this->gui_width) || (gui_height != this->gui_height) ) { + + this->gui_x = gui_x; + this->gui_y = gui_y; + this->gui_width = gui_width; + this->gui_height = gui_height; + + syncfb_compute_output_size (this); + + syncfb_clean_output_area (this); + + ret = 1; + } + + return ret; +} static void syncfb_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { @@ -760,7 +786,6 @@ static void syncfb_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) printf ("video_out_xv: xv_display_frame... not displayed, waiting for completion event\n"); } else { - int gui_x, gui_y, gui_width, gui_height; /* * queue frames (deinterlacing) @@ -797,25 +822,9 @@ static void syncfb_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) * ask for offset and output size */ - this->frame_output_cb (this->user_data, - this->ideal_width, this->ideal_height, - &gui_x, &gui_y, &gui_width, &gui_height); - - if ( (gui_x != this->gui_x) || (gui_y != this->gui_y) - || (gui_width != this->gui_width) || (gui_height != this->gui_height) ) { - - this->gui_x = gui_x; - this->gui_y = gui_y; - this->gui_width = gui_width; - this->gui_height = gui_height; - - syncfb_compute_output_size (this); - - syncfb_clean_output_area (this); - } - + syncfb_redraw_needed( this_gen ); - /* the rest is only successful and safe, if the overlay is really on */ + /* the rest is only successful and safe, if the overlay is really on */ if(this->overlay_state) { if(this->bufinfo.id != -1) { printf("video_out_syncfb: error. (invalid syncfb image buffer state)\n"); @@ -838,7 +847,6 @@ static void syncfb_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) printf("video_out_syncfb: error. (commit ioctl failed)\n"); } - frame->vo_frame.displayed(&frame->vo_frame); this->bufinfo.id = -1; } } @@ -1200,6 +1208,7 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) { this->vo_driver.get_property_min_max = syncfb_get_property_min_max; this->vo_driver.gui_data_exchange = syncfb_gui_data_exchange; this->vo_driver.exit = syncfb_exit; + this->vo_driver.redraw_needed = syncfb_redraw_needed; /* * init properties @@ -1221,7 +1230,7 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) { } static vo_info_t vo_info_syncfb = { - 4, + 5, "SyncFB", "xine video output plugin using the SyncFB module for Matrox G200/G400 cards", VISUAL_TYPE_X11, diff --git a/src/video_out/video_out_xshm.c b/src/video_out/video_out_xshm.c index 6411b4282..9c6bbfb83 100644 --- a/src/video_out/video_out_xshm.c +++ b/src/video_out/video_out_xshm.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_xshm.c,v 1.67 2002/03/07 13:26:16 jcdutton Exp $ + * $Id: video_out_xshm.c,v 1.68 2002/03/21 16:21:01 miguelfreitas Exp $ * * video_out_xshm.c, X11 shared memory extension interface for xine * @@ -787,7 +787,7 @@ static void clean_output_area (xshm_driver_t *this) { XSetForeground (this->display, this->gc, this->black.pixel); XFillRectangle(this->display, this->drawable, this->gc, - this->gui_x, this->gui_y, + 0, 0, this->gui_width, this->gui_height); #if 0 @@ -821,6 +821,38 @@ static void clean_output_area (xshm_driver_t *this) { XUnlockDisplay (this->display); } +static int xshm_redraw_needed (vo_driver_t *this_gen) { + xshm_driver_t *this = (xshm_driver_t *) this_gen; + int gui_x, gui_y, gui_width, gui_height; + int ret = 0; + + if( this->cur_frame ) + { + this->frame_output_cb (this->user_data, + this->cur_frame->output_width, this->cur_frame->output_height, + &gui_x, &gui_y, &gui_width, &gui_height); + + if ( (this->gui_x != gui_x) || (this->gui_y != gui_y) + || (this->gui_width != gui_width) + || (this->gui_height != gui_height) ) { + + this->gui_x = gui_x; + this->gui_y = gui_y; + this->gui_width = gui_width; + this->gui_height = gui_height; + + clean_output_area (this); + ret = 1; + } + } + else + { + ret = 1; + } + + return ret; +} + static void xshm_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { xshm_driver_t *this = (xshm_driver_t *) this_gen; @@ -880,8 +912,8 @@ static void xshm_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { this->cur_frame = frame; - xoffset = (this->gui_width - frame->output_width) / 2 + this->gui_x; - yoffset = (this->gui_height - frame->output_height) / 2 + this->gui_y; + xoffset = (this->gui_width - frame->output_width) / 2; + yoffset = (this->gui_height - frame->output_height) / 2; XLockDisplay (this->display); #ifdef LOG @@ -1014,8 +1046,8 @@ static void xshm_translate_gui2video (xshm_driver_t *this, * gui area. This is the case in fullscreen mode, where we often * have black borders on the top/bottom/left/right side. */ - x -= ((this->gui_width - frame->output_width) >> 1) + this->gui_x; - y -= ((this->gui_height - frame->output_height) >> 1) + this->gui_y; + x -= ((this->gui_width - frame->output_width) >> 1); + y -= ((this->gui_height - frame->output_height) >> 1); /* * 2. @@ -1271,6 +1303,7 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) { this->vo_driver.get_property_min_max = xshm_get_property_min_max; this->vo_driver.gui_data_exchange = xshm_gui_data_exchange; this->vo_driver.exit = xshm_exit; + this->vo_driver.redraw_needed = xshm_redraw_needed; XAllocNamedColor (this->display, DefaultColormap (this->display, this->screen), @@ -1405,7 +1438,7 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) { } static vo_info_t vo_info_shm = { - 4, /* interface version */ + 5, /* interface version */ "XShm", /* id */ "xine video output plugin using the MIT X shared memory extension", VISUAL_TYPE_X11, /* visual_type */ diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c index a2514bd73..f98226b42 100644 --- a/src/video_out/video_out_xv.c +++ b/src/video_out/video_out_xv.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_xv.c,v 1.105 2002/03/07 13:26:16 jcdutton Exp $ + * $Id: video_out_xv.c,v 1.106 2002/03/21 16:21:02 miguelfreitas Exp $ * * video_out_xv.c, X11 video extension interface for xine * @@ -161,7 +161,7 @@ struct xv_driver_s { int gui_x, gui_y; int gui_width, gui_height; - + /* * "output" size: * @@ -575,7 +575,7 @@ static void xv_clean_output_area (xv_driver_t *this) { XSetForeground (this->display, this->gc, this->black.pixel); XFillRectangle(this->display, this->drawable, this->gc, - this->gui_x, this->gui_y, this->gui_width, this->gui_height); + 0, 0, this->gui_width, this->gui_height); if (this->use_colorkey) { XSetForeground (this->display, this->gc, this->colorkey); @@ -700,8 +700,8 @@ static void xv_compute_output_size (xv_driver_t *this) { this->output_height = (double) this->ideal_height * y_factor ; } - this->output_xoffset = (this->gui_width - this->output_width) / 2 + this->gui_x; - this->output_yoffset = (this->gui_height - this->output_height) / 2 + this->gui_y; + this->output_xoffset = (this->gui_width - this->output_width) / 2; + this->output_yoffset = (this->gui_height - this->output_height) / 2; #ifdef LOG printf ("video_out_xv: frame source %d x %d => screen output %d x %d\n", @@ -757,7 +757,33 @@ static void xv_flush_recent_frames (xv_driver_t *this) { } #endif +static int xv_redraw_needed (vo_driver_t *this_gen) { + xv_driver_t *this = (xv_driver_t *) this_gen; + int gui_x, gui_y, gui_width, gui_height; + int ret = 0; + + this->frame_output_cb (this->user_data, + this->ideal_width, this->ideal_height, + &gui_x, &gui_y, &gui_width, &gui_height); + + if ( (gui_x != this->gui_x) || (gui_y != this->gui_y) + || (gui_width != this->gui_width) || (gui_height != this->gui_height) ) { + + this->gui_x = gui_x; + this->gui_y = gui_y; + this->gui_width = gui_width; + this->gui_height = gui_height; + xv_compute_output_size (this); + + xv_clean_output_area (this); + + ret = 1; + } + + return ret; +} + static void xv_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { xv_driver_t *this = (xv_driver_t *) this_gen; @@ -774,8 +800,6 @@ static void xv_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { } else { - int gui_x, gui_y, gui_width, gui_height; - /* * queue frames (deinterlacing) * free old frames @@ -819,24 +843,7 @@ static void xv_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { * tell gui that we are about to display a frame, * ask for offset and output size */ - - this->frame_output_cb (this->user_data, - this->ideal_width, this->ideal_height, - &gui_x, &gui_y, &gui_width, &gui_height); - - if ( (gui_x != this->gui_x) || (gui_y != this->gui_y) - || (gui_width != this->gui_width) || (gui_height != this->gui_height) ) { - - this->gui_x = gui_x; - this->gui_y = gui_y; - this->gui_width = gui_width; - this->gui_height = gui_height; - - xv_compute_output_size (this); - - xv_clean_output_area (this); - } - + xv_redraw_needed (this_gen); XLockDisplay (this->display); @@ -1005,7 +1012,7 @@ static int xv_gui_data_exchange (vo_driver_t *this_gen, XExposeEvent * xev = (XExposeEvent *) data; /* FIXME : take care of completion events */ - + if (xev->count == 0) { if (this->cur_frame) { XLockDisplay (this->display); @@ -1308,6 +1315,7 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) { this->vo_driver.get_property_min_max = xv_get_property_min_max; this->vo_driver.gui_data_exchange = xv_gui_data_exchange; this->vo_driver.exit = xv_exit; + this->vo_driver.redraw_needed = xv_redraw_needed; /* * init properties @@ -1434,7 +1442,7 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) { } static vo_info_t vo_info_xv = { - 4, + 5, "Xv", "xine video output plugin using the MIT X video extension", VISUAL_TYPE_X11, diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c index 6a278758b..3e14a4229 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.82 2002/03/21 12:58:20 miguelfreitas Exp $ + * $Id: video_out.c,v 1.83 2002/03/21 16:21:02 miguelfreitas Exp $ * * frame allocation / queuing / scheduling / output functions */ @@ -60,7 +60,8 @@ typedef struct { vo_frame_t *last_frame; vo_frame_t *img_backup; int backup_is_logo; - + int redraw_needed; + int video_loop_running; int video_opened; pthread_t video_thread; @@ -453,15 +454,16 @@ static vo_frame_t *get_next_frame (vos_t *this, int64_t cur_vpts) { this->img_backup->decoder_locked = 0; this->img_backup->display_locked = 1; this->img_backup->driver_locked = 0; - this->img_backup->duration = 10000; + this->img_backup->duration = 3000; xine_fast_memcpy(this->img_backup->base[0], this->logo_yuy2, this->logo_w*this->logo_h*2); this->backup_is_logo = 1; + this->redraw_needed = 1; } - if (this->img_backup) { + if (this->img_backup && this->redraw_needed) { #ifdef LOG printf("video_out: generating still frame (cur_vpts = %lld) \n", @@ -576,9 +578,26 @@ static void overlay_and_display_frame (vos_t *this, this->video_loop_running && this->overlay_enabled); } - this->driver->display_frame (this->driver, img); + this->driver->display_frame (this->driver, img); + + this->redraw_needed = 0; +} + +static void check_redraw_needed (vos_t *this, int64_t vpts) { + + if (this->overlay_source) { + /* This is the only way for the overlay manager to get pts values + * for flushing its buffers. So don't remove it! */ + + if( this->overlay_source->redraw_needed (this->overlay_source, vpts) ) + this->redraw_needed = 1; + } + + if( this->driver->redraw_needed (this->driver) ) + this->redraw_needed = 1; } + static void *video_out_loop (void *this_gen) { int64_t vpts, diff; @@ -622,6 +641,10 @@ static void *video_out_loop (void *this_gen) { #endif overlay_and_display_frame (this, img); } + else + { + check_redraw_needed( this, vpts ); + } /* * if we haven't heared from the decoder for some time @@ -666,15 +689,6 @@ static void *video_out_loop (void *this_gen) { usec_to_sleep, vpts); #endif - /* - if( usec_to_sleep > 1000000 ) - { - printf ("video_out: master clock changed\n"); - next_frame_vpts = vpts; - usec_to_sleep = 0; - } - */ - if (usec_to_sleep>0) xine_usec_sleep (usec_to_sleep); diff --git a/src/xine-engine/video_out.h b/src/xine-engine/video_out.h index 78147f1c2..58fc2c397 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.50 2002/03/14 13:57:15 miguelfreitas Exp $ + * $Id: video_out.h,v 1.51 2002/03/21 16:21:02 miguelfreitas Exp $ * * * xine version of video_out.h @@ -259,7 +259,7 @@ struct vo_instance_s { * from generic vo functions. */ -#define VIDEO_OUT_DRIVER_IFACE_VERSION 4 +#define VIDEO_OUT_DRIVER_IFACE_VERSION 5 struct vo_driver_s { @@ -307,6 +307,12 @@ struct vo_driver_s { void *data); void (*exit) (vo_driver_t *this); + + /* check if a redraw is needed (due to resize) + * this is only used for still frames, normal video playback + * must call that inside display_frame() function. + */ + int (*redraw_needed) (vo_driver_t *this); }; @@ -354,6 +360,8 @@ struct video_overlay_instance_s { void (*flush_events) (video_overlay_instance_t *this_gen ); + int (*redraw_needed) (video_overlay_instance_t *this_gen, int64_t vpts ); + void (*multiple_overlay_blend) (video_overlay_instance_t *this_gen, int64_t vpts, vo_driver_t *output, vo_frame_t *vo_img, int enabled); }; diff --git a/src/xine-engine/video_overlay.c b/src/xine-engine/video_overlay.c index 52b01beb8..2101cc455 100644 --- a/src/xine-engine/video_overlay.c +++ b/src/xine-engine/video_overlay.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_overlay.c,v 1.16 2002/03/14 13:57:15 miguelfreitas Exp $ + * $Id: video_overlay.c,v 1.17 2002/03/21 16:21:03 miguelfreitas Exp $ * */ @@ -328,16 +328,19 @@ static void video_overlay_print_overlay( vo_overlay_t *ovl ) { /* process overlay events if vpts == 0 will process everything now (used in flush) + return true if something has been processed */ -static void video_overlay_event( video_overlay_t *this, int64_t vpts ) { +static int video_overlay_event( video_overlay_t *this, int64_t vpts ) { int32_t handle; uint32_t this_event; + int processed = 0; pthread_mutex_lock (&this->video_overlay_events_mutex); this_event=this->video_overlay_events[0].next_event; while ( this_event && (vpts > this->video_overlay_events[this_event].event->vpts || vpts == 0) ) { + processed++; handle=this->video_overlay_events[this_event].event->object.handle; switch( this->video_overlay_events[this_event].event->event_type ) { case EVENT_SHOW_SPU: @@ -597,6 +600,8 @@ static void video_overlay_event( video_overlay_t *this, int64_t vpts ) { } pthread_mutex_unlock (&this->video_overlay_events_mutex); + + return processed; } /* This is called from video_out.c @@ -636,6 +641,17 @@ static void video_overlay_flush_events(video_overlay_instance_t *this_gen ) video_overlay_event( this, 0 ); } +/* this is called from video_out.c on still frames to check + if a redraw is needed. +*/ +static int video_overlay_redraw_needed(video_overlay_instance_t *this_gen, int64_t vpts ) +{ + video_overlay_t *this = (video_overlay_t *) this_gen; + + return video_overlay_event( this, vpts ); +} + + static void video_overlay_dispose(video_overlay_instance_t *this_gen) { video_overlay_t *this = (video_overlay_t *) this_gen; @@ -663,6 +679,7 @@ video_overlay_instance_t *video_overlay_new_instance () { this->video_overlay.free_handle = video_overlay_free_handle; this->video_overlay.add_event = video_overlay_add_event; this->video_overlay.flush_events = video_overlay_flush_events; + this->video_overlay.redraw_needed = video_overlay_redraw_needed; this->video_overlay.multiple_overlay_blend = video_overlay_multiple_overlay_blend; return (video_overlay_instance_t *) &this->video_overlay; -- cgit v1.2.3