コード例 #1
0
VSFlowReturn
_configDeinterlace (void *vshandle, void *config)
{
  VS_FLOW ("Fun %s in\n", __FUNCTION__);

  VideoSurface *vs;
  vs = (VideoSurface *) vshandle;
  int *mode = (int *) config;

  VS_LOCK (gVSlock);

  VS_MESSAGE ("set deinterlace mode %d\n", *mode);

  if (*mode) {
    INPUT_ENABLE_DEINTERLACE (&vs->itask);
  } else {
    INPUT_DISABLE_DEINTERLACE (&vs->itask);
  }

  INPUT_DEINTERLACE_MODE (&vs->itask) = *mode;

  VS_UNLOCK (gVSlock);

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

  return VS_FLOW_OK;
}
コード例 #2
0
VSFlowReturn 
_configMasterVideoLayer(void * vshandle, void  * config)
{
    VS_FLOW("Fun %s in\n", __FUNCTION__);

    VideoSurface * vs;
    vs = (VideoSurface *)vshandle;

    if (NEXTSURFACE(vs)==NULL)
        return VS_FLOW_OK;

    VideoDevice * vd=SURFACE2DEVICE(vs);
      
    VS_LOCK(gVSlock);

    _removeVideoSurfaceFromDevice(vd,vs);
    _addVideoSurface2Device(vd,vs);
    
    _refreshOnDevice(vd);

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

    return VS_FLOW_OK;
}
コード例 #3
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;
}
コード例 #4
0
VSFlowReturn 
_configMasterVideoSurface(void * vshandle, void  * config)
{
    VS_FLOW("Fun %s in\n", __FUNCTION__);
    DestinationFmt * des = (DestinationFmt *)config;

    VideoSurface * vs;
    SourceFmt src;
    vs = (VideoSurface *)vshandle;

    VS_MESSAGE("reconfig win from "WIN_FMT" to "WIN_FMT"\n", WIN_ARGS(&vs->desfmt.rect), WIN_ARGS(&des->rect));

    VideoDevice * vd=SURFACE2DEVICE(vs);

      
    VS_LOCK(gVSlock);
    vs->desfmt = *des;
    vs->outside = _adjustDestRect(&des->rect, vd);
    vs->adjustdesrect = des->rect;

    if (NEXTSURFACE(vs)){
        _removeVideoSurfaceFromDevice(vd,vs);
        _addVideoSurface2Device(vd,vs);
    }

    _clearVideoSurfaceBackground(vd, vs);
    
    if (_checkOnDevice(vd)){
        _reconfigAllVideoSurfaces(vd);
        _setDeviceConfig(vd);
    }else{
        _initVSIPUTask(vs);
    }
    if (vd->setalpha)
        _setAlpha(vd);

    vs->mainframeupdate = 1;

    if (vs->itask.mode){
        _reconfigSubFrameBuffer(vs);
        vs->mainframeupdate = 0;
        _updateSubFrame(vs);
    }

    
    _refreshOnDevice(vd);

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

    return VS_FLOW_OK;

}
コード例 #5
0
int
_setDeviceConfig (VideoDevice * vd)
{
  VS_FLOW ("Fun %s in\n", __FUNCTION__);

  struct fb_var_screeninfo fb_var;
  struct fb_fix_screeninfo fb_fix;
  struct mxcfb_pos pos;
  Rect *rect;
  int i;

  int fd = _getDevicefd (vd);

  /* Workaround for ipu hardware, it need set to 0,0 before change another offset */
  pos.x = 0;
  pos.y = 0;
  VS_IOCTL (fd, MXCFB_SET_OVERLAY_POS, here1, &pos);
here1:
  VS_IOCTL (fd, FBIOBLANK, done, FB_BLANK_POWERDOWN);

  //VS_MESSAGE("Set device win"WIN_FMT"\n", WIN_ARGS(&vd->disp));

  rect = &vd->disp;

  VS_IOCTL (fd, FBIOGET_VSCREENINFO, done, &fb_var);

  fb_var.xres = RECT_WIDTH (rect);
  fb_var.xres_virtual = fb_var.xres;
  fb_var.yres = RECT_HEIGHT (rect);
  fb_var.yres_virtual = fb_var.yres * FB_NUM_BUFFERS;
  fb_var.activate |= FB_ACTIVATE_FORCE;
  fb_var.nonstd = vd->fmt;

  fb_var.bits_per_pixel = fmt2bit (vd->fmt);
  VS_IOCTL (fd, FBIOPUT_VSCREENINFO, done, &fb_var);

  VS_IOCTL (fd, FBIOGET_VSCREENINFO, done, &fb_var);
  VS_IOCTL (fd, FBIOGET_FSCREENINFO, done, &fb_fix);

  pos.x = vd->disp.left;
  pos.y = vd->disp.top;
  VS_IOCTL (fd, MXCFB_SET_OVERLAY_POS, here2, &pos);
here2:

  VS_IOCTL (fd, FBIOBLANK, done, FB_BLANK_UNBLANK);

  for (i = 0; i < FB_NUM_BUFFERS; i++) {
    vd->bufaddr[i] =
        (void *) (fb_fix.smem_start + fb_var.yres * fb_fix.line_length * i);
  }


  if (fmt2cs (vd->fmt) == 0) {
    _clearBackground (vd, NULL);
  }


done:
  return 0;
}
コード例 #6
0
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;
}
コード例 #7
0
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;
}
コード例 #8
0
void video_surface_destroy(void)
{
    VS_FLOW("Fun %s in\n", __FUNCTION__);
    VideoSurface * vs = gvslocal, *vsnext;
    while(vs){
        vsnext = vs->next;
        _destroyVideoSurface(vs, 1);
        vs = vsnext;
    }
}
コード例 #9
0
static void
_reconfigAllVideoSurfaces (VideoDevice * vd)
{
  VS_FLOW ("Fun %s in\n", __FUNCTION__);

  VideoSurface *vs = DEVICE2HEADSURFACE (vd);
  while (vs) {
    _initVSIPUTask (vs);
    vs = NEXTSURFACE (vs);
  }
}
コード例 #10
0
static int
_checkOnDevice (VideoDevice * vd)
{
  VS_FLOW ("Fun %s in\n", __FUNCTION__);

  int reconfig = ((vd->init == 0) ? 1 : 0);

  if (reconfig) {
    vd->disp.left = 0;
    vd->disp.top = 0;
    vd->disp.right = vd->resX;
    vd->disp.bottom = vd->resY;
  }
  return reconfig;
}
コード例 #11
0
static void
_removeVideoSurfaceFromDevice (VideoDevice * vd, VideoSurface * vs)
{
  VS_FLOW ("Fun %s in\n", __FUNCTION__);
  VideoSurface *pvs = DEVICE2HEADSURFACE (vd);
  if (pvs == vs) {
    SET_DEVICEHEADSURFACE (vd, NEXTSURFACE (vs));
  } else {
    while (NEXTSURFACE (pvs) != vs) {
      pvs = NEXTSURFACE (pvs);
    }
    SET_NEXTSURFACE (pvs, NEXTSURFACE (vs));
  }

}
コード例 #12
0
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;
}
コード例 #13
0
static void
_addVideoSurface2Device (VideoDevice * vd, VideoSurface * vs)
{
  VS_FLOW ("Fun %s in\n", __FUNCTION__);
  VideoSurface *pvs = DEVICE2HEADSURFACE (vd);

  vs->nextid = 0;

  if (pvs) {
    while (NEXTSURFACE (pvs))
      pvs = NEXTSURFACE (pvs);
    SET_NEXTSURFACE (pvs, vs);
  } else {
    SET_DEVICEHEADSURFACE (vd, vs);
  }
}
コード例 #14
0
int
_needRender (VideoSurface * curSurf, Updated * updated, int renderidx)
{
  VS_FLOW ("Fun %s in\n", __FUNCTION__);

  if (curSurf->paddr == NULL)
    return 0;
  if (curSurf->status == VS_STATUS_INVISIBLE)
    return 0;
  if ((curSurf->rendmask & (1 << renderidx)) == 0)
    return 1;
  if ((updated->updated)
      && (OVERLAPED_RECT ((&(curSurf->adjustdesrect)), (&updated->rect))))
    return 1;

  return 0;
}
コード例 #15
0
void
_initVSIPUTask (VideoSurface * surf)
{
  VideoDevice *vd = SURFACE2DEVICE (surf);
  IPUTaskOne *t1 = &surf->itask;
  Rect *rect = &(surf->srcfmt.croprect.win), *desrect;

  VS_FLOW ("Fun %s in\n", __FUNCTION__);

  desrect = &(surf->adjustdesrect);

  if (surf->outside & VS_INVISIBLE) {
    surf->status = VS_STATUS_INVISIBLE;
    return;
  }
  surf->status = VS_STATUS_VISIBLE;

  INPUT_FORMAT (t1) = surf->srcfmt.fmt;
  INPUT_WIDTH (t1) = surf->srcfmt.croprect.width;
  INPUT_HEIGHT (t1) = surf->srcfmt.croprect.height;

  INPUT_CROP_X (t1) = rect->left;
  INPUT_CROP_Y (t1) = rect->top;
  INPUT_CROP_WIDTH (t1) = RECT_WIDTH (rect);
  INPUT_CROP_HEIGHT (t1) = RECT_HEIGHT (rect);
  if (surf->outside) {

    /* output outside of screen, need crop in input */
    int xx[4] = { 0, 0, 0, 0 };
    Rect *origrect = &surf->desfmt.rect;
    int x_len, y_len;


    if (surf->desfmt.rot <= ROTATION_180_CLOCKWISE) {
      x_len = RECT_WIDTH (rect);
      y_len = RECT_HEIGHT (rect);
    } else {
      y_len = RECT_WIDTH (rect);
      x_len = RECT_HEIGHT (rect);
    }

    if (surf->outside & VS_LEFT_OUT) {
      xx[0] =
          (DEVICE_LEFT_EDGE - origrect->left) * x_len / RECT_WIDTH (origrect);
      xx[0] = ALIGNLEFT8 (xx[0]);
    }
    if (surf->outside & VS_RIGHT_OUT) {
      xx[1] = (origrect->right - vd->resX) * x_len / RECT_WIDTH (origrect);
      xx[1] = ALIGNLEFT8 (xx[1]);
    }
    if (surf->outside & VS_TOP_OUT) {
      xx[2] =
          (DEVICE_TOP_EDGE - origrect->top) * y_len / RECT_HEIGHT (origrect);
      xx[2] = ALIGNLEFT8 (xx[2]);
    }
    if (surf->outside & VS_BOTTOM_OUT) {
      xx[3] = (origrect->bottom - vd->resY) * y_len / RECT_HEIGHT (origrect);
      xx[3] = ALIGNLEFT8 (xx[3]);
    }

    if (surf->desfmt.rot <= ROTATION_180_CLOCKWISE) {
      INPUT_CROP_WIDTH (t1) -= (xx[0] + xx[1]);
      INPUT_CROP_HEIGHT (t1) -= (xx[2] + xx[3]);
    } else {
      INPUT_CROP_WIDTH (t1) -= (xx[2] + xx[3]);
      INPUT_CROP_HEIGHT (t1) -= (xx[0] + xx[1]);
    }

    INPUT_CROP_X (t1) += xx[g_vstable[surf->desfmt.rot][0]];
    INPUT_CROP_Y (t1) += xx[g_vstable[surf->desfmt.rot][1]];



  }
  OUTPUT_FORMAT (t1) = vd->fmt;
  OUTPUT_WIDTH (t1) = vd->disp.right - vd->disp.left;
  OUTPUT_HEIGHT (t1) = vd->disp.bottom - vd->disp.top;
  OUTPUT_CROP_X (t1) = desrect->left - vd->disp.left;
  OUTPUT_CROP_Y (t1) = desrect->top - vd->disp.top;
  OUTPUT_CROP_WIDTH (t1) = desrect->right - desrect->left;
  OUTPUT_CROP_HEIGHT (t1) = desrect->bottom - desrect->top;
  OUTPUT_ROTATION (t1) = surf->desfmt.rot;
  if ((INPUT_CROP_WIDTH (t1) < 16) || (INPUT_CROP_HEIGHT (t1) < 16)
      || (OUTPUT_CROP_WIDTH (t1) < 16) || (OUTPUT_CROP_HEIGHT (t1) < 16)) {
    surf->status = VS_STATUS_INVISIBLE;
  }


}
コード例 #16
0
void
_initVSIPUTask(VideoSurface * surf)
{
    VS_FLOW("Fun %s in\n", __FUNCTION__);

    VideoDevice * vd = SURFACE2DEVICE(surf);
    ipu_lib_input_param_t * input = &surf->itask.input;

    Rect * rect = &(surf->srcfmt.croprect.win), *desrect;
    
    desrect = &(surf->adjustdesrect);
   
    input->fmt = surf->srcfmt.fmt;
    input->width = surf->srcfmt.croprect.width;
    input->height = surf->srcfmt.croprect.height;

    if (surf->outside==0){
        input->input_crop_win.pos.x = rect->left;
        input->input_crop_win.pos.y = rect->top;
        input->input_crop_win.win_w = RECT_WIDTH(rect);
        input->input_crop_win.win_h = RECT_HEIGHT(rect);
    }else{
        /* output outside of screen, need crop in input */
        int xl=0, xr=0, xt=0, xb=0;
        Rect * origrect = &surf->desfmt.rect;
        if (surf->outside&VS_LEFT_OUT){
            xl = (DEVICE_LEFT_EDGE-origrect->left)*RECT_WIDTH(rect)/RECT_WIDTH(origrect);
            ALIGNLEFT8(xl);
        }
        if (surf->outside&VS_RIGHT_OUT){
            xr = (origrect->right-vd->resX)*RECT_WIDTH(rect)/RECT_WIDTH(origrect);
            ALIGNLEFT8(xr);
        }
        if (surf->outside&VS_TOP_OUT){
            xt = (DEVICE_TOP_EDGE-origrect->top)*RECT_HEIGHT(rect)/RECT_HEIGHT(origrect);
            ALIGNLEFT8(xt);
        }
        if (surf->outside&VS_BOTTOM_OUT){
            xb = (origrect->bottom-vd->resY)*RECT_HEIGHT(rect)/RECT_HEIGHT(origrect);
            ALIGNLEFT8(xb);
        }
        
        input->input_crop_win.pos.x = rect->left+xl;
        input->input_crop_win.pos.y = rect->top+xt;
        input->input_crop_win.win_w = RECT_WIDTH(rect)-xl-xr;
        input->input_crop_win.win_h = RECT_HEIGHT(rect)-xt-xb;
        
    }

    input->user_def_paddr[0] = input->user_def_paddr[1] = 0;
    
    ipu_lib_output_param_t * output = &surf->itask.output;
    
    output->fmt = vd->fmt;
    output->width = vd->disp.right-vd->disp.left;
    output->height = vd->disp.bottom-vd->disp.top;
    output->output_win.pos.x = desrect->left-vd->disp.left;
    output->output_win.pos.y = desrect->top-vd->disp.top;
    output->output_win.win_w = desrect->right-desrect->left;
    output->output_win.win_h = desrect->bottom-desrect->top;
    output->user_def_paddr[0] = output->user_def_paddr[1] = 0;
    output->rot = surf->desfmt.rot;

}
コード例 #17
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;
}