Mercurial > mplayer.hg
view libvo/vosub_vidix.c @ 11619:179138947307
This patch contains bugfixes for the esd audio output driver that I
uncovered while trying to send sound to a remote esd server over a
wireless (11 mbs, just enough to handle to sound) link.
First, the sound was full "ticking" sounds. I found a bug that
prevented the "send the remainder of this block" code from ever being
called - so large chunks of audio were simply being ignored. Fixing
this bug removed the "ticking" from audio streams.
Fixing this bug, however, uncovered another problem - when the socket
buffer was full, doing a blocking write to finish the buffer would take
far too long and would turn video into a chunky mess. I'd imagine this
blocking write would be fine for an audio-only stream, but it turns out
to hold up the video far too much.
The solution in this patch is to write as much data as possible to the
socket, and then return as soon as possible, reporting the number of
bytes actually written accurately back to mplayer. I've tested it on
both local and remote esd servers, and it works well.
Patch by Benjamin Osheroff <ben@gimbo.net>
author | attila |
---|---|
date | Wed, 10 Dec 2003 12:19:13 +0000 |
parents | 656932ca58ab |
children | e49a62a6e3cb |
line wrap: on
line source
/* * vosub_vidix.c * * Copyright (C) Nick Kurshev <nickols_k@mail.ru> - 2002 * Copyright (C) Alex Beregszaszi * * You can redistribute this file under terms and conditions * of GNU General Public licence v2. * * This file contains vidix interface to any mplayer's VO plugin. * (Partly based on vesa_lvo.c from mplayer's package) */ #include <inttypes.h> #include <unistd.h> #include <fcntl.h> #ifndef __MINGW32__ #include <sys/ioctl.h> #include <sys/mman.h> #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include "config.h" #include "vosub_vidix.h" #include "../vidix/vidixlib.h" #include "../postproc/rgb2rgb.h" #include "fastmemcpy.h" #include "osd.h" #include "video_out.h" #include "sub.h" #include "../libmpcodecs/vfcap.h" #include "../libmpcodecs/mp_image.h" #define NUM_FRAMES VID_PLAY_MAXFRAMES /* Temporary: driver will overwrite it */ static VDL_HANDLE vidix_handler = NULL; static uint8_t *vidix_mem = NULL; static uint8_t next_frame; static unsigned image_Bpp,image_height,image_width,src_format,forced_fourcc=0; extern int verbose; static int video_on=0; static vidix_capability_t vidix_cap; static vidix_playback_t vidix_play; static vidix_fourcc_t vidix_fourcc; static vo_functions_t * vo_server; static vidix_yuv_t dstrides; /*static uint32_t (*server_control)(uint32_t request, void *data, ...);*/ static int vidix_get_video_eq(vidix_video_eq_t *info); static int vidix_set_video_eq(const vidix_video_eq_t *info); static int vidix_get_num_fx(unsigned *info); static int vidix_get_oem_fx(vidix_oem_fx_t *info); static int vidix_set_oem_fx(const vidix_oem_fx_t *info); static int vidix_set_deint(const vidix_deinterlace_t *info); int vidix_start(void) { int err; if((err=vdlPlaybackOn(vidix_handler))!=0) { printf("vosub_vidix: Can't start playback: %s\n",strerror(err)); return -1; } video_on=1; return 0; } int vidix_stop(void) { int err; if((err=vdlPlaybackOff(vidix_handler))!=0) { printf("vosub_vidix: Can't stop playback: %s\n",strerror(err)); return -1; } video_on=0; return 0; } void vidix_term( void ) { if(verbose > 1) printf("vosub_vidix: vidix_term() was called\n"); vidix_stop(); vdlClose(vidix_handler); // ((vo_functions_t *)vo_server)->control=server_control; } static uint32_t vidix_draw_slice_420(uint8_t *image[], int stride[], int w,int h,int x,int y) { uint8_t *src; uint8_t *dest; int i; /* Plane Y */ dest = vidix_mem + vidix_play.offsets[next_frame] + vidix_play.offset.y; dest += dstrides.y*y + x; src = image[0]; for(i=0;i<h;i++){ memcpy(dest,src,w); src+=stride[0]; dest += dstrides.y; } if (vidix_play.flags & VID_PLAY_INTERLEAVED_UV) { int hi,wi; uint8_t *src2; dest = vidix_mem + vidix_play.offsets[next_frame] + vidix_play.offset.v; dest += dstrides.y*y/2 + x; // <- is this correct ? h/=2; w/=2; src = image[1]; src2 = image[2]; for(hi = 0; hi < h; hi++) { for(wi = 0; wi < w; wi++) { dest[2*wi+0] = src[wi]; dest[2*wi+1] = src2[wi]; } dest += dstrides.y; src += stride[1]; src2+= stride[2]; } } else { /* Plane V */ dest = vidix_mem + vidix_play.offsets[next_frame] + vidix_play.offset.v; dest += dstrides.v*y/4 + x; src = image[1]; for(i=0;i<h/2;i++){ memcpy(dest,src,w/2); src+=stride[1]; dest+=dstrides.v/2; } /* Plane U */ dest = vidix_mem + vidix_play.offsets[next_frame] + vidix_play.offset.u; dest += dstrides.u*y/4 + x; src = image[2]; for(i=0;i<h/2;i++){ memcpy(dest,src,w/2); src+=stride[2]; dest += dstrides.u/2; } return 0; } return -1; } static uint32_t vidix_draw_slice_410(uint8_t *image[], int stride[], int w,int h,int x,int y) { uint8_t *src; uint8_t *dest; int i; /* Plane Y */ dest = vidix_mem + vidix_play.offsets[next_frame] + vidix_play.offset.y; dest += dstrides.y*y + x; src = image[0]; for(i=0;i<h;i++){ memcpy(dest,src,w); src+=stride[0]; dest += dstrides.y; } if (vidix_play.flags & VID_PLAY_INTERLEAVED_UV) { printf("vosub_vidix: interleaved uv for yuv410p not supported\n"); } else { /* Plane V */ dest = vidix_mem + vidix_play.offsets[next_frame] + vidix_play.offset.v; dest += dstrides.v*y/8 + x; src = image[1]; for(i=0;i<h/4;i++){ memcpy(dest,src,w/4); src+=stride[1]; dest+=dstrides.v/4; } /* Plane U */ dest = vidix_mem + vidix_play.offsets[next_frame] + vidix_play.offset.u; dest += dstrides.u*y/8 + x; src = image[2]; for(i=0;i<h/4;i++){ memcpy(dest,src,w/4); src+=stride[2]; dest += dstrides.u/4; } return 0; } return -1; } static uint32_t vidix_draw_slice_410_fast(uint8_t *image[], int stride[], int w, int h, int x, int y) { uint8_t *src; uint8_t *dest; dest = vidix_mem + vidix_play.offsets[next_frame] + vidix_play.offset.y; dest += dstrides.y*y + x; src = image[0]; memcpy(dest, src, dstrides.y*h*9/8); return 0; } static uint32_t vidix_draw_slice_400(uint8_t *image[], int stride[], int w,int h,int x,int y) { uint8_t *src; uint8_t *dest; int i; dest = vidix_mem + vidix_play.offsets[next_frame] + vidix_play.offset.y; dest += dstrides.y*y + x; src = image[0]; for(i=0;i<h;i++){ memcpy(dest,src,w); src+=stride[0]; dest += dstrides.y; } return 0; } static uint32_t vidix_draw_slice_packed(uint8_t *image[], int stride[], int w,int h,int x,int y) { uint8_t *src; uint8_t *dest; int i; dest = vidix_mem + vidix_play.offsets[next_frame] + vidix_play.offset.y; dest += dstrides.y*y + x; src = image[0]; for(i=0;i<h;i++){ memcpy(dest,src,w*image_Bpp); src+=stride[0]; dest += dstrides.y; } return 0; } uint32_t vidix_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y) { printf("vosub_vidix: dummy vidix_draw_slice() was called\n"); return -1; } static uint32_t vidix_draw_image(mp_image_t *mpi){ if(verbose > 1) printf("vosub_vidix: vidix_draw_image() was called\n"); // if -dr or -slices then do nothing: if(mpi->flags&(MP_IMGFLAG_DIRECT|MP_IMGFLAG_DRAW_CALLBACK)) return VO_TRUE; vo_server->draw_slice(mpi->planes,mpi->stride, vidix_play.src.w,vidix_play.src.h,vidix_play.src.x,vidix_play.src.y); return VO_TRUE; } uint32_t vidix_draw_frame(uint8_t *image[]) { printf("vosub_vidix: dummy vidix_draw_frame() was called\n"); return -1; } void vidix_flip_page(void) { if(verbose > 1) printf("vosub_vidix: vidix_flip_page() was called\n"); if(vo_doublebuffering) { vdlPlaybackFrameSelect(vidix_handler,next_frame); next_frame=(next_frame+1)%vidix_play.num_frames; } } static void draw_alpha(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride) { uint32_t apitch,bespitch; void *lvo_mem; lvo_mem = vidix_mem + vidix_play.offsets[next_frame] + vidix_play.offset.y; apitch = vidix_play.dest.pitch.y-1; switch(vidix_play.fourcc){ case IMGFMT_YV12: case IMGFMT_IYUV: case IMGFMT_I420: case IMGFMT_YVU9: case IMGFMT_IF09: case IMGFMT_Y8: case IMGFMT_Y800: bespitch = (vidix_play.src.w + apitch) & (~apitch); vo_draw_alpha_yv12(w,h,src,srca,stride,lvo_mem+bespitch*y0+x0,bespitch); break; case IMGFMT_YUY2: bespitch = (vidix_play.src.w*2 + apitch) & (~apitch); vo_draw_alpha_yuy2(w,h,src,srca,stride,lvo_mem+bespitch*y0+2*x0,bespitch); break; case IMGFMT_UYVY: bespitch = (vidix_play.src.w*2 + apitch) & (~apitch); vo_draw_alpha_yuy2(w,h,src,srca,stride,lvo_mem+bespitch*y0+2*x0+1,bespitch); break; case IMGFMT_RGB32: case IMGFMT_BGR32: bespitch = (vidix_play.src.w*4 + apitch) & (~apitch); vo_draw_alpha_rgb32(w,h,src,srca,stride,lvo_mem+y0*bespitch+4*x0,bespitch); break; case IMGFMT_RGB24: case IMGFMT_BGR24: bespitch = (vidix_play.src.w*3 + apitch) & (~apitch); vo_draw_alpha_rgb24(w,h,src,srca,stride,lvo_mem+y0*bespitch+3*x0,bespitch); break; case IMGFMT_RGB16: case IMGFMT_BGR16: bespitch = (vidix_play.src.w*2 + apitch) & (~apitch); vo_draw_alpha_rgb16(w,h,src,srca,stride,lvo_mem+y0*bespitch+2*x0,bespitch); break; case IMGFMT_RGB15: case IMGFMT_BGR15: bespitch = (vidix_play.src.w*2 + apitch) & (~apitch); vo_draw_alpha_rgb15(w,h,src,srca,stride,lvo_mem+y0*bespitch+2*x0,bespitch); break; default: return; } } void vidix_draw_osd(void) { if(verbose > 1) printf("vosub_vidix: vidix_draw_osd() was called\n"); /* TODO: hw support */ vo_draw_text(vidix_play.src.w,vidix_play.src.h,draw_alpha); } uint32_t vidix_query_fourcc(uint32_t format) { if(verbose > 1) printf("vosub_vidix: query_format was called: %x (%s)\n",format,vo_format_name(format)); vidix_fourcc.fourcc = format; vdlQueryFourcc(vidix_handler,&vidix_fourcc); if (vidix_fourcc.depth == VID_DEPTH_NONE) return 0; return VFCAP_CSP_SUPPORTED|VFCAP_CSP_SUPPORTED_BY_HW|VFCAP_HWSCALE_UP|VFCAP_HWSCALE_DOWN|VFCAP_OSD|VFCAP_ACCEPT_STRIDE; } int vidix_grkey_support(void) { return(vidix_fourcc.flags & VID_CAP_COLORKEY); } int vidix_grkey_get(vidix_grkey_t *gr_key) { return(vdlGetGrKeys(vidix_handler, gr_key)); } int vidix_grkey_set(const vidix_grkey_t *gr_key) { return(vdlSetGrKeys(vidix_handler, gr_key)); } static int vidix_get_video_eq(vidix_video_eq_t *info) { if(!video_on) return EPERM; return vdlPlaybackGetEq(vidix_handler, info); } static int vidix_set_video_eq(const vidix_video_eq_t *info) { if(!video_on) return EPERM; return vdlPlaybackSetEq(vidix_handler, info); } static int vidix_get_num_fx(unsigned *info) { if(!video_on) return EPERM; return vdlQueryNumOemEffects(vidix_handler, info); } static int vidix_get_oem_fx(vidix_oem_fx_t *info) { if(!video_on) return EPERM; return vdlGetOemEffect(vidix_handler, info); } static int vidix_set_oem_fx(const vidix_oem_fx_t *info) { if(!video_on) return EPERM; return vdlSetOemEffect(vidix_handler, info); } static int vidix_set_deint(const vidix_deinterlace_t *info) { if(!video_on) return EPERM; return vdlPlaybackSetDeint(vidix_handler, info); } static int is_422_planes_eq=0; int vidix_init(unsigned src_width,unsigned src_height, unsigned x_org,unsigned y_org,unsigned dst_width, unsigned dst_height,unsigned format,unsigned dest_bpp, unsigned vid_w,unsigned vid_h) { size_t i; int err; uint32_t sstride,apitch; if(verbose > 1) printf("vosub_vidix: vidix_init() was called\n" "src_w=%u src_h=%u dest_x_y_w_h = %u %u %u %u\n" "format=%s dest_bpp=%u vid_w=%u vid_h=%u\n" ,src_width,src_height,x_org,y_org,dst_width,dst_height ,vo_format_name(format),dest_bpp,vid_w,vid_h); if(vidix_query_fourcc(format) == 0) { printf("vosub_vidix: unsupported fourcc for this vidix driver: %x (%s)\n", format,vo_format_name(format)); return -1; } if(((vidix_cap.maxwidth != -1) && (vid_w > vidix_cap.maxwidth)) || ((vidix_cap.minwidth != -1) && (vid_w < vidix_cap.minwidth)) || ((vidix_cap.maxheight != -1) && (vid_h > vidix_cap.maxheight)) || ((vidix_cap.minwidth != -1 ) && (vid_h < vidix_cap.minheight))) { printf("vosub_vidix: video server has unsupported resolution (%dx%d), supported: %dx%d-%dx%d\n", vid_w, vid_h, vidix_cap.minwidth, vidix_cap.minheight, vidix_cap.maxwidth, vidix_cap.maxheight); return -1; } err = 0; switch(dest_bpp) { case 1: err = ((vidix_fourcc.depth & VID_DEPTH_1BPP) != VID_DEPTH_1BPP); break; case 2: err = ((vidix_fourcc.depth & VID_DEPTH_2BPP) != VID_DEPTH_2BPP); break; case 4: err = ((vidix_fourcc.depth & VID_DEPTH_4BPP) != VID_DEPTH_4BPP); break; case 8: err = ((vidix_fourcc.depth & VID_DEPTH_8BPP) != VID_DEPTH_8BPP); break; case 12:err = ((vidix_fourcc.depth & VID_DEPTH_12BPP) != VID_DEPTH_12BPP); break; case 15:err = ((vidix_fourcc.depth & VID_DEPTH_15BPP) != VID_DEPTH_15BPP); break; case 16:err = ((vidix_fourcc.depth & VID_DEPTH_16BPP) != VID_DEPTH_16BPP); break; case 24:err = ((vidix_fourcc.depth & VID_DEPTH_24BPP) != VID_DEPTH_24BPP); break; case 32:err = ((vidix_fourcc.depth & VID_DEPTH_32BPP) != VID_DEPTH_32BPP); break; default: err=1; break; } if(err) { printf("vosub_vidix: video server has unsupported color depth by vidix (%d)\n" ,vidix_fourcc.depth); return -1; } if((dst_width > src_width || dst_height > src_height) && (vidix_cap.flags & FLAG_UPSCALER) != FLAG_UPSCALER) { printf("vosub_vidix: vidix driver can't upscale image (%d%d -> %d%d)\n", src_width, src_height, dst_width, dst_height); return -1; } if((dst_width > src_width || dst_height > src_height) && (vidix_cap.flags & FLAG_DOWNSCALER) != FLAG_DOWNSCALER) { printf("vosub_vidix: vidix driver can't downscale image (%d%d -> %d%d)\n", src_width, src_height, dst_width, dst_height); return -1; } image_width = src_width; image_height = src_height; src_format = format; if(forced_fourcc) format = forced_fourcc; memset(&vidix_play,0,sizeof(vidix_playback_t)); vidix_play.fourcc = format; vidix_play.capability = vidix_cap.flags; /* every ;) */ vidix_play.blend_factor = 0; /* for now */ /* display the full picture. Nick: we could implement here zooming to a specified area -- alex */ vidix_play.src.x = vidix_play.src.y = 0; vidix_play.src.w = src_width; vidix_play.src.h = src_height; vidix_play.dest.x = x_org; vidix_play.dest.y = y_org; vidix_play.dest.w = dst_width; vidix_play.dest.h = dst_height; // vidix_play.num_frames=vo_doublebuffering?NUM_FRAMES-1:1; /* we aren't mad...3 buffers are more than enough */ vidix_play.num_frames=vo_doublebuffering?3:1; vidix_play.src.pitch.y = vidix_play.src.pitch.u = vidix_play.src.pitch.v = 0; if((err=vdlConfigPlayback(vidix_handler,&vidix_play))!=0) { printf("vosub_vidix: Can't configure playback: %s\n",strerror(err)); return -1; } if (verbose) printf("vosub_vidix: using %d buffer(s)\n", vidix_play.num_frames); vidix_mem = vidix_play.dga_addr; /* select first frame */ next_frame = 0; // vdlPlaybackFrameSelect(vidix_handler,next_frame); /* clear every frame with correct address and frame_size */ for (i = 0; i < vidix_play.num_frames; i++) memset(vidix_mem + vidix_play.offsets[i], 0x80, vidix_play.frame_size); switch(format) { case IMGFMT_YV12: case IMGFMT_I420: case IMGFMT_IYUV: case IMGFMT_YVU9: case IMGFMT_IF09: case IMGFMT_Y800: case IMGFMT_Y8: apitch = vidix_play.dest.pitch.y-1; dstrides.y = (image_width + apitch) & ~apitch; apitch = vidix_play.dest.pitch.v-1; dstrides.v = (image_width + apitch) & ~apitch; apitch = vidix_play.dest.pitch.u-1; dstrides.u = (image_width + apitch) & ~apitch; image_Bpp=1; break; case IMGFMT_RGB32: case IMGFMT_BGR32: apitch = vidix_play.dest.pitch.y-1; dstrides.y = (image_width*4 + apitch) & ~apitch; dstrides.u = dstrides.v = 0; image_Bpp=4; break; case IMGFMT_RGB24: case IMGFMT_BGR24: apitch = vidix_play.dest.pitch.y-1; dstrides.y = (image_width*3 + apitch) & ~apitch; dstrides.u = dstrides.v = 0; image_Bpp=3; break; default: apitch = vidix_play.dest.pitch.y-1; dstrides.y = (image_width*2 + apitch) & ~apitch; dstrides.u = dstrides.v = 0; image_Bpp=2; break; } /* tune some info here */ sstride = src_width*image_Bpp; if(!forced_fourcc) { is_422_planes_eq = sstride == dstrides.y; if(src_format == IMGFMT_YV12 || src_format == IMGFMT_I420 || src_format == IMGFMT_IYUV) vo_server->draw_slice = vidix_draw_slice_420; else if (src_format == IMGFMT_YVU9 || src_format == IMGFMT_IF09) vo_server->draw_slice = vidix_draw_slice_410; else vo_server->draw_slice = vidix_draw_slice_packed; } return 0; } static uint32_t vidix_get_image(mp_image_t *mpi) { if(mpi->type==MP_IMGTYPE_STATIC && vidix_play.num_frames>1) return VO_FALSE; if(mpi->flags&MP_IMGFLAG_READABLE) return VO_FALSE; /* slow video ram */ if(( (mpi->stride[0]==dstrides.y && (!(mpi->flags&MP_IMGFLAG_PLANAR) || (mpi->stride[1]==dstrides.u && mpi->stride[2]==dstrides.v)) ) || (mpi->flags&(MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_ACCEPT_WIDTH))) && (!forced_fourcc && !(vidix_play.flags & VID_PLAY_INTERLEAVED_UV))) { if(mpi->flags&MP_IMGFLAG_ACCEPT_WIDTH){ // check if only width is enough to represent strides: if(mpi->flags&MP_IMGFLAG_PLANAR){ if((dstrides.y>>1)!=dstrides.v || dstrides.v!=dstrides.u) return VO_FALSE; } else { if(dstrides.y % (mpi->bpp/8)) return VO_FALSE; } } mpi->planes[0]=vidix_mem+vidix_play.offsets[next_frame]+vidix_play.offset.y; mpi->width=mpi->stride[0]=dstrides.y; if(mpi->flags&MP_IMGFLAG_PLANAR) { mpi->planes[1]=vidix_mem+vidix_play.offsets[next_frame]+vidix_play.offset.v; mpi->stride[1]=dstrides.v >> mpi->chroma_x_shift; mpi->planes[2]=vidix_mem+vidix_play.offsets[next_frame]+vidix_play.offset.u; mpi->stride[2]=dstrides.u >> mpi->chroma_x_shift; } else mpi->width/=mpi->bpp/8; mpi->flags|=MP_IMGFLAG_DIRECT; return VO_TRUE; } return VO_FALSE; } uint32_t vidix_control(uint32_t request, void *data, ...) { switch (request) { case VOCTRL_QUERY_FORMAT: return vidix_query_fourcc(*((uint32_t*)data)); case VOCTRL_GET_IMAGE: return vidix_get_image(data); case VOCTRL_DRAW_IMAGE: return vidix_draw_image(data); case VOCTRL_GET_FRAME_NUM: *(uint32_t *)data = next_frame; return VO_TRUE; case VOCTRL_SET_FRAME_NUM: next_frame = *(uint32_t *)data; return VO_TRUE; case VOCTRL_GET_NUM_FRAMES: *(uint32_t *)data = vidix_play.num_frames; return VO_TRUE; case VOCTRL_SET_EQUALIZER: { va_list ap; int value; vidix_video_eq_t info; if(!video_on) return VO_FALSE; va_start(ap, data); value = va_arg(ap, int); va_end(ap); // printf("vidix seteq %s -> %d \n",data,value); /* vidix eq ranges are -1000..1000 */ if (!strcasecmp(data, "brightness")) { info.brightness = value*10; info.cap = VEQ_CAP_BRIGHTNESS; } else if (!strcasecmp(data, "contrast")) { info.contrast = value*10; info.cap = VEQ_CAP_CONTRAST; } else if (!strcasecmp(data, "saturation")) { info.saturation = value*10; info.cap = VEQ_CAP_SATURATION; } else if (!strcasecmp(data, "hue")) { info.hue = value*10; info.cap = VEQ_CAP_HUE; } if (vdlPlaybackSetEq(vidix_handler, &info) == 0) return VO_TRUE; return VO_FALSE; } case VOCTRL_GET_EQUALIZER: { va_list ap; int *value; vidix_video_eq_t info; if(!video_on) return VO_FALSE; if (vdlPlaybackGetEq(vidix_handler, &info) != 0) return VO_FALSE; va_start(ap, data); value = va_arg(ap, int*); va_end(ap); /* vidix eq ranges are -1000..1000 */ if (!strcasecmp(data, "brightness")) { if (info.cap & VEQ_CAP_BRIGHTNESS) *value = info.brightness/10; } else if (!strcasecmp(data, "contrast")) { if (info.cap & VEQ_CAP_CONTRAST) *value = info.contrast/10; } else if (!strcasecmp(data, "saturation")) { if (info.cap & VEQ_CAP_SATURATION) *value = info.saturation/10; } else if (!strcasecmp(data, "hue")) { if (info.cap & VEQ_CAP_HUE) *value = info.hue/10; } return VO_TRUE; } } return VO_NOTIMPL; // WARNING: we drop extra parameters (...) here! // return server_control(request,data); //VO_NOTIMPL; } int vidix_preinit(const char *drvname,void *server) { int err; if(verbose > 1) printf("vosub_vidix: vidix_preinit(%s) was called\n",drvname); if(vdlGetVersion() != VIDIX_VERSION) { printf("vosub_vidix: You have wrong version of VIDIX library\n"); return -1; } #ifndef __MINGW32__ vidix_handler = vdlOpen(MPLAYER_LIBDIR "/mplayer/vidix/", drvname ? drvname[0] == ':' ? &drvname[1] : drvname[0] ? drvname : NULL : NULL, TYPE_OUTPUT, verbose); #else vidix_handler = vdlOpen(get_path("vidix/"), drvname ? drvname[0] == ':' ? &drvname[1] : drvname[0] ? drvname : NULL : NULL, TYPE_OUTPUT, verbose); #endif if(vidix_handler == NULL) { printf("vosub_vidix: Couldn't find working VIDIX driver\n"); return -1; } if((err=vdlGetCapability(vidix_handler,&vidix_cap)) != 0) { printf("vosub_vidix: Couldn't get capability: %s\n",strerror(err)); return -1; } printf("VIDIX: Description: %s\n", vidix_cap.name); printf("VIDIX: Author: %s\n", vidix_cap.author); /* we are able to tune up this stuff depend on fourcc format */ ((vo_functions_t *)server)->draw_slice=vidix_draw_slice; ((vo_functions_t *)server)->draw_frame=vidix_draw_frame; ((vo_functions_t *)server)->flip_page=vidix_flip_page; ((vo_functions_t *)server)->draw_osd=vidix_draw_osd; // server_control = ((vo_functions_t *)server)->control; // ((vo_functions_t *)server)->control=vidix_control; vo_server = server; return 0; }