Hi,
I have referred to the H.264 Encoder User Guide and the following posts and have not been able to find an answer to this:
http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/716/p/288641/1007735.aspx#1007735
http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/100/t/303485.aspx
I am using EVSDK 5.05.02.
I'm trying to change the bit rate of the VENC while it is running. Here is the setup code I use for the VENC:
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;
int captureWidth, captureHeight;
captureWidth = m_capture_width;
captureHeight = m_capture_height;
pHandle = m_omx_handle;
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 = GetNumInputBuffers(0);
/* set the video format settings */
tPortDef.format.video.nFrameWidth = captureWidth;
tPortDef.format.video.nStride = captureWidth;
tPortDef.format.video.nFrameHeight = captureHeight;
tPortDef.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
/* settings for OMX_IndexParamVideoPortFormat */
tPortDef.nBufferSize = (captureWidth * captureHeight * 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 = GetNumOutputBuffers(0);
tPortDef.format.video.nFrameWidth = captureWidth;
tPortDef.format.video.nFrameHeight = captureHeight;
tPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
tPortDef.format.video.xFramerate = (m_nFrameRate << 16);
tVideoParams.xFramerate = (m_nFrameRate << 16);
/* 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;//OMX_Video_ControlRateDisable;
tVidEncBitRate.nTargetBitrate = m_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 baseline 4.2 level */
tProfileLevel.eProfile = OMX_VIDEO_AVCProfileHigh;
tProfileLevel.eLevel = OMX_VIDEO_AVCLevel51;
eError = OMX_SetParameter (pHandle, OMX_IndexParamVideoProfileLevelCurrent,
&tProfileLevel);
if (eError != OMX_ErrorNone)
ERROR ("failed to set encoder pfofile \n");
/* Encoder Preset settings */
OMX_INIT_PARAM (&tEncoderPreset);
tEncoderPreset.nPortIndex = OMX_VIDENC_OUTPUT_PORT;
eError = OMX_GetParameter (pHandle, (OMX_INDEXTYPE)OMX_TI_IndexParamVideoEncoderPreset,
&tEncoderPreset);
tEncoderPreset.eEncodingModePreset = OMX_Video_Enc_High_Quality;
tEncoderPreset.eRateControlPreset = OMX_Video_RC_User_Defined; //OMX_Video_RC_Storage;//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 (&tStaticParam);
tStaticParam.nPortIndex = OMX_VIDENC_OUTPUT_PORT;
eError = OMX_GetParameter(pHandle, (OMX_INDEXTYPE)OMX_TI_IndexParamVideoStaticParams,&tStaticParam);
tStaticParam.videoStaticParams.h264EncStaticParams.videnc2Params.encodingPreset = XDM_USER_DEFINED;
tStaticParam.videoStaticParams.h264EncStaticParams.videnc2Params.rateControlPreset = IVIDEO_USER_DEFINED; //IVIDEO_STORAGE;//IVIDEO_LOW_DELAY;
tStaticParam.videoStaticParams.h264EncStaticParams.rateControlParams.rateControlParamsPreset = IH264_RATECONTROLPARAMS_USERDEFINED; //IH264_RATECONTROLPARAMS_DEFAULT;
tStaticParam.videoStaticParams.h264EncStaticParams.rateControlParams.rcAlgo = IH264_RATECONTROL_PRC_LOW_DELAY;
tStaticParam.videoStaticParams.h264EncStaticParams.rateControlParams.VBRDuration = 1;
tStaticParam.videoStaticParams.h264EncStaticParams.numTemporalLayer = IH264_TEMPORAL_LAYERS_1;
tStaticParam.videoStaticParams.h264EncStaticParams.videnc2Params.maxBitRate = -1; //m_nBitRate * 1.5;
tStaticParam.videoStaticParams.h264EncStaticParams.videnc2Params.minBitRate = 0;//16 * 1024;
/* for base profile */
tStaticParam.videoStaticParams.h264EncStaticParams.transformBlockSize = IH264_TRANSFORM_ADAPTIVE;
tStaticParam.videoStaticParams.h264EncStaticParams.entropyCodingMode = IH264_ENTROPYCODING_CAVLC;
// for the mask bits, please refer to codec user guide
tStaticParam.videoStaticParams.h264EncStaticParams.nalUnitControlParams.naluControlPreset = IH264_NALU_CONTROL_USERDEFINED;
tStaticParam.videoStaticParams.h264EncStaticParams.nalUnitControlParams.naluPresentMaskStartOfSequence |= 0x01A0;
tStaticParam.videoStaticParams.h264EncStaticParams.nalUnitControlParams.naluPresentMaskIDRPicture |= 0x01A0;
tStaticParam.videoStaticParams.h264EncStaticParams.nalUnitControlParams.naluPresentMaskIntraPicture |= 0x01A0;
tStaticParam.videoStaticParams.h264EncStaticParams.nalUnitControlParams.naluPresentMaskNonIntraPicture |= 0x0002;
tStaticParam.videoStaticParams.h264EncStaticParams.nalUnitControlParams.naluPresentMaskEndOfSequence |= 0x0C00;
//
// This seems to work in all but the first time the app is run.
//
tStaticParam.videoStaticParams.h264EncStaticParams.IDRFrameInterval=1;
eError = OMX_SetParameter(pHandle, (OMX_INDEXTYPE)OMX_TI_IndexParamVideoStaticParams,&tStaticParam);
if (eError != OMX_ErrorNone)
ERROR("Failed to set static params");
/* before creating use set_parameters, for run-time change use set_config
all codec supported parameters can be set using this index */
OMX_INIT_PARAM (&tDynParams);
tDynParams.nPortIndex = OMX_VIDENC_OUTPUT_PORT;
eError = OMX_GetParameter(pHandle, (OMX_INDEXTYPE)OMX_TI_IndexParamVideoDynamicParams,&tDynParams);
/* setting I frame interval */
printf("Setting iframe interval: %d\n", m_nIFrameFreq);
tDynParams.videoDynamicParams.h264EncDynamicParams.videnc2DynamicParams.intraFrameInterval = m_nIFrameFreq * m_nFrameRate;
tDynParams.videoDynamicParams.h264EncDynamicParams.videnc2DynamicParams.targetBitRate = m_nBitRate;
tDynParams.videoDynamicParams.h264EncDynamicParams.rateControlParams.rateControlParamsPreset = IH264_RATECONTROLPARAMS_USERDEFINED;
tDynParams.videoDynamicParams.h264EncDynamicParams.rateControlParams.rcAlgo = IH264_RATECONTROL_PRC_LOW_DELAY;
eError = OMX_SetParameter(pHandle, (OMX_INDEXTYPE)OMX_TI_IndexParamVideoDynamicParams,&tDynParams);
Here is the code i'm using to try and dynamically change the bitrate:
OMX_VIDEO_CONFIG_BITRATETYPE tBitRate;
OMX_INIT_PARAM(&tBitRate);
eError=OMX_GetConfig(pHandle,OMX_IndexConfigVideoBitrate,&tBitRate);
printf( "CURRENT BIT RATE IS %d\n", tBitRate.nEncodeBitrate );
//tBitRate.eControlRate = OMX_Video_ControlRateConstant; //OMX_Video_ControlRateVariable;
tBitRate.nPortIndex=OMX_VIDENC_OUTPUT_PORT;
tBitRate.nEncodeBitrate=value;
eError=OMX_SetConfig(pHandle,OMX_IndexConfigVideoBitrate,&tBitRate);
if(eError!=OMX_ErrorNone) {
printf("Bit Rate Config Error %i\n",eError);
}
else {
printf( "Bit rate changed to %d\n", value );
m_nBitRate=value;
}
I call this every 300 frames at 30fps. I use a tool I downloaded called Bitrate Viewer to view the changes in bitrate. It looks like the bitrate changes are never applied.
Is there a setting I need to change to get this to work?
Thanks,
Steven
