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; }
/*============================================================================= FUNCTION: updateSubFrame2VideoSurface DESCRIPTION: This function updata a subframe to video surface. ==============================================================================*/ VSFlowReturn updateSubFrame2VideoSurface (void *vshandle, SubFrame * subframe, int idx) { VideoSurface *vsurface; if (vshandle == NULL) return VS_FLOW_PARAMETER_ERROR; vsurface = (VideoSurface *) vshandle; VS_LOCK (gVSlock); if (subframe) { vsurface->subframes[idx].width = subframe->width; vsurface->subframes[idx].height = subframe->height; vsurface->subframes[idx].posx = subframe->posx; vsurface->subframes[idx].posy = subframe->posy; vsurface->subframes[idx].image = subframe->image; vsurface->subframes[idx].fmt = SUBFRAME_DEFAULT_FMT; vsurface->itask.mode = 1; if (vsurface->mainframeupdate) { _reconfigSubFrameBuffer (vsurface); vsurface->mainframeupdate = 0; } _updateSubFrame (vsurface); } else { vsurface->itask.mode = 0; } VS_UNLOCK (gVSlock); return VS_FLOW_OK; }
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; }
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; }
void _destroyVideoSurface (void *vshandle, int force) { VideoSurface *vs, *vs1; VideoDevice *vd; vs = (VideoSurface *) vshandle; if (vs == NULL) return; VS_LOCK (gVSlock); if (force == 0) { vs1 = gvslocal; if (vs1 == vs) { gvslocal = vs->next; } else { while (vs1->next != vs) vs1 = vs1->next; vs1->next = vs->next; } } vd = SURFACE2DEVICE (vs); _removeVideoSurfaceFromDevice (vd, vs); // _clearBackground(vd, vs); _destroySubFrameBuffer (vs); vd->cleanmask = 0xffffffff; vd->cnt--; if (DEVICE2HEADSURFACE (vd) == NULL) { _closeDevice (vd); vd->init = 0; } else { if (_checkOnDevice (vd)) { _reconfigAllVideoSurfaces (vd); _setDeviceConfig (vd); } if (vd->setalpha) _setAlpha (vd); _refreshOnDevice (vd); } VS_MESSAGE ("VS%d destroyed, force=%d!\n", vs->id - 1, force); vs->status = VS_STATUS_IDLE; VS_UNLOCK (gVSlock); }
/*============================================================================= 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; }
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; }
/* * Reset device (device-wide). This erases all queues, i.e., * all the queues become invalid (though we don't wipe out the * internal pointers, we just clear the VQ_ALLOC flag). * * It resets negotiated features to "none". * * If MSI-X is enabled, this also resets all the vectors to NO_VECTOR. */ void vi_reset_dev(struct virtio_softc *vs) { struct vqueue_info *vq; int i, nvq; nvq = vs->vs_vc->vc_nvq; for (vq = vs->vs_queues, i = 0; i < nvq; vq++, i++) { vq->vq_flags = 0; vq->vq_last_avail = 0; vq->vq_pfn = 0; vq->vq_msix_idx = VIRTIO_MSI_NO_VECTOR; } vs->vs_negotiated_caps = 0; vs->vs_curq = 0; /* vs->vs_status = 0; -- redundant */ VS_LOCK(vs); if (vs->vs_isr) pci_lintr_deassert(vs->vs_pi); vs->vs_isr = 0; VS_UNLOCK(vs); vs->vs_msix_cfg_idx = VIRTIO_MSI_NO_VECTOR; }
/*============================================================================= 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; }