From 1ea4db56951b30cb6fda2957e43c02e017afa285 Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Fri, 16 Aug 2002 21:10:02 +0000 Subject: - simplify sdl video driver with scaling helper - bugfixes CVS patchset: 2464 CVS date: 2002/08/16 21:10:02 --- src/video_out/video_out_sdl.c | 316 ++++++++++-------------------------------- src/xine-engine/vo_scale.c | 10 +- 2 files changed, 80 insertions(+), 246 deletions(-) diff --git a/src/video_out/video_out_sdl.c b/src/video_out/video_out_sdl.c index e111aafd8..d03432cde 100644 --- a/src/video_out/video_out_sdl.c +++ b/src/video_out/video_out_sdl.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_sdl.c,v 1.11 2002/08/10 21:25:20 miguelfreitas Exp $ + * $Id: video_out_sdl.c,v 1.12 2002/08/16 21:10:02 miguelfreitas Exp $ * * video_out_sdl.c, Simple DirectMedia Layer * @@ -53,6 +53,7 @@ #include "xine_internal.h" #include "alphablend.h" #include "xineutils.h" +#include "vo_scale.h" #ifdef HAVE_X11 #include @@ -84,8 +85,6 @@ struct sdl_driver_s { pthread_mutex_t mutex; - int user_ratio; - uint32_t capabilities; #ifdef HAVE_X11 @@ -95,70 +94,8 @@ struct sdl_driver_s { Drawable drawable; #endif - /* - * "delivered" size: - * frame dimension / aspect as delivered by the decoder - * used (among other things) to detect frame size changes - */ - int delivered_width; - int delivered_height; - int delivered_ratio_code; - - /* - * displayed part of delivered images, - * taking zoom into account - */ - - int displayed_xoffset; - int displayed_yoffset; - int displayed_width; - int displayed_height; - - /* - * "ideal" size : - * displayed width/height corrected by aspect ratio - */ - - int ideal_width, ideal_height; - double ratio_factor; /* output frame must fullfill: - height = width * ratio_factor */ - - /* - * "gui" size / offset: - * what gui told us about where to display the video - */ - - int gui_x, gui_y; - int gui_width, gui_height; - int gui_win_x, gui_win_y; - - /* - * "output" size: - * - * this is finally the ideal size "fitted" into the - * gui size while maintaining the aspect ratio - * - */ - - /* Window */ - int output_width; - int output_height; - int output_xoffset; - int output_yoffset; - - /* display anatomy */ - double display_ratio; /* given by visual parameter - from init function */ - - void *user_data; - - /* gui callback */ + vo_scale_t sc; - void (*frame_output_cb) (void *user_data, - int video_width, int video_height, - int *dest_x, int *dest_y, - int *dest_height, int *dest_width, - int *win_x, int *win_y); }; static uint32_t sdl_get_capabilities (vo_driver_t *this_gen) { @@ -205,106 +142,23 @@ static vo_frame_t *sdl_alloc_frame (vo_driver_t *this_gen) { return (vo_frame_t *) frame; } -/* - * make ideal width/height "fit" into the gui - */ -static void sdl_compute_output_size (sdl_driver_t *this) { - - double x_factor, y_factor; +static void sdl_compute_ideal_size (sdl_driver_t *this) { - x_factor = (double) this->gui_width / (double) this->ideal_width; - y_factor = (double) this->gui_height / (double) this->ideal_height; - - if ( x_factor < y_factor ) { - this->output_width = (double) this->gui_width; - this->output_height = (double) this->ideal_height * x_factor ; - } else { - this->output_width = (double) this->ideal_width * y_factor ; - this->output_height = (double) this->gui_height; - } + vo_scale_compute_ideal_size( &this->sc ); +} - 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; +static void sdl_compute_output_size (sdl_driver_t *this) { + + vo_scale_compute_output_size( &this->sc ); #ifdef LOG printf ("video_out_sdl: frame source %d x %d => screen output %d x %d\n", - this->delivered_width, this->delivered_height, - this->output_width, this->output_height); + this->sc.delivered_width, this->sc.delivered_height, + this->sc.output_width, this->sc.output_height); #endif } -static void sdl_compute_ideal_size (sdl_driver_t *this) { - - double image_ratio, desired_ratio, corr_factor; - - this->displayed_xoffset = (this->delivered_width - this->displayed_width) / 2; - this->displayed_yoffset = (this->delivered_height - this->displayed_height) / 2; - - /* - * aspect ratio - */ - - image_ratio = (double) this->delivered_width / (double) this->delivered_height; - - switch (this->user_ratio) { - case ASPECT_AUTO: - switch (this->delivered_ratio_code) { - case XINE_ASPECT_RATIO_ANAMORPHIC: /* anamorphic */ - case XINE_ASPECT_RATIO_PAN_SCAN: /* we display pan&scan as widescreen */ - desired_ratio = 16.0 /9.0; - break; - case XINE_ASPECT_RATIO_211_1: /* 2.11:1 */ - desired_ratio = 2.11/1.0; - break; - case XINE_ASPECT_RATIO_SQUARE: /* square pels */ - case XINE_ASPECT_RATIO_DONT_TOUCH: /* probably non-mpeg stream => don't touch aspect ratio */ - desired_ratio = image_ratio; - break; - case 0: /* forbidden -> 4:3 */ - printf ("video_out_sdl: invalid ratio, using 4:3\n"); - default: - printf ("video_out_sdl: unknown aspect ratio (%d) in stream => using 4:3\n", - this->delivered_ratio_code); - case XINE_ASPECT_RATIO_4_3: /* 4:3 */ - desired_ratio = 4.0 / 3.0; - break; - } - break; - case ASPECT_ANAMORPHIC: - desired_ratio = 16.0 / 9.0; - break; - case ASPECT_DVB: - desired_ratio = 2.0 / 1.0; - break; - case ASPECT_SQUARE: - desired_ratio = image_ratio; - break; - case ASPECT_FULL: - default: - desired_ratio = 4.0 / 3.0; - } - - this->ratio_factor = this->display_ratio * desired_ratio; - - corr_factor = this->ratio_factor / image_ratio ; - - if (fabs(corr_factor - 1.0) < 0.005) { - this->ideal_width = this->delivered_width; - this->ideal_height = this->delivered_height; - - } else { - - if (corr_factor >= 1.0) { - this->ideal_width = this->delivered_width * corr_factor + 0.5; - this->ideal_height = this->delivered_height; - } else { - this->ideal_width = this->delivered_width; - this->ideal_height = this->delivered_height / corr_factor + 0.5; - } - } -} - static void sdl_update_frame_format (vo_driver_t *this_gen, vo_frame_t *frame_gen, @@ -384,13 +238,13 @@ static void sdl_check_events (sdl_driver_t * this) while (SDL_PollEvent (&event)) { if (event.type == SDL_VIDEORESIZE) { - if( event.resize.w != this->gui_width || event.resize.h != this->gui_height ) { - this->gui_width = event.resize.w; - this->gui_height = event.resize.h; + if( event.resize.w != this->sc.gui_width || event.resize.h != this->sc.gui_height ) { + this->sc.gui_width = event.resize.w; + this->sc.gui_height = event.resize.h; sdl_compute_output_size(this); - this->surface = SDL_SetVideoMode (this->gui_width, this->gui_height, + this->surface = SDL_SetVideoMode (this->sc.gui_width, this->sc.gui_height, this->bpp, this->sdlflags); } } @@ -400,45 +254,38 @@ static void sdl_check_events (sdl_driver_t * this) static int sdl_redraw_needed (vo_driver_t *this_gen) { sdl_driver_t *this = (sdl_driver_t *) this_gen; int ret = 0; + #ifdef HAVE_X11 - int gui_x, gui_y, gui_width, gui_height, gui_win_x, gui_win_y; - - this->frame_output_cb (this->user_data, - this->ideal_width, this->ideal_height, - &gui_x, &gui_y, &gui_width, &gui_height, - &gui_win_x, &gui_win_y ); - - if ( (gui_x != this->gui_x) || (gui_y != this->gui_y) - || (gui_width != this->gui_width) || (gui_height != this->gui_height) - || (gui_win_x != this->gui_win_x) || (gui_win_y != this->gui_win_y) ) { - - this->gui_x = gui_x; - this->gui_y = gui_y; - this->gui_width = gui_width; - this->gui_height = gui_height; - this->gui_win_x = gui_win_x; - this->gui_win_y = gui_win_y; + + if( vo_scale_redraw_needed( &this->sc ) ) { sdl_compute_output_size (this); ret = 1; } - + return ret; + #else + static int last_gui_width, last_gui_height; - if( last_gui_width != this->gui_width || - last_gui_height != this->gui_height ) { + if( last_gui_width != this->sc.gui_width || + last_gui_height != this->sc.gui_height || + this->sc.force_redraw ) { - last_gui_width = this->gui_width; - last_gui_height = this->gui_height; + last_gui_width = this->sc.gui_width; + last_gui_height = this->sc.gui_height; sdl_compute_output_size (this); ret = 1; } - return 0; + + this->sc.force_redraw = 0; + + return ret; + #endif } @@ -451,16 +298,18 @@ static void sdl_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { pthread_mutex_lock(&this->mutex); - if ( (frame->width != this->delivered_width) - || (frame->height != this->delivered_height) - || (frame->ratio_code != this->delivered_ratio_code) ) { + if ( (frame->width != this->sc.delivered_width) + || (frame->height != this->sc.delivered_height) + || (frame->ratio_code != this->sc.delivered_ratio_code) ) { printf("video_out_sdl: change frame format\n"); - this->delivered_width = frame->width; - this->delivered_height = frame->height; - this->delivered_ratio_code = frame->ratio_code; + this->sc.delivered_width = frame->width; + this->sc.delivered_height = frame->height; + this->sc.delivered_ratio_code = frame->ratio_code; sdl_compute_ideal_size( this ); + + this->sc.force_redraw = 1; } /* @@ -471,19 +320,15 @@ static void sdl_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { sdl_redraw_needed (this_gen); SDL_UnlockYUVOverlay (frame->overlay); - /* - SDL_DisplayYUVOverlay (frame->overlay, &(this->surface->clip_rect)); - */ - clip_rect.x = this->output_xoffset; - clip_rect.y = this->output_yoffset; - clip_rect.w = this->output_width; - clip_rect.h = this->output_height; + clip_rect.x = this->sc.output_xoffset; + clip_rect.y = this->sc.output_yoffset; + clip_rect.w = this->sc.output_width; + clip_rect.h = this->sc.output_height; SDL_DisplayYUVOverlay (frame->overlay, &clip_rect); frame->vo_frame.displayed (&frame->vo_frame); pthread_mutex_unlock(&this->mutex); - } static int sdl_get_property (vo_driver_t *this_gen, int property) { @@ -491,29 +336,11 @@ static int sdl_get_property (vo_driver_t *this_gen, int property) { sdl_driver_t *this = (sdl_driver_t *) this_gen; if ( property == VO_PROP_ASPECT_RATIO) - return this->user_ratio ; + return this->sc.user_ratio ; return 0; } -static char *aspect_ratio_name(int a) -{ - switch (a) { - case ASPECT_AUTO: - return "auto"; - case ASPECT_SQUARE: - return "square"; - case ASPECT_FULL: - return "4:3"; - case ASPECT_ANAMORPHIC: - return "16:9"; - case ASPECT_DVB: - return "2:1"; - default: - return "unknown"; - } -} - static int sdl_set_property (vo_driver_t *this_gen, int property, int value) { @@ -522,13 +349,14 @@ static int sdl_set_property (vo_driver_t *this_gen, if ( property == VO_PROP_ASPECT_RATIO) { if (value>=NUM_ASPECT_RATIOS) value = ASPECT_AUTO; - this->user_ratio = value; + this->sc.user_ratio = value; printf("video_out_sdl: aspect ratio changed to %s\n", - aspect_ratio_name(value)); + vo_scale_aspect_ratio_name(value)); sdl_compute_ideal_size (this); + this->sc.force_redraw = 1; } - + return value; } @@ -538,12 +366,6 @@ static void sdl_get_property_min_max (vo_driver_t *this_gen, /* sdl_driver_t *this = (sdl_driver_t *) this_gen; */ } -static void sdl_translate_gui2video(sdl_driver_t *this, - int x, int y, - int *vid_x, int *vid_y) -{ -} - static int sdl_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *data) { @@ -571,6 +393,22 @@ static int sdl_gui_data_exchange (vo_driver_t *this_gen, #endif break; + case GUI_DATA_EX_TRANSLATE_GUI_TO_VIDEO: + { + int x1, y1, x2, y2; + x11_rectangle_t *rect = data; + + vo_scale_translate_gui2video(&this->sc, rect->x, rect->y, + &x1, &y1); + vo_scale_translate_gui2video(&this->sc, rect->x + rect->w, rect->y + rect->h, + &x2, &y2); + rect->x = x1; + rect->y = y1; + rect->w = x2-x1; + rect->h = y2-y1; + } + break; + default: ret = -1; } @@ -617,16 +455,18 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) { #ifdef HAVE_X11 this->display = visual->display; this->screen = visual->screen; - this->display_ratio = visual->display_ratio; this->drawable = visual->d; - this->frame_output_cb = visual->frame_output_cb; - this->user_data = visual->user_data; + + vo_scale_init( &this->sc, visual->display_ratio, 0, 0 ); + this->sc.frame_output_cb = visual->frame_output_cb; + this->sc.user_data = visual->user_data; + /* set SDL to use our existing X11 window */ sprintf(SDL_windowhack,"SDL_WINDOWID=0x%x", (uint32_t) this->drawable ); putenv(SDL_windowhack); #else - this->display_ratio = 1.0; + vo_scale_init( &this->sc, 1.0, 0, 0 ); #endif if (SDL_Init (SDL_INIT_VIDEO)) { @@ -653,22 +493,18 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) { this->config = config; pthread_mutex_init (&this->mutex, NULL); - this->output_xoffset = 0; - this->output_yoffset = 0; - this->output_width = 0; - this->output_height = 0; this->capabilities = VO_CAP_YUY2 | VO_CAP_YV12; #ifdef HAVE_X11 XGetWindowAttributes(this->display, this->drawable, &window_attributes); - this->gui_width = window_attributes.width; - this->gui_height = window_attributes.height; + this->sc.gui_width = window_attributes.width; + this->sc.gui_height = window_attributes.height; #else - this->gui_width = 320; - this->gui_height = 240; + this->sc.gui_width = 320; + this->sc.gui_height = 240; #endif - this->surface = SDL_SetVideoMode (this->gui_width, this->gui_height, + this->surface = SDL_SetVideoMode (this->sc.gui_width, this->sc.gui_height, this->bpp, this->sdlflags); this->vo_driver.get_capabilities = sdl_get_capabilities; @@ -702,5 +538,3 @@ vo_info_t *get_video_out_plugin_info() { vo_info_sdl.description = _("xine video output plugin using Simple DirectMedia Layer"); return &vo_info_sdl; } - - diff --git a/src/xine-engine/vo_scale.c b/src/xine-engine/vo_scale.c index 40639c9aa..592dc0d77 100644 --- a/src/xine-engine/vo_scale.c +++ b/src/xine-engine/vo_scale.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: vo_scale.c,v 1.1 2002/08/15 03:12:27 miguelfreitas Exp $ + * $Id: vo_scale.c,v 1.2 2002/08/16 21:10:02 miguelfreitas Exp $ * * Contains common code to calculate video scaling parameters. * In short, it will map frame dimensions to screen/window size. @@ -285,10 +285,9 @@ void vo_scale_translate_gui2video(vo_scale_t *this, * translate output area coordianates into the delivered area * coordiantes. */ - x = x * this->delivered_width / this->output_width; - y = y * this->delivered_height / this->output_height; - - /* FIXME: not that trivial, must take zoom into account */ + + x = x * this->displayed_width / this->output_width + this->displayed_xoffset; + y = y * this->displayed_height / this->output_height + this->displayed_yoffset; } *vid_x = x; @@ -332,5 +331,6 @@ void vo_scale_init(vo_scale_t *this, double display_ratio, this->force_redraw = 1; this->zoom_factor_x = 1.0; this->zoom_factor_y = 1.0; + this->user_ratio = ASPECT_AUTO; } -- cgit v1.2.3