unichrome_vid.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 982 行 · 第 1/2 页

C
982
字号
	      dname = dname ? dname : "Unknown chip";	      printf ("[unichrome] Found chip: %s\n", dname);	      if ((lst[i].command & PCI_COMMAND_IO) == 0)		{		  printf ("[unichrome] Device is disabled, ignoring\n");		  continue;		}	      uc_cap.device_id = lst[i].device;	      err = 0;	      memcpy (&pci_info, &lst[i], sizeof (pciinfo_t));	      break;	    }	}    }  if (err && verbose)    printf ("[unichrome] Can't find chip\n");  return err;}/** * @brief Initializes driver. * * @returns 0 if ok. *          a negative error code otherwise. */static intunichrome_init (void){  long tmp;  uc_mem = map_phys_mem (pci_info.base0, VIDEOMEMORY_SIZE);  enable_app_io ();  outb (0x2f, 0x3c4);  tmp = inb (0x3c5) << 0x18;  vio = map_phys_mem (tmp, 0x1000);  outb (0x16, 0x3c4);  mclk_save[0] = inb (0x3c5);  outb (0x17, 0x3c4);  mclk_save[1] = inb (0x3c5);  outb (0x18, 0x3c4);  mclk_save[2] = inb (0x3c5);  uc_grkey.ckey.blue = 0x00;  uc_grkey.ckey.green = 0x00;  uc_grkey.ckey.red = 0x00;  /* Detect whether we have a CLE266Ax or CLE266Cx */  outb (0x4f, 0x3d4);  tmp = inb (0x3d5);  outb (0x4f, 0x3d4);  outb (0x55, 0x3d5);  outb (0x4f, 0x3d4);  if (0x55 == inb (0x3d5))  {    /* Only CLE266Cx supports CR4F */    hwrev = 0x11;  }  else  {    /* Otherwise assume to be a CLE266Ax */    hwrev = 0x00;  }  outb (0x4f, 0x3d4);  outb (tmp, 0x3d5);#ifdef DEBUG_LOGFILE  logfile = fopen ("/tmp/uc_vidix.log", "w");#endif  return 0;}/** * @brief Destroys driver. */static voidunichrome_destroy (void){#ifdef DEBUG_LOGFILE  if (logfile)    fclose (logfile);#endif  outb (0x16, 0x3c4);  outb (mclk_save[0], 0x3c5);  outb (0x17, 0x3c4);  outb (mclk_save[1], 0x3c5);  outb (0x18, 0x3c4);  outb (mclk_save[2], 0x3c5);  disable_app_io ();  unmap_phys_mem (uc_mem, VIDEOMEMORY_SIZE);  unmap_phys_mem (vio, 0x1000);}/** * @brief Get chipset's hardware capabilities. * * @param to Pointer to the vidix_capability_t structure to be filled. * * @returns 0. */static intunichrome_get_caps (vidix_capability_t * to){  memcpy (to, &uc_cap, sizeof (vidix_capability_t));  return 0;}/** * @brief Report if the video FourCC is supported by hardware. * * @param fourcc input image format. * * @returns 1 if the fourcc is supported. *          0 otherwise. */static intis_supported_fourcc (uint32_t fourcc){  switch (fourcc)    {    case IMGFMT_YV12:    case IMGFMT_I420:    case IMGFMT_UYVY:    case IMGFMT_YVYU:    case IMGFMT_YUY2:    case IMGFMT_BGR15:    case IMGFMT_BGR16:    case IMGFMT_BGR32:      return 1;    default:      return 0;    }}/** * @brief Try to configure video memory for given fourcc. * * @param to Pointer to the vidix_fourcc_t structure to be filled. * * @returns 0 if ok. *          errno otherwise. */static intunichrome_query_fourcc (vidix_fourcc_t * to){  if (is_supported_fourcc (to->fourcc))    {      to->depth = VID_DEPTH_ALL;      to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY;      return 0;    }  else    to->depth = to->flags = 0;  return ENOSYS;}/** * @brief Get the GrKeys * * @param grkey Pointer to the vidix_grkey_t structure to be filled by driver. * * @return 0. */static intunichrome_get_gkey (vidix_grkey_t * grkey){  memcpy (grkey, &uc_grkey, sizeof (vidix_grkey_t));  return (0);}/** * @brief Set the GrKeys * * @param grkey Colorkey to be set. * * @return 0. */static intunichrome_set_gkey (const vidix_grkey_t * grkey){  unsigned long dwCompose = VIDEO_IN (vio, V_COMPOSE_MODE) & ~0x0f;  memcpy (&uc_grkey, grkey, sizeof (vidix_grkey_t));  if (uc_grkey.ckey.op != CKEY_FALSE)    {      /* Set colorkey (how do I detect BPP in hardware ??) */      unsigned long ckey;      if (1) /* Assume 16-bit graphics */	{	  ckey = (grkey->ckey.blue & 0x1f)	    | ((grkey->ckey.green & 0x3f) << 5)	    | ((grkey->ckey.red & 0x1f) << 11);	}      else	{	  ckey = (grkey->ckey.blue)	    | (grkey->ckey.green << 8) | (grkey->ckey.red << 16);	}      VIDEO_OUT (vio, V_COLOR_KEY, ckey);      dwCompose |= SELECT_VIDEO_IF_COLOR_KEY;    }  /* Execute the changes */  VIDEO_OUT (vio, V_COMPOSE_MODE, dwCompose | V1_COMMAND_FIRE);  return (0);}/** * @brief Unichrome driver equalizer capabilities. */static vidix_video_eq_t equal = {  VEQ_CAP_BRIGHTNESS | VEQ_CAP_SATURATION | VEQ_CAP_HUE,  300, 100, 0, 0, 0, 0, 0, 0};/** * @brief Get the equalizer capabilities. * * @param eq Pointer to the vidix_video_eq_t structure to be filled by driver. * * @return 0. */static intunichrome_get_eq (vidix_video_eq_t * eq){  memcpy (eq, &equal, sizeof (vidix_video_eq_t));  return 0;}/** * @brief Set the equalizer capabilities for color correction * * @param eq equalizer capabilities to be set. * * @return 0. */static intunichrome_set_eq (const vidix_video_eq_t * eq){  return 0;}/** * @brief Y, U, V offsets. */static int YOffs, UOffs, VOffs;static int unichrome_frame_select (unsigned int frame);/** * @brief Configure driver for playback. Driver should prepare BES. * * @param info configuration description for playback. * * @returns  0 in case of success. *          -1 otherwise. */static intunichrome_config_playback (vidix_playback_t * info){  int src_w, drw_w;  int src_h, drw_h;  long base0, pitch = 0;  int uv_size = 0, swap_uv;  unsigned int i;  int extfifo_on;  /* Overlay register settings */  uint32_t win_start, win_end;  uint32_t zoom, mini;  uint32_t dcount, falign, qwfetch;  uint32_t v_ctrl, fifo_ctrl;  if (!is_supported_fourcc (info->fourcc))    return -1;  src_w = info->src.w;  src_h = info->src.h;  drw_w = info->dest.w;  drw_h = info->dest.h;  /* Setup FIFO */  uc_ovl_setup_fifo (&extfifo_on, src_w);  /* Get image format, FIFO size, etc. */  uc_ovl_map_v1_control (info->fourcc, src_w, hwrev, extfifo_on,			 &v_ctrl, &fifo_ctrl);  /* Setup layer window */  win_start = (info->dest.x << 16) | info->dest.y;  win_end = ((info->dest.x + drw_w - 1) << 16) | (info->dest.y + drw_h - 1);  /* Get scaling and data-fetch parameters */  zoom = 0;  mini = 0;  uc_ovl_map_vzoom (src_h, drw_h, &zoom, &mini);  uc_ovl_map_hzoom (src_w, drw_w, &zoom, &mini, (int *) &falign, (int *) &dcount);  qwfetch = uc_ovl_map_qwfetch (info->fourcc, src_w);  /* Calculate buffer sizes */  swap_uv = 0;  switch (info->fourcc)    {    case IMGFMT_YV12:      swap_uv = 1;    case IMGFMT_I420:    case IMGFMT_UYVY:    case IMGFMT_YVYU:      pitch = ALIGN_TO (src_w, 32);      uv_size = (pitch >> 1) * (src_h >> 1);      break;    case IMGFMT_YUY2:    case IMGFMT_BGR15:    case IMGFMT_BGR16:      pitch = ALIGN_TO (src_w << 1, 32);      uv_size = 0;      break;    case IMGFMT_BGR32:      pitch = ALIGN_TO (src_w << 2, 32);      uv_size = 0;      break;    }  if ((src_w > 4096) || (src_h > 4096) ||      (src_w < 32) || (src_h < 1) || (pitch > 0x1fff))    {      printf ("[unichrome] Layer size out of bounds\n");    }  /* Calculate offsets */  info->offset.y = 0;  info->offset.v = info->offset.y + pitch * src_h;  info->offset.u = info->offset.v + uv_size;  info->frame_size = info->offset.u + uv_size;  YOffs = info->offset.y;  UOffs = (swap_uv ? info->offset.v : info->offset.u);  VOffs = (swap_uv ? info->offset.u : info->offset.v);  /* Assume we have 2 MB to play with */  info->num_frames = FRAMEBUFFER_SIZE / info->frame_size;  if (info->num_frames > VID_PLAY_MAXFRAMES)    info->num_frames = VID_PLAY_MAXFRAMES;  /* Start at 6 MB. Let's hope it's not in use. */  base0 = FRAMEBUFFER_START;  info->dga_addr = uc_mem + base0;  info->dest.pitch.y = 32;  info->dest.pitch.u = 32;  info->dest.pitch.v = 32;  for (i = 0; i < info->num_frames; i++)    {      info->offsets[i] = info->frame_size * i;      frames[i] = base0 + info->offsets[i];    }  /* Write to the hardware */  uc_ovl_vcmd_wait (vio);  /* Configure diy_pitchlay parameters now */  if (v_ctrl & V1_COLORSPACE_SIGN)    {      if (hwrev >= 0x10)	{	  VIDEO_OUT (vio, V1_ColorSpaceReg_2, ColorSpaceValue_2_3123C0);	  VIDEO_OUT (vio, V1_ColorSpaceReg_1, ColorSpaceValue_1_3123C0);	}      else	{      VIDEO_OUT (vio, V1_ColorSpaceReg_2, ColorSpaceValue_2);      VIDEO_OUT (vio, V1_ColorSpaceReg_1, ColorSpaceValue_1);    }    }  VIDEO_OUT (vio, V1_CONTROL, v_ctrl);  VIDEO_OUT (vio, V_FIFO_CONTROL, fifo_ctrl);  VIDEO_OUT (vio, V1_WIN_START_Y, win_start);  VIDEO_OUT (vio, V1_WIN_END_Y, win_end);  VIDEO_OUT (vio, V1_SOURCE_HEIGHT, (src_h << 16) | dcount);  VIDEO_OUT (vio, V12_QWORD_PER_LINE, qwfetch << 20);  VIDEO_OUT (vio, V1_STRIDE, pitch | ((pitch >> 1) << 16));  VIDEO_OUT (vio, V1_MINI_CONTROL, mini);  VIDEO_OUT (vio, V1_ZOOM_CONTROL, zoom);  /* Configure buffer address and execute the changes now! */  unichrome_frame_select (0);  return 0;}/** * @brief Set playback on : driver should activate BES on this call. * * @return 0. */static intunichrome_playback_on (void){  LOGWRITE ("Enable overlay\n");  /* Turn on overlay */  VIDEO_OUT (vio, V1_CONTROL, VIDEO_IN (vio, V1_CONTROL) | V1_ENABLE);  /* Execute the changes */  VIDEO_OUT (vio, V_COMPOSE_MODE,	     VIDEO_IN (vio, V_COMPOSE_MODE) | V1_COMMAND_FIRE);  return 0;}/** * @brief Set playback off : driver should deactivate BES on this call. * * @return 0. */static intunichrome_playback_off (void){  LOGWRITE ("Disable overlay\n");  uc_ovl_vcmd_wait (vio);  /* Restore FIFO */  VIDEO_OUT (vio, V_FIFO_CONTROL, UC_MAP_V1_FIFO_CONTROL (16, 12, 8));  /* Turn off overlay */  VIDEO_OUT (vio, V1_CONTROL, VIDEO_IN (vio, V1_CONTROL) & ~V1_ENABLE);  /* Execute the changes */  VIDEO_OUT (vio, V_COMPOSE_MODE,	     VIDEO_IN (vio, V_COMPOSE_MODE) | V1_COMMAND_FIRE);  return 0;}/** * @brief Driver should prepare and activate corresponded frame. * * @param frame the frame index. * * @return 0. * * @note This function is used only for double and triple buffering *       and never used for single buffering playback. */static intunichrome_frame_select (unsigned int frame){  LOGWRITE ("Frame select\n");  uc_ovl_vcmd_wait (vio);  /* Configure buffer address */  VIDEO_OUT (vio, V1_STARTADDR_Y0, frames[frame] + YOffs);  VIDEO_OUT (vio, V1_STARTADDR_CB0, frames[frame] + UOffs);  VIDEO_OUT (vio, V1_STARTADDR_CR0, frames[frame] + VOffs);  /* Execute the changes */  VIDEO_OUT (vio, V_COMPOSE_MODE,	     VIDEO_IN (vio, V_COMPOSE_MODE) | V1_COMMAND_FIRE);  return 0;}VDXDriver unichrome_drv = {  "unichrome",  NULL,  .probe = unichrome_probe,  .get_caps = unichrome_get_caps,  .query_fourcc = unichrome_query_fourcc,  .init = unichrome_init,  .destroy = unichrome_destroy,  .config_playback = unichrome_config_playback,  .playback_on = unichrome_playback_on,  .playback_off = unichrome_playback_off,  .frame_sel = unichrome_frame_select,  .get_eq = unichrome_get_eq,  .set_eq = unichrome_set_eq,  .get_gkey = unichrome_get_gkey,  .set_gkey = unichrome_set_gkey,};

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?