summaryrefslogtreecommitdiff
path: root/src/video_out/video_out_vidix.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_out/video_out_vidix.c')
-rw-r--r--src/video_out/video_out_vidix.c306
1 files changed, 275 insertions, 31 deletions
diff --git a/src/video_out/video_out_vidix.c b/src/video_out/video_out_vidix.c
index 56ff2f787..9a98630b1 100644
--- a/src/video_out/video_out_vidix.c
+++ b/src/video_out/video_out_vidix.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_vidix.c,v 1.17 2002/12/21 12:56:51 miguelfreitas Exp $
+ * $Id: video_out_vidix.c,v 1.18 2003/01/13 23:36:01 miguelfreitas Exp $
*
* video_out_vidix.c
*
@@ -43,6 +43,7 @@
#include "xine.h"
#include "vidixlib.h"
+#include "fourcc.h"
#include "video_out.h"
#include "xine_internal.h"
@@ -53,10 +54,22 @@
#undef LOG
-#define NUM_FRAMES 1
+#define NUM_FRAMES 3
typedef struct vidix_driver_s vidix_driver_t;
+
+typedef struct vidix_property_s {
+ int value;
+ int min;
+ int max;
+
+ cfg_entry_t *entry;
+
+ vidix_driver_t *this;
+} vidix_property_t;
+
+
typedef struct vidix_frame_s {
vo_frame_t vo_frame;
int width, height, ratio_code, format;
@@ -74,26 +87,33 @@ struct vidix_driver_s {
uint8_t *vidix_mem;
vidix_capability_t vidix_cap;
vidix_playback_t vidix_play;
- vidix_fourcc_t vidix_fourcc;
+ vidix_grkey_t vidix_grkey;
+ vidix_video_eq_t vidix_eq;
vidix_yuv_t dstrides;
int vidix_started;
int next_frame;
+ int use_colourkey;
+ uint32_t colourkey;
+ int use_doublebuffer;
+
int yuv_format;
pthread_mutex_t mutex;
+ vidix_property_t props[VO_NUM_PROPERTIES];
uint32_t capabilities;
/* X11 / Xv related stuff */
Display *display;
int screen;
Drawable drawable;
+ GC gc;
+ int depth;
vo_scale_t sc;
int delivered_format;
- int zoom_x, zoom_y;
};
typedef struct {
@@ -287,6 +307,65 @@ static void write_frame_sfb(vidix_driver_t* this, vidix_frame_t* frame)
}
+static void vidix_clean_output_area(vidix_driver_t *this) {
+
+ XLockDisplay(this->display);
+
+ XSetForeground(this->display, this->gc, BlackPixel(this->display, this->screen));
+ XFillRectangle(this->display, this->drawable, this->gc, this->sc.border[0].x, this->sc.border[0].y, this->sc.border[0].w, this->sc.border[0].h);
+ XFillRectangle(this->display, this->drawable, this->gc, this->sc.border[1].x, this->sc.border[1].y, this->sc.border[1].w, this->sc.border[1].h);
+ XFillRectangle(this->display, this->drawable, this->gc, this->sc.border[2].x, this->sc.border[2].y, this->sc.border[2].w, this->sc.border[2].h);
+ XFillRectangle(this->display, this->drawable, this->gc, this->sc.border[3].x, this->sc.border[3].y, this->sc.border[3].w, this->sc.border[3].h);
+
+ if(this->use_colourkey) {
+ XSetForeground(this->display, this->gc, this->colourkey);
+ XFillRectangle(this->display, this->drawable, this->gc, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height);
+ }
+
+ XFlush(this->display);
+
+ XUnlockDisplay(this->display);
+}
+
+
+static void vidix_update_colourkey(vidix_driver_t *this) {
+
+ if(this->use_colourkey) {
+ this->vidix_grkey.ckey.op = CKEY_TRUE;
+
+ switch(this->depth) {
+
+ case 15:
+ this->colourkey = ((this->vidix_grkey.ckey.red & 0xF8) << 7) |
+ ((this->vidix_grkey.ckey.green & 0xF8) << 2) |
+ ((this->vidix_grkey.ckey.blue & 0xF8) >> 3);
+ break;
+
+ case 16:
+ this->colourkey = ((this->vidix_grkey.ckey.red & 0xF8) << 8) |
+ ((this->vidix_grkey.ckey.green & 0xFC) << 3) |
+ ((this->vidix_grkey.ckey.blue & 0xF8) >> 3);
+ break;
+
+ case 24:
+ case 32:
+ this->colourkey = ((this->vidix_grkey.ckey.red & 0xFF) << 16) |
+ ((this->vidix_grkey.ckey.green & 0xFF) << 8) |
+ ((this->vidix_grkey.ckey.blue & 0xFF));
+ break;
+
+ default:
+ break;
+ }
+
+ vidix_clean_output_area(this);
+ } else
+ this->vidix_grkey.ckey.op = CKEY_FALSE;
+
+ vdlSetGrKeys(this->vidix_handler, &this->vidix_grkey);
+}
+
+
static uint32_t vidix_get_capabilities (vo_driver_t *this_gen) {
vidix_driver_t *this = (vidix_driver_t *) this_gen;
@@ -378,7 +457,7 @@ static void vidix_compute_output_size (vidix_driver_t *this) {
this->vidix_play.dest.y = this->sc.gui_win_y+this->sc.output_yoffset;
this->vidix_play.dest.w = this->sc.output_width;
this->vidix_play.dest.h = this->sc.output_height;
- this->vidix_play.num_frames=NUM_FRAMES;
+ this->vidix_play.num_frames= this->use_doublebuffer ? NUM_FRAMES : 1;
this->vidix_play.src.pitch.y = this->vidix_play.src.pitch.u = this->vidix_play.src.pitch.v = 0;
if((err=vdlConfigPlayback(this->vidix_handler,&this->vidix_play))!=0)
@@ -499,6 +578,7 @@ static int vidix_redraw_needed (vo_driver_t *this_gen) {
if( vo_scale_redraw_needed( &this->sc ) ) {
vidix_compute_output_size (this);
+ vidix_clean_output_area(this);
ret = 1;
}
@@ -548,16 +628,12 @@ static int vidix_get_property (vo_driver_t *this_gen, int property) {
vidix_driver_t *this = (vidix_driver_t *) this_gen;
- if ( property == VO_PROP_ASPECT_RATIO)
- return this->sc.user_ratio ;
-
- if ( property == VO_PROP_ZOOM_X )
- return this->zoom_x;
-
- if ( property == VO_PROP_ZOOM_Y )
- return this->zoom_y;
+#ifdef LOG
+ printf ("video_out_vidix: property #%d = %d\n", property,
+ this->props[property].value);
+#endif
- return 0;
+ return this->props[property].value;
}
@@ -565,11 +641,14 @@ static int vidix_set_property (vo_driver_t *this_gen,
int property, int value) {
vidix_driver_t *this = (vidix_driver_t *) this_gen;
+ int err;
+
+ if ((value >= this->props[property].min) &&
+ (value <= this->props[property].max))
+ {
+ this->props[property].value = value;
if ( property == VO_PROP_ASPECT_RATIO) {
- if (value>=NUM_ASPECT_RATIOS)
- value = ASPECT_AUTO;
- this->sc.user_ratio = value;
printf("video_out_vidix: aspect ratio changed to %s\n",
vo_scale_aspect_ratio_name(value));
@@ -578,37 +657,93 @@ static int vidix_set_property (vo_driver_t *this_gen,
}
if ( property == VO_PROP_ZOOM_X ) {
- if ((value >= VO_ZOOM_MIN) && (value <= VO_ZOOM_MAX)) {
- this->zoom_x = value;
this->sc.zoom_factor_x = (double)value / (double)VO_ZOOM_STEP;
vidix_compute_ideal_size (this);
this->sc.force_redraw = 1;
- }
}
if ( property == VO_PROP_ZOOM_Y ) {
- if ((value >= VO_ZOOM_MIN) && (value <= VO_ZOOM_MAX)) {
- this->zoom_y = value;
this->sc.zoom_factor_y = (double)value / (double)VO_ZOOM_STEP;
vidix_compute_ideal_size (this);
this->sc.force_redraw = 1;
- }
}
+ if ( property == VO_PROP_HUE ) {
+ this->vidix_eq.cap = VEQ_CAP_HUE;
+ this->vidix_eq.hue = value;
+
+ if((err = vdlPlaybackSetEq(this->vidix_handler, &this->vidix_eq)) != 0)
+ printf("video_out_vidix:\n");
+ }
+
+ if ( property == VO_PROP_SATURATION ) {
+ this->vidix_eq.cap = VEQ_CAP_SATURATION;
+ this->vidix_eq.saturation = value;
+
+ if((err = vdlPlaybackSetEq(this->vidix_handler, &this->vidix_eq)) != 0)
+ printf("video_out_vidix:\n");
+ }
+
+ if ( property == VO_PROP_BRIGHTNESS ) {
+ this->vidix_eq.cap = VEQ_CAP_BRIGHTNESS;
+ this->vidix_eq.brightness = value;
+
+ if((err = vdlPlaybackSetEq(this->vidix_handler, &this->vidix_eq)) != 0)
+ printf("video_out_vidix:\n");
+ }
+
+ if ( property == VO_PROP_CONTRAST ) {
+ this->vidix_eq.cap = VEQ_CAP_CONTRAST;
+ this->vidix_eq.contrast = value;
+
+ if((err = vdlPlaybackSetEq(this->vidix_handler, &this->vidix_eq)) != 0)
+ printf("video_out_vidix:\n");
+ }
+ }
+
return value;
}
+
+static void vidix_config_callback(vo_driver_t *this_gen, xine_cfg_entry_t *entry) {
+
+ vidix_driver_t *this = (vidix_driver_t *) this_gen;
+
+ if(strcmp(entry->key, "video.vidix_use_double_buffer") == 0) {
+ this->use_doublebuffer = entry->num_value;
+ this->sc.force_redraw = 1;
+ return;
+ }
+
+ if(strcmp(entry->key, "video.vidix_use_colour_key") == 0) {
+ this->use_colourkey = entry->num_value;
+ }
+
+ if(strcmp(entry->key, "video.vidix_colour_key_red") == 0) {
+ this->vidix_grkey.ckey.red = entry->num_value;
+ }
+
+ if(strcmp(entry->key, "video.vidix_colour_key_green") == 0) {
+ this->vidix_grkey.ckey.green = entry->num_value;
+ }
+
+ if(strcmp(entry->key, "video.vidix_colour_key_blue") == 0) {
+ this->vidix_grkey.ckey.blue = entry->num_value;
+ }
+
+ vidix_update_colourkey(this);
+}
+
+
static void vidix_get_property_min_max (vo_driver_t *this_gen,
int property, int *min, int *max) {
-/* vidix_driver_t *this = (vidix_driver_t *) this_gen; */
+ vidix_driver_t *this = (vidix_driver_t *) this_gen;
- if ( property == VO_PROP_ZOOM_X || property == VO_PROP_ZOOM_Y ) {
- *min = VO_ZOOM_MIN;
- *max = VO_ZOOM_MAX;
- }
+ *min = this->props[property].min;
+ *max = this->props[property].max;
}
static int vidix_gui_data_exchange (vo_driver_t *this_gen,
@@ -627,12 +762,17 @@ static int vidix_gui_data_exchange (vo_driver_t *this_gen,
#endif
this->drawable = (Drawable) data;
+ XLockDisplay(this->display);
+ XFreeGC(this->display, this->gc);
+ this->gc = XCreateGC(this->display, this->drawable, 0, NULL);
+ XUnlockDisplay(this->display);
break;
case XINE_GUI_SEND_EXPOSE_EVENT:
#ifdef LOG
printf ("video_out_vidix: GUI_DATA_EX_EXPOSE_EVENT\n");
#endif
+ vidix_clean_output_area(this);
break;
case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO:
@@ -675,6 +815,7 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
vidix_driver_t *this;
x11_visual_t *visual = (x11_visual_t *) visual_gen;
XWindowAttributes window_attributes;
+ vidix_fourcc_t vidix_fourcc;
int err;
this = malloc (sizeof (vidix_driver_t));
@@ -693,20 +834,123 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
this->display = visual->display;
this->screen = visual->screen;
this->drawable = visual->d;
+ this->gc = XCreateGC(this->display, this->drawable, 0, NULL);
vo_scale_init( &this->sc, 1, /*this->vidix_cap.flags & FLAG_UPSCALER,*/ 0, config );
this->sc.frame_output_cb = visual->frame_output_cb;
this->sc.user_data = visual->user_data;
- this->zoom_x = this->zoom_y = 100;
this->config = config;
- this->capabilities = VO_CAP_YUY2 | VO_CAP_YV12;
+ this->capabilities = 0;
XGetWindowAttributes(this->display, this->drawable, &window_attributes);
this->sc.gui_width = window_attributes.width;
this->sc.gui_height = window_attributes.height;
-
+ this->depth = window_attributes.depth;
+
+ /* Detect if YUY2 is supported */
+ memset(&vidix_fourcc, 0, sizeof(vidix_fourcc_t));
+ vidix_fourcc.fourcc = IMGFMT_YUY2;
+ vidix_fourcc.depth = this->depth;
+
+ if((err = vdlQueryFourcc(this->vidix_handler, &vidix_fourcc)) == 0) {
+ this->capabilities |= VO_CAP_YUY2;
+ printf("video_out_vidix: adaptor supports the yuy2 format\n");
+ }
+
+ /* Detect if YV12 is supported */
+ vidix_fourcc.fourcc = IMGFMT_YV12;
+
+ if((err = vdlQueryFourcc(this->vidix_handler, &vidix_fourcc)) == 0) {
+ this->capabilities |= VO_CAP_YV12;
+ printf("video_out_vidix: adaptor supports the yuy2 format\n");
+ }
+
+ /* Find what equalizer flags are supported */
+ if(this->vidix_cap.flags & FLAG_EQUALIZER) {
+ if((err = vdlPlaybackGetEq(this->vidix_handler, &this->vidix_eq)) != 0) {
+ printf("video_out_vidix: Couldn't get equalizer capabilities: %s\n", strerror(err));
+ } else {
+ if(this->vidix_eq.cap & VEQ_CAP_BRIGHTNESS) {
+ this->capabilities |= VO_CAP_BRIGHTNESS;
+
+ this->props[VO_PROP_BRIGHTNESS].value = 0;
+ this->props[VO_PROP_BRIGHTNESS].min = -1000;
+ this->props[VO_PROP_BRIGHTNESS].max = 1000;
+ }
+
+ if(this->vidix_eq.cap & VEQ_CAP_CONTRAST) {
+ this->capabilities |= VO_CAP_CONTRAST;
+
+ this->props[VO_PROP_CONTRAST].value = 0;
+ this->props[VO_PROP_CONTRAST].min = -1000;
+ this->props[VO_PROP_CONTRAST].max = 1000;
+ }
+
+ if(this->vidix_eq.cap & VEQ_CAP_SATURATION) {
+ this->capabilities |= VO_CAP_SATURATION;
+
+ this->props[VO_PROP_SATURATION].value = 0;
+ this->props[VO_PROP_SATURATION].min = -1000;
+ this->props[VO_PROP_SATURATION].max = 1000;
+ }
+
+ if(this->vidix_eq.cap & VEQ_CAP_HUE) {
+ this->capabilities |= VO_CAP_HUE;
+
+ this->props[VO_PROP_HUE].value = 0;
+ this->props[VO_PROP_HUE].min = -1000;
+ this->props[VO_PROP_HUE].max = 1000;
+ }
+ }
+ }
+
+ /* We'll assume all drivers support colour keying (which they do
+ at the moment) */
+ this->capabilities |= VO_CAP_COLORKEY;
+
+ /* Someone might want to disable colour keying (?) */
+ this->use_colourkey = config->register_bool(config,
+ "video.vidix_use_colour_key", 1, "enable use of overlay colour key",
+ NULL, 10, (void*) vidix_config_callback, this);
+
+ /* Colour key components */
+ this->vidix_grkey.ckey.red = config->register_range(config,
+ "video.vidix_colour_key_red", 255, 0, 255,
+ "video overlay colour key red component", NULL, 10,
+ (void*) vidix_config_callback, this);
+
+ this->vidix_grkey.ckey.green = config->register_range(config,
+ "video.vidix_colour_key_green", 0, 0, 255,
+ "video overlay colour key green component", NULL, 10,
+ (void*) vidix_config_callback, this);
+
+ this->vidix_grkey.ckey.blue = config->register_range(config,
+ "video.vidix_colour_key_blue", 255, 0, 255,
+ "video overlay colour key blue component", NULL, 10,
+ (void*) vidix_config_callback, this);
+
+ vidix_update_colourkey(this);
+
+ /* Configuration for double buffering */
+ this->use_doublebuffer = config->register_bool(config,
+ "video.vidix_use_double_buffer", 1, "double buffer to sync video to retrace", NULL, 10,
+ (void*) vidix_config_callback, this);
+
+ /* Set up remaining props */
+ this->props[VO_PROP_ASPECT_RATIO].value = ASPECT_AUTO;
+ this->props[VO_PROP_ASPECT_RATIO].min = 0;
+ this->props[VO_PROP_ASPECT_RATIO].max = NUM_ASPECT_RATIOS;
+
+ this->props[VO_PROP_ZOOM_X].value = 100;
+ this->props[VO_PROP_ZOOM_X].min = VO_ZOOM_MIN;
+ this->props[VO_PROP_ZOOM_X].max = VO_ZOOM_MAX;
+
+ this->props[VO_PROP_ZOOM_Y].value = 100;
+ this->props[VO_PROP_ZOOM_Y].min = VO_ZOOM_MIN;
+ this->props[VO_PROP_ZOOM_Y].max = VO_ZOOM_MAX;
+
this->vo_driver.get_capabilities = vidix_get_capabilities;
this->vo_driver.alloc_frame = vidix_alloc_frame;
this->vo_driver.update_frame_format = vidix_update_frame_format;