This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

OMX VENC cant change bitrate dynamically

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

  • Hi,

    Can someone at TI please respond to this. We need to rectify this issue for our customers.

    As an example I recorded at 1Mbps but tried to increase the bitrate by 100000 every 10 seconds. Bitrate Viewer shows that this did not happen.

    Thanks,

    Steven