DvevmStRetCode dvtb_MPEG4Enc1Control(DvevmStMPEG4Enc1Info *ve) { int status = -1, i = 0; DvevmStRetCode retCode = DVEVM_ST_SUCCESS; ASSERT(ve != NULL); ASSERT(ve->ceHdl != NULL); status = VIDENC1_control(ve->venc1Hdl, ve->venc1Cmd, (IVIDENC1_DynamicParams *) (&ve->venc1DynParams), (IVIDENC1_Status *) (&ve->venc1Status)); if (VIDENC1_EOK != status) { SYS_ERROR("Error (%d), Codec Error (%d) in Video Encoder Control\n", status, (int) ve->venc1Status.videncStatus.extendedError); retCode = DVEVM_ST_FAIL; } else { if (XDM_GETBUFINFO == ve->venc1Cmd) { ve->inBuf.numBufs = ve->venc1Status.videncStatus.bufInfo.minNumInBufs; for (i = 0; i < ve->inBuf.numBufs; i++) ve->inBuf.bufSizes[i] = ve->venc1Status.videncStatus.bufInfo.minInBufSize[i]; ve->outBuf.numBufs = ve->venc1Status.videncStatus.bufInfo.minNumOutBufs; for (i = 0; i < ve->outBuf.numBufs; i++) ve->outBuf.bufSizes[i] = ve->venc1Status.videncStatus.bufInfo.minOutBufSize[i]; } else if(XDM_GETSTATUS == ve->venc1Cmd) { if(ve->venc1Status.videncStatus.extendedError) { if(XDM_ISFATALERROR(ve->venc1Status.videncStatus.extendedError)) { SYS_ERROR("Exiting: Encode Failed with a Codec fatal error %x.\n", (int) ve->venc1Status.videncStatus.extendedError); retCode = DVEVM_ST_FAIL; } else SYS_DEBUG("Continue: Codec generated an non fatal error %x.\n", (int) ve->venc1Status.videncStatus.extendedError); } } } return retCode; }
XDAS_Int32 ALG_vidEncSetDynamicParams(ALG_VidEncObj *pObj) { XDAS_Int32 status; if(pObj==NULL) return OSA_EFAIL; //test only pObj->createPrm.qpinit = 36; pObj->createPrm.qpmin = 30; pObj->createPrm.qpmax = 50; pObj->createPrm.packetsize = 100; if(pObj->createPrm.codec==ALG_VID_CODEC_MJPEG) { OSA_mutexLock(&vnf_imcop_lock); OSA_mutexLock(&vicp_imcop_lock); ALG_jpgEncSetQvalue(pObj->hJpgEncode, pObj->createPrm.qValue); OSA_mutexUnlock(&vnf_imcop_lock); OSA_mutexUnlock(&vicp_imcop_lock); return OSA_SOK; } if(pObj->createPrm.codec==ALG_VID_CODEC_H264) { memcpy(&pObj->dynamicParams_h264, &H264VENC_TI_IH264VENC_DYNAMICPARAMS, sizeof(pObj->dynamicParams_h264)); pObj->dynamicParams.size = sizeof(pObj->dynamicParams_h264); } else if(pObj->createPrm.codec==ALG_VID_CODEC_MPEG4) { pObj->dynamicParams.size = sizeof(pObj->dynamicParams_mpeg4); } else { pObj->dynamicParams.size = sizeof(pObj->dynamicParams); } pObj->dynamicParams.inputHeight = pObj->createPrm.height; pObj->dynamicParams.inputWidth = pObj->createPrm.width; pObj->dynamicParams.targetBitRate = pObj->createPrm.bitrate < 0 ? 0 : pObj->createPrm.bitrate; pObj->dynamicParams.generateHeader = XDM_ENCODE_AU; pObj->dynamicParams.captureWidth = pObj->createPrm.offsetH; pObj->dynamicParams.targetFrameRate = pObj->createPrm.framerate; pObj->dynamicParams.refFrameRate = pObj->createPrm.framerate; pObj->dynamicParams.interFrameInterval = 0; pObj->dynamicParams.mbDataFlag = XDAS_FALSE; switch(pObj->createPrm.codec) { case ALG_VID_CODEC_H264: pObj->dynamicParams.intraFrameInterval = 0; pObj->dynamicParams.forceFrame = IVIDEO_NA_FRAME;//(pObj->createPrm.forceKeyFrame==TRUE)?IVIDEO_IDR_FRAME:IVIDEO_NA_FRAME; pObj->dynamicParams_h264.sliceSize = ((pObj->createPrm.height/16)*pObj->createPrm.packetsize)/100; pObj->dynamicParams_h264.airRate = 0; pObj->dynamicParams_h264.intraFrameQP = pObj->createPrm.qpinit; pObj->dynamicParams_h264.interPFrameQP = pObj->createPrm.qpinit; pObj->dynamicParams_h264.initQ = pObj->createPrm.qpinit; pObj->dynamicParams_h264.rcQMax = (pObj->createPrm.qpmax>51)?51:pObj->createPrm.qpmax; pObj->dynamicParams_h264.rcQMin = (pObj->createPrm.qpmin<=0)?1:pObj->createPrm.qpmin; pObj->dynamicParams_h264.rcQMaxI = (pObj->createPrm.qpmax>51)?51:pObj->createPrm.qpmax; pObj->dynamicParams_h264.rcQMinI = (pObj->createPrm.qpmin<=0)?1:pObj->createPrm.qpmin; pObj->dynamicParams_h264.maxDelay = 2000; pObj->dynamicParams_h264.aspectRatioX = 1; pObj->dynamicParams_h264.aspectRatioY = 1; pObj->dynamicParams_h264.lfDisableIdc = 0; pObj->dynamicParams_h264.enableBufSEI = 0; /*!< Enable Buffering period SEI */ pObj->dynamicParams_h264.enablePicTimSEI = 1; /*!< Enable Picture Timing SEI */ pObj->dynamicParams_h264.perceptualRC = 1; pObj->dynamicParams_h264.idrFrameInterval = 100;//pObj->createPrm.keyFrameInterval; pObj->dynamicParams_h264.mvSADoutFlag = pObj->createPrm.mbMvOutEnable; pObj->dynamicParams_h264.resetHDVICPeveryFrame = pObj->createPrm.resetHDVICP; pObj->dynamicParams_h264.enableROI = 1; pObj->dynamicParams_h264.metaDataGenerateConsume = 0; pObj->dynamicParams_h264.maxBitrateCVBR = 0; pObj->dynamicParams_h264.interlaceRefMode = 0; pObj->dynamicParams_h264.enableGDR = 0; pObj->dynamicParams_h264.GDRduration = 0; pObj->dynamicParams_h264.GDRinterval = 0; pObj->dynamicParams_h264.LongTermRefreshInterval = 0; pObj->dynamicParams_h264.UseLongTermFrame = 0; pObj->dynamicParams_h264.SetLongTermFrame = 0; pObj->dynamicParams_h264.CustomScaleMatrix_Buffer = NULL; pObj->dynamicParams_h264.CVBRsensitivity = 0; pObj->dynamicParams_h264.CVBRminbitrate = 0; pObj->dynamicParams_h264.LBRmaxpicsize = 0; pObj->dynamicParams_h264.LBRminpicsize = 0; pObj->dynamicParams_h264.LBRskipcontrol = 0x050004; pObj->dynamicParams_h264.maxHighCmpxIntCVBR = 0; pObj->dynamicParams_h264.disableMVDCostFactor = 0; pObj->dynamicParams_h264.putDataGetSpaceFxn = NULL; pObj->dynamicParams_h264.dataSyncHandle = NULL; pObj->dynamicParams_h264.VUI_Buffer->timingInfoPresentFlag= 1; pObj->dynamicParams_h264.VUI_Buffer->timeScale = 240*(pObj->createPrm.framerate/1000); pObj->dynamicParams_h264.VUI_Buffer->numUnitsInTicks = 120; /* these three fields are not set as they are reserved */ /* intraSliceNum, meMultiPart and intraThrQF */ switch(pObj->createPrm.rateControlType) { case ALG_VID_ENC_RATE_CONTROL_CBR: pObj->dynamicParams_h264.rcAlgo = 5; break; default: case ALG_VID_ENC_RATE_CONTROL_VBR: pObj->dynamicParams_h264.rcAlgo = 5;//1; break; case ALG_VID_ENC_RATE_CONTROL_RCOFF: pObj->dynamicParams_h264.rcAlgo = 2; break; } if( pObj->dynamicParams_h264.sliceSize > (pObj->createPrm.height/16) ) { pObj->dynamicParams_h264.sliceSize = (pObj->createPrm.height/16); } break; case ALG_VID_CODEC_MPEG4: pObj->dynamicParams.inputHeight = pObj->createPrm.height; pObj->dynamicParams.inputWidth = pObj->createPrm.offsetH; pObj->dynamicParams.captureWidth = 0; pObj->dynamicParams.intraFrameInterval = pObj->createPrm.keyFrameInterval; pObj->dynamicParams.forceFrame = (pObj->createPrm.forceKeyFrame==TRUE)?IVIDEO_I_FRAME:IVIDEO_NA_FRAME; pObj->dynamicParams_mpeg4.numMBRows = ((pObj->createPrm.height/16)*pObj->createPrm.packetsize)/100; pObj->dynamicParams_mpeg4.initQ = pObj->createPrm.qpinit; pObj->dynamicParams_mpeg4.rcQMin = (pObj->createPrm.qpmin<=1)?2:pObj->createPrm.qpmin; pObj->dynamicParams_mpeg4.rcQMax = (pObj->createPrm.qpmax>31)?31:pObj->createPrm.qpmax; pObj->dynamicParams_mpeg4.rateFix = 0; pObj->dynamicParams_mpeg4.rateFixRange = 2; pObj->dynamicParams_mpeg4.interFrameQP = 0; pObj->dynamicParams_mpeg4.intraFrameQP = 0; if( pObj->dynamicParams_mpeg4.numMBRows > (pObj->createPrm.height/16) ) { pObj->dynamicParams_mpeg4.numMBRows = (pObj->createPrm.height/16); } if((pObj->createPrm.encodePreset&ALG_VID_ENC_PRESET_MASK) == ALG_VID_ENC_PRESET_AUTO) { pObj->dynamicParams_mpeg4.intraAlgo = IMP4VENC_INTRA_INTER_DECISION_LQ_HP; pObj->dynamicParams_mpeg4.skipMBAlgo = IMP4VENC_SKIP_MB_LQ_HP; pObj->dynamicParams_mpeg4.unrestrictedMV = IMP4VENC_UMV_LQ_HP; //(pObj->createPrm.mode == ALG_VID_ENC_MODE_FAST_FPS) ? IMP4VENC_UMV_LQ_HP:IMP4VENC_UMV_HQ_LP; if(pObj->createPrm.width<=720) // for D1 or QVGA pObj->dynamicParams_mpeg4.meAlgo = IMP4VENC_ME_MQ_MP; else if(pObj->createPrm.width==1280) // for 720P or SXVGA pObj->dynamicParams_mpeg4.meAlgo = IMP4VENC_ME_HQ_MP; else // 1080P or others. pObj->dynamicParams_mpeg4.meAlgo = IMP4VENC_ME_LQ_HP; } else { pObj->dynamicParams_mpeg4.intraAlgo = IMP4VENC_INTRA_INTER_DECISION_HQ_LP; pObj->dynamicParams_mpeg4.skipMBAlgo = IMP4VENC_SKIP_MB_HQ_LP; pObj->dynamicParams_mpeg4.unrestrictedMV = IMP4VENC_UMV_LQ_HP; //switched off due to UMV bug pObj->dynamicParams_mpeg4.meAlgo = IMP4VENC_ME_HQ_LP; } pObj->dynamicParams_mpeg4.mvDataEnable = pObj->createPrm.mbMvOutEnable; break; case ALG_VID_CODEC_MJPEG: pObj->createPrm.mbMvOutEnable = 0; break; } #ifdef ALG_VID_ENC_DEBUG OSA_printf(" ALG: VidEnc: DynamicParams: bitrate = %ld bps, Key-frame-interval = %ld\n", pObj->dynamicParams.targetBitRate, pObj->dynamicParams_h264.idrFrameInterval ); #endif if(pObj->createPrm.codec!=ALG_VID_CODEC_H264) { OSA_mutexLock(&vnf_imcop_lock); OSA_mutexLock(&vicp_imcop_lock); } else { if (pObj->params_h264.enableDDRbuff==0) OSA_mutexLock(&vicp_imcop_lock); } /* Set video encoder dynamic parameters */ pObj->encStatus.size = sizeof(VIDENC1_Status); pObj->encStatus.data.buf = NULL; status = VIDENC1_control(pObj->hEncode, XDM_SETPARAMS, (VIDENC1_DynamicParams*)&pObj->dynamicParams, &pObj->encStatus); if (status != VIDENC1_EOK) { OSA_ERROR("XDM_SETPARAMS failed, status=%ld\n", status); return OSA_EFAIL; } pObj->encStatus.data.buf = NULL; status = VIDENC1_control(pObj->hEncode, XDM_GETBUFINFO, (VIDENC1_DynamicParams*)&pObj->dynamicParams, &pObj->encStatus); if (status != VIDENC1_EOK) { OSA_ERROR("XDM_GETBUFINFO failed, status=%ld\n", status); return OSA_EFAIL; } #ifdef ALG_VID_ENC_DEBUG OSA_printf(" ALG: VidEnc: mbMvOutEnable =%d \n",(int)pObj->createPrm.mbMvOutEnable); OSA_printf(" ALG: VidEnc: encStatus.bufInfo.minNumOutBufs is %d\n", (int)pObj->encStatus.bufInfo.minNumOutBufs); //2 OSA_printf(" ALG: VidEnc: encStatus.bufInfo.minOutBufSize[0] is %d\n", (int)pObj->encStatus.bufInfo.minOutBufSize[0]); OSA_printf(" ALG: VidEnc: encStatus.bufInfo.minOutBufSize[1] is %d\n", (int)pObj->encStatus.bufInfo.minOutBufSize[1]); OSA_printf(" ALG: VidEnc: XDM_GETBUFINFO: min in bufs:%ld buf(0):%ld buf(1):%ld\n", pObj->encStatus.bufInfo.minNumInBufs, pObj->encStatus.bufInfo.minInBufSize[0], pObj->encStatus.bufInfo.minInBufSize[1]); #endif if( pObj->createPrm.mbMvOutEnable ) { if( pObj->encStatus.bufInfo.minNumOutBufs > 1 ) { if( pObj->MV_Size == 0 ) { pObj->MV_Size = pObj->encStatus.bufInfo.minOutBufSize[1]; pObj->MV_Addr = OSA_cmemAlloc(pObj->MV_Size,32); if( pObj->MV_Addr == NULL ) { OSA_ERROR("OSA_cmemAlloc failed \n"); return OSA_EFAIL; } #ifdef ALG_VID_ENC_DEBUG OSA_printf(" ALG: VidEnc: pObj->MV algName =%s \n",pObj->algName); OSA_printf(" ALG: VidEnc: pObj->MV_Size =%d \n",(int)pObj->MV_Size); OSA_printf(" ALG: VidEnc: Default is Disable MV data output \n"); #endif /* Default is Disable MV data output */ pObj->createPrm.mbMvOutEnable = 0; switch(pObj->createPrm.codec) { case ALG_VID_CODEC_H264: pObj->dynamicParams_h264.mvSADoutFlag = 0; break; case ALG_VID_CODEC_MPEG4: pObj->dynamicParams_mpeg4.mvDataEnable = 0; break; } status = VIDENC1_control(pObj->hEncode, XDM_SETPARAMS, (VIDENC1_DynamicParams*)&pObj->dynamicParams, &pObj->encStatus); if (status != VIDENC1_EOK) { OSA_ERROR("XDM_SETPARAMS failed, status=%ld\n", status); return OSA_EFAIL; } } }else{ OSA_ERROR("pObj->encStatus.bufInfo.minNumOutBufs is incorrect for MV_DATA \n"); return OSA_EFAIL; } } /* Reset Force Frame Flag */ pObj->createPrm.forceKeyFrame = FALSE; if(pObj->createPrm.codec!=ALG_VID_CODEC_H264){ OSA_mutexUnlock(&vnf_imcop_lock); OSA_mutexUnlock(&vicp_imcop_lock); } else { if (pObj->params_h264.enableDDRbuff== 0) OSA_mutexUnlock(&vicp_imcop_lock); } return OSA_SOK; }
/* * ======== encode_decode ======== */ static Void encode_decode(VIDENC1_Handle enc, VIDDEC2_Handle dec, FILE *in, FILE *out) { Int n; Int32 status; VIDDEC2_InArgs decInArgs; VIDDEC2_OutArgs decOutArgs; VIDDEC2_DynamicParams decDynParams; VIDDEC2_Status decStatus; VIDENC1_InArgs encInArgs; VIDENC1_OutArgs encOutArgs; VIDENC1_DynamicParams encDynParams; VIDENC1_Status encStatus; IVIDEO1_BufDescIn encInBufDesc; XDM_BufDesc encOutBufDesc; XDAS_Int8 *encoded[XDM_MAX_IO_BUFFERS]; XDAS_Int32 encBufSizes[XDM_MAX_IO_BUFFERS]; XDM1_BufDesc decInBufDesc; XDM_BufDesc decOutBufDesc; XDAS_Int8 *dst[XDM_MAX_IO_BUFFERS]; XDAS_Int32 outBufSizes[XDM_MAX_IO_BUFFERS]; /* clear and initialize the buffer descriptors */ memset(encoded, 0, sizeof(encoded[0]) * XDM_MAX_IO_BUFFERS); memset(dst, 0, sizeof(dst[0]) * XDM_MAX_IO_BUFFERS); encoded[0] = encodedBuf; dst[0] = outBuf; encInBufDesc.numBufs = encOutBufDesc.numBufs = decInBufDesc.numBufs = decOutBufDesc.numBufs = 1; encOutBufDesc.bufSizes = encBufSizes; decOutBufDesc.bufSizes = outBufSizes; encInBufDesc.bufDesc[0].bufSize = encBufSizes[0] = decInBufDesc.descs[0].bufSize = outBufSizes[0] = NSAMPLES; encInBufDesc.bufDesc[0].buf = inBuf; encOutBufDesc.bufs = encoded; decInBufDesc.descs[0].buf = encoded[0]; decOutBufDesc.bufs = dst; encInBufDesc.frameWidth = 0; /* TODO */ encInBufDesc.frameHeight = 0; /* TODO */ encInBufDesc.framePitch = 0; /* TODO */ /* initialize all "sized" fields */ encInArgs.size = sizeof(encInArgs); decInArgs.size = sizeof(decInArgs); encOutArgs.size = sizeof(encOutArgs); decOutArgs.size = sizeof(decOutArgs); encDynParams.size = sizeof(encDynParams); decDynParams.size = sizeof(decDynParams); encStatus.size = sizeof(encStatus); decStatus.size = sizeof(decStatus); /* * Note that we use versionBuf in both the encoder and decoder. In this * application, this is okay, as there is always only one user of * the buffer. Not all applications can make this assumption. */ encStatus.data.buf = decStatus.data.buf = versionBuf; encStatus.data.bufSize = decStatus.data.bufSize = MAXVERSIONSIZE; /* if the codecs support it, dump their versions */ status = VIDDEC2_control(dec, XDM_GETVERSION, &decDynParams, &decStatus); Log_print1(Diags_USER1, "[+1] Decoder version: %s", (IArg)((status == VIDDEC2_EOK ? ((char *)decStatus.data.buf) : "[unknown]"))); status = VIDENC1_control(enc, XDM_GETVERSION, &encDynParams, &encStatus); Log_print1(Diags_USER1, "[+1] Encoder version: %s", (IArg)((status == VIDENC1_EOK ? ((char *)encStatus.data.buf) : "[unknown]"))); /* * This app expects the encoder to provide 1 buf in and get 1 buf out, * and the buf sizes of the in and out buffer must be able to handle * NSAMPLES bytes of data. */ status = VIDENC1_control(enc, XDM_GETSTATUS, &encDynParams, &encStatus); if (status != VIDENC1_EOK) { /* failure, report error and exit */ Log_print1(Diags_USER7, "[+7] encode control status = %ld", (IArg)status); return; } /* Validate this encoder codec will meet our buffer requirements */ if ((encInBufDesc.numBufs < encStatus.bufInfo.minNumInBufs) || (IFRAMESIZE < encStatus.bufInfo.minInBufSize[0]) || (encOutBufDesc.numBufs < encStatus.bufInfo.minNumOutBufs) || (EFRAMESIZE < encStatus.bufInfo.minOutBufSize[0])) { /* failure, report error and exit */ Log_print0(Diags_USER7, "[+7] Error: encoder codec feature conflict"); return; } status = VIDDEC2_control(dec, XDM_GETSTATUS, &decDynParams, &decStatus); if (status != VIDDEC2_EOK) { /* failure, report error and exit */ Log_print1(Diags_USER7, "[+7] decode control status = %ld", (IArg)status); return; } /* Validate this decoder codec will meet our buffer requirements */ if ((decInBufDesc.numBufs < decStatus.bufInfo.minNumInBufs) || (EFRAMESIZE < decStatus.bufInfo.minInBufSize[0]) || (decOutBufDesc.numBufs < decStatus.bufInfo.minNumOutBufs) || (OFRAMESIZE < decStatus.bufInfo.minOutBufSize[0])) { /* failure, report error and exit */ Log_print0(Diags_USER7, "[+7] App-> ERROR: decoder does not meet buffer requirements."); return; } /* * Read complete frames from in, encode, decode, and write to out. */ for (n = 0; fread(inBuf, IFRAMESIZE, 1, in) == 1; n++) { #ifdef CACHE_ENABLED #if defined(xdc_target__isaCompatible_64P) || \ defined(xdc_target__isaCompatible_64T) /* * fread() on this processor is implemented using CCS's stdio, which * is known to write into the cache, not physical memory. To meet * XDAIS DMA Rule 7, we must writeback the cache into physical * memory. Also, per DMA Rule 7, we must invalidate the buffer's * cache before providing it to any xDAIS algorithm. */ Memory_cacheWbInv(inBuf, IFRAMESIZE); #else #error Unvalidated config - add appropriate fread-related cache maintenance #endif /* Per DMA Rule 7, our output buffer cache lines must be cleaned */ Memory_cacheInv(encodedBuf, EFRAMESIZE); #endif Log_print1(Diags_USER1, "[+1] App-> Processing frame %d...", (IArg)n); /* * Encode the frame. * * Note, inputID == 0 is an error. This example doesn't account * for the case where 'n + 1' wraps to zero. */ encInArgs.inputID = n + 1; status = VIDENC1_process(enc, &encInBufDesc, &encOutBufDesc, &encInArgs, &encOutArgs); Log_print2(Diags_USER2, "[+2] App-> Encoder frame %d process returned - 0x%x)", (IArg)n, (IArg)status); if (status != VIDENC1_EOK) { Log_print3(Diags_USER7, "[+7] App-> Encoder frame %d processing FAILED, status = 0x%x, " "extendedError = 0x%x", (IArg)n, (IArg)status, (IArg)(encOutArgs.extendedError)); break; } /* * So far, so good. Validate our assumption that the encoder * provided encodedBuf as it's encOutArgs->encodedBuf.buf. If * that's not the case, we may be dealing with a codec that's * giving us out of order frames... and this simple app * doesn't support that. */ if (encOutArgs.encodedBuf.buf != encodedBuf) { Log_print0(Diags_USER7, "[+7] App-> Internal error. Unsupported encoder"); break; } #ifdef CACHE_ENABLED /* * Conditionally writeback the encoded buf from the previous * call. Also, as encodedBuf is an inBuf to the next process * call, conditionally invalidate it as well. */ if (XDM_ISACCESSMODE_WRITE(encOutArgs.encodedBuf.accessMask)) { Memory_cacheWbInv(encodedBuf, EFRAMESIZE); } /* * Per DMA Rule 7, our output buffer cache lines (for the * upcoming decoder) must be cleaned. */ Memory_cacheInv(outBuf, OFRAMESIZE); #endif /* decode the frame */ decInArgs.numBytes = EFRAMESIZE; decInArgs.inputID = 1; /* typically this varies by each frame */ status = VIDDEC2_process(dec, &decInBufDesc, &decOutBufDesc, &decInArgs, &decOutArgs); Log_print2(Diags_USER2, "[+2] App-> Decoder frame %d process returned - 0x%x)", (IArg)n, (IArg)status); if (status != VIDDEC2_EOK) { Log_print2(Diags_USER7, "[+7] App-> Decoder frame %d processing FAILED, status =" " 0x%x", (IArg)n, (IArg)status); break; } /* again, validate our assumption that we don't get out-of-order bufs */ if (decOutArgs.decodedBufs.bufDesc[0].buf != outBuf) { Log_print0(Diags_USER7, "[+7] App-> Internal error. Unsupported decoder"); break; } #ifdef CACHE_ENABLED /* Conditionally writeback the decoded buf */ if (XDM_ISACCESSMODE_WRITE( decOutArgs.decodedBufs.bufDesc[0].accessMask)) { Memory_cacheWb(outBuf, OFRAMESIZE); } #endif /* write to file */ fwrite(dst[0], OFRAMESIZE, 1, out); } Log_print1(Diags_USER1, "[+1] %d frames encoded/decoded", (IArg)n); }
/* * ======== call ======== */ static VISA_Status call(VISA_Handle visaHandle, VISA_Msg visaMsg) { _VIDENC1_Msg *msg = (_VIDENC1_Msg *)visaMsg; VIDENC1_Handle handle = (VIDENC1_Handle)visaHandle; Int i; IVIDEO1_BufDescIn inBufs; XDM_BufDesc outBufs; IVIDENC1_OutArgs *pOutArgs; IVIDENC1_Status *pStatus; IVIDENC1_CodecClassConfig *codecClassConfig; Int numBufs; /* get stub/skeleton config data; can be NULL (for old codecs) */ codecClassConfig = (IVIDENC1_CodecClassConfig *) VISA_getCodecClassConfig( visaHandle ); /* perform the requested VIDENC1 operation by parsing message. */ switch (msg->visa.cmd) { case _VIDENC1_CPROCESS: { /* unmarshall inBufs and outBufs */ inBufs = msg->cmd.process.inBufs; outBufs.bufs = msg->cmd.process.outBufs; outBufs.numBufs = msg->cmd.process.numOutBufs; outBufs.bufSizes = msg->cmd.process.outBufSizes; if (SKEL_cachingPolicy == SKEL_LOCALBUFFERINVWB) { /* invalidate cache for all input buffers */ for (i = 0, numBufs = 0; i < XDM_MAX_IO_BUFFERS; i++) { if (inBufs.bufDesc[i].buf != NULL) { /* valid member of sparse array, * invalidate it unless user configured it not to */ if (codecClassConfig != NULL && codecClassConfig->manageInBufsCache[i] == FALSE) { /* do nothing, i.e. don't invalidate */ } else { Memory_cacheInv(inBufs.bufDesc[i].buf, inBufs.bufDesc[i].bufSize); } if (++numBufs == inBufs.numBufs) { break; } } } /* invalidate cache for all output buffers */ for (i = 0, numBufs = 0; i < XDM_MAX_IO_BUFFERS; i++) { if (outBufs.bufs[i] != NULL) { /* valid member of sparse array, * invalidate it unless user configured it not to */ if (codecClassConfig != NULL && codecClassConfig->manageOutBufsCache[i] == FALSE) { /* do nothing, i.e. don't invalidate */ } else { Memory_cacheInv(outBufs.bufs[i], outBufs.bufSizes[i]); } if (++numBufs == outBufs.numBufs) { break; } } } } /* SKEL_cachingPolicy == SKEL_LOCALBUFFERINVWB */ /* unmarshall outArgs based on the "size" of inArgs */ pOutArgs = (IVIDENC1_OutArgs *)((UInt)(&(msg->cmd.process.inArgs)) + msg->cmd.process.inArgs.size); /* * Note, there's no need to invalidate cache for * pOutArgs->encodedBuf bufs nor pOutArgs->reconBufs bufs as they're * not _really_ OUT buffers. Rather they're references to * the _real_ OUT buffers that are provided in outBufs - which * were already invalidated above. */ /* make the process call */ msg->visa.status = VIDENC1_process(handle, &inBufs, &outBufs, &(msg->cmd.process.inArgs), pOutArgs); if (SKEL_cachingPolicy == SKEL_WBINVALL) { Memory_cacheWbInvAll(); } else if (SKEL_cachingPolicy == SKEL_LOCALBUFFERINVWB) { /* writeback cache for encoded buffer */ if ((pOutArgs->encodedBuf.buf != NULL) && (XDM_ISACCESSMODE_WRITE(pOutArgs->encodedBuf.accessMask))) { Memory_cacheWb(pOutArgs->encodedBuf.buf, pOutArgs->encodedBuf.bufSize); /* * Since we've cacheWb this buffer, we arguably should * reflect this cache state and clear the WRITE bit in * the .accessMask field. However, we know the stub * doesn't propogate this field to the calling app, so * this extra buffer management detail isn't necessary: * * XDM_CLEARACCESSMODE_WRITE(pOutArgs->encodedBuf.accessMask); */ } /* writeback cache for recon buffers */ for (i = 0; ((i < pOutArgs->reconBufs.numBufs) && (i < IVIDEO_MAX_YUV_BUFFERS)); i++) { if ((pOutArgs->reconBufs.bufDesc[i].buf != NULL) && (XDM_ISACCESSMODE_WRITE( pOutArgs->reconBufs.bufDesc[i].accessMask))) { Memory_cacheWb(pOutArgs->reconBufs.bufDesc[i].buf, pOutArgs->reconBufs.bufDesc[i].bufSize); /* * Since we've cacheWb this buffer, we arguably should * reflect this cache state and clear the WRITE bit in * the .accessMask field. However, we know the stub * doesn't propogate this field to the calling app, so * this extra buffer management detail isn't necessary: * * XDM_CLEARACCESSMODE_WRITE( * pOutArgs->reconBufs.bufDesc[i].accessMask); */ } } } /* * Note that any changes to individual outBufs[i] values made by * the codec will automatically update msg->cmd.process.outBufs * as we pass the outBufs array by reference. */ break; } case _VIDENC1_CCONTROL: { /* unmarshall status based on the "size" of params */ pStatus = (IVIDENC1_Status *)((UInt)(&(msg->cmd.control.params)) + msg->cmd.control.params.size); /* invalidate data buffer */ if (pStatus->data.buf != NULL) { Memory_cacheInv(pStatus->data.buf, pStatus->data.bufSize); } msg->visa.status = VIDENC1_control(handle, msg->cmd.control.id, &(msg->cmd.control.params), pStatus); /* writeback data buffer */ if ((pStatus->data.buf != NULL) && XDM_ISACCESSMODE_WRITE(pStatus->data.accessMask)) { Memory_cacheWb(pStatus->data.buf, pStatus->data.bufSize); /* * Since we've cacheWb this buffer, we arguably should * reflect this cache state and clear the WRITE bit in * the .accessMask field. However, we know the stub * doesn't propogate this field to the calling app, so * this extra buffer management detail isn't necessary: * * XDM_CLEARACCESSMODE_WRITE(pStatus->data.accessMask); */ } break; } default: { msg->visa.status = VISA_EFAIL; break; } } return (VISA_EOK); }