diff options
Diffstat (limited to 'src/video_out/video_out_vidix.c')
-rw-r--r-- | src/video_out/video_out_vidix.c | 872 |
1 files changed, 872 insertions, 0 deletions
diff --git a/src/video_out/video_out_vidix.c b/src/video_out/video_out_vidix.c new file mode 100644 index 000000000..1d70f9f97 --- /dev/null +++ b/src/video_out/video_out_vidix.c @@ -0,0 +1,872 @@ +/* + * 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: video_out_vidix.c,v 1.1 2002/06/01 14:08:37 f1rmb Exp $ + * + * video_out_vidix.c + * + * xine video_out driver to vidix library by Miguel Freitas 30/05/2002 + * + * based on video_out_xv.c and video_out_syncfb.c + * + * some vidix specific code from mplayer (file vosub_vidix.c) + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <inttypes.h> +#include <math.h> +#include "vidixlib.h" + +#include "video_out.h" +#include "xine_internal.h" +#include "alphablend.h" +#include "xineutils.h" + +#include <X11/Xlib.h> +#include "video_out_x11.h" + + +#define LOG + + +#define LIBDIR "/usr/local/lib" +#define NUM_FRAMES 1 + +typedef struct vidix_driver_s vidix_driver_t; + +typedef struct vidix_frame_s { + vo_frame_t vo_frame; + int width, height, ratio_code, format; +} vidix_frame_t; + + +struct vidix_driver_s { + + vo_driver_t vo_driver; + + config_values_t *config; + + char *vidix_name; + VDL_HANDLE vidix_handler; + uint8_t *vidix_mem; + vidix_capability_t vidix_cap; + vidix_playback_t vidix_play; + vidix_fourcc_t vidix_fourcc; + vidix_yuv_t dstrides; + int vidix_started; + int next_frame; + + int yuv_format; + + pthread_mutex_t mutex; + + int user_ratio; + + uint32_t capabilities; + + /* X11 / Xv related stuff */ + Display *display; + int screen; + Drawable drawable; + + /* + * "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; + int delivered_format; + + /* + * 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 */ + + 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 void free_framedata(vidix_frame_t* frame) +{ + if(frame->vo_frame.base[0]) { + free(frame->vo_frame.base[0]); + frame->vo_frame.base[0] = NULL; + } + + if(frame->vo_frame.base[1]) { + free(frame->vo_frame.base[1]); + frame->vo_frame.base[1] = NULL; + } + + if(frame->vo_frame.base[2]) { + free(frame->vo_frame.base[2]); + frame->vo_frame.base[2] = NULL; + } +} + + +static void write_frame_YUV422(vidix_driver_t* this, vidix_frame_t* frame) +{ + uint8_t* y = (uint8_t *)frame->vo_frame.base[0]; + uint8_t* cb = (uint8_t *)frame->vo_frame.base[1]; + uint8_t* cr = (uint8_t *)frame->vo_frame.base[2]; + uint8_t* crp; + uint8_t* cbp; + uint32_t* dst32 = (uint32_t *)(this->vidix_mem + + this->vidix_play.offsets[this->next_frame] + + this->vidix_play.offset.y); + int h,w; + + for(h = 0; h < (frame->height / 2); h++) { + cbp = cb; + crp = cr; + + for(w = 0; w < (frame->width / 2); w++) { + *dst32++ = (*y) + ((*cb)<<8) + ((*(y+1))<<16) + ((*cr)<<24); + y++; y++; cb++; cr++; + } + + dst32 += (this->dstrides.y - frame->width) / 2; + + for(w=0; w < (frame->width / 2); w++) { + *dst32++ = (*y) + ((*cbp)<<8) + ((*(y+1))<<16) + ((*crp)<<24); + y++; y++; cbp++; crp++; + } + + dst32 += (this->dstrides.y - frame->width) / 2; + } +} + +static void write_frame_YUV420P2(vidix_driver_t* this, vidix_frame_t* frame) +{ + uint8_t* y = (uint8_t *)frame->vo_frame.base[0]; + uint8_t* cb = (uint8_t *)frame->vo_frame.base[1]; + uint8_t* cr = (uint8_t *)frame->vo_frame.base[2]; + uint8_t* dst8 = (this->vidix_mem + this->vidix_play.offset.u + + this->vidix_play.offsets[this->next_frame] + + this->vidix_play.offset.u); + int h, w; + + register uint32_t* tmp32; + register uint8_t* rcr; + register uint8_t* rcb; + + rcr = cr; + rcb = cb; + + for(h = 0; h < (frame->height / 2); h++) { + tmp32 = (uint32_t *)dst8; + w = (frame->width / 8) * 2; + + while(w--) { + register uint32_t temp; + + temp = (*rcb) | (*rcr << 8); + rcr++; + rcb++; + temp |= (*rcb << 16) | (*rcr << 24); + rcr++; + rcb++; + *tmp32 = temp; + tmp32++; + } + + dst8 += this->dstrides.y; + } + + dst8 = (this->vidix_mem + + this->vidix_play.offsets[this->next_frame] + + this->vidix_play.offset.y); + for(h = 0; h < frame->height; h++) { + xine_fast_memcpy(dst8, y, frame->width); + y += frame->width; + dst8 += this->dstrides.y; + } +} + +static void write_frame_YUV420P3(vidix_driver_t* this, vidix_frame_t* frame) +{ + uint8_t* y = (uint8_t *)frame->vo_frame.base[0]; + uint8_t* cb = (uint8_t *)frame->vo_frame.base[1]; + uint8_t* cr = (uint8_t *)frame->vo_frame.base[2]; + uint8_t* dst8 = (this->vidix_mem + + this->vidix_play.offsets[this->next_frame] + + this->vidix_play.offset.y); + int h, half_width = (frame->width/2); + + for(h = 0; h < frame->height; h++) { + xine_fast_memcpy(dst8, y, frame->width); + y += frame->width; + dst8 += this->dstrides.y; + } + + dst8 = (this->vidix_mem + + this->vidix_play.offsets[this->next_frame]); + for(h = 0; h < (frame->height / 2); h++) { + xine_fast_memcpy((dst8 + this->vidix_play.offset.v), cb, half_width); + xine_fast_memcpy((dst8 + this->vidix_play.offset.u), cr, half_width); + + cb += half_width; + cr += half_width; + + dst8 += (this->dstrides.y / 2); + } +} + +static void write_frame_YUY2(vidix_driver_t* this, vidix_frame_t* frame) +{ + uint8_t* src8 = (uint8_t *)frame->vo_frame.base[0]; + uint8_t* dst8 = (uint8_t *)(this->vidix_mem + + this->vidix_play.offsets[this->next_frame] + + this->vidix_play.offset.y); + int h, double_width = (frame->width * 2); + + for(h = 0; h < frame->height; h++) { + xine_fast_memcpy(dst8, src8, double_width); + + dst8 += (this->dstrides.y * 2); + src8 += double_width; + } +} + +static void write_frame_sfb(vidix_driver_t* this, vidix_frame_t* frame) +{ + switch(frame->format) { + case IMGFMT_YUY2: + write_frame_YUY2(this, frame); +/* + else + printf("video_out_vidix: error. (YUY2 not supported by your graphic card)\n"); +*/ + break; + + case IMGFMT_YV12: + write_frame_YUV420P3(this, frame); +/* switch(this->yuv_format) { + case VIDEO_PALETTE_YUV422: + write_frame_YUV422(this, frame); + break; + case VIDEO_PALETTE_YUV420P2: + write_frame_YUV420P2(this, frame); + break; + case VIDEO_PALETTE_YUV420P3: + write_frame_YUV420P3(this, frame); + break; + default: + printf("video_out_vidix: error. (YV12 not supported by your graphic card)\n"); + } +*/ + break; + + default: + printf("video_out_vidix: error. (unknown frame format)\n"); + break; + } + + frame->vo_frame.displayed(&frame->vo_frame); +} + + +static uint32_t vidix_get_capabilities (vo_driver_t *this_gen) { + + vidix_driver_t *this = (vidix_driver_t *) this_gen; + + return this->capabilities; +} + +static void vidix_frame_field (vo_frame_t *vo_img, int which_field) { + /* not needed for vidix */ +} + +static void vidix_frame_dispose (vo_frame_t *vo_img) { + + vidix_frame_t *frame = (vidix_frame_t *) vo_img ; + + free_framedata(frame); + free (frame); +} + +static vo_frame_t *vidix_alloc_frame (vo_driver_t *this_gen) { + + vidix_frame_t *frame ; + + frame = (vidix_frame_t *) malloc (sizeof (vidix_frame_t)); + memset (frame, 0, sizeof(vidix_frame_t)); + + if (frame==NULL) { + printf ("vidix_alloc_frame: out of memory\n"); + } + + pthread_mutex_init (&frame->vo_frame.mutex, NULL); + + frame->vo_frame.base[0] = NULL; + frame->vo_frame.base[1] = NULL; + frame->vo_frame.base[2] = NULL; + + /* + * supply required functions + */ + + frame->vo_frame.copy = NULL; + frame->vo_frame.field = vidix_frame_field; + frame->vo_frame.dispose = vidix_frame_dispose; + + return (vo_frame_t *) frame; +} +/* + * make ideal width/height "fit" into the gui + */ + +static void vidix_compute_output_size (vidix_driver_t *this) { + + double x_factor, y_factor; + uint32_t apitch; + int err,i; + + if( !this->ideal_width || !this->ideal_height ) + return; + + 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; + } + + 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; + +#ifdef LOG + printf ("video_out_vidix: frame source %d x %d => screen output %d x %d\n", + this->delivered_width, this->delivered_height, + this->output_width, this->output_height); +#endif + + if( this->vidix_started ) { + vdlPlaybackOff(this->vidix_handler); + } + + memset(&this->vidix_play,0,sizeof(vidix_playback_t)); + + this->vidix_play.fourcc = this->delivered_format; + this->vidix_play.capability = this->vidix_cap.flags; /* every ;) */ + this->vidix_play.blend_factor = 0; /* for now */ + this->vidix_play.src.x = this->vidix_play.src.y = 0; + this->vidix_play.src.w = this->delivered_width; + this->vidix_play.src.h = this->delivered_height; + this->vidix_play.dest.x = this->gui_win_x+this->output_xoffset; + this->vidix_play.dest.y = this->gui_win_y+this->output_yoffset; + this->vidix_play.dest.w = this->output_width; + this->vidix_play.dest.h = this->output_height; + this->vidix_play.num_frames=NUM_FRAMES; + 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) + { + printf("video_out_vidix: Can't configure playback: %s\n",strerror(err)); + } + +#ifdef LOG + printf("video_out_vidix: dga_addr = %p frame_size = %d frames = %d\n", + this->vidix_play.dga_addr, this->vidix_play.frame_size, + this->vidix_play.num_frames ); + + printf("video_out_vidix: offsets[0..2] = %d %d %d\n", + this->vidix_play.offsets[0], this->vidix_play.offsets[1], + this->vidix_play.offsets[2] ); + + printf("video_out_vidix: offset.y/u/v = %d/%d/%d\n", + this->vidix_play.offset.y, this->vidix_play.offset.u, + this->vidix_play.offset.v ); + + printf("video_out_vidix: dest.pitch.y/u/v = %d/%d/%d\n", + this->vidix_play.dest.pitch.y, this->vidix_play.dest.pitch.u, + this->vidix_play.dest.pitch.v ); +#endif + + this->vidix_mem = this->vidix_play.dga_addr; + + this->next_frame = 0; + + /* clear every frame with correct address and frame_size */ + for (i = 0; i < this->vidix_play.num_frames; i++) + memset(this->vidix_mem + this->vidix_play.offsets[i], 0x80, + this->vidix_play.frame_size); + + apitch = this->vidix_play.dest.pitch.y-1; + this->dstrides.y = (this->delivered_width + apitch) & ~apitch; + apitch = this->vidix_play.dest.pitch.v-1; + this->dstrides.v = (this->delivered_width + apitch) & ~apitch; + apitch = this->vidix_play.dest.pitch.u-1; + this->dstrides.u = (this->delivered_width + apitch) & ~apitch; + + vdlPlaybackOn(this->vidix_handler); + this->vidix_started = 1; +} + +static void vidix_compute_ideal_size (vidix_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 */ + 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_vidix: invalid ratio, using 4:3\n"); + default: + printf ("video_out_vidix: 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 vidix_update_frame_format (vo_driver_t *this_gen, + vo_frame_t *frame_gen, + uint32_t width, uint32_t height, + int ratio_code, int format, int flags) { + + vidix_frame_t *frame = (vidix_frame_t *) frame_gen; + uint32_t frame_size = width*height; + + if ((frame->width != width) + || (frame->height != height) + || (frame->format != format)) { + + /* + * (re-) allocate image + */ + + free_framedata(frame); + + frame->width = width; + frame->height = height; + frame->format = format; + + switch(format) { + case IMGFMT_YV12: + frame->vo_frame.base[0] = malloc(frame_size); + frame->vo_frame.base[1] = malloc(frame_size/4); + frame->vo_frame.base[2] = malloc(frame_size/4); + break; + case IMGFMT_YUY2: + frame->vo_frame.base[0] = malloc(frame_size*2); + frame->vo_frame.base[1] = NULL; + frame->vo_frame.base[2] = NULL; + break; + default: + printf("video_out_vidix: error. (unable to allocate framedata because of unknown frame format: %04x)\n", format); + } + + if((format == IMGFMT_YV12 && (frame->vo_frame.base[0] == NULL || frame->vo_frame.base[1] == NULL || frame->vo_frame.base[2] == NULL)) + || (format == IMGFMT_YUY2 && frame->vo_frame.base[0] == NULL)) { + printf("video_out_vidix: error. (framedata allocation failed: out of memory)\n"); + + free_framedata(frame); + } + } + + frame->ratio_code = ratio_code; +} + + +/* + * + */ +static void vidix_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { + + vidix_frame_t *frame = (vidix_frame_t *) frame_gen; + + if (overlay->rle) { + if( frame->format == IMGFMT_YV12 ) + blend_yuv( frame->vo_frame.base, overlay, frame->width, frame->height); + else + blend_yuy2( frame->vo_frame.base[0], overlay, frame->width, frame->height); + } +} + +static int vidix_redraw_needed (vo_driver_t *this_gen) { + vidix_driver_t *this = (vidix_driver_t *) this_gen; + int ret = 0; + + 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; + + vidix_compute_output_size (this); + + ret = 1; + } + + return ret; +} + + +static void vidix_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { + + vidix_driver_t *this = (vidix_driver_t *) this_gen; + vidix_frame_t *frame = (vidix_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) + || (frame->format != this->delivered_format ) ) { + printf("video_out_vidix: change frame format\n"); + + this->delivered_width = frame->width; + this->delivered_height = frame->height; + this->delivered_ratio_code = frame->ratio_code; + this->delivered_format = frame->format; + + vidix_compute_ideal_size( this ); + this->gui_width = 0; /* trigger re-calc of output size */ + } + + /* + * tell gui that we are about to display a frame, + * ask for offset and output size + */ + vidix_redraw_needed (this_gen); + + write_frame_sfb(this, frame); + if( this->vidix_play.num_frames > 1 ) { + vdlPlaybackFrameSelect(this->vidix_handler,this->next_frame); + this->next_frame=(this->next_frame+1)%this->vidix_play.num_frames; + } + + pthread_mutex_unlock(&this->mutex); +} + +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->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 vidix_set_property (vo_driver_t *this_gen, + int property, int value) { + + vidix_driver_t *this = (vidix_driver_t *) this_gen; + + if ( property == VO_PROP_ASPECT_RATIO) { + if (value>=NUM_ASPECT_RATIOS) + value = ASPECT_AUTO; + this->user_ratio = value; + printf("video_out_vidix: aspect ratio changed to %s\n", + aspect_ratio_name(value)); + + vidix_compute_ideal_size (this); + } + + return value; +} + +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; */ +} + +static void vidix_translate_gui2video(vidix_driver_t *this, + int x, int y, + int *vid_x, int *vid_y) +{ +} + +static int vidix_gui_data_exchange (vo_driver_t *this_gen, + int data_type, void *data) { + + int ret = 0; + vidix_driver_t *this = (vidix_driver_t *) this_gen; + + pthread_mutex_lock(&this->mutex); + + switch (data_type) { + + case GUI_DATA_EX_DRAWABLE_CHANGED: +#ifdef LOG + printf ("video_out_vidix: GUI_DATA_EX_DRAWABLE_CHANGED\n"); +#endif + + this->drawable = (Drawable) data; + break; + + case GUI_DATA_EX_EXPOSE_EVENT: +#ifdef LOG + printf ("video_out_vidix: GUI_DATA_EX_EXPOSE_EVENT\n"); +#endif + break; + + default: + ret = -1; + } + pthread_mutex_unlock(&this->mutex); + + return ret; +} + +static void vidix_exit (vo_driver_t *this_gen) { + + vidix_driver_t *this = (vidix_driver_t *) this_gen; + + if( this->vidix_started ) { + vdlPlaybackOff(this->vidix_handler); + } + vdlClose(this->vidix_handler); +} + +vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) { + + vidix_driver_t *this; + x11_visual_t *visual = (x11_visual_t *) visual_gen; + XWindowAttributes window_attributes; + int err; + + this = malloc (sizeof (vidix_driver_t)); + + if (!this) { + printf ("video_out_vidix: malloc failed\n"); + return NULL; + } + memset (this, 0, sizeof(vidix_driver_t)); + + + if(vdlGetVersion() != VIDIX_VERSION) + { + printf("video_out_vidix: You have wrong version of VIDIX library\n"); + return NULL; + } + this->vidix_handler = vdlOpen((XINE_PLUGINDIR"/vidix/"), NULL, TYPE_OUTPUT, 0); + if(this->vidix_handler == NULL) + { + printf("video_out_vidix: Couldn't find working VIDIX driver\n"); + return NULL; + } + if((err=vdlGetCapability(this->vidix_handler,&this->vidix_cap)) != 0) + { + printf("video_out_vidix: Couldn't get capability: %s\n",strerror(err)); + return NULL; + } + printf("video_out_vidix: Using: %s by %s\n",this->vidix_cap.name,this->vidix_cap.author); + + 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; + + + 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; + + XGetWindowAttributes(this->display, this->drawable, &window_attributes); + this->gui_width = window_attributes.width; + this->gui_height = window_attributes.height; + + + + 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; + this->vo_driver.overlay_blend = vidix_overlay_blend; + this->vo_driver.display_frame = vidix_display_frame; + this->vo_driver.get_property = vidix_get_property; + this->vo_driver.set_property = vidix_set_property; + this->vo_driver.get_property_min_max = vidix_get_property_min_max; + this->vo_driver.gui_data_exchange = vidix_gui_data_exchange; + this->vo_driver.exit = vidix_exit; + this->vo_driver.redraw_needed = vidix_redraw_needed; + + printf ("video_out_vidix: warning, xine's vidix driver is EXPERIMENTAL\n"); + return &this->vo_driver; +} + +static vo_info_t vo_info_vidix = { + 5, + "vidix", + "xine video output plugin using libvidix", + VISUAL_TYPE_X11, + 4 +}; + +vo_info_t *get_video_out_plugin_info() { + return &vo_info_vidix; +} + + |