/****************************************************************************** * function : 1D1 User send pictures for H264 encode ******************************************************************************/ HI_S32 SAMPLE_VENC_1D1_USER_SEND_PICTURES(HI_VOID) { VB_CONF_S stVbConf; VENC_GRP VencGrp = 0; VENC_CHN VencChn = 0; PIC_SIZE_E enSize = PIC_D1; HI_S32 s32Ret = HI_SUCCESS; HI_U32 u32BlkSize; SIZE_S stSize; VB_POOL hPool = VB_INVALID_POOLID; FILE *pfp_img = HI_NULL; HI_U32 u32PicLStride = 0; HI_U32 u32PicCStride = 0; HI_U32 u32LumaSize = 0; HI_U32 u32ChrmSize = 0; HI_U32 u32Cnt = 0; HI_U32 u32ChnCnt = 1; /****************************************** step 1: init variable ******************************************/ memset(&stVbConf,0,sizeof(VB_CONF_S)); u32BlkSize = SAMPLE_COMM_SYS_CalcPicVbBlkSize(gs_enNorm,\ enSize, SAMPLE_PIXEL_FORMAT, SAMPLE_SYS_ALIGN_WIDTH); stVbConf.u32MaxPoolCnt = 128; /*ddr0 video buffer*/ stVbConf.astCommPool[0].u32BlkSize = u32BlkSize; stVbConf.astCommPool[0].u32BlkCnt = 10; memset(stVbConf.astCommPool[0].acMmzName,0, sizeof(stVbConf.astCommPool[0].acMmzName)); /****************************************** step 2: mpp system init. ******************************************/ s32Ret = SAMPLE_COMM_SYS_Init(&stVbConf); if (HI_SUCCESS != s32Ret) { SAMPLE_PRT("system init failed with %d!\n", s32Ret); goto END_VENC_USER_0; } /****************************************** step 3: open yuv file ******************************************/ if (pfp_img != HI_NULL) { fclose(pfp_img); pfp_img = HI_NULL; } pfp_img = fopen(SAMPLE_YUV_D1_FILEPATH, "rb" ); if (pfp_img == HI_NULL) { SAMPLE_PRT("Open yuv file failed!Check if the file %s exit\n",SAMPLE_YUV_D1_FILEPATH); goto END_VENC_USER_0; } /****************************************** step 4: create private pool on ddr0 ******************************************/ hPool = HI_MPI_VB_CreatePool( u32BlkSize, 10,NULL ); if (hPool == VB_INVALID_POOLID) { SAMPLE_PRT("HI_MPI_VB_CreatePool failed! \n"); goto END_VENC_USER_1; } /****************************************** step 5: encode process ******************************************/ s32Ret = SAMPLE_COMM_SYS_GetPicSize(gs_enNorm, enSize, &stSize); if (HI_SUCCESS != s32Ret) { SAMPLE_PRT("SAMPLE_COMM_SYS_GetPicSize failed!\n"); goto END_VENC_USER_2; } s32Ret = SAMPLE_COMM_VENC_Start(VencGrp, VencChn, PT_H264, gs_enNorm, enSize, SAMPLE_RC_CBR); if (HI_SUCCESS != s32Ret) { SAMPLE_PRT("Start snap failed!\n"); goto END_VENC_USER_2; } /****************************************** step 6: stream venc process -- get stream, then save it to file. ******************************************/ s32Ret = SAMPLE_COMM_VENC_StartGetStream(u32ChnCnt); if (HI_SUCCESS != s32Ret) { SAMPLE_PRT("StartGetStream failed!\n"); goto END_VENC_USER_3; } u32PicLStride = CEILING_2_POWER(stSize.u32Width, SAMPLE_SYS_ALIGN_WIDTH); u32PicCStride = CEILING_2_POWER(stSize.u32Width, SAMPLE_SYS_ALIGN_WIDTH); u32LumaSize = (u32PicLStride * stSize.u32Height); u32ChrmSize = (u32PicCStride * stSize.u32Height) >> 2; while(0 == feof(pfp_img)) { SAMPLE_MEMBUF_S stMem = {0}; VIDEO_FRAME_INFO_S stFrmInfo; stMem.hPool = hPool; u32Cnt ++; while((stMem.hBlock = HI_MPI_VB_GetBlock(stMem.hPool, u32BlkSize,NULL)) == VB_INVALID_HANDLE) { ; } stMem.u32PhyAddr = HI_MPI_VB_Handle2PhysAddr(stMem.hBlock); stMem.pVirAddr = (HI_U8 *) HI_MPI_SYS_Mmap( stMem.u32PhyAddr, u32BlkSize ); if(stMem.pVirAddr == NULL) { SAMPLE_PRT("Mem dev may not open\n"); goto END_VENC_USER_4; } memset(&stFrmInfo.stVFrame, 0, sizeof(VIDEO_FRAME_S)); stFrmInfo.stVFrame.u32PhyAddr[0] = stMem.u32PhyAddr; stFrmInfo.stVFrame.u32PhyAddr[1] = stFrmInfo.stVFrame.u32PhyAddr[0] + u32LumaSize; stFrmInfo.stVFrame.u32PhyAddr[2] = stFrmInfo.stVFrame.u32PhyAddr[1] + u32ChrmSize; stFrmInfo.stVFrame.pVirAddr[0] = stMem.pVirAddr; stFrmInfo.stVFrame.pVirAddr[1] = (HI_U8 *) stFrmInfo.stVFrame.pVirAddr[0] + u32LumaSize; stFrmInfo.stVFrame.pVirAddr[2] = (HI_U8 *) stFrmInfo.stVFrame.pVirAddr[1] + u32ChrmSize; stFrmInfo.stVFrame.u32Width = stSize.u32Width; stFrmInfo.stVFrame.u32Height = stSize.u32Height; stFrmInfo.stVFrame.u32Stride[0] = u32PicLStride; stFrmInfo.stVFrame.u32Stride[1] = u32PicLStride; stFrmInfo.stVFrame.u32Stride[2] = u32PicLStride; stFrmInfo.stVFrame.u64pts = (u32Cnt * 40); stFrmInfo.stVFrame.u32TimeRef = (u32Cnt * 2); /* Different channsel with different picture sequence */ SAMPLE_COMM_VENC_ReadOneFrame( pfp_img, stFrmInfo.stVFrame.pVirAddr[0], stFrmInfo.stVFrame.pVirAddr[1], stFrmInfo.stVFrame.pVirAddr[2], stFrmInfo.stVFrame.u32Width, stFrmInfo.stVFrame.u32Height, stFrmInfo.stVFrame.u32Stride[0], stFrmInfo.stVFrame.u32Stride[1] >> 1 ); SAMPLE_COMM_VENC_PlanToSemi( stFrmInfo.stVFrame.pVirAddr[0], stFrmInfo.stVFrame.u32Stride[0], stFrmInfo.stVFrame.pVirAddr[1], stFrmInfo.stVFrame.u32Stride[1], stFrmInfo.stVFrame.pVirAddr[2], stFrmInfo.stVFrame.u32Stride[1], stFrmInfo.stVFrame.u32Width, stFrmInfo.stVFrame.u32Height ); stFrmInfo.stVFrame.enPixelFormat = SAMPLE_PIXEL_FORMAT; stFrmInfo.stVFrame.u32Field = VIDEO_FIELD_FRAME; stMem.u32PoolId = HI_MPI_VB_Handle2PoolId( stMem.hBlock ); stFrmInfo.u32PoolId = stMem.u32PoolId; s32Ret = HI_MPI_VENC_SendFrame(VencGrp, &stFrmInfo); HI_MPI_SYS_Munmap( stMem.pVirAddr, u32BlkSize ); HI_MPI_VB_ReleaseBlock(stMem.hBlock); } /****************************************** step 7: exit process ******************************************/ END_VENC_USER_4: SAMPLE_COMM_VENC_StopGetStream(); END_VENC_USER_3: s32Ret = SAMPLE_COMM_VENC_Stop(VencGrp,VencChn);; if (HI_SUCCESS != s32Ret) { SAMPLE_PRT("Stop encode failed!\n"); goto END_VENC_USER_2; } END_VENC_USER_2: //before destroy private pool,must stop venc HI_MPI_VB_DestroyPool( hPool ); END_VENC_USER_1: //close the yuv file fclose( pfp_img ); pfp_img = HI_NULL; END_VENC_USER_0: //system exit SAMPLE_COMM_SYS_Exit(); return s32Ret; }
/****************************************************************************** * function : Get from YUV ******************************************************************************/ HI_S32 SAMPLE_COMM_VI_GetVFrameFromYUV(FILE *pYUVFile, HI_U32 u32Width, HI_U32 u32Height,HI_U32 u32Stride, VIDEO_FRAME_INFO_S *pstVFrameInfo) { HI_U32 u32LStride; HI_U32 u32CStride; HI_U32 u32LumaSize; HI_U32 u32ChrmSize; HI_U32 u32Size; VB_BLK VbBlk; HI_U32 u32PhyAddr; HI_U8 *pVirAddr; u32LStride = u32Stride; u32CStride = u32Stride; u32LumaSize = (u32LStride * u32Height); u32ChrmSize = (u32CStride * u32Height) >> 2;/* YUV 420 */ u32Size = u32LumaSize + (u32ChrmSize << 1); /* alloc video buffer block ---------------------------------------------------------- */ VbBlk = HI_MPI_VB_GetBlock(VB_INVALID_POOLID, u32Size, NULL); if (VB_INVALID_HANDLE == VbBlk) { SAMPLE_PRT("HI_MPI_VB_GetBlock err! size:%d\n",u32Size); return -1; } u32PhyAddr = HI_MPI_VB_Handle2PhysAddr(VbBlk); if (0 == u32PhyAddr) { return -1; } pVirAddr = (HI_U8 *) HI_MPI_SYS_Mmap(u32PhyAddr, u32Size); if (NULL == pVirAddr) { return -1; } pstVFrameInfo->u32PoolId = HI_MPI_VB_Handle2PoolId(VbBlk); if (VB_INVALID_POOLID == pstVFrameInfo->u32PoolId) { return -1; } SAMPLE_PRT("pool id :%d, phyAddr:%x,virAddr:%x\n" ,pstVFrameInfo->u32PoolId,u32PhyAddr,(int)pVirAddr); pstVFrameInfo->stVFrame.u32PhyAddr[0] = u32PhyAddr; pstVFrameInfo->stVFrame.u32PhyAddr[1] = pstVFrameInfo->stVFrame.u32PhyAddr[0] + u32LumaSize; pstVFrameInfo->stVFrame.u32PhyAddr[2] = pstVFrameInfo->stVFrame.u32PhyAddr[1] + u32ChrmSize; pstVFrameInfo->stVFrame.pVirAddr[0] = pVirAddr; pstVFrameInfo->stVFrame.pVirAddr[1] = pstVFrameInfo->stVFrame.pVirAddr[0] + u32LumaSize; pstVFrameInfo->stVFrame.pVirAddr[2] = pstVFrameInfo->stVFrame.pVirAddr[1] + u32ChrmSize; pstVFrameInfo->stVFrame.u32Width = u32Width; pstVFrameInfo->stVFrame.u32Height = u32Height; pstVFrameInfo->stVFrame.u32Stride[0] = u32LStride; pstVFrameInfo->stVFrame.u32Stride[1] = u32CStride; pstVFrameInfo->stVFrame.u32Stride[2] = u32CStride; pstVFrameInfo->stVFrame.enPixelFormat = PIXEL_FORMAT_YUV_SEMIPLANAR_420; pstVFrameInfo->stVFrame.u32Field = VIDEO_FIELD_INTERLACED;/* Intelaced D1,otherwise VIDEO_FIELD_FRAME */ /* read Y U V data from file to the addr ----------------------------------------------*/ SAMPLE_COMM_VI_ReadFrame(pYUVFile, pstVFrameInfo->stVFrame.pVirAddr[0], pstVFrameInfo->stVFrame.pVirAddr[1], pstVFrameInfo->stVFrame.pVirAddr[2], pstVFrameInfo->stVFrame.u32Width, pstVFrameInfo->stVFrame.u32Height, pstVFrameInfo->stVFrame.u32Stride[0], pstVFrameInfo->stVFrame.u32Stride[1] >> 1 ); /* convert planar YUV420 to sem-planar YUV420 -----------------------------------------*/ SAMPLE_COMM_VI_PlanToSemi(pstVFrameInfo->stVFrame.pVirAddr[0], pstVFrameInfo->stVFrame.u32Stride[0], pstVFrameInfo->stVFrame.pVirAddr[1], pstVFrameInfo->stVFrame.u32Stride[1], pstVFrameInfo->stVFrame.pVirAddr[2], pstVFrameInfo->stVFrame.u32Stride[1], pstVFrameInfo->stVFrame.u32Width, pstVFrameInfo->stVFrame.u32Height); HI_MPI_SYS_Munmap(pVirAddr, u32Size); return 0; }
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); } } }