int
queryVideoDevice (int idx, VideoDeviceDesc * vd_desc)
{
  VS_FLOW ("Fun %s in\n", __FUNCTION__);
  VideoDevice *vd;

  if ((idx < 0) || (idx >= VD_MAX) || (vd_desc == NULL))
    goto bail;



  if (gVSctl == NULL) {
    gVSlock = _getAndLockVSLock (VS_IPC_CREATE);
    if (gVSlock == NULL) {
      VS_ERROR ("Can not create/open ipc semphone!\n");
      goto bail;
    }

    gVSctl = _getVSControl (VS_IPC_CREATE);
    if (gVSctl == NULL) {
      VS_ERROR ("Can not create/open ipc sharememory!\n");
      VS_UNLOCK (gVSlock);
      goto bail;
    }
  } else {

    VS_LOCK (gVSlock);
  }


  vd = &gVSctl->devices[idx];

  vd_desc->resx = vd->resX;
  vd_desc->resy = vd->resY;

  if (vd->fbidx >= 0) {

    int i;

    vd_desc->devid = vd->fbidx;
    vd_desc->custom_mode_num = vd->mode_num;
    memcpy (vd_desc->name, vd->name, NAME_LEN);
    for (i = 0; i < vd_desc->custom_mode_num; i++) {
      vd_desc->modes[i] = vd->modes[i];
    }
  } else {
    VS_UNLOCK (gVSlock);
    goto bail;
  }


  VS_UNLOCK (gVSlock);

  return 0;
bail:
  return -1;
}
VideoSurfacesControl *
_getVSControl (int flag)
{
  VS_FLOW ("Fun %s in\n", __FUNCTION__);

  VideoSurfacesControl *control;
  int shmid;
  struct stat shmStat;
  int ret;

  int oflag = O_RDWR;
  if (flag & VS_IPC_CREATE)
    oflag |= O_CREAT;
  if (flag & VS_IPC_EXCL)
    oflag |= O_EXCL;

  shmid = shm_open (VS_SHMEM_NAME, oflag, 0666);

  if (shmid == -1) {
    VS_ERROR ("%s: can not get share memory %s!\n", __FUNCTION__,
        VS_SHMEM_NAME);
    goto err;
  }

  ret = ftruncate (shmid, (off_t) (3 * sizeof (VideoSurfacesControl)));
  if (ret < 0) {
    goto err;
  }
  /* Connect to the shm */
  fstat (shmid, &shmStat);

  control =
      (VideoSurfacesControl *) mmap (NULL, shmStat.st_size,
      PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
  if ((control == NULL) || (control == MAP_FAILED)) {
    VS_ERROR ("%s: can not mmap share memory %d!\n", __FUNCTION__, shmid);
    goto err;
  }

  if (control->init == 0) {
    _initVSControl (control);
    control->init = 1;
  }

  return control;
err:
  return NULL;
}
int
_openDevice (VideoDevice * vd)
{
  FILE *pfb1_mode;
  char buf[100];
  if (vd->mode_num) {
    sprintf (buf, "/sys/class/graphics/fb%d/mode", vd->fbidx);
    pfb1_mode = fopen (buf, "w");
    if (pfb1_mode == NULL) {
      VS_ERROR ("No /sys/class/graphics/fb1/mode device to open\n");
      goto error;
    }

    video_mode_to_str (buf, &vd->modes[vd->current_mode]);

    fwrite (buf, 1, strlen (buf), pfb1_mode);
    fflush (pfb1_mode);
    fclose (pfb1_mode);
  }

  return 0;

error:
  return -1;
}
VSLock *
_getAndLockVSLock (int flag)
{
  VS_FLOW ("Fun %s in\n", __FUNCTION__);

  VSLock *lock;

  int oflag = 0;
  if (flag & VS_IPC_CREATE)
    oflag |= O_CREAT;

  if (flag & VS_IPC_EXCL)
    oflag |= O_EXCL;

  umask (0);

  lock = sem_open (VS_LOCK_NAME, oflag, 0666, 1);

  if (SEM_FAILED == lock) {
    VS_ERROR ("%s: can not get lock %s!\n", __FUNCTION__, VS_LOCK_NAME);
    goto err;
  }

  VS_LOCK (lock);

  return lock;
err:
  return NULL;
}
Beispiel #5
0
/*=============================================================================
FUNCTION:           render2VideoSurface

DESCRIPTION:        This function render a new frame on specific video surface
                    It also will refresh other video surfaces in same video device
                    automaticallly.
==============================================================================*/
VSFlowReturn 
render2VideoSurface(void * vshandle, SourceFrame * frame, SourceFmt * srcfmt)
{
    VS_FLOW("Fun %s in\n", __FUNCTION__);

    VideoDevice * vd;
    VideoSurface * vsurface, *vsurface1;
    Updated updated;

    if ((vshandle==NULL)||(frame==NULL)){
        VS_ERROR("%s: parameters error!\n", __FUNCTION__);
        return VS_FLOW_PARAMETER_ERROR;
    }

    vsurface = (VideoSurface *)vshandle;

    if (vsurface->status == VS_STATUS_INVISIBLE) /* no need to render */
        return VS_FLOW_OK;
    
    vsurface->paddr = frame->paddr;
    vsurface->rendmask = 0;/*clear mask*/
    
    vd = SURFACE2DEVICE(vsurface);

    if (sem_trywait(gVSlock))
        return VS_FLOW_PENDING;



    vsurface1 = DEVICE2HEADSURFACE(vd);

    memset((void *)(&updated), 0, sizeof(Updated));
    while(vsurface1){
        if (_needRender(vsurface1, &updated, vd->renderidx)){
            _renderSuface(vsurface1, vd, &updated);
        }
        vsurface1 = NEXTSURFACE(vsurface1);
    };

    _FlipOnDevice(vd);

#if 0 /* no need to sleep anymore */
    if (vd->cnt>1)
        usleep(10000);
#endif

done:
    VS_UNLOCK(gVSlock);

    VS_FLOW("Fun %s out\n", __FUNCTION__);
    return VS_FLOW_OK;
err:
    return VS_FLOW_ERROR;
}
int
_setAlpha (VideoDevice * vd)
{

  int fd;
  void *alpha_buf0, *alpha_buf1;
  unsigned long loc_alpha_phy_addr0;
  unsigned long loc_alpha_phy_addr1;

  struct mxcfb_loc_alpha l_alpha;

  unsigned long l_alpha_buf_size;


  //return 0;

  fd = _getDevicefd (vd);

  if (0) {                      //(vd->cnt==1){
    struct mxcfb_gbl_alpha g_alpha;
    printf ("set global alpha\n");
    g_alpha.alpha = ALPHA_SOLID;
    g_alpha.enable = 1;
    VS_IOCTL (fd, MXCFB_SET_GBL_ALPHA, done, &g_alpha);
  } else {

    l_alpha.enable = 1;
    l_alpha.alpha_in_pixel = 0;
    l_alpha.alpha_phy_addr0 = 0;
    l_alpha.alpha_phy_addr1 = 0;


    VS_IOCTL (fd, MXCFB_SET_LOC_ALPHA, done, &l_alpha);



    l_alpha_buf_size =
        (vd->disp.right - vd->disp.left) * (vd->disp.bottom - vd->disp.top);

    loc_alpha_phy_addr0 = (unsigned long) (l_alpha.alpha_phy_addr0);
    loc_alpha_phy_addr1 = (unsigned long) (l_alpha.alpha_phy_addr1);

    alpha_buf0 = mmap (0, l_alpha_buf_size,
        PROT_READ | PROT_WRITE, MAP_SHARED, fd, loc_alpha_phy_addr0);
    if ((int) alpha_buf0 == -1) {
      VS_ERROR ("Error: failed to map alpha buffer 0" " to memory.\n");
      goto done;
    }
    alpha_buf1 = mmap (0, l_alpha_buf_size,
        PROT_READ | PROT_WRITE, MAP_SHARED, fd, loc_alpha_phy_addr1);
    if ((int) alpha_buf1 == -1) {
      VS_ERROR ("Error: failed to map alpha buffer 1" " to memory.\n");
      munmap ((void *) alpha_buf0, l_alpha_buf_size);
      return -1;
    }

    memset (alpha_buf0, ALPHA_TRANSPARENT, l_alpha_buf_size);
    memset (alpha_buf1, ALPHA_TRANSPARENT, l_alpha_buf_size);

    _fillDeviceLocalAlphaBuf (vd, alpha_buf0, alpha_buf1);
    munmap (alpha_buf0, l_alpha_buf_size);
    munmap (alpha_buf1, l_alpha_buf_size);
  }
done:
  return 0;
}
/*=============================================================================
FUNCTION:           createVideoSurface

DESCRIPTION:        This function create a video surface.
==============================================================================*/
void *
createVideoSurface (int devid, int mode_idx, SourceFmt * src,
    DestinationFmt * des)
{
  VS_FLOW ("Fun %s in\n", __FUNCTION__);

  VideoSurfacesControl *vc;
  VideoSurface *vs = NULL;
  VideoDevice *vd;
  int i;

  if (_checkSource (src)) {
    VS_ERROR ("source fmt error\n");
    goto err;
  }

  if ((des == NULL) || (src == NULL)) {
    VS_ERROR ("%s: parameters error!\n", __FUNCTION__);
    goto err;
  }

  if (gVSctl == NULL) {
    gVSlock = _getAndLockVSLock (VS_IPC_CREATE);
    if (gVSlock == NULL) {
      VS_ERROR ("Can not create/open ipc semphone!\n");
      goto err;
    }

    gVSctl = _getVSControl (VS_IPC_CREATE);
    if (gVSctl == NULL) {
      VS_ERROR ("Can not create/open ipc sharememory!\n");
      VS_UNLOCK (gVSlock);
      goto err;
    }
  } else {

    VS_LOCK (gVSlock);
  }

  vc = gVSctl;

  if ((vd = _getDevicebyDevID (devid)) == NULL) {
    VS_ERROR ("Can not find dev id %d!\n", devid);
    VS_UNLOCK (gVSlock);
    goto err;
  }

  if (vd->cnt >= vd->vsmax) {
    VS_UNLOCK (gVSlock);
    VS_ERROR ("%s: max surfaces on device support on device%d exceeded!\n",
        __FUNCTION__, devid);
    goto err;
  }

  for (i = 0; i < VS_MAX; i++) {
    if (vc->surfaces[i].status == VS_STATUS_IDLE) {
      break;
    }
  }

  if (i == VS_MAX) {
    VS_UNLOCK (gVSlock);
    VS_ERROR ("%s: max surface support exceeded!\n", __FUNCTION__);
    goto err;
  }

  vs = &vc->surfaces[i];
  vs->status = VS_STATUS_VISIBLE;
  vs->vd_id = vd->id;
  vs->srcfmt = *src;
  vs->desfmt = *des;

  vs->itask.mode = 0;
  vs->mainframeupdate = 1;

  memset (&vs->itask, 0, sizeof (IPUTaskOne));

  if (vd->init == 0) {
    if (_initVideoDevice (vd, mode_idx)) {
      VS_UNLOCK (gVSlock);
      VS_ERROR ("%s: error config!\n", __FUNCTION__);
      goto err;
    }

  }

  vs->outside = _adjustDestRect (&des->rect, vd);
  vs->adjustdesrect = des->rect;

  VS_MESSAGE ("VS%d created. in fmt[" FOURCC_FMT "] win" WIN_FMT " out win"
      WIN_FMT "\n", vs->id - 1, FOURCC_ARGS (src->fmt),
      WIN_ARGS (&src->croprect.win), WIN_ARGS (&vs->desfmt.rect));

  vs->next = gvslocal;
  gvslocal = vs;

  vd->cnt++;

  if (vd->cnt == 1) {
    _openDevice (vd);

  }
  _addVideoSurface2Device (vd, vs);

  if (_checkOnDevice (vd)) {
    _reconfigAllVideoSurfaces (vd);
    _setDeviceConfig (vd);
  }

  vd->init = 1;
  _initVSIPUTask (vs);

  if (vd->setalpha)
    _setAlpha (vd);

  VS_UNLOCK (gVSlock);
  VS_FLOW ("Fun %s out\n", __FUNCTION__);

  return (void *) vs;
err:
  if (vs) {
    vs->status = VS_STATUS_IDLE;
  }
  return NULL;
}