/** Get buffer size based on data format pFormat - data format information *size - buffer size *cOffset - C plane offset for YUV420SP data */ Int32 Utils_memFrameGetSize(FVID2_Format * pFormat, UInt32 * size, UInt32 * cOffset) { UInt32 bufferHeight; Int32 status = 0; bufferHeight = pFormat->height; switch (pFormat->dataFormat) { case FVID2_DF_YUV422I_YUYV: case FVID2_DF_YUV422I_YVYU: case FVID2_DF_YUV422I_UYVY: case FVID2_DF_YUV422I_VYUY: case FVID2_DF_YUV444I: case FVID2_DF_RGB24_888: case FVID2_DF_RAW_VBI: /* for single plane data format's */ *size = pFormat->pitch[0] * bufferHeight; break; case FVID2_DF_YUV422SP_UV: case FVID2_DF_YUV420SP_UV: /* for Y plane */ *size = pFormat->pitch[0] * bufferHeight; /* cOffset is at end of Y plane */ *cOffset = *size; if (pFormat->dataFormat == FVID2_DF_YUV420SP_UV) { /* C plane height is 1/2 of Y plane */ bufferHeight = bufferHeight / 2; } /* for C plane */ *size += pFormat->pitch[1] * bufferHeight; break; default: /* illegal data format */ status = -1; break; } /* align size to minimum required frame buffer alignment */ *size = VpsUtils_align(*size, VPS_BUFFER_ALIGNMENT); return status; }
static Int32 HelloWorldLink_createOutObj(HelloWorldLink_Obj * pObj) { HelloWorldLink_OutObj *pOutObj; System_LinkChInfo *pOutChInfo; Int32 status; UInt32 bufIdx; Int i,j,queueId,chId; UInt32 totalBufCnt; /*************************************************************************/ /* One link can have multiple output queues with different/same output */ /* data queued to it's output queue. Create here outobj for all output */ /* queue */ /*************************************************************************/ for(queueId = 0; queueId < HELLOWORLD_LINK_MAX_OUT_QUE; queueId++) { pOutObj = &pObj->outObj[queueId]; pObj->outObj[queueId].numAllocPools = 1; pOutObj->bufSize[0] = HELLOWORLD_LINK_OUT_BUF_SIZE; /*********************************************************************/ /* Set the buffer alignment as per need. Typically 128 suggested for */ /* better cache and DMA efficiency. */ /*********************************************************************/ pOutObj->bufSize[0] = VpsUtils_align(pOutObj->bufSize[0], HELLOWORLD_BUFFER_ALIGNMENT); /*********************************************************************/ /* Create output queue */ /*********************************************************************/ status = Utils_bitbufCreate(&pOutObj->bufOutQue, TRUE, FALSE, pObj->outObj[queueId].numAllocPools); UTILS_assert(status == FVID2_SOK); totalBufCnt = 0; /*********************************************************************/ /* Allocate output buffers */ /*********************************************************************/ for (i = 0; i < pOutObj->numAllocPools; i++) { /*****************************************************************/ /* Number of output buffers per channel. In this example hello */ /* world, outNumBufs set via user input. */ /*****************************************************************/ pOutObj->outNumBufs[i] = (pObj->createArgs.maxChannels * pObj->createArgs.numBufsPerCh); for (j = 0; j < pObj->createArgs.maxChannels; j++) { pOutObj->ch2poolMap[j] = i; } /*****************************************************************/ /* Allocate the buffer from shared memory pool for bitstream */ /* buffer. If you like to allocate memory for frame buffers, */ /* you can either call Utils_tilerFrameAlloc() to allocate */ /* memory from tiler memory or you can call Utils_memFrameAlloc */ /* to allocate memory from shared buffer pool */ /*****************************************************************/ status = Utils_memBitBufAlloc(&(pOutObj->outBufs[totalBufCnt]), pOutObj->bufSize[i], pOutObj->outNumBufs[i]); UTILS_assert(status == FVID2_SOK); /*****************************************************************/ /* Push the buffers to the output queue that's just been created */ /*****************************************************************/ for (bufIdx = 0; bufIdx < pOutObj->outNumBufs[i]; bufIdx++) { UTILS_assert((bufIdx + totalBufCnt) < HELLOWORLD_LINK_MAX_OUT_FRAMES); pOutObj->outBufs[bufIdx + totalBufCnt].allocPoolID = i; pOutObj->outBufs[bufIdx + totalBufCnt].doNotDisplay = FALSE; status = Utils_bitbufPutEmptyBuf(&pOutObj->bufOutQue, &pOutObj->outBufs[bufIdx + totalBufCnt]); UTILS_assert(status == FVID2_SOK); } totalBufCnt += pOutObj->outNumBufs[i]; } } pObj->info.numQue = HELLOWORLD_LINK_MAX_OUT_QUE; /*************************************************************************/ /* queInfo is used by next link to create it's instance. */ /* Set numCh - number of channel information */ /*************************************************************************/ for (queueId = 0u; queueId < HELLOWORLD_LINK_MAX_OUT_QUE; queueId++) { pObj->info.queInfo[queueId].numCh = pObj->inQueInfo.numCh; } /*************************************************************************/ /* Set the information for output buffer of each channel. Again, next */ /* link connected to hello world link will use this information to */ /* create it's own instance. */ /*************************************************************************/ for (chId = 0u; chId < pObj->inQueInfo.numCh; chId++) { for (queueId = 0u; queueId < HELLOWORLD_LINK_MAX_OUT_QUE; queueId++) { pOutChInfo = &pObj->info.queInfo[queueId].chInfo[chId]; pOutChInfo->bufType = SYSTEM_BUF_TYPE_VIDBITSTREAM; pOutChInfo->codingformat = NULL; pOutChInfo->memType = NULL; pOutChInfo->scanFormat = pObj->inQueInfo.chInfo[chId].scanFormat; pOutChInfo->width = pObj->inQueInfo.chInfo[chId].width; pOutChInfo->height = pObj->inQueInfo.chInfo[chId].height; } } return (status); }
Int32 Utils_tilerFrameAlloc(FVID2_Format * pFormat, FVID2_Frame * pFrame, UInt16 numFrames) { UInt32 frameId; /* align height to multiple of 2 */ pFormat->height = VpsUtils_align(pFormat->height, 2); for (frameId = 0; frameId < numFrames; frameId++) { /* init FVID2_Frame to 0's */ memset(pFrame, 0, sizeof(*pFrame)); /* copy channelNum to FVID2_Frame from FVID2_Format */ pFrame->channelNum = pFormat->channelNum; switch (pFormat->dataFormat) { case FVID2_DF_YUV422SP_UV: /* Y plane */ pFrame->addr[0][0] = (Ptr) SystemTiler_alloc(SYSTEM_TILER_CNT_8BIT, pFormat->width, pFormat->height); UTILS_assert((UInt32)(pFrame->addr[0][0]) != SYSTEM_TILER_INVALID_ADDR); /* C plane */ pFrame->addr[0][1] = (Ptr) SystemTiler_alloc(SYSTEM_TILER_CNT_16BIT, pFormat->width, pFormat->height); UTILS_assert((UInt32)(pFrame->addr[0][1]) != SYSTEM_TILER_INVALID_ADDR); break; case FVID2_DF_YUV420SP_UV: /* Y plane */ pFrame->addr[0][0] = (Ptr) SystemTiler_alloc(SYSTEM_TILER_CNT_8BIT, pFormat->width, pFormat->height); if ((UInt32)pFrame->addr[0][0] == SYSTEM_TILER_INVALID_ADDR) System_memPrintHeapStatus(); UTILS_assert((UInt32)(pFrame->addr[0][0]) != SYSTEM_TILER_INVALID_ADDR); /* C plane */ pFrame->addr[0][1] = (Ptr) SystemTiler_alloc(SYSTEM_TILER_CNT_16BIT, pFormat->width, pFormat->height / 2); if ((UInt32)pFrame->addr[0][1] == SYSTEM_TILER_INVALID_ADDR) System_memPrintHeapStatus(); UTILS_assert((UInt32)(pFrame->addr[0][1]) != SYSTEM_TILER_INVALID_ADDR); break; default: UTILS_assert(0); break; } pFrame++; } return 0; }
static Int32 AlgLink_createOutObj(AlgLink_Obj * pObj) { AlgLink_OutObj *pOutObj; System_LinkChInfo *pOutChInfo; Int32 status; UInt32 bufIdx; Int i,j,queueId,chId; UInt32 totalBufCnt; for(queueId = 0; queueId < ALG_LINK_MAX_OUT_QUE; queueId++) { pOutObj = &pObj->outObj[queueId]; pObj->outObj[queueId].numAllocPools = 1; pOutObj->buf_size[0] = UTILS_SCD_GET_OUTBUF_SIZE(); pOutObj->buf_size[0] = VpsUtils_align(pOutObj->buf_size[0], SharedRegion_getCacheLineSize(SYSTEM_IPC_SR_CACHED)); status = Utils_bitbufCreate(&pOutObj->bufOutQue, TRUE, FALSE, pObj->outObj[queueId].numAllocPools); UTILS_assert(status == FVID2_SOK); totalBufCnt = 0; for (i = 0; i < pOutObj->numAllocPools; i++) { pOutObj->outNumBufs[i] = (pObj->scdAlg.createArgs.numValidChForSCD * pObj->scdAlg.createArgs.numBufPerCh); for (j = 0; j < pObj->scdAlg.createArgs.numValidChForSCD; j++) { pOutObj->ch2poolMap[j] = i; } status = Utils_memBitBufAlloc(&(pOutObj->outBufs[totalBufCnt]), pOutObj->buf_size[i], pOutObj->outNumBufs[i]); UTILS_assert(status == FVID2_SOK); for (bufIdx = 0; bufIdx < pOutObj->outNumBufs[i]; bufIdx++) { UTILS_assert((bufIdx + totalBufCnt) < ALG_LINK_SCD_MAX_OUT_FRAMES); pOutObj->outBufs[bufIdx + totalBufCnt].allocPoolID = i; pOutObj->outBufs[bufIdx + totalBufCnt].doNotDisplay = FALSE; status = Utils_bitbufPutEmptyBuf(&pOutObj->bufOutQue, &pOutObj->outBufs[bufIdx + totalBufCnt]); UTILS_assert(status == FVID2_SOK); } /* align size to minimum required frame buffer alignment */ totalBufCnt += pOutObj->outNumBufs[i]; } } pObj->info.numQue = ALG_LINK_MAX_OUT_QUE; for (queueId = 0u; queueId < ALG_LINK_MAX_OUT_QUE; queueId++) { pObj->info.queInfo[queueId].numCh = pObj->inQueInfo.numCh; } for (chId = 0u; chId < pObj->inQueInfo.numCh; chId++) { for (queueId = 0u; queueId < ALG_LINK_MAX_OUT_QUE; queueId++) { pOutChInfo = &pObj->info.queInfo[queueId].chInfo[chId]; pOutChInfo->bufType = SYSTEM_BUF_TYPE_VIDBITSTREAM; pOutChInfo->codingformat = NULL; pOutChInfo->memType = NULL; pOutChInfo->scanFormat = pObj->inQueInfo.chInfo[chId].scanFormat; pOutChInfo->width = pObj->inQueInfo.chInfo[chId].width; pOutChInfo->height = pObj->inQueInfo.chInfo[chId].height; } } return (status); }
Int32 Utils_memBitBufAlloc(Bitstream_Buf * pBuf, UInt32 size, UInt16 numFrames) { UInt32 bufId; Int32 status = 0; UInt8 *pBaseAddr; Error_Block ebObj; Error_Block *eb = &ebObj; Error_init(eb); /* init Bitstream_Buf to 0's */ memset(pBuf, 0, sizeof(*pBuf)); /* align size to minimum required frame buffer alignment */ size = VpsUtils_align(size, IVACODEC_VDMA_BUFFER_ALIGNMENT); /* allocate the memory for 'numFrames' */ /* for all 'numFrames' memory is contigously allocated */ pBaseAddr = Memory_alloc(gUtils_heapMemHandle[UTILS_MEM_VID_BITS_BUF_HEAP], (size * numFrames), IVACODEC_VDMA_BUFFER_ALIGNMENT, eb); #ifdef UTILS_MEM_DEBUG Vps_printf(" UTILS: MEM: BITS ALLOC, addr = 0x%08x, size = %d bytes\n", pBaseAddr, (size * numFrames)); #endif if (!Error_check(eb) && (pBaseAddr != NULL) && gUtils_memClearBuf[UTILS_MEM_VID_BITS_BUF_HEAP]) memset(pBaseAddr, 0x80, (size * numFrames)); if (pBaseAddr == NULL) { status = -1; /* Error in * allocation, * exit with error */ } if (!UTILS_ISERROR(status)) { /* init memory pointer for 'numFrames' */ for (bufId = 0; bufId < numFrames; bufId++) { /* copy channelNum to Bitstream_Buf from FVID2_Format */ pBuf->channelNum = bufId; pBuf->addr = pBaseAddr; /* On the RTOS side, we assume Virtual addr == PhyAddr */ pBuf->phyAddr = (UInt32)pBaseAddr; pBuf->bufSize = size; /* go to next frame */ pBuf++; /* increment base address */ pBaseAddr += size; } } UTILS_assert(status == 0); return status; }
Int32 Utils_memFrameAlloc(FVID2_Format * pFormat, FVID2_Frame * pFrame, UInt16 numFrames) { UInt32 size, cOffset, frameId; Int32 status; UInt8 *pBaseAddr; /* init FVID2_Frame to 0's */ memset(pFrame, 0, sizeof(*pFrame)); /* align height to multiple of 2 */ pFormat->height = VpsUtils_align(pFormat->height, 2); /* get frame size for given pFormat */ status = Utils_memFrameGetSize(pFormat, &size, &cOffset); if (status == 0) { /* allocate the memory for 'numFrames' */ /* for all 'numFrames' memory is contigously allocated */ pBaseAddr = Utils_memAlloc(size * numFrames, VPS_BUFFER_ALIGNMENT); if (pBaseAddr == NULL) { status = -1; /* Error in * allocation, * exit with error */ } } if (status == 0) { /* init memory pointer for 'numFrames' */ for (frameId = 0; frameId < numFrames; frameId++) { /* copy channelNum to FVID2_Frame from FVID2_Format */ pFrame->channelNum = pFormat->channelNum; pFrame->addr[0][0] = pBaseAddr; switch (pFormat->dataFormat) { case FVID2_DF_RAW_VBI: case FVID2_DF_YUV422I_UYVY: case FVID2_DF_YUV422I_VYUY: case FVID2_DF_YUV422I_YUYV: case FVID2_DF_YUV422I_YVYU: case FVID2_DF_YUV444I: case FVID2_DF_RGB24_888: break; case FVID2_DF_YUV422SP_UV: case FVID2_DF_YUV420SP_UV: /* assign pointer for C plane */ pFrame->addr[0][1] = (UInt8 *) pFrame->addr[0][0] + cOffset; break; default: /* illegal data format */ status = -1; break; } /* go to next frame */ pFrame++; /* increment base address */ pBaseAddr += size; } } if (status != 0) Vps_printf("Memory allocation failed due to insufficient free memory \n"); /* commented out, so please always check the status immediately after the * Utils_memFrameAlloc() call and handle accordingly */ // UTILS_assert(status == 0); return status; }