Hi All,
I am working on TDA2x with ARM having Linux Distribution generated from Arago. I have generated a custom firmware for IPU2 core with reference from IPUMM firmware. I am able to load all the binaries of CODEC in firmware generation. Also I am able to create and control the MPEG-4 encoder. As I liked to start humble, all my parameter setting and IO buffers creation and handling are within IPU2 core. My final goal is to use a custom application from ARM to pass on details to IPU2 to launch the IVAHD encoder.
In the process stage, I am facing XDM_INSUFFICIENTDATA error(bit 10 of extended error). I have tried creating IO buffers with malloc, Memory_Alloc and global buffers. But all has the same issue. Kindly help me to solve this error.
Some code snippets are below(I have used omapdrmtest application for encoder as reference):
static void init_common_static_params(encoder *enc)
{
VIDENC2_Params *params = enc->params;
params->encodingPreset = XDM_USER_DEFINED; //XDM_USER_DEFINED; //XDM_EncodingPreset
params->rateControlPreset = IVIDEO_USER_DEFINED;
params->maxHeight = 480;
params->maxWidth = 720;
params->dataEndianness = XDM_BYTE; //XDM_DataFormat
params->maxBitRate = -1; //IGNORED
params->minBitRate = 0;
params->inputChromaFormat = XDM_YUV_420SP; //XDM_ChromaFormat
params->inputContentType = IVIDEO_PROGRESSIVE; //IVIDEO_ContentType
params->operatingMode = IVIDEO_ENCODE_ONLY; //IVIDEO_OperatingMode
params->profile = 3;
params->level = 6;
params->inputDataMode = IVIDEO_ENTIREFRAME; //IVIDEO_DataMode
params->outputDataMode = IVIDEO_ENTIREFRAME; //IVIDEO_DataMode
params->numInputDataUnits = 1;
params->numOutputDataUnits = 1;
params->metadataType[0] = IVIDEO_METADATAPLANE_NONE;
params->metadataType[1] = IVIDEO_METADATAPLANE_NONE;
params->metadataType[2] = IVIDEO_METADATAPLANE_NONE;
return;
}
static int init_mpeg4_static_params(encoder *enc)
{
IMPEG4ENC_Params *mpeg4enc_params = NULL;
enc->inArgs = (VIDENC2_InArgs*)malloc(sizeof(IMPEG4ENC_InArgs));
if (!enc->inArgs) goto bail;
enc->inArgs->size = sizeof(IMPEG4ENC_InArgs);
enc->outArgs = (VIDENC2_OutArgs*)malloc(sizeof(IMPEG4ENC_OutArgs));
if(!enc->outArgs) goto bail;
enc->outArgs->size = sizeof (IMPEG4ENC_OutArgs);
enc->mpeg4enc_outArgs = (IMPEG4ENC_OutArgs *) enc->outArgs;
enc->params = (VIDENC2_Params*)malloc(sizeof(IMPEG4ENC_Params));
if(!enc->params) goto bail;
enc->params->size = sizeof(IMPEG4ENC_Params);
init_common_static_params(enc);
enc->params->maxInterFrameInterval = 0;
mpeg4enc_params = enc->mpeg4enc_params = (IMPEG4ENC_Params *) enc->params;
mpeg4enc_params->useDataPartitioning = 0;
mpeg4enc_params->useRvlc = 0;
if (CODEC == H263) {
mpeg4enc_params->useShortVideoHeader = 1;
}
else {
mpeg4enc_params->useShortVideoHeader = 0;
}
mpeg4enc_params->vopTimeIncrementResolution = 30;
mpeg4enc_params->nonMultiple16RefPadMethod = IMPEG4_PAD_METHOD_MPEG4;
mpeg4enc_params->pixelRange = IMPEG4ENC_PR_0_255;
mpeg4enc_params->enableSceneChangeAlgo = IMPEG4ENC_SCDA_DISABLE;
mpeg4enc_params->useVOS = 0;
mpeg4enc_params->enableMONA = 0;
mpeg4enc_params->enableAnalyticinfo = -1;
mpeg4enc_params->debugTraceLevel = 0;
mpeg4enc_params->lastNFramesToLog = 0;
// IMPEG4ENC_RateControlParams
mpeg4enc_params->rateControlParams.rateControlParamsPreset = IMPEG4_RATECONTROLPARAMS_DEFAULT;
mpeg4enc_params->rateControlParams.rcAlgo = IMPEG4_RATECONTROLALGO_VBR;
mpeg4enc_params->rateControlParams.qpI = 5;
mpeg4enc_params->rateControlParams.qpP = 5;
mpeg4enc_params->rateControlParams.seIntialQP = 5;
mpeg4enc_params->rateControlParams.qpMax = 31;
mpeg4enc_params->rateControlParams.qpMin = 1;
mpeg4enc_params->rateControlParams.enablePerceptualQuantMode = 0;
mpeg4enc_params->rateControlParams.allowFrameSkip = 0;
mpeg4enc_params->rateControlParams.initialBufferLevel = 0;
mpeg4enc_params->rateControlParams.vbvBufferSize = 0;
mpeg4enc_params->rateControlParams.qpMinIntra = 0;
// IMPEG4ENC_InterCodingParams
mpeg4enc_params->interCodingParams.interCodingPreset = IMPEG4_INTERCODING_DEFAULT;
mpeg4enc_params->interCodingParams.searchRangeHorP = 144;
mpeg4enc_params->interCodingParams.searchRangeVerP = 32;
mpeg4enc_params->interCodingParams.globalOffsetME = 1;
mpeg4enc_params->interCodingParams.earlySkipThreshold = 200;
mpeg4enc_params->interCodingParams.enableThresholdingMethod = 1;
mpeg4enc_params->interCodingParams.minBlockSizeP = IMPEG4_BLOCKSIZE_8x8;
mpeg4enc_params->interCodingParams.enableRoundingControl = 1;
// IMPEG4ENC_IntraCodingParams
mpeg4enc_params->intraCodingParams.intraCodingPreset = IMPEG4_INTRACODING_DEFAULT;
mpeg4enc_params->intraCodingParams.intraRefreshMethod = 0;
mpeg4enc_params->intraCodingParams.intraRefreshRate = 0;
mpeg4enc_params->intraCodingParams.acpredEnable = 1;
mpeg4enc_params->intraCodingParams.insertGOVHdrBeforeIframe = 0;
mpeg4enc_params->intraCodingParams.enableDriftControl = 1;
// IMPEG4ENC_sliceCodingParams
mpeg4enc_params->sliceCodingParams.sliceCodingPreset = IMPEG4_SLICECODING_DEFAULT;
mpeg4enc_params->sliceCodingParams.sliceMode = IMPEG4_SLICEMODE_NONE;
mpeg4enc_params->sliceCodingParams.sliceUnitSize = 0;
mpeg4enc_params->sliceCodingParams.gobInterval = 0;
mpeg4enc_params->sliceCodingParams.useHec = 0;
MSG("alloc VIDENC2_Params successful mpeg4enc_params=%p", mpeg4enc_params);
enc->codec = VIDENC2_create(enc->engine, (String)"ivahd_mpeg4enc", (VIDENC2_Params *)mpeg4enc_params);
if(!enc->codec){
MSG("Codec could not be created %p\n", enc->codec);
goto bail;
}
return 0;
bail:
encoder_deinit(enc);
return -1;
}
static void set_common_dyn_params(encoder *enc)
{
VIDENC2_DynamicParams *dynParams = enc->dynParams;
dynParams->inputHeight = enc->height;
dynParams->inputWidth = enc->width;
dynParams->refFrameRate = enc->fps * 1000; // refFrameRate in fps * 1000
dynParams->targetFrameRate= enc->fps * 1000; // Target frame rate in fps * 1000
dynParams->targetBitRate = enc->bps;
MSG("targetFramerate = %d, targetbitrate = %d\n", dynParams->targetFrameRate, dynParams->targetBitRate);
dynParams->intraFrameInterval = 30; //Only 1st frame to be intra frame (I-frame)
dynParams->generateHeader = XDM_ENCODE_AU;
dynParams->captureWidth = enc->width;
dynParams->forceFrame = IVIDEO_NA_FRAME;
dynParams->sampleAspectRatioHeight = 1;
dynParams->sampleAspectRatioWidth = 1;
dynParams->ignoreOutbufSizeFlag = XDAS_FALSE; // If this is XDAS_TRUE then getBufferFxn and getBufferHandle needs to be set.
dynParams->putDataFxn = NULL;
dynParams->putDataHandle = NULL;
dynParams->getDataFxn = NULL;
dynParams->getDataHandle = NULL;
dynParams->getBufferFxn = NULL;
dynParams->getBufferHandle = NULL;
dynParams->lateAcquireArg = -1;
return;
}
static int init_mpeg4_dyn_params(encoder *enc)
{
VIDENC2_DynamicParams *dynParams = NULL;
XDAS_Int32 err;
IMPEG4ENC_DynamicParams *mpeg4enc_dynParams;
dynParams = enc->dynParams = (VIDENC2_DynamicParams*)malloc(sizeof(IMPEG4ENC_DynamicParams));
if(!enc->dynParams) goto bail;
enc->dynParams->size = sizeof(IMPEG4ENC_DynamicParams);
MSG("alloc dynParams successful dynParams=%p size=%d", enc->dynParams, enc->dynParams->size);
set_common_dyn_params(enc);
dynParams->interFrameInterval = 0;
dynParams->mvAccuracy = IVIDENC2_MOTIONVECTOR_HALFPEL;
mpeg4enc_dynParams = (IMPEG4ENC_DynamicParams *) dynParams;
mpeg4enc_dynParams->aspectRatioIdc = IMPEG4ENC_ASPECTRATIO_SQUARE;
// IMPEG4ENC_RateControlParams
memcpy(&mpeg4enc_dynParams->rateControlParams, &(enc->mpeg4enc_params->rateControlParams), sizeof(IMPEG4ENC_RateControlParams));
// IMPEG4ENC_InterCodingParams
memcpy(&mpeg4enc_dynParams->interCodingParams, &(enc->mpeg4enc_params->interCodingParams), sizeof(IMPEG4ENC_InterCodingParams));
// IMPEG4ENC_sliceCodingParams
memcpy(&mpeg4enc_dynParams->sliceCodingParams, &(enc->mpeg4enc_params->sliceCodingParams), sizeof(IMPEG4ENC_sliceCodingParams));
enc->mpeg4enc_status = (IMPEG4ENC_Status*)malloc(sizeof(IMPEG4ENC_Status));
if(!enc->mpeg4enc_status) goto bail;
((VIDENC2_Status *)(enc->mpeg4enc_status))->size = sizeof(IMPEG4ENC_Status);
err = VIDENC2_control(enc->codec, XDM_SETPARAMS, (VIDENC2_DynamicParams *) mpeg4enc_dynParams, (VIDENC2_Status *) (enc->mpeg4enc_status));
if(err){
MSG("Codec_control returned err=%d, extendedError=%08x", err, enc->mpeg4enc_status->videnc2Status.extendedError);
goto bail;
}
return 0;
bail:
encoder_deinit(enc);
return -1;
}
Output Buffer Creation:
#define GET_PHY_ADDRESS MEMUTILS_getPhysicalAddr
enc->outBufs->descs[0].memType = XDM_MEMTYPE_RAW;
enc->outBufs->descs[0].bufSize.bytes = enc->width * enc->height * 2;
#if USE_GLOBAL_MEMORY
enc->outBufs->descs[0].buf = outBuf;
enc->outBufs->descs[0].buf = GET_PHY_ADDRESS(outBuf);
#elif USE_MALLOC
enc->outBufs->descs[0].buf = (XDAS_Int8 *)malloc(enc->width * enc->height * 2);
enc->outBufs->descs[0].buf = GET_PHY_ADDRESS(enc->outBufs->descs[0].buf);
#else
Memory_AllocParams alc_params = Memory_DEFAULTPARAMS;
alc_params.type = ti_sdo_ce_osal_Memory_CONTIGHEAP;
alc_params.flags = ti_sdo_ce_osal_Memory_CACHED;
enc->outBufs->descs[0].buf = (XDAS_Int8 *)ti_sdo_ce_osal_Memory_alloc(enc->width * enc->height * 2, &alc_params);
enc->outBufs->descs[0].buf = GET_PHY_ADDRESS(enc->outBufs->descs[0].buf);
#endif
Input Buffer Creation:
#if USE_GLOBAL_MEMORY
enc->inBufs->planeDesc[0].buf = yBuf;
enc->inBufs->planeDesc[1].buf = uvBuf;
enc->inBufs->planeDesc[0].buf = GET_PHY_ADDRESS(yBuf);
enc->inBufs->planeDesc[1].buf = GET_PHY_ADDRESS(uvBuf);
#elif USE_MALLOC
enc->inBufs->planeDesc[0].buf = (XDAS_Int8 *)malloc(enc->width * enc->height);
enc->inBufs->planeDesc[1].buf = (XDAS_Int8 *)malloc(enc->width * enc->height);
enc->inBufs->planeDesc[0].buf = GET_PHY_ADDRESS(enc->inBufs->planeDesc[0].buf);
enc->inBufs->planeDesc[1].buf = GET_PHY_ADDRESS(enc->inBufs->planeDesc[1].buf);
#else
enc->inBufs->planeDesc[0].buf = (XDAS_Int8 *)ti_sdo_ce_osal_Memory_alloc(enc->width * enc->height, &alc_params);
enc->inBufs->planeDesc[1].buf = (XDAS_Int8 *)ti_sdo_ce_osal_Memory_alloc(enc->width * enc->height, &alc_params);
enc->inBufs->planeDesc[0].buf = GET_PHY_ADDRESS(enc->inBufs->planeDesc[0].buf);
enc->inBufs->planeDesc[1].buf = GET_PHY_ADDRESS(enc->inBufs->planeDesc[1].buf);
#endif
Creation of MPEG4 Encoder (Successful):
enc->codec = VIDENC2_create(enc->engine, (String)"ivahd_mpeg4enc", (VIDENC2_Params *)mpeg4enc_params);
Control of MPEG4 Encoder (Successful):
err = VIDENC2_control(enc->codec, XDM_SETPARAMS, (VIDENC2_DynamicParams *) mpeg4enc_dynParams, (VIDENC2_Status *) (enc->mpeg4enc_status));
err = VIDENC2_control(enc->codec, XDM_GETBUFINFO, enc->dynParams, (VIDENC2_Status*) enc->status);
Process of MPEG4 Encoder (Failed):
err = VIDENC2_process(enc->codec, enc->inBufs, enc->outBufs, (VIDENC2_InArgs *) mpeg4enc_inArgs, (VIDENC2_OutArgs *) mpeg4enc_outArgs);
Any help would be appreciated and thanks in advance.