Part Number: TMS320DM8148
Hi TI Team !
I have a problem with omx encode in DM8148.
I try to config encode in CBR rate control mode.
Encode component running successful with CBR. But video quality very low.
Please tell me the way to improve video quality
This my config and video input with bitrate 500k
OMX_ERRORTYPE IL_ClientSetEncodeParams (IL_Client *pAppData)
{
OMX_ERRORTYPE eError = OMX_ErrorUndefined;
OMX_HANDLETYPE pHandle = NULL;
OMX_VIDEO_PARAM_PROFILELEVELTYPE tProfileLevel;
OMX_VIDEO_PARAM_ENCODER_PRESETTYPE tEncoderPreset;
OMX_VIDEO_PARAM_BITRATETYPE tVidEncBitRate;
//OMX_VIDEO_PARAM_PORTFORMATTYPE tVideoParams;
OMX_PARAM_PORTDEFINITIONTYPE tPortDef;
OMX_VIDEO_CONFIG_DYNAMICPARAMS tDynParams;
OMX_VIDEO_PARAM_STATICPARAMS tStaticParam;
//OMX_VIDEO_PARAM_FRAMEDATACONTENTTYPE tFrameType;
pHandle = pAppData->pEncHandle;
/* Number of frames to be encoded, not used by defaualt */
pAppData->encILComp->numFrames = pAppData->nEncodedFrms;
OMX_INIT_PARAM (&tPortDef);
/* Get the Number of Ports */
tPortDef.nPortIndex = OMX_VIDENC_INPUT_PORT;
eError = OMX_GetParameter (pHandle, OMX_IndexParamPortDefinition, &tPortDef);
/* set the actual number of buffers required */
tPortDef.nBufferCountActual = IL_CLIENT_ENC_INPUT_BUFFER_COUNT;
/* set the video format settings */
tPortDef.format.video.nFrameWidth = pAppData->nWidth;
tPortDef.format.video.nStride = pAppData->nWidth;
tPortDef.format.video.nFrameHeight = pAppData->nHeight;
tPortDef.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
/* settings for OMX_IndexParamVideoPortFormat */
tPortDef.nBufferSize = (pAppData->nWidth * pAppData->nHeight * 3) >> 1;
eError = OMX_SetParameter (pHandle, OMX_IndexParamPortDefinition, &tPortDef);
if (eError != OMX_ErrorNone)
{
ERROR ("failed to set Encode OMX_IndexParamPortDefinition for input \n");
}
OMX_INIT_PARAM (&tPortDef);
tPortDef.nPortIndex = OMX_VIDENC_OUTPUT_PORT;
eError = OMX_GetParameter (pHandle, OMX_IndexParamPortDefinition, &tPortDef);
/* settings for OMX_IndexParamPortDefinition */
/* set the actual number of buffers required */
tPortDef.nBufferCountActual = IL_CLIENT_ENC_OUTPUT_BUFFER_COUNT;
tPortDef.format.video.nFrameWidth = pAppData->nWidth;
tPortDef.format.video.nFrameHeight = pAppData->nHeight;
tPortDef.format.video.eCompressionFormat = pAppData->eCompressionFormat;
tPortDef.format.video.xFramerate = (pAppData->nFrameRate << 16);
tPortDef.format.video.nBitrate = pAppData->nBitRate;
/* settings for OMX_IndexParamVideoPortFormat */
eError = OMX_SetParameter (pHandle, OMX_IndexParamPortDefinition, &tPortDef);
if (eError != OMX_ErrorNone)
{
ERROR ("failed to set Encode OMX_IndexParamPortDefinition for output \n");
}
/* For changing bit rate following index can be used */
OMX_INIT_PARAM (&tVidEncBitRate);
tVidEncBitRate.nPortIndex = OMX_VIDENC_OUTPUT_PORT;
eError = OMX_GetParameter (pHandle, OMX_IndexParamVideoBitrate,
&tVidEncBitRate);
tVidEncBitRate.eControlRate = OMX_Video_ControlRateConstant;
tVidEncBitRate.nTargetBitrate = pAppData->nBitRate;
eError = OMX_SetParameter (pHandle, OMX_IndexParamVideoBitrate,
&tVidEncBitRate);
if (eError != OMX_ErrorNone)
{
ERROR ("failed to set Encode bitrate \n");
}
/* Set the profile and level for H264 */
OMX_INIT_PARAM (&tProfileLevel);
tProfileLevel.nPortIndex = OMX_VIDENC_OUTPUT_PORT;
eError = OMX_GetParameter (pHandle, OMX_IndexParamVideoProfileLevelCurrent,
&tProfileLevel);
/* set as profile / level */
if(pAppData->eCompressionFormat == OMX_VIDEO_CodingAVC) {
//tProfileLevel.eProfile = OMX_VIDEO_AVCProfileHigh;
tProfileLevel.eProfile = OMX_VIDEO_AVCProfileBaseline;
tProfileLevel.eLevel = OMX_VIDEO_AVCLevel42;
}
else if (pAppData->eCompressionFormat == OMX_VIDEO_CodingMPEG4) {
tProfileLevel.eProfile = OMX_VIDEO_MPEG4ProfileSimple;
tProfileLevel.eLevel = OMX_VIDEO_MPEG4Level5;
}
else if (pAppData->eCompressionFormat == OMX_VIDEO_CodingH263) {
tProfileLevel.eProfile = OMX_VIDEO_H263ProfileBaseline;
tProfileLevel.eLevel = OMX_VIDEO_H263Level40;
}
eError = OMX_SetParameter (pHandle, OMX_IndexParamVideoProfileLevelCurrent,
&tProfileLevel);
if (eError != OMX_ErrorNone)
ERROR ("failed to set encoder pfofile \n");
/* before creating use set_parameters, for run-time change use set_config
all codec supported parameters can be set using this index */
/* example for h264 parameters settings */
if(pAppData->eCompressionFormat == OMX_VIDEO_CodingAVC) {
/* Encoder Preset settings */
OMX_INIT_PARAM (&tEncoderPreset);
tEncoderPreset.nPortIndex = OMX_VIDENC_OUTPUT_PORT;
eError = OMX_GetParameter (pHandle,(OMX_INDEXTYPE)OMX_TI_IndexParamVideoEncoderPreset,
&tEncoderPreset);
#if ENABLE_GDR
tEncoderPreset.eEncodingModePreset = OMX_Video_Enc_User_Defined;
#else
tEncoderPreset.eEncodingModePreset = OMX_Video_Enc_Med_Speed_High_Quality;
#endif
tEncoderPreset.eRateControlPreset = OMX_Video_RC_Low_Delay;
eError = OMX_SetParameter (pHandle, (OMX_INDEXTYPE)OMX_TI_IndexParamVideoEncoderPreset,
&tEncoderPreset);
if (eError != OMX_ErrorNone)
{
ERROR ("failed to Encoder Preset \n");
}
OMX_INIT_PARAM (&tDynParams);
tDynParams.nPortIndex = OMX_VIDENC_OUTPUT_PORT;
eError = OMX_GetParameter (pHandle, (OMX_INDEXTYPE)OMX_TI_IndexParamVideoDynamicParams,
&tDynParams);
/* setting I frame interval */
tDynParams.videoDynamicParams.h264EncDynamicParams.videnc2DynamicParams.targetFrameRate = pAppData->nFrameRate * 1000;
tDynParams.videoDynamicParams.h264EncDynamicParams.videnc2DynamicParams.targetBitRate = pAppData->nBitRate;
#if ENABLE_GDR
/*Parameter setting for GDR*/
tDynParams.videoDynamicParams.h264EncDynamicParams.rateControlParams.rateControlParamsPreset = IH264_RATECONTROLPARAMS_USERDEFINED;
tDynParams.videoDynamicParams.h264EncDynamicParams.intraCodingParams.intraCodingPreset = IH264_INTRACODING_USERDEFINED;
tDynParams.videoDynamicParams.h264EncDynamicParams.intraCodingParams.intraRefreshMethod = IH264_INTRAREFRESH_GDR;
tDynParams.videoDynamicParams.h264EncDynamicParams.intraCodingParams.intraRefreshRate = 4;
tDynParams.videoDynamicParams.h264EncDynamicParams.intraCodingParams.gdrOverlapRowsBtwFrames = 0;
/* updating rows to be intra refresh */
tDynParams.videoDynamicParams.h264EncDynamicParams.intraRefreshRateGDRDynamic = 4;
/* updating overlap rows */
tDynParams.videoDynamicParams.h264EncDynamicParams.gdrOverlapRowsBtwFramesDynamic = 0;
#else
tDynParams.videoDynamicParams.h264EncDynamicParams.rateControlParams.rateControlParamsPreset = IH264_RATECONTROLPARAMS_USERDEFINED;
tDynParams.videoDynamicParams.h264EncDynamicParams.rateControlParams.rcAlgo = IH264_RATECONTROL_PRC_LOW_DELAY;
tDynParams.videoDynamicParams.h264EncDynamicParams.rateControlParams.allowFrameSkip = 0;
tDynParams.videoDynamicParams.h264EncDynamicParams.rateControlParams.enablePartialFrameSkip = 0;
tDynParams.videoDynamicParams.h264EncDynamicParams.rateControlParams.HRDBufferSize = pAppData->nBitRate * 10;
tDynParams.videoDynamicParams.h264EncDynamicParams.rateControlParams.initialBufferLevel = pAppData->nBitRate * 10;
#endif
tDynParams.videoDynamicParams.h264EncDynamicParams.videnc2DynamicParams.intraFrameInterval = 90;
eError = OMX_SetParameter (pHandle, (OMX_INDEXTYPE)OMX_TI_IndexParamVideoDynamicParams,
&tDynParams);
OMX_INIT_PARAM (&tStaticParam);
tStaticParam.nPortIndex = OMX_VIDENC_OUTPUT_PORT;
eError = OMX_GetParameter (pHandle, (OMX_INDEXTYPE)OMX_TI_IndexParamVideoStaticParams,
&tStaticParam);
#if ENABLE_GDR
/*Parameter setting for GDR*/
tStaticParam.videoStaticParams.h264EncStaticParams.videnc2Params.encodingPreset = XDM_USER_DEFINED;
tStaticParam.videoStaticParams.h264EncStaticParams.intraCodingParams.intraCodingPreset = IH264_INTRACODING_USERDEFINED;
tStaticParam.videoStaticParams.h264EncStaticParams.intraCodingParams.intraRefreshMethod = IH264_INTRAREFRESH_GDR;
tStaticParam.videoStaticParams.h264EncStaticParams.intraCodingParams.intraRefreshRate = 4;
tStaticParam.videoStaticParams.h264EncStaticParams.intraCodingParams.gdrOverlapRowsBtwFrames = 0;
#else
tStaticParam.videoStaticParams.h264EncStaticParams.videnc2Params.encodingPreset = XDM_USER_DEFINED;
//If ratecontrolpreset is set as user defined then the rcAlgo should be set. In case is set as IVIDEO_LOW_DELAY the rcAlgo should be not set
tStaticParam.videoStaticParams.h264EncStaticParams.videnc2Params.rateControlPreset = IVIDEO_LOW_DELAY;
tStaticParam.videoStaticParams.h264EncStaticParams.rateControlParams.rateControlParamsPreset = IH264_RATECONTROLPARAMS_DEFAULT;//IH264_RATECONTROLPARAMS_USERDEFINED;
tStaticParam.videoStaticParams.h264EncStaticParams.rateControlParams.rcAlgo = IH264_RATECONTROL_PRC_LOW_DELAY;
tStaticParam.videoStaticParams.h264EncStaticParams.videnc2Params.maxBitRate = pAppData->nBitRate;
tStaticParam.videoStaticParams.h264EncStaticParams.rateControlParams.enablePartialFrameSkip = 1;
tStaticParam.videoStaticParams.h264EncStaticParams.rateControlParams.allowFrameSkip = 1;
tStaticParam.videoStaticParams.h264EncStaticParams.rateControlParams.HRDBufferSize = pAppData->nBitRate * 0.5;
tStaticParam.videoStaticParams.h264EncStaticParams.rateControlParams.initialBufferLevel = pAppData->nBitRate * 0.5;
tStaticParam.videoStaticParams.h264EncStaticParams.interCodingParams.interCodingPreset = IH264_INTERCODING_MED_SPEED_HIGH_QUALITY;
tStaticParam.videoStaticParams.h264EncStaticParams.rateControlParams.IPQualityFactor = IH264_QUALITY_FACTOR_DEFAULT;
tStaticParam.videoStaticParams.h264EncStaticParams.numTemporalLayer = IH264_TEMPORAL_LAYERS_1;
/* for base profile */
tStaticParam.videoStaticParams.h264EncStaticParams.transformBlockSize = IH264_TRANSFORM_DEFAULT;
tStaticParam.videoStaticParams.h264EncStaticParams.entropyCodingMode = IH264_ENTROPYCODING_DEFAULT;
tStaticParam.videoStaticParams.h264EncStaticParams.IDRFrameInterval = 1;
tStaticParam.videoStaticParams.h264EncStaticParams.referencePicMarking = IH264_LONG_TERM_PICTURE;
// for the mask bits, please refer to codec user guide
tStaticParam.videoStaticParams.h264EncStaticParams.nalUnitControlParams.naluControlPreset = IH264_NALU_CONTROL_USERDEFINED;
tStaticParam.videoStaticParams.h264EncStaticParams.nalUnitControlParams.naluPresentMaskStartOfSequence |= 0x21A0;
tStaticParam.videoStaticParams.h264EncStaticParams.nalUnitControlParams.naluPresentMaskIDRPicture |= 0x21A0;
tStaticParam.videoStaticParams.h264EncStaticParams.nalUnitControlParams.naluPresentMaskIntraPicture |= 0x21A0;
tStaticParam.videoStaticParams.h264EncStaticParams.nalUnitControlParams.naluPresentMaskNonIntraPicture |= 0x21A0;
tStaticParam.videoStaticParams.h264EncStaticParams.nalUnitControlParams.naluPresentMaskEndOfSequence |= 0x21A0;
tStaticParam.videoStaticParams.h264EncStaticParams.vuiCodingParams.vuiCodingPreset = IH264_VUICODING_USERDEFINED;
tStaticParam.videoStaticParams.h264EncStaticParams.vuiCodingParams.aspectRatioInfoPresentFlag = 0;
tStaticParam.videoStaticParams.h264EncStaticParams.vuiCodingParams.aspectRatioIdc = 0;
tStaticParam.videoStaticParams.h264EncStaticParams.vuiCodingParams.videoSignalTypePresentFlag = 0;
tStaticParam.videoStaticParams.h264EncStaticParams.vuiCodingParams.videoFormat = IH264ENC_VIDEOFORMAT_PAL;
tStaticParam.videoStaticParams.h264EncStaticParams.vuiCodingParams.videoFullRangeFlag = 0;
tStaticParam.videoStaticParams.h264EncStaticParams.vuiCodingParams.timingInfoPresentFlag = 1;
tStaticParam.videoStaticParams.h264EncStaticParams.vuiCodingParams.hrdParamsPresentFlag = 1;
tStaticParam.videoStaticParams.h264EncStaticParams.vuiCodingParams.numUnitsInTicks = 1000;
#endif /* ENABLE_GDR */
eError = OMX_SetParameter (pHandle, (OMX_INDEXTYPE)OMX_TI_IndexParamVideoStaticParams,
&tStaticParam);
}
if((pAppData->eCompressionFormat == OMX_VIDEO_CodingMPEG4) ||
(pAppData->eCompressionFormat == OMX_VIDEO_CodingH263))
{
OMX_INIT_PARAM(&tStaticParam);
tStaticParam.nPortIndex = OMX_VIDENC_OUTPUT_PORT;
eError =
OMX_GetParameter(pHandle, (OMX_INDEXTYPE)OMX_TI_IndexParamVideoStaticParams,
&tStaticParam);
if (eError != OMX_ErrorNone)
{
ERROR ("failed to Encoder OMX_GetParameter StaticParams \n");
}
tStaticParam.videoStaticParams.mpeg4EncStaticParams.videnc2Params.encodingPreset
= XDM_USER_DEFINED;
tStaticParam.videoStaticParams.mpeg4EncStaticParams.vopTimeIncrementResolution
= pAppData->nFrameRate;
eError =
OMX_SetParameter(pHandle, (OMX_INDEXTYPE)OMX_TI_IndexParamVideoStaticParams,
&tStaticParam);
if (eError != OMX_ErrorNone)
{
ERROR ("failed to Encoder OMX_SetParameter StaticParams \n");
}
}
return eError;
}