summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_out/video_out_sdl.c316
-rw-r--r--src/xine-engine/vo_scale.c10
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 <X11/Xlib.h>
@@ -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;
}