/***************************************************************************** * function : start vpss. VPSS chn with frame *****************************************************************************/ static HI_S32 SAMPLE_COMM_IVE_VpssStart(HI_S32 s32VpssGrpCnt, SIZE_S astSize[], VPSS_CHN aVpssChn[], HI_S32 s32VpssChnCnt, VPSS_GRP_ATTR_S *pstVpssGrpAttr) { VPSS_GRP VpssGrp; VPSS_CHN VpssChn; VPSS_GRP_ATTR_S stGrpAttr = {0}; //VPSS_CHN_ATTR_S stChnAttr = {0}; VPSS_NR_PARAM_U unNrParam = {{0}}; VPSS_CHN_MODE_S stVpssChnMode = {0}; VPSS_FRAME_RATE_S stVpssFrmRate = {30, 30}; HI_S32 s32Ret = HI_SUCCESS; HI_S32 i, j; HI_U32 u32Depth = 1; HI_ASSERT(s32VpssGrpCnt>0); HI_ASSERT(s32VpssChnCnt>0); /*** Set Vpss Grp Attr ***/ if(NULL == pstVpssGrpAttr) { stGrpAttr.u32MaxW = astSize[0].u32Width; stGrpAttr.u32MaxH = astSize[0].u32Height; stGrpAttr.bIeEn = HI_FALSE; stGrpAttr.bNrEn = HI_TRUE; stGrpAttr.bHistEn = HI_FALSE; stGrpAttr.enDieMode = VPSS_DIE_MODE_NODIE; stGrpAttr.enPixFmt = SAMPLE_PIXEL_FORMAT; } else { memcpy(&stGrpAttr,pstVpssGrpAttr,sizeof(VPSS_GRP_ATTR_S)); } for(i=0; i<s32VpssGrpCnt; i++) { VpssGrp = i; /*** create vpss group ***/ s32Ret = HI_MPI_VPSS_CreateGrp(VpssGrp, &stGrpAttr); if (HI_SUCCESS != s32Ret) { SAMPLE_PRT("HI_MPI_VPSS_CreateGrp failed with errno: %#x!\n", s32Ret); return HI_FAILURE; } //*** set vpss param ***/ s32Ret = HI_MPI_VPSS_GetNRParam(VpssGrp, &unNrParam); if (HI_SUCCESS != s32Ret) { SAMPLE_PRT("HI_MPI_VPSS_GetNRParam failed with errno: %#x!\n", s32Ret); return HI_FAILURE; } s32Ret = HI_MPI_VPSS_SetNRParam(VpssGrp, &unNrParam); if (HI_SUCCESS != s32Ret) { SAMPLE_PRT("HI_MPI_VPSS_SetNRParam failed with errno: %#x!\n", s32Ret); return HI_FAILURE; } s32Ret = HI_MPI_VPSS_SetGrpFrameRate(VpssGrp, &stVpssFrmRate); if (HI_SUCCESS != s32Ret) { SAMPLE_PRT("HI_MPI_VPSS_SetGrpFrameRate failed with errno: %#x!\n", s32Ret); return HI_FAILURE; } /*** enable vpss chn, with frame ***/ for(j=0; j<s32VpssChnCnt; j++) { VpssChn = aVpssChn[j]; stVpssChnMode.enChnMode = VPSS_CHN_MODE_USER; stVpssChnMode.u32Width = astSize[j].u32Width; stVpssChnMode.u32Height = astSize[j].u32Height; stVpssChnMode.enPixelFormat = SAMPLE_PIXEL_FORMAT; stVpssChnMode.enCompressMode = COMPRESS_MODE_NONE; s32Ret = HI_MPI_VPSS_SetChnMode(VpssGrp, VpssChn, &stVpssChnMode); if (HI_SUCCESS != s32Ret) { SAMPLE_PRT("HI_MPI_VPSS_SetChnMode failed with errno: %#x\n", s32Ret); return HI_FAILURE; } s32Ret = HI_MPI_VPSS_SetDepth(VpssGrp, VpssChn, u32Depth); if (HI_SUCCESS != s32Ret) { SAMPLE_PRT("HI_MPI_VPSS_SetDepth failed with errno: %#x\n", s32Ret); return HI_FAILURE; } s32Ret = HI_MPI_VPSS_EnableChn(VpssGrp, VpssChn); if (HI_SUCCESS != s32Ret) { SAMPLE_PRT("HI_MPI_VPSS_EnableChn failed with errno: %#x\n", s32Ret); return HI_FAILURE; } } /*** start vpss group ***/ s32Ret = HI_MPI_VPSS_StartGrp(VpssGrp); if (HI_SUCCESS != s32Ret) { SAMPLE_PRT("HI_MPI_VPSS_StartGrp failed with %#x\n", s32Ret); return HI_FAILURE; } } return HI_SUCCESS; }
static HI_VOID* SampleGetH264StreamAndSend(HI_VOID *p) { HI_S32 s32Ret; HI_S32 s32VencFd; VENC_CHN VeChn; VENC_CHN_STAT_S stStat; VENC_STREAM_S stStream; fd_set read_fds; FILE *pFile = NULL; struct timeval TimeoutVal; VeChn = (HI_S32)p; pFile = fopen("stream.h264","wb"); if(pFile == NULL) { HI_ASSERT(0); return NULL; } s32VencFd = HI_MPI_VENC_GetFd(VeChn); while (HI_TRUE != g_bVencStopFlag) { FD_ZERO(&read_fds); FD_SET(s32VencFd,&read_fds); TimeoutVal.tv_sec = 2; TimeoutVal.tv_usec = 0; s32Ret = select(s32VencFd+1, &read_fds, NULL, NULL, &TimeoutVal); if (s32Ret < 0) { printf("select err\n"); return NULL; } else if (0 == s32Ret) { printf("time out\n"); return NULL; } else { if (FD_ISSET(s32VencFd, &read_fds)) { s32Ret = HI_MPI_VENC_Query(VeChn, &stStat); if (s32Ret != HI_SUCCESS) { printf("HI_MPI_VENC_Query:0x%x err\n",s32Ret); fflush(stdout); return NULL; } stStream.pstPack = (VENC_PACK_S*)malloc(sizeof(VENC_PACK_S)*stStat.u32CurPacks); if (NULL == stStream.pstPack) { printf("malloc memory err!\n"); return NULL; } stStream.u32PackCount = stStat.u32CurPacks; s32Ret = HI_MPI_VENC_GetStream(VeChn, &stStream, HI_IO_NOBLOCK); if (HI_SUCCESS != s32Ret) { printf("HI_MPI_VENC_GetStream:0x%x\n",s32Ret); free(stStream.pstPack); stStream.pstPack = NULL; return NULL; } /* if you need to save current stream, open this switch. */ #ifdef SAVE_STREAM_SWITCH SampleSaveH264Stream(pFile, &stStream); #endif /* send stream to VDEC while encoding... */ if(HI_SUCCESS != SendStreamToVdec(VeChn, &stStream)) { printf("SendStreamToVdec failed!\n"); return NULL; } s32Ret = HI_MPI_VENC_ReleaseStream(VeChn,&stStream); if (s32Ret) { printf("HI_MPI_VENC_ReleaseStream:0x%x\n",s32Ret); free(stStream.pstPack); stStream.pstPack = NULL; return NULL; } free(stStream.pstPack); stStream.pstPack = NULL; } } } fclose(pFile); return NULL; }
int main() { HI_S32 s32Ret; PCIV_MSGHEAD_S stMsg; pthread_t stThread[2]; PCIV_THREAD_PARAM_S stThreadParam[2]; /* set AD tw2815 */ s32Ret = SAMPLE_2815_open(); HI_ASSERT((HI_SUCCESS == s32Ret)); s32Ret = SAMPLE_2815_set_2d1(); HI_ASSERT((HI_SUCCESS == s32Ret)); /* mpp sys init */ s32Ret = PCIV_Slave_SysInit(); HI_ASSERT((HI_SUCCESS == s32Ret)); /* Open the message port. On slave board only 0 can be used. */ s32Ret = PCIV_OpenMsgPort(0); HI_ASSERT((HI_SUCCESS == s32Ret)); { PCIV_BASEWINDOW_S stbase; stbase.s32SlotIndex = 0; s32Ret = HI_MPI_PCIV_GetBaseWindow(&stbase); HI_ASSERT((HI_SUCCESS == s32Ret)); g_u32PfAhbBase = stbase.u32PfAHBAddr; printf("AHB PF Address is 0x%08x\n", g_u32PfAhbBase); } PCIV_InitBuffer(); stThreadParam[0].s32DstTarget = 0; stThreadParam[0].s32LocalId = HI_MPI_PCIV_GetLocalId(); s32Ret = pthread_create(&stThread[0], NULL, PCIV_ThreadRev, &stThreadParam[0]); HI_ASSERT((HI_SUCCESS == s32Ret)); stThreadParam[1].s32DstTarget = 0; stThreadParam[1].s32LocalId = HI_MPI_PCIV_GetLocalId(); s32Ret = pthread_create(&stThread[1], NULL, PCIV_ThreadSend, &stThreadParam[1]); HI_ASSERT((HI_SUCCESS == s32Ret)); while(1) { s32Ret = PCIV_ReadMsg(0, PCIV_MSGPORT_USERCMD, &stMsg); HI_ASSERT((HI_SUCCESS == s32Ret)); switch(stMsg.enMsgType) { case PCIV_MSGTYPE_CREATE: { switch(stMsg.enDevType) { case PCIV_DEVTYPE_VICHN: { s32Ret = PCIV_Slave_StartVi(&stMsg); HI_ASSERT((HI_SUCCESS == s32Ret)); break; } case PCIV_DEVTYPE_VOCHN: { s32Ret = PCIV_Slave_StartVo(&stMsg); HI_ASSERT((HI_SUCCESS == s32Ret)); break; } case PCIV_DEVTYPE_PCIV: { s32Ret = PCIV_Slave_CreatePciv(&stMsg); HI_ASSERT((HI_SUCCESS == s32Ret)); break; } case PCIV_DEVTYPE_GROUP: { s32Ret = PCIV_Slave_StartGrp(&stMsg); HI_ASSERT((HI_SUCCESS == s32Ret)); break; } case PCIV_DEVTYPE_VENCCHN: { s32Ret = PCIV_Slave_StartVenc(&stMsg); HI_ASSERT((HI_SUCCESS == s32Ret)); break; } default: break; } break; } case PCIV_MSGTYPE_START: { switch(stMsg.enDevType) { case PCIV_DEVTYPE_PCIV: { s32Ret = PCIV_Slave_StartPciv(&stMsg); HI_ASSERT((HI_SUCCESS == s32Ret)); break; } default: break; } break; } case PCIV_MSGTYPE_DESTROY: { switch(stMsg.enDevType) { case PCIV_DEVTYPE_VICHN: { s32Ret = PCIV_Slave_StopVi(&stMsg); HI_ASSERT((HI_SUCCESS == s32Ret)); break; } case PCIV_DEVTYPE_VOCHN: { s32Ret = PCIV_Slave_StopVo(&stMsg); HI_ASSERT((HI_SUCCESS == s32Ret)); break; } case PCIV_DEVTYPE_PCIV: { s32Ret = PCIV_Slave_StopPciv(&stMsg); HI_ASSERT((HI_SUCCESS == s32Ret)); break; } case PCIV_DEVTYPE_GROUP: { s32Ret = PCIV_Slave_StopGrp(&stMsg); HI_ASSERT((HI_SUCCESS == s32Ret)); break; } case PCIV_DEVTYPE_VENCCHN: { s32Ret = PCIV_Slave_StopVenc(&stMsg); HI_ASSERT((HI_SUCCESS == s32Ret)); break; } default: break; } break; } case PCIV_MSGTYPE_SETATTR: { switch(stMsg.enDevType) { case PCIV_DEVTYPE_PCIV: { s32Ret = PCIV_Slave_SetPcivAttr(&stMsg); HI_ASSERT((HI_SUCCESS == s32Ret)); break; } default: break; } break; } case PCIV_MSGTYPE_GETATTR: { switch(stMsg.enDevType) { case PCIV_DEVTYPE_PCIV: { s32Ret = PCIV_Slave_GetPcivAttr(&stMsg); HI_ASSERT((HI_SUCCESS == s32Ret)); break; } default: break; } break; } default: break; } } return 0; }
HI_S32 PCIV_Slave_CreatePciv(PCIV_MSGHEAD_S *pMsg) { HI_S32 s32Ret, i; PCIV_PCIVCMD_CREATE_S *pCmd = (PCIV_PCIVCMD_CREATE_S *)pMsg->cMsgBody; PCIV_PCIVCMD_ECHO_S *pCmdEcho = (PCIV_PCIVCMD_ECHO_S *)pMsg->cMsgBody; PCIV_DEVICE_S *pPcivDev = NULL; pPcivDev = &(pCmd->stDevAttr.stPCIDevice); s32Ret = HI_MPI_PCIV_Create(pPcivDev); HI_ASSERT((HI_SUCCESS == s32Ret)); if(pCmd->bMalloc) { s32Ret = HI_MPI_PCIV_Malloc(&pCmd->stDevAttr); if(HI_SUCCESS != s32Ret) { /* May be buffer is used by vo, wait a minute and try again. */ usleep(40000); s32Ret = HI_MPI_PCIV_Malloc(&pCmd->stDevAttr); } HI_ASSERT((HI_SUCCESS == s32Ret)); /* Attation: return the offset from PCI shm_phys_addr */ for(i=0; i<pCmd->stDevAttr.u32Count; i++) { pCmd->stDevAttr.u32AddrArray[i] -= g_u32PfAhbBase; } } else { s32Ret = HI_MPI_PCIV_SetAttr(&pCmd->stDevAttr); HI_ASSERT((HI_SUCCESS == s32Ret)); switch(pCmd->stBindObj.stBindObj.enType) { /* through flow. No Break */ case PCIV_BIND_VENC: { s32Ret = PCIV_InitCreater(&pCmd->stDevAttr, &pCmd->stBindObj.stBindObj); break; } case PCIV_BIND_VSTREAMSND: { s32Ret = PCIV_InitCreater(&pCmd->stDevAttr, NULL); break; } case PCIV_BIND_VSTREAMREV: { printf("The type is PCIV_BIND_VSTREAMREV. Something may be wrong!"); s32Ret = HI_FAILURE; break; } default: { // Do nothing! break; } } HI_ASSERT((HI_SUCCESS == s32Ret)); } pPcivDev = &(pCmd->stBindObj.stPCIDevice); memcpy(pPcivDev, &(pCmd->stDevAttr.stPCIDevice), sizeof(PCIV_DEVICE_S)); s32Ret = HI_MPI_PCIV_Bind(&pCmd->stBindObj); HI_ASSERT((HI_SUCCESS == s32Ret)); /* Echo the cmd. Attation: the memory may be overlay. */ memmove(&pCmdEcho->stDevAttr, &pCmd->stDevAttr, sizeof(PCIV_DEVICE_ATTR_S)); pCmdEcho->s32Echo = HI_SUCCESS; pMsg->enMsgType = PCIV_MSGTYPE_CMDECHO; pMsg->enDevType = PCIV_DEVTYPE_PCIV; pMsg->u32Target = 0; /* To host */ pMsg->u32MsgLen = sizeof(PCIV_PCIVCMD_ECHO_S); s32Ret = PCIV_SendMsg(0, PCIV_MSGPORT_USERCMD, pMsg); HI_ASSERT((HI_FAILURE != s32Ret)); return HI_SUCCESS; }
/*获取单路H264码流*/ HI_VOID* SampleGetH264Stream(HI_VOID *p) { HI_S32 s32Ret; HI_S32 s32VencFd; HI_U32 u32FrameIdx = 0; VENC_CHN VeChn; VENC_CHN_STAT_S stStat; VENC_STREAM_S stStream; fd_set read_fds; FILE *pFile = NULL; pFile = fopen("stream.h264","wb"); if(pFile == NULL) { HI_ASSERT(0); return NULL; } VeChn = (HI_S32)p; s32VencFd = HI_MPI_VENC_GetFd(VeChn); do{ FD_ZERO(&read_fds); FD_SET(s32VencFd,&read_fds); s32Ret = select(s32VencFd+1, &read_fds, NULL, NULL, NULL); if (s32Ret < 0) { printf("select err\n"); return NULL; } else if (0 == s32Ret) { printf("time out\n"); return NULL; } else { if (FD_ISSET(s32VencFd, &read_fds)) { s32Ret = HI_MPI_VENC_Query(VeChn, &stStat); if (s32Ret != HI_SUCCESS) { printf("HI_MPI_VENC_Query:0x%x err\n",s32Ret); fflush(stdout); return NULL; } stStream.pstPack = (VENC_PACK_S*)malloc(sizeof(VENC_PACK_S)*stStat.u32CurPacks); if (NULL == stStream.pstPack) { printf("malloc memory err!\n"); return NULL; } stStream.u32PackCount = stStat.u32CurPacks; s32Ret = HI_MPI_VENC_GetStream(VeChn, &stStream, HI_TRUE); if (HI_SUCCESS != s32Ret) { printf("HI_MPI_VENC_GetStream:0x%x\n",s32Ret); free(stStream.pstPack); stStream.pstPack = NULL; return NULL; } SampleSaveH264Stream(pFile, &stStream); s32Ret = HI_MPI_VENC_ReleaseStream(VeChn,&stStream); if (s32Ret) { printf("HI_MPI_VENC_ReleaseStream:0x%x\n",s32Ret); free(stStream.pstPack); stStream.pstPack = NULL; return NULL; } free(stStream.pstPack); stStream.pstPack = NULL; } } u32FrameIdx ++; }while (bVencStopFlag != HI_TRUE); fclose(pFile); return HI_SUCCESS; }
HI_VOID * PCIV_ThreadSend(HI_VOID *p) { HI_S32 s32Ret, i, j, k, s32DstTarget, s32LocalId, s32SndPort; HI_S32 s32Size, s32Offset[PCIV_MAX_DEV_NUM][PCIV_MAX_PORT_NUM]; HI_BOOL bHit; VENC_CHN vencChn; VB_BLK vbBlkHdl; const HI_U32 u32BlkSize = 0x20000; PCIV_MSGHEAD_S stMsgSend; PCIV_DEVICE_S stDev; VENC_STREAM_S stVStream[PCIV_MAX_DEV_NUM][PCIV_MAX_PORT_NUM]; VENC_PACK_S stPack[PCIV_MAX_DEV_NUM][PCIV_MAX_PORT_NUM][128]; PCIV_STREAM_CREATOR_S *pCreator = NULL; PCIV_NOTIFY_STREAMWRITE_S *pStreamInfo = NULL; s32DstTarget = ((PCIV_THREAD_PARAM_S *)p)->s32DstTarget; s32LocalId = ((PCIV_THREAD_PARAM_S *)p)->s32LocalId; /* If the local device is the host */ if(s32LocalId == 0) { s32SndPort = PCIV_MSGPORT_USERNOTIFY2SLAVE; } else { s32SndPort = PCIV_MSGPORT_USERNOTIFY2HOST; } memset(stPack, 0, sizeof(stPack)); memset(stVStream, 0, sizeof(stVStream)); for(i=0; i<PCIV_MAX_DEV_NUM; i++) { for(j=0; j<PCIV_MAX_PORT_NUM; j++) { stVStream[i][j].pstPack = stPack[i][j]; s32Offset[i][j] = -1; } } while(1) { bHit = HI_FALSE; for(i=0; i<PCIV_MAX_DEV_NUM; i++) { for(j=0; j<PCIV_MAX_PORT_NUM; j++) { stDev.s32PciDev = i; stDev.s32Port = j; pCreator = PCIV_GetCreater(&stDev); if(pCreator->s32TargetId == -1) continue; if((pCreator->vencChn == -1) && (pCreator->pFile == NULL)) continue; /* Get new stream from venc */ /* If last frame is not send out then try again */ vencChn = pCreator->vencChn; if(stVStream[i][j].u32PackCount == 0) { if(vencChn != -1) { s32Ret = PCIV_GetStreamFromVenc(vencChn, &stVStream[i][j]); if(s32Ret != HI_SUCCESS) { continue; } /* Only when get a new frame we set te hit flag */ bHit = HI_TRUE; } else { vbBlkHdl = HI_MPI_VB_GetBlock(VB_INVALID_POOLID, u32BlkSize); if(vbBlkHdl == VB_INVALID_HANDLE) { printf("No free block\n"); continue; } s32Ret = PCIV_GetStreamFromFile(pCreator->pFile, &stVStream[i][j]); if(s32Ret != HI_SUCCESS) { continue; } } } /* If the last buffer is not used then do not malloc new */ if( s32Offset[i][j] == -1) { s32Size = 0; for(k=0; k<stVStream[i][j].u32PackCount; k++) { s32Size += stVStream[i][j].pstPack[k].u32Len[0]; s32Size += stVStream[i][j].pstPack[k].u32Len[1]; } s32Ret = PCIV_GetBuffer(&stDev, s32Size, &s32Offset[i][j]); if(HI_SUCCESS != s32Ret) { continue; } /* Only when get a new frame we set te hit flag */ bHit = HI_TRUE; } /* Call the driver to send on frame. */ { PCIV_DMA_TASK_S stTask; PCIV_DMA_BLOCK_S stDmaBlk[PCIV_MAX_DMABLK]; HI_U32 u32Count, u32DstAddr; u32Count = 0; s32Size = 0; u32DstAddr = pCreator->stBuffer.s32BaseAddr + s32Offset[i][j]; for(k=0; k<stVStream[i][j].u32PackCount; k++) { stDmaBlk[u32Count].u32BlkSize = stVStream[i][j].pstPack[k].u32Len[0]; stDmaBlk[u32Count].u32DstAddr = u32DstAddr + (HI_U32)s32Size; s32Size += stDmaBlk[u32Count].u32BlkSize; stDmaBlk[u32Count].u32SrcAddr = stVStream[i][j].pstPack[k].u32PhyAddr[0]; u32Count++; if(stVStream[i][j].pstPack[k].u32Len[1] == 0) { continue; } stDmaBlk[u32Count].u32BlkSize = stVStream[i][j].pstPack[k].u32Len[1]; stDmaBlk[u32Count].u32DstAddr = u32DstAddr + (HI_U32)s32Size; s32Size += stDmaBlk[u32Count].u32BlkSize; stDmaBlk[u32Count].u32SrcAddr = stVStream[i][j].pstPack[k].u32PhyAddr[1]; u32Count++; } stTask.pBlock = &stDmaBlk[0]; stTask.u32Count = u32Count; stTask.bRead = HI_FALSE; s32Ret = HI_MPI_PCIV_DmaTask(&stTask); while(HI_ERR_PCIV_BUSY == s32Ret) { usleep(0); s32Ret = HI_MPI_PCIV_DmaTask(&stTask); } } if(HI_SUCCESS != s32Ret) { continue; } /* Notify the receiver */ stMsgSend.enDevType = PCIV_DEVTYPE_PCIV; stMsgSend.enMsgType = PCIV_MSGTYPE_WRITEDONE; stMsgSend.u32MsgLen = sizeof(PCIV_NOTIFY_STREAMWRITE_S); stMsgSend.u32Target = pCreator->s32TargetId; pStreamInfo = (PCIV_NOTIFY_STREAMWRITE_S *)&stMsgSend.cMsgBody; pStreamInfo->stDstDev.s32PciDev = pCreator->stTargetPciDev.s32PciDev; pStreamInfo->stDstDev.s32Port = pCreator->stTargetPciDev.s32Port; pStreamInfo->s32Start = s32Offset[i][j]; pStreamInfo->s32End = s32Offset[i][j] + s32Size; pStreamInfo->u32Seq = stVStream[i][j].u32Seq; pStreamInfo->u64PTS = stVStream[i][j].pstPack[0].u64PTS; pStreamInfo->bFieldEnd = stVStream[i][j].pstPack[0].bFieldEnd; pStreamInfo->bFrameEnd = stVStream[i][j].pstPack[0].bFrameEnd; pStreamInfo->enDataType = stVStream[i][j].pstPack[0].DataType; if(s32LocalId == 0) { s32Ret = PCIV_SendMsg(stMsgSend.u32Target, s32SndPort, &stMsgSend); } else { s32Ret = PCIV_SendMsg(0, s32SndPort, &stMsgSend); } HI_ASSERT((HI_FAILURE != s32Ret)); if(vencChn != -1) { s32Ret = HI_MPI_VENC_ReleaseStream(vencChn,&stVStream[i][j]); HI_ASSERT((HI_SUCCESS == s32Ret)); } else { } stVStream[i][j].u32PackCount = 0; stVStream[i][j].u32Seq = 0; s32Offset[i][j] = -1; } } if(!bHit) { usleep(0); } } }
/* ** Function: ** 1. If the message target is not the host then transmit it. ** 2. If */ HI_VOID * PCIV_ThreadRev(HI_VOID *p) { HI_S32 s32Ret, s32DstTarget, s32LocalId, s32RevPort, s32SndPort; PCIV_MSGHEAD_S stMsgRev, stMsgEcho; PCIV_NOTIFY_STREAMWRITE_S *pStreamInfo = NULL; PCIV_NOTIFY_STREAMREAD_S *pReadInfo = NULL; PCIV_STREAM_RECEIVER_S *pReceiver = NULL; s32DstTarget = ((PCIV_THREAD_PARAM_S *)p)->s32DstTarget; s32LocalId = ((PCIV_THREAD_PARAM_S *)p)->s32LocalId; /* If the local device is the host */ if(s32LocalId == 0) { s32RevPort = PCIV_MSGPORT_USERNOTIFY2HOST; s32SndPort = PCIV_MSGPORT_USERNOTIFY2SLAVE; } else { s32RevPort = PCIV_MSGPORT_USERNOTIFY2SLAVE; s32SndPort = PCIV_MSGPORT_USERNOTIFY2HOST; } while(1) { s32Ret = PCIV_ReadMsg(s32DstTarget, s32RevPort, &stMsgRev); HI_ASSERT((HI_SUCCESS == s32Ret)); /* If not send to the host then transmit it */ if((s32LocalId == 0) && (stMsgRev.u32Target != 0)) { s32Ret = PCIV_SendMsg(stMsgRev.u32Target, s32SndPort,&stMsgRev); HI_ASSERT(HI_FAILURE != s32Ret); continue; } if(stMsgRev.enDevType != PCIV_DEVTYPE_PCIV) { printf("Device Type %d is wrong\n", stMsgRev.enDevType); continue; } /* If read end message is send to host then free the buffer */ pReadInfo = (PCIV_NOTIFY_STREAMREAD_S *)&stMsgRev.cMsgBody; if(stMsgRev.enMsgType == PCIV_MSGTYPE_READDONE) { s32Ret = PCIV_ReleaseBuffer(&pReadInfo->stDstDev, pReadInfo->s32End); HI_ASSERT(HI_SUCCESS == s32Ret); continue; } /* Process the stream */ pStreamInfo = (PCIV_NOTIFY_STREAMWRITE_S *)&stMsgRev.cMsgBody; pReceiver = PCIV_GetReceiver(&pStreamInfo->stDstDev); HI_ASSERT(NULL != pReceiver); if(pReceiver->pRevStreamFun != NULL) { pReceiver->pRevStreamFun(s32LocalId, pStreamInfo); } /* The data is used, then we free it */ stMsgEcho.enDevType = PCIV_DEVTYPE_PCIV; stMsgEcho.enMsgType = PCIV_MSGTYPE_READDONE; stMsgEcho.u32MsgLen = sizeof(PCIV_NOTIFY_STREAMREAD_S); stMsgEcho.u32Target = pReceiver->s32TargetId; pReadInfo = (PCIV_NOTIFY_STREAMREAD_S *)&stMsgEcho.cMsgBody; pReadInfo->stDstDev.s32PciDev = pReceiver->stTargetPciDev.s32PciDev; pReadInfo->stDstDev.s32Port = pReceiver->stTargetPciDev.s32Port; pReadInfo->s32Start = pStreamInfo->s32Start; pReadInfo->s32End = pStreamInfo->s32End; if(s32LocalId == 0) { HI_ASSERT(stMsgEcho.u32Target == s32DstTarget); s32Ret = PCIV_SendMsg(stMsgEcho.u32Target, s32SndPort,&stMsgEcho); } else { s32Ret = PCIV_SendMsg(0, s32SndPort,&stMsgEcho); } HI_ASSERT(HI_FAILURE != s32Ret); } }