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)
{
  void *tmp, *tmpa;
  size_t i;
  int err;
  uint32_t sstride,apitch;
  if( mp_msg_test(MSGT_VO,MSGL_DBG2) )
     mp_msg(MSGT_VO,MSGL_DBG2, "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)
	{
	  mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SUB_VIDIX_UnsupportedFourccForThisVidixDriver,
	    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)))
	{
	  mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SUB_VIDIX_VideoServerHasUnsupportedResolution,
	    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)
	{
	  mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SUB_VIDIX_VideoServerHasUnsupportedColorDepth
	  ,vidix_fourcc.depth);
	  return -1;
	}
	if((dst_width > src_width || dst_height > src_height) && (vidix_cap.flags & FLAG_UPSCALER) != FLAG_UPSCALER)
	{
	  mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SUB_VIDIX_DriverCantUpscaleImage,
	  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)
	{
	  mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SUB_VIDIX_DriverCantDownscaleImage,
	  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)
	{
 		mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SUB_VIDIX_CantConfigurePlayback,strerror(err));
		return -1;
	}
	if ( mp_msg_test(MSGT_VO,MSGL_V) ) {
		mp_msg(MSGT_VO,MSGL_V, "vosub_vidix: using %d buffer(s)\n", vidix_play.num_frames); }

	vidix_mem = vidix_play.dga_addr;

	tmp = calloc(image_width, image_height);
	tmpa = malloc(image_width * image_height);
	memset(tmpa, 1, image_width * image_height);
	/* clear every frame with correct address and frame_size */
	/* HACK: use draw_alpha to clear Y component */
	for (i = 0; i < vidix_play.num_frames; i++) {
	    next_frame = i;
	    memset(vidix_mem + vidix_play.offsets[i], 0x80,
		vidix_play.frame_size);
	    draw_alpha(0, 0, image_width, image_height, tmp, tmpa, image_width);
	}
	free(tmp);
	free(tmpa);
	/* show one of the "clear" frames */
	vidix_flip_page();

	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;
}
/* ----------------------------------------------------------------------------
 */
void cVidixVideoOut::AllocLayer(void)
{
    int       err;
    uint8_t   *dst;
    uint32_t  apitch;

  if (currentPixelFormat == 2)
    vidix_play.src.pitch.y *= 2;

  if ((err = vdlPlaybackOff(vidix_handler)) != 0)
  {
    softlog->Log(SOFT_LOG_ERROR, 0,
              "[cVidixVideoOut] Can't stop playback: %s exiting\n",
              strerror(err));
    exit(1);
  }

  if ((err = vdlConfigPlayback(vidix_handler, &vidix_play)) != 0)
  {
    softlog->Log(SOFT_LOG_ERROR, 0,
               "[cVidixVideoOut] Can't configure playback: %s exiting\n",
               strerror(err));
    exit(1);
  }

  if ((err = vdlPlaybackOn(vidix_handler)) != 0)
  {
    softlog->Log(SOFT_LOG_ERROR, 0,
              "[cVidixVideoOut] Can't start playback: %s exiting\n",
              strerror(err));
    exit(1);
  }

  if (vidix_fourcc.flags & VID_CAP_COLORKEY)
  {
    int res = 0;

    softlog->Log(SOFT_LOG_INFO, 0,
              "[cVidixVideoOut] set colorkey\n");
    vdlGetGrKeys(vidix_handler, &gr_key);

    gr_key.key_op = KEYS_PUT;
#ifdef CKEY_ALPHA
    if (vidix_fourcc.flags & VID_CAP_BLEND) {
      useVidixAlpha = true;
      gr_key.ckey.op = CKEY_ALPHA;
    } else {
      gr_key.ckey.op = CKEY_TRUE;
    }
#else
    gr_key.ckey.op = CKEY_TRUE;
#endif
    gr_key.ckey.red = gr_key.ckey.green = gr_key.ckey.blue = 0;
    res = vdlSetGrKeys(vidix_handler, &gr_key);
    softlog->Log(SOFT_LOG_INFO, 0,
              "[cVidixVideoOut] vdlSetGrKeys() = %d\n", res);

    if (res) {
      gr_key.ckey.op = CKEY_TRUE;
      res = vdlSetGrKeys(vidix_handler, &gr_key);
      softlog->Log(SOFT_LOG_INFO, 0,
                "[cVidixVideoOut] vdlSetGrKeys() = %d (noAlpha)\n", res);
      useVidixAlpha = false;
    }
  }

  next_frame = 0;

  apitch     = vidix_play.dest.pitch.y-1;
  dstrides.y = (swidth + apitch) & ~apitch;

  apitch     = vidix_play.dest.pitch.v-1;
  dstrides.v = (swidth + apitch) & ~apitch;

  apitch     = vidix_play.dest.pitch.u-1;
  dstrides.u = (swidth + apitch) & ~apitch;

  // clear every frame
  for (uint8_t i = 0; i < vidix_play.num_frames; i++)
  {
    dst = (uint8_t *) vidix_play.dga_addr + vidix_play.offsets[i] +
                      vidix_play.offset.y;
    if (currentPixelFormat == 2)
    {
        int *ldst = (int *) dst;

      for (unsigned int j = 0; j < dstrides.y * sheight/2; j++)
      {
        *ldst++ = 0x80008000;
      }
    }
    else
    {
      memset(dst, 0x00, dstrides.y * sheight);

      dst = (uint8_t *) vidix_play.dga_addr + vidix_play.offsets[i] +
                        vidix_play.offset.u;
      memset(dst, 0x80, (dstrides.u/2) * (sheight/2));

      dst = (uint8_t *) vidix_play.dga_addr + vidix_play.offsets[i] +
                        vidix_play.offset.v;
      memset(dst, 0x80, (dstrides.v/2) * (sheight/2));
    }
  }

}