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; }
/*============================================================================= 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; }