From: Eduard H. <eha...@us...> - 2001-07-26 16:03:13
|
Update of /cvsroot/xine/xine-lib/src/dxr3 In directory usw-pr-cvs1:/tmp/cvs-serv16886 Modified Files: Makefile.am video_out_dxr3.c Added Files: dxr3_overlay.h overlay.c Log Message: New Feature: Hardware overlay in xine output window --- NEW FILE: dxr3_overlay.h --- /* * Copyright (C) 2000-2001 the xine project * * This file is part of xine, a unix video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * $Id: dxr3_overlay.h,v 1.1 2001/07/26 16:03:10 ehasenle Exp $ * * Overlay support routines for video_out_dxr3 */ struct coeff { float k,m; }; typedef struct { int fd_control; int overlay_enabled; int xoffset; int yoffset; int xcorr; int jitter; int stability; int colorkey; float color_interval; int screen_xres; int screen_yres; int screen_depth; struct coeff colcal_upper[3]; struct coeff colcal_lower[3]; } dxr3_overlay_t; int dxr3_overlay_set_mode(dxr3_overlay_t *this, int mode); int dxr3_overlay_set_attributes(dxr3_overlay_t *this); int dxr3_overlay_set_screen(dxr3_overlay_t *this); int dxr3_overlay_set_window(dxr3_overlay_t *this, int xpos, int ypos, int width, int height); void dxr3_overlay_buggy_preinit(dxr3_overlay_t *this, int fd); int dxr3_overlay_read_state(dxr3_overlay_t *this); --- NEW FILE: overlay.c --- /* * Copyright (C) 2000-2001 the xine project * * This file is part of xine, a unix video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * $Id: overlay.c,v 1.1 2001/07/26 16:03:10 ehasenle Exp $ * * Overlay support routines for video_out_dxr3 */ #include <sys/types.h> #include <sys/ioctl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <linux/em8300.h> #include "dxr3_overlay.h" #define TYPE_INT 1 #define TYPE_XINT 2 #define TYPE_COEFF 3 #define TYPE_FLOAT 4 struct lut_entry { char *name; int type; void *ptr; }; static struct lut_entry *new_lookuptable(dxr3_overlay_t *this) { struct lut_entry m[] = { {"xoffset", TYPE_INT, &this->xoffset}, {"yoffset", TYPE_INT, &this->yoffset}, {"xcorr", TYPE_INT, &this->xcorr}, {"jitter", TYPE_INT, &this->jitter}, {"stability", TYPE_INT, &this->stability}, {"keycolor", TYPE_XINT, &this->colorkey}, {"colcal_upper", TYPE_COEFF, &this->colcal_upper[0]}, {"colcal_lower", TYPE_COEFF, &this->colcal_lower[0]}, {"color_interval", TYPE_FLOAT, &this->color_interval}, {0,0,0} },*p; p = malloc(sizeof(m)); memcpy(p,m,sizeof(m)); return p; } static int lookup_parameter(struct lut_entry *lut, char *name, void **ptr, int *type) { int i; for(i=0; lut[i].name; i++) if(!strcmp(name,lut[i].name)) { *ptr = lut[i].ptr; *type = lut[i].type; return 1; } return 0; } int dxr3_overlay_read_state(dxr3_overlay_t *this) { char *tok; char fname[128],tmp[128],line[256]; FILE *fp; struct lut_entry *lut; void *ptr; int type; int j; strcpy(fname,getenv("HOME")); strcat(fname,"/.overlay"); sprintf(tmp,"/res_%dx%dx%d", this->screen_xres,this->screen_yres,this->screen_depth); strcat(fname,tmp); if(!(fp=fopen(fname,"r"))){ printf("ERRROR Reading overlay init file!! run autocal !!!\n"); return -1; } lut = new_lookuptable(this); while(!feof(fp)) { if(!fgets(line,256,fp)) break; tok=strtok(line," "); if(lookup_parameter(lut,tok,&ptr,&type)) { tok=strtok(NULL," "); switch(type) { case TYPE_INT: sscanf(tok,"%d",(int *)ptr); break; case TYPE_XINT: sscanf(tok,"%x",(int *)ptr); break; case TYPE_FLOAT: sscanf(tok,"%f",(float *)ptr); break; case TYPE_COEFF: for(j=0;j<3;j++) { sscanf(tok,"%f",&((struct coeff *)ptr)[j].k); tok=strtok(NULL," "); sscanf(tok,"%f",&((struct coeff *)ptr)[j].m); tok=strtok(NULL," "); } break; } } } free(lut); fclose(fp); return 0; } static int col_interp(float x, struct coeff c) { int y; y = rint(x*c.k + c.m); if (y > 255) y = 255; if (y < 0) y = 0; return y; } int dxr3_overlay_set_keycolor(dxr3_overlay_t *this) { float r = (this->colorkey & 0xff0000) >> 16; float g = (this->colorkey & 0x00ff00) >> 8; float b = (this->colorkey & 0x0000ff); float interval = this->color_interval; int ret; int32_t overlay_limit; em8300_attribute_t attr; overlay_limit = /* lower limit */ col_interp(r - interval, this->colcal_upper[0]) << 16 | col_interp(g - interval, this->colcal_upper[1]) << 8 | col_interp(b - interval, this->colcal_upper[2]); attr.attribute = EM9010_ATTRIBUTE_KEYCOLOR_LOWER; attr.value = overlay_limit; ret = ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr); if (ret < 0) return ret; overlay_limit = /* upper limit */ col_interp(r + interval, this->colcal_upper[0]) << 16 | col_interp(g + interval, this->colcal_upper[1]) << 8 | col_interp(b + interval, this->colcal_upper[2]); attr.attribute = EM9010_ATTRIBUTE_KEYCOLOR_UPPER; attr.value = overlay_limit; return ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr); } int dxr3_overlay_set_mode(dxr3_overlay_t *this, int mode) { return ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SETMODE, &mode); } int dxr3_overlay_set_attributes(dxr3_overlay_t *this) { em8300_attribute_t attr; attr.attribute = EM9010_ATTRIBUTE_XOFFSET; attr.value = this->xoffset; if(ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr) == -1) return -1; attr.attribute = EM9010_ATTRIBUTE_YOFFSET; attr.value = this->yoffset; if(ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr) == -1) return -1; attr.attribute = EM9010_ATTRIBUTE_XCORR; attr.value = this->xcorr; if(ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr) == -1) return -1; attr.attribute = EM9010_ATTRIBUTE_STABILITY; attr.value = this->stability; if(ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr) == -1) return -1; attr.attribute = EM9010_ATTRIBUTE_JITTER; attr.value = this->jitter; return ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr); } int dxr3_overlay_set_screen(dxr3_overlay_t *this) { em8300_overlay_screen_t scr; scr.xsize = this->screen_xres; scr.ysize = this->screen_yres; return ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SETSCREEN, &scr); } int dxr3_overlay_set_window(dxr3_overlay_t *this, int xpos, int ypos, int width, int height) { em8300_overlay_window_t win; /* is some part of the picture visible? */ if (xpos+width < 0) return 0; if (ypos+height < 0) return 0; if (xpos > this->screen_xres) return 0; if (ypos > this->screen_yres) return 0; win.xpos = xpos; win.ypos = ypos; win.width = width; win.height = height; return ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SETWINDOW, &win); } int dxr3_overlay_set_signalmode(dxr3_overlay_t *this,int mode) { return ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SIGNALMODE, &mode); } void dxr3_overlay_buggy_preinit(dxr3_overlay_t *this, int fd) { int mode = 0; /* TODO: catch errors */ this->fd_control = fd; dxr3_overlay_set_mode(this,EM8300_OVERLAY_MODE_OFF ); dxr3_overlay_set_screen(this); dxr3_overlay_set_window(this, 1,1, 320,240); dxr3_overlay_set_mode(this, EM8300_OVERLAY_MODE_OVERLAY); ioctl(this->fd_control, EM8300_IOCTL_SET_VIDEOMODE, &mode); dxr3_overlay_set_screen(this); dxr3_overlay_set_window(this, 1,1, 320,240); dxr3_overlay_set_attributes(this); dxr3_overlay_set_keycolor(this); dxr3_overlay_set_mode(this, EM8300_OVERLAY_MODE_OVERLAY); } Index: Makefile.am =================================================================== RCS file: /cvsroot/xine/xine-lib/src/dxr3/Makefile.am,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- Makefile.am 2001/07/25 15:03:14 1.4 +++ Makefile.am 2001/07/26 16:03:10 1.5 @@ -1,6 +1,6 @@ CFLAGS = @GLOBAL_CFLAGS@ $(LINUX_INCLUDE) -EXTRA_DIST = dxr3_decoder.c video_out_dxr3.c +EXTRA_DIST = dxr3_decoder.c video_out_dxr3.c overlay.c LIBTOOL = $(SHELL) $(top_builddir)/libtool-nofpic @@ -15,8 +15,10 @@ xineplug_decode_dxr3_la_SOURCES = dxr3_decoder.c xineplug_decode_dxr3_la_LDFLAGS = -avoid-version -module -xineplug_vo_out_dxr3_la_SOURCES = video_out_dxr3.c +xineplug_vo_out_dxr3_la_SOURCES = video_out_dxr3.c overlay.c xineplug_vo_out_dxr3_la_LDFLAGS = -avoid-version -module + +include_HEADERS = dxr3_overlay.h debug: @$(MAKE) CFLAGS="$(DEBUG_CFLAGS) $(LINUX_INCLUDE)" Index: video_out_dxr3.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/dxr3/video_out_dxr3.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- video_out_dxr3.c 2001/07/25 15:03:15 1.4 +++ video_out_dxr3.c 2001/07/26 16:03:10 1.5 @@ -36,7 +36,13 @@ #include <linux/em8300.h> #include "video_out.h" #include "xine_internal.h" +#include "dxr3_overlay.h" +#include <X11/Xlib.h> +#include <X11/Xatom.h> +#include <X11/Xutil.h> +#include "../video_out/video_out_x11.h" + char devname[]="/dev/em8300"; typedef struct dxr3_driver_s { @@ -45,8 +51,95 @@ int aspectratio; int tv_mode; em8300_bcs_t bcs; + + /* for overlay */ + dxr3_overlay_t overlay; + Display *display; + Drawable win; + GC gc; + XColor color; + int xpos, ypos; + int width, height; + int overlay_enabled; + float desired_ratio; + void (*request_dest_size) (int video_width, int video_height, int *dest_x, + int *dest_y, int *dest_height, int *dest_width); } dxr3_driver_t; +static void dxr3_overlay_adapt_area(dxr3_driver_t *this, + int dest_x, int dest_y, int dest_width, int dest_height) +{ + XWindowAttributes a; + Window junkwin; + int rx, ry; + + XLockDisplay(this->display); + + XSetForeground(this->display, this->gc, this->color.pixel); + XGetWindowAttributes(this->display, this->win, &a); + XTranslateCoordinates (this->display, this->win, a.root, + dest_x, dest_y, &rx, &ry, &junkwin); + + XUnlockDisplay(this->display); + + this->xpos = rx; this->ypos = ry; + this->width = dest_width; this->height = dest_height; + + dxr3_overlay_set_window(&this->overlay, this->xpos, this->ypos, + this->width, this->height); +} + +static void dxr3_get_keycolor(dxr3_driver_t *this) +{ + this->color.red = ((this->overlay.colorkey >> 16) & 0xff) * 256; + this->color.green = ((this->overlay.colorkey >> 8) & 0xff) * 256; + this->color.blue = ((this->overlay.colorkey ) & 0xff) * 256; + + XAllocColor(this->display, DefaultColormap(this->display,0), &this->color); +} + +void dxr3_read_config(dxr3_driver_t *this, config_values_t *config) +{ + char* str; + + if (ioctl(this->fd_control, EM8300_IOCTL_GETBCS, &this->bcs)) + fprintf(stderr, "dxr3_vo: cannot read bcs values (%s)\n", + strerror(errno)); + this->vo_driver.set_property(&this->vo_driver, + VO_PROP_ASPECT_RATIO, ASPECT_FULL); + + str = config->lookup_str(config, "dxr3_tvmode", "default"); + if (!strcmp(str, "ntsc")) { + this->tv_mode = EM8300_VIDEOMODE_NTSC; + fprintf(stderr, "dxr3_vo: setting tv_mode to NTSC\n"); + } else if (!strcmp(str, "pal")) { + this->tv_mode = EM8300_VIDEOMODE_PAL; + fprintf(stderr, "dxr3_vo: setting tv_mode to PAL 50Hz\n"); + } else if (!strcmp(str, "pal60")) { + this->tv_mode = EM8300_VIDEOMODE_PAL60; + fprintf(stderr, "dxr3_vo: setting tv_mode to PAL 60Hz\n"); + } else if (!strcmp(str, "overlay")) { + this->tv_mode = EM8300_VIDEOMODE_DEFAULT; + fprintf(stderr, "dxr3_vo: setting up overlay mode\n"); + if (dxr3_overlay_read_state(&this->overlay) == 0) { + this->overlay_enabled = 1; + + str = config->lookup_str(config, "dxr3_keycolor", "0x80a040"); + sscanf(str, "%x", &this->overlay.colorkey); + + str = config->lookup_str(config, "dxr3_color_interval", "50.0"); + sscanf(str, "%f", &this->overlay.color_interval); + } else { + fprintf(stderr, "dxr3_vo: please run autocal, overlay disabled\n"); + } + } else { + this->tv_mode = EM8300_VIDEOMODE_DEFAULT; + } + if (this->tv_mode != EM8300_VIDEOMODE_DEFAULT) + if (ioctl(this->fd_control, EM8300_IOCTL_SET_VIDEOMODE, &this->tv_mode)) + fprintf(stderr, "dxr3_vo: setting video mode failed."); +} + static uint32_t dxr3_get_capabilities (vo_driver_t *this_gen) { /* Since we have no vo format, we return dummy values here */ @@ -127,6 +220,10 @@ case VO_PROP_ASPECT_RATIO: val = this->aspectratio; break; + + case VO_PROP_COLORKEY: + val = this->overlay.colorkey; + break; default: val = 0; fprintf(stderr, "dxr3_vo: property %d not implemented!\n", property); @@ -135,11 +232,27 @@ return val; } +static int is_fullscreen(dxr3_driver_t *this) +{ + XWindowAttributes a; + + XGetWindowAttributes(this->display, this->win, &a); + /* this is a good place for gathering the with and height + * although it is a mis-use for is_fullscreen */ + this->width = a.width; + this->height = a.height; + + return a.x==0 && a.y==0 && + a.width == this->overlay.screen_xres && + a.height == this->overlay.screen_yres; +} + static int dxr3_set_property (vo_driver_t *this_gen, int property, int value) { dxr3_driver_t *this = (dxr3_driver_t *) this_gen; int val, bcs_changed = 0; + int fullscreen; switch (property) { case VO_PROP_SATURATION: @@ -155,25 +268,39 @@ bcs_changed = 1; break; case VO_PROP_ASPECT_RATIO: - /* xitk just increments the value, so we make + /* xitk-ui just increments the value, so we make * just a two value "loop" */ if (value > ASPECT_FULL) value = ASPECT_ANAMORPHIC; this->aspectratio = value; + fullscreen = is_fullscreen(this); if (value == ASPECT_ANAMORPHIC) { fprintf(stderr, "dxr3_vo: setting aspect ratio to anamorphic\n"); - val = EM8300_ASPECTRATIO_16_9; + if (!this->overlay_enabled || fullscreen) + val = EM8300_ASPECTRATIO_16_9; + else /* The overlay window can adapt to the ratio */ + val = EM8300_ASPECTRATIO_4_3; + this->desired_ratio = 16.0/9.0; } else { fprintf(stderr, "dxr3_vo: setting aspect ratio to full\n"); val = EM8300_ASPECTRATIO_4_3; + this->desired_ratio = 4.0/3.0; } if (ioctl(this->fd_control, EM8300_IOCTL_SET_ASPECTRATIO, &val)) fprintf(stderr, "dxr3_vo: failed to set aspect ratio (%s)\n", strerror(errno)); - + if (this->overlay_enabled && !fullscreen){ + int foo; + this->request_dest_size(this->width, + this->width/this->desired_ratio, &foo, &foo, &foo, &foo); + } + break; + case VO_PROP_COLORKEY: + fprintf(stderr, "dxr3_vo: VO_PROP_COLORKEY not implemented!"); + this->overlay.colorkey = val; break; } @@ -206,45 +333,90 @@ static int dxr3_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *data) { - /* dxr3_driver_t *this = (dxr3_driver_t *) this_gen; */ - return 0; + dxr3_driver_t *this = (dxr3_driver_t*) this_gen; + x11_rectangle_t *area; + XWindowAttributes a; + + if (!this->overlay_enabled) return 0; + + switch (data_type) { + case GUI_DATA_EX_DEST_POS_SIZE_CHANGED: + area = (x11_rectangle_t*) data; + dxr3_overlay_adapt_area(this, area->x, area->y, area->w, area->h); + break; + case GUI_DATA_EX_EXPOSE_EVENT: + XLockDisplay(this->display); + XFillRectangle(this->display, this->win, + this->gc, 0, 0, this->width, this->height); + XUnlockDisplay(this->display); + break; + case GUI_DATA_EX_DRAWABLE_CHANGED: + this->win = (Drawable) data; + this->gc = XCreateGC(this->display, this->win, 0, NULL); + XGetWindowAttributes(this->display, this->win, &a); + dxr3_set_property((vo_driver_t*) this, + VO_PROP_ASPECT_RATIO, this->aspectratio); + break; + } + return 0; } static void dxr3_exit (vo_driver_t *this_gen) { dxr3_driver_t *this = (dxr3_driver_t *) this_gen; + + if(this->overlay_enabled) + dxr3_overlay_set_mode(&this->overlay, EM8300_OVERLAY_MODE_OFF ); close(this->fd_control); } vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) { - dxr3_driver_t *this; - char* str; + dxr3_driver_t *this; + x11_visual_t *vis; + Screen *xscrn; + + /* + * allocate plugin struct + */ + + this = malloc (sizeof (dxr3_driver_t)); + + if (!this) { + printf ("video_out_dxr3: malloc failed\n"); + return NULL; + } + + memset (this, 0, sizeof(dxr3_driver_t)); - /* - * allocate plugin struct - */ - - this = malloc (sizeof (dxr3_driver_t)); - - if (!this) { - printf ("video_out_dxr3: malloc failed\n"); - return NULL; - } - - memset (this, 0, sizeof(dxr3_driver_t)); - - this->vo_driver.get_capabilities = dxr3_get_capabilities; - this->vo_driver.alloc_frame = dxr3_alloc_frame; - this->vo_driver.update_frame_format = dxr3_update_frame_format; - this->vo_driver.display_frame = dxr3_display_frame; - this->vo_driver.overlay_blend = dxr3_overlay_blend; - this->vo_driver.get_property = dxr3_get_property; - this->vo_driver.set_property = dxr3_set_property; - this->vo_driver.get_property_min_max = dxr3_get_property_min_max; - this->vo_driver.gui_data_exchange = dxr3_gui_data_exchange; - this->vo_driver.exit = dxr3_exit; + this->vo_driver.get_capabilities = dxr3_get_capabilities; + this->vo_driver.alloc_frame = dxr3_alloc_frame; + this->vo_driver.update_frame_format = dxr3_update_frame_format; + this->vo_driver.display_frame = dxr3_display_frame; + this->vo_driver.overlay_blend = dxr3_overlay_blend; + this->vo_driver.get_property = dxr3_get_property; + this->vo_driver.set_property = dxr3_set_property; + this->vo_driver.get_property_min_max = dxr3_get_property_min_max; + this->vo_driver.gui_data_exchange = dxr3_gui_data_exchange; + this->vo_driver.exit = dxr3_exit; + + /* visual */ + vis = visual_gen; + this->win = vis->d; + this->display = vis->display; + this->gc = XCreateGC(this->display, this->win, 0, NULL); + xscrn = ScreenOfDisplay(this->display, 0); + this->overlay.screen_xres = xscrn->width; + this->overlay.screen_yres = xscrn->height; + this->overlay.screen_depth = xscrn->root_depth; + this->request_dest_size = vis->request_dest_size; + + /* default values */ + this->overlay_enabled = 0; + this->aspectratio = ASPECT_FULL; + dxr3_set_property((vo_driver_t*) this, + VO_PROP_ASPECT_RATIO, this->aspectratio); /* open control device */ if ((this->fd_control = open(devname, O_WRONLY)) < 0) { @@ -252,31 +424,15 @@ devname, strerror(errno)); return 0; } - - if (ioctl(this->fd_control, EM8300_IOCTL_GETBCS, &this->bcs)) - fprintf(stderr, "dxr3_vo: cannot read bcs values (%s)\n", - strerror(errno)); - this->vo_driver.set_property(&this->vo_driver, - VO_PROP_ASPECT_RATIO, ASPECT_FULL); - str = config->lookup_str(config, "dxr3_tvmode", "default"); - if (!strcmp(str, "ntsc")) { - this->tv_mode = EM8300_VIDEOMODE_NTSC; - fprintf(stderr, "dxr3_vo: setting tv_mode to NTSC\n"); - } else if (!strcmp(str, "pal")) { - this->tv_mode = EM8300_VIDEOMODE_PAL; - fprintf(stderr, "dxr3_vo: setting tv_mode to PAL 50Hz\n"); - } else if (!strcmp(str, "pal60")) { - this->tv_mode = EM8300_VIDEOMODE_PAL60; - fprintf(stderr, "dxr3_vo: setting tv_mode to PAL 60Hz\n"); - } else { - this->tv_mode = EM8300_VIDEOMODE_DEFAULT; + dxr3_read_config(this, config); + + if (this->overlay_enabled) { + dxr3_get_keycolor(this); + dxr3_overlay_buggy_preinit(&this->overlay, this->fd_control); } - if (this->tv_mode != EM8300_VIDEOMODE_DEFAULT) - if (ioctl(this->fd_control, EM8300_IOCTL_SET_VIDEOMODE, &this->tv_mode)) - fprintf(stderr, "dxr3_vo: setting video mode failed."); - return &this->vo_driver; + return &this->vo_driver; } static vo_info_t vo_info_dxr3 = { |