📄 vp_capture.c
字号:
Ptr cbArg) //Point to GIO_Obj
{
Int chanid;
Int retVal = IOM_COMPLETED;
CapChan_Handle hCapChan;
CapVP_Handle hCapVP = (CapVP_Handle)devp;
CapChan_Params *paramCapChan = (CapChan_Params *)chanParams;
//通道模式检测
if(mode != IOM_INPUT){
return(IOM_EBADARGS);
}
//通道名检测
if(*name ++ != '/'){
return(IOM_EBADARGS);
}else{
chanid = *name ++ - 'A';
}
//检查该视频端口驱动是否绑定
if(!(hCapVP->status & VP_STATUS_OPENED)){
return(IOM_EBADARGS);
}
//检查视频通道号是否合法
if(chanid == 0){
if(hCapVP->status & VP_STATUS_CHAOPENED){
return(IOM_EINUSE);
}else{
if(hCapVP->supCMode & (((Uns) 1) << paramCapChan->capMode)){
hCapVP->status |= VP_STATUS_CHAOPENED;
}else{
return(IOM_EBADARGS);
}
}
}else{
if(hCapVP->status & VP_STATUS_CHBOPENED){
return(IOM_EINUSE);
}else{
if(hCapVP->supCMode & (((Uns) 1) << paramCapChan->capMode)){
hCapVP->status |= VP_STATUS_CHAOPENED;
}else{
return(IOM_EBADARGS);
}
}
}
hCapChan = &hCapVP->capChan[chanid];
//配置通道设备及其管理器.
QUE_new(&hCapChan->iomPktQue);
hCapChan->cbFxn = cbFxn;
hCapChan->cbArg = (Arg)cbArg;
hCapChan->vSnapStarted = FALSE;
//配置通道寄存器.
if(paramCapChan != INV){
if(IOM_COMPLETED != (retVal = CapChan_chanConfig(hCapChan, paramCapChan))){
if(0 == hCapChan->chanid){
hCapVP->status &= (~VP_STATUS_CHAOPENED);
}else{
hCapVP->status &= (~VP_STATUS_CHBOPENED);
}
return(retVal);
}
}
//分配视频数据缓冲区.
if(IOM_COMPLETED != (retVal = CapChan_memAlloc(hCapChan, paramCapChan))){
goto DelAllocatedForChan;
}
//分配EDMA通道及相关资源.
if(IOM_COMPLETED != (retVal = CapChan_edmaAllocConfig(hCapChan, paramCapChan))){
goto DelAllocatedForChan;
}
//打开并配置外部设备.
if(hCapChan->edcFxns != INV){
if((EDC_Handle)EDC_FAILED == (hCapChan->hEDC = hCapChan->edcFxns->open(name, (Arg)INV))){
retVal = IOM_EALLOC;
goto DelAllocatedForChan;
}
}
//设置返回值.
*chanp = hCapChan;
return(retVal);
//异常处理.
DelAllocatedForChan:
mdDeleteChan(hCapChan);
*chanp = NULL;
return(retVal);
}
/*
* =================== mdDeleteChan ============================
* create a capture channel
*/
static Int mdDeleteChan(Ptr chanp)
{
Uns *baseAddr;
CapChan_Handle hCapChan = (CapChan_Handle)chanp;
CapVP_Handle hCapVP = (CapVP_Handle)hCapChan->hCapVP;
//复位该通道;
baseAddr = (Uns *)hCapChan->baseAddr;
baseAddr[_VP_VCACTL_OFFSETA] = VP_VCACTL_DEFAULT | (VP_VCACTL_RSTCH_RESET << _VP_VCACTL_RSTCH_SHIFT);
//释放MEM资源.
CapChan_memFree(hCapChan);
//释放EDMA资源.
CapChan_edmaFree(hCapChan);
//清除状态位.
if(0 == hCapChan->chanid){
hCapVP->status &= (~VP_STATUS_CHAOPENED);
}else{
hCapVP->status &= (~VP_STATUS_CHBOPENED);
}
return(IOM_COMPLETED);
}
/*
* =================== mdSubmitChan ============================
* submit a IOM_Packet to capture channel
*/
static Int mdSubmitChan(Ptr chanp, IOM_Packet *packet)
{
Int i, retVal;
Uns *baseAddr;
Char **ycbrBuf;
CapChan_Handle hCapChan = (CapChan_Handle)chanp;
CapChan_VideoBufElem *hVideoBuf;
//用户缓冲区.
baseAddr = (Uns *)hCapChan->baseAddr;
ycbrBuf = (Char **)packet->addr;
//命令解析处理.b
switch(packet->cmd){
case CAPVP_CMD_GET:
if(!QUE_empty(&hCapChan->vFullBufQue)){
hVideoBuf = QUE_get(&hCapChan->vFullBufQue);
QUE_put(&hCapChan->vEmptingBufQue, hVideoBuf);
for(i=0; i<VP_YCBR_CHAN_CNT; i++){
*(ycbrBuf + i) = hVideoBuf->ycrbBuf.ycbr[i];
}
retVal = IOM_COMPLETED;
}else{
QUE_put(&hCapChan->iomPktQue, packet);
if(hCapChan->edmaConfigFlg){
if(VP_CAP_SINGLE == hCapChan->vConCap){
if(!hCapChan->vSnapStarted){
baseAddr[_VP_VCACTL_OFFSETA] &= ~_VP_VCACTL_BLKCAP_MASK;
baseAddr[_VP_VCACTL_OFFSETA] |= _VP_VCACTL_VCEN_MASK;
hCapChan->vSnapStarted = TRUE;
}else{
baseAddr[_VP_VCACTL_OFFSETA] |= _VP_VCACTL_BLKCAP_MASK;
baseAddr[_VP_VCASTAT_OFFSETA] = VP_VCASTAT_RMK(VP_VCASTAT_FRMC_CLEAR, VP_VCASTAT_F2C_CLEAR, VP_VCASTAT_F1C_CLEAR);
baseAddr[_VP_VCACTL_OFFSETA] &= ~_VP_VCACTL_BLKCAP_MASK;
}
hCapChan->edmaConfigFlg = FALSE;
}
}else if((!QUE_empty(&hCapChan->vEmptyBufQue)) && ((baseAddr[_VP_VCASTAT_OFFSETA]) & (_VP_VCASTAT_FRMC_MASK | _VP_VCASTAT_F2C_MASK |_VP_VCASTAT_F1C_MASK))){
hVideoBuf = (CapChan_VideoBufElem *)QUE_get(&hCapChan->vEmptyBufQue);
QUE_put(&hCapChan->vFillingBufQue, hVideoBuf);
hCapChan->edmaCfg[0].dst = (Uint32)hVideoBuf->ycrbBuf.ycbr[0];
hCapChan->edmaCfg[1].dst = (Uint32)hVideoBuf->ycrbBuf.ycbr[1];
hCapChan->edmaCfg[2].dst = (Uint32)hVideoBuf->ycrbBuf.ycbr[2];
EDMA_config(hCapChan->hEdma[0], &hCapChan->edmaCfg[0]);
EDMA_config(hCapChan->hEdma[1], &hCapChan->edmaCfg[1]);
EDMA_config(hCapChan->hEdma[2], &hCapChan->edmaCfg[2]);
EDMA_link(hCapChan->hEdma[0], EDMA_hNull);
EDMA_link(hCapChan->hEdma[1], EDMA_hNull);
EDMA_link(hCapChan->hEdma[2], EDMA_hNull);
hCapChan->edmaConfigFlg = TRUE;
if(VP_CAP_SINGLE == hCapChan->vConCap){
baseAddr[_VP_VCACTL_OFFSETA] |= _VP_VCACTL_BLKCAP_MASK;
baseAddr[_VP_VCASTAT_OFFSETA] = VP_VCASTAT_RMK(VP_VCASTAT_FRMC_CLEAR, VP_VCASTAT_F2C_CLEAR, VP_VCASTAT_F1C_CLEAR);
baseAddr[_VP_VCACTL_OFFSETA] &= ~_VP_VCACTL_BLKCAP_MASK;
hCapChan->edmaConfigFlg = FALSE;
}
}
retVal = IOM_PENDING;
}
break;
case CAPVP_CMD_PUT:
if(!QUE_empty(&hCapChan->vEmptingBufQue)){
hVideoBuf = QUE_get(&hCapChan->vEmptingBufQue);
for(i=0; i<VP_YCBR_CHAN_CNT; i++){
hVideoBuf->bufSt[i] = VP_VBUF_IS_EMPTY;
}
QUE_put(&hCapChan->vEmptyBufQue, hVideoBuf);
retVal = IOM_COMPLETED;
}else{
retVal = IOM_EBADARGS;
}
break;
case CAPVP_CMD_EXCHANGE:
if(!QUE_empty(&hCapChan->vEmptingBufQue)){
hVideoBuf = QUE_get(&hCapChan->vEmptingBufQue);
for(i=0; i<VP_YCBR_CHAN_CNT; i++){
hVideoBuf->bufSt[i] = VP_VBUF_IS_EMPTY;
}
QUE_put(&hCapChan->vEmptyBufQue, hVideoBuf);
if(!QUE_empty(&hCapChan->vFullBufQue)){
hVideoBuf = QUE_get(&hCapChan->vFullBufQue);
QUE_put(&hCapChan->vEmptingBufQue, hVideoBuf);
for(i=0; i<VP_YCBR_CHAN_CNT; i++){
*(ycbrBuf + i) = hVideoBuf->ycrbBuf.ycbr[i];
}
retVal = IOM_COMPLETED;
}else{
QUE_put(&hCapChan->iomPktQue, packet);
if(hCapChan->edmaConfigFlg){
if(VP_CAP_SINGLE == hCapChan->vConCap){
baseAddr[_VP_VCACTL_OFFSETA] |= _VP_VCACTL_BLKCAP_MASK;
baseAddr[_VP_VCASTAT_OFFSETA] = VP_VCASTAT_RMK(VP_VCASTAT_FRMC_CLEAR, VP_VCASTAT_F2C_CLEAR, VP_VCASTAT_F1C_CLEAR);
baseAddr[_VP_VCACTL_OFFSETA] &= ~_VP_VCACTL_BLKCAP_MASK;
hCapChan->edmaConfigFlg = FALSE;
}
}else if((!QUE_empty(&hCapChan->vEmptyBufQue)) && ((baseAddr[_VP_VCASTAT_OFFSETA]) & (_VP_VCASTAT_FRMC_MASK | _VP_VCASTAT_F2C_MASK |_VP_VCASTAT_F1C_MASK))){
hVideoBuf = (CapChan_VideoBufElem *)QUE_get(&hCapChan->vEmptyBufQue);
QUE_put(&hCapChan->vFillingBufQue, hVideoBuf);
hCapChan->edmaCfg[0].dst = (Uint32)hVideoBuf->ycrbBuf.ycbr[0];
hCapChan->edmaCfg[1].dst = (Uint32)hVideoBuf->ycrbBuf.ycbr[1];
hCapChan->edmaCfg[2].dst = (Uint32)hVideoBuf->ycrbBuf.ycbr[2];
EDMA_config(hCapChan->hEdma[0], &hCapChan->edmaCfg[0]);
EDMA_config(hCapChan->hEdma[1], &hCapChan->edmaCfg[1]);
EDMA_config(hCapChan->hEdma[2], &hCapChan->edmaCfg[2]);
EDMA_link(hCapChan->hEdma[0], EDMA_hNull);
EDMA_link(hCapChan->hEdma[1], EDMA_hNull);
EDMA_link(hCapChan->hEdma[2], EDMA_hNull);
hCapChan->edmaConfigFlg = TRUE;
if(VP_CAP_SINGLE == hCapChan->vConCap){
baseAddr[_VP_VCACTL_OFFSETA] |= _VP_VCACTL_BLKCAP_MASK;
baseAddr[_VP_VCASTAT_OFFSETA] = VP_VCASTAT_RMK(VP_VCASTAT_FRMC_CLEAR, VP_VCASTAT_F2C_CLEAR, VP_VCASTAT_F1C_CLEAR);
baseAddr[_VP_VCACTL_OFFSETA] &= ~_VP_VCACTL_BLKCAP_MASK;
hCapChan->edmaConfigFlg = FALSE;
}
}
retVal = IOM_PENDING;
}
}else{
retVal = IOM_EBADARGS;
}
break;
default:
retVal = IOM_ENOTIMPL;
break;
}
return(retVal);
}
/*
* =================== mdControlChan ============================
*/
static Int mdControlChan(Ptr chanp, Uns cmd, Ptr args)
{
Int retVal;
Uns *baseAddr;
CapChan_Handle hCapChan = (CapChan_Handle)chanp;
baseAddr = (Uns *)hCapChan->baseAddr;
switch(cmd){
case CAPVP_CMD_STARTCAP:
if(VP_CAP_CONTINUOUS == hCapChan->vConCap){
baseAddr[_VP_VCACTL_OFFSETA] &= ~_VP_VCACTL_BLKCAP_MASK;
baseAddr[_VP_VCACTL_OFFSETA] |= _VP_VCACTL_VCEN_MASK;
retVal = IOM_COMPLETED;
}else{
retVal = IOM_EBADARGS;
}
break;
case CAPVP_CMD_STOPCAP:
if(VP_CAP_CONTINUOUS == hCapChan->vConCap){
baseAddr[_VP_VCACTL_OFFSETA] &= ~_VP_VCACTL_VCEN_MASK;
baseAddr[_VP_VCACTL_OFFSETA] |= _VP_VCACTL_BLKCAP_MASK;
retVal = IOM_COMPLETED;
}else{
retVal = IOM_EBADARGS;
}
break;
default:
if(INV != hCapChan->edcFxns){
retVal = hCapChan->edcFxns->ctrl(hCapChan->hEDC, cmd - CAPVP_CMD_EDC_BASE, (Arg)args);
}else{
retVal = IOM_ENOTIMPL;
}
}
return(retVal);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -