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.

AM5728: H.264 CBR encoding problem

Part Number: AM5728

We are transcoding a motion JPEG stream to H.264 on an AM5728 processor, using TI’s “ducati” plugin for GStreamer.
The encoding seems to work all right, but I cannot figure out how to get a constant bitrate (CBR) stream.
Reading the source code suggests that “rate-preset=low-delay” should activate CBR mode, but the bitrate still varies.

I am using the following pipeline:

gst-launch-1.0 -e v4l2src device=/dev/video1 ! \
image/jpeg,width=1920,height=1080,framerate=60/1 ! \
videorate max-rate=30 drop-only=true ! \
queue max-size-buffers=1 leaky=upstream ! \
ducatijpegdec ! video/x-raw,format=NV12 ! \
ducatih264enc bitrate=1600 rate-preset=low-delay ! \
h264parse ! mp4mux faststart=true ! \
filesink location=out-1080p.mp4

So I would expect the bitrate to remain about 1600 kbps.
However, what I see in is:

• In a still scene, the bitrate is about 1390 kbps.
• In a scene with motion, the bitrate is about 3100 kbps.

How can we achieve a constant bitrate with the “ducati” encoder?

  • Hi

    Please refer the below thread & do the same configuration.

    Thanks

    Gaviraju

  • Hi Gaviraju,

    Can you show me how to use that configuration in a GStreamer pipeline?

  • Can you show me how to use that configuration in a GStreamer pipeline?

  • I tried another pipeline which is closer to the parameters you linked to:

    gst-launch-1.0 -e v4l2src device/dev/video1 ! \
    image/jpeg,width=1920,height=1080,framerate=60/1 ! \
    videorate max-rate=30 drop-only=true ! \
    queue max-size-buffers=1 leaky=upstream ! \
    ducatijpegdec ! video/x-raw,format=NV12 ! \
    ducatih264enc bitrate=1600 rate-preset=user-defined rate-control-params-preset=rate-control-params-preset-user-defined rate-control-algo=low-delay-rate-control hrd-buffer-size=800000 ! \
    h264parse ! mp4mux faststart=true ! \
    filesink location=out-1080p.mp4

    But it results in an error:

    ERROR: from element /GstPipeline:pipeline0/GstDucatiH264Enc:ducatih264enc0: Could not encode stream.
    Additional debug info:
    gstducatividenc.c(758): gst_ducati_videnc_handle_frame (): /GstPipeline:pipeline0/GstDucatiH264Enc:ducatih264enc0

  • Hi,

    Seems the encoding parameter is not correct so please refer the Encode user-guide then set parameter correctly.

    6622.H264_Encoder_HDVICP2_UserGuide.pdf

    Thanks

    Gaviraju

  • Hi Gaviraju,

    I have referred to the user guide but cannot find which encoding parameter I have set incorrectly. Can you please tell me which parameter is incorrect and tell me how to set it correctly?

    Thanks!

  • Hi,

    The CBR encoding is not supported from the GStreamer command line application because only few parameter are exposed in the command-line to set required the property. 

    For more information run the command "gst-inspect-1.0 ducatih264enc

    Thanks

    Gaviraju

  • Hi Gaviraju,

    We are fine with modifying the ducati source code if the necessary options are not available through the command-line application.

    I tried these changes, following the post you linked to earlier:

    diff --git a/gst/ducati/gstducatih264enc.c b/gst/ducati/gstducatih264enc.c
    index 5c5f234..c5c8ef8 100644
    --- a/gst/ducati/gstducatih264enc.c
    +++ b/gst/ducati/gstducatih264enc.c
    @@ -575,12 +575,15 @@ gst_ducati_h264enc_configure (GstDucatiVidEnc * videnc)
       /* Dynamic params */
       dynParams = (IH264ENC_DynamicParams *) videnc->dynParams;
       dynParams->rateControlParams.rateControlParamsPreset =
    -      self->rate_control_params_preset;
    -  dynParams->rateControlParams.rcAlgo = self->rate_control_algo;
    +      IH264_RATECONTROLPARAMS_USERDEFINED;
    +  dynParams->rateControlParams.rcAlgo = IH264_RATECONTROL_PRC_LOW_DELAY;
       dynParams->rateControlParams.qpI = self->qpi;
       dynParams->rateControlParams.qpMaxI = self->qp_max_i;
       dynParams->rateControlParams.qpMinI = self->qp_min_i;
    -  dynParams->rateControlParams.HRDBufferSize = self->hrd_buffer_size;
    +  dynParams->rateControlParams.initialBufferLevel =
    +      videnc->dynParams->targetBitRate / 2;
    +  dynParams->rateControlParams.HRDBufferSize =
    +      videnc->dynParams->targetBitRate / 2;
       dynParams->sliceCodingParams.sliceMode = self->slice_mode;
       videnc->dynParams->interFrameInterval = inter_interval;
    
    diff --git a/gst/ducati/gstducatividenc.c b/gst/ducati/gstducatividenc.c
    index 4d7cb25..75ba785 100644
    --- a/gst/ducati/gstducatividenc.c
    +++ b/gst/ducati/gstducatividenc.c
    @@ -461,8 +461,8 @@ gst_ducati_videnc_configure_default (GstDucatiVidEnc * self)
         self->rect.h = GST_VIDEO_INFO_HEIGHT (&state->info);
    
       params = (VIDENC2_Params *) self->params;
    -  params->encodingPreset = 0x03;
    -  params->rateControlPreset = self->rate_preset;
    +  params->encodingPreset = XDM_USER_DEFINED;
    +  params->rateControlPreset = IVIDEO_USER_DEFINED;
       params->maxHeight = self->rect.h;
       params->maxWidth = self->rect.w;
       params->dataEndianness = XDM_BYTE;
    

    There is definitely some visible difference in the encoded stream, but not what we were hoping for. Quality (especially frame rate) seem to suffer dramatically vs. the default VBR setting, yet the bitrate is actually a little higher.

    Does this match the behavior that you see?

    Thanks,
    John

  • Hi,

    To support CBR the B frame encoding should be disabled, so please set the property inter-interval=1 in the command-line & try again.

    Thanks

    Gaviraju

  • Hi Gaviraju,

    Setting inter-interval=1 in the command-line did not help with the low frame rate issue.

    Can you point me to a working demo/example of CBR encoding?

  • Hi,

    The CBR features is not supported currently in the gstreamer command line pipe-line, so I will discuss with the team regarding this feature implementation & let you know.

    Thanks

    Gaviraju

  • Hi John Lindgren,

    There is an standalone example for encoder here: https://git.ti.com/cgit/glsdk/omapdrmtest

    You can refer to the videnc2test.c. It has example on how to change/modify the static and dynamic encoder parameters. You can look into h264enc_params->rateControlParams settings. The more information(which you might be already aware of) on the parameter settings can be found in Encoder User guide here: https://git.ti.com/cgit/ivimm/ipumm/tree/extrel/ti/ivahd_codecs/packages/ti/sdo/codecs/h264enc/docs/H264_Encoder_HDVICP2_UserGuide.pdf

    There is a FAQ with more information on how to configure CBR mode, you can find it here: https://e2e.ti.com/support/processors/f/processors-forum/948856/faq-tda2sx-how-do-i-configure-the-h-264-encoder-constant-bit-rate-cbr-and-variable-bit-rate-vbr-on-ivahd

    If you want to change the configuration settings in run time please refer this patch attached below(as there is attachment issue, I am posting the patch as plain text in next post., you can save it as .patch file and apply directly on top of this repo) With these changes you can provide the configuration file as an command line argument to videnc2test.

    Usage will be: ./videcn2test   input_nv12.yuv   input.cfg   h264

    Output will be generated in name input_nv12.yuv.h264

    Only NV12 yuv input format is supported.

    With all the above information can you try to replicate the same in your use case to configure CBR in gstreamer?


  • Hi Prashanth,

    What system is omapdrmtest meant to be run on?

    I am using PROCESSOR-SDK-LINUX-AM57X 06_03_00_106 and I do not seem to have all the required libraries:

    CCLD videnc2test
    /usr/lib/gcc/arm-linux-gnueabi/8.3.0/../../../../arm-linux-gnueabi/bin/ld: cannot find -lavcodec
    collect2: error: ld returned 1 exit status
    make: *** [Makefile:613: videnc2test] Error 1

    Do I need to install FFmpeg for this example to work?

  • Hi Prashanth,

    I managed to get the omapdrmtest project to compile after installing FFmpeg and libdce.

    I am getting an error when I try to run videnc2test:

    $ videnc2test 1280 720 500 in.yuv out.h264 30 2500 h264 baseline 10 OMAPDRM
    videnc2test.c:911: init_h264_dyn_params error: Codec_control returned err=-1, extendedError=00000001
    videnc2test.c:1060: encoder_init error: H264 encoder static parameter error

    Can you help me to solve this error? Thanks!

  • The extended error means one of the parameter is going wrong which is set in command line.

    You can map the error code as below:

    in interface file (ih264enc.h), you can find the meaning of each error bit in this enum IH264ENC_ErrorBit.

    extendedError=00000001, the first bit is set, which means: IH264ENC_LEVEL_INCOMPLAINT_PARAMETER.

    Can you try with below command?

    videnc2test 1280 720 500 in.yuv out.h264 30 2500 h264 baseline 40 OMAPDRM

  • I am using the default videnc2test for now. I tried changing the "level" parameter to 40 as you suggested, and that fixes the error. Thank you!

    For CBR encoding, I changed the parameters as follows based on the forum page that you linked to:

    diff --git a/videnc2test.c b/videnc2test.c
    index 9a3c334..44ad2e5 100644
    --- a/videnc2test.c
    +++ b/videnc2test.c
    @@ -439,7 +439,7 @@ static int init_h264_static_params(encoder *enc)
         //rate control params
         h264enc_params->rateControlParams.rateControlParamsPreset = IH264_RATECONTROLPARAMS_USERDEFINED;
         h264enc_params->rateControlParams.scalingMatrixPreset = IH264_SCALINGMATRIX_NONE;
    -    h264enc_params->rateControlParams.rcAlgo = IH264_RATECONTROL_DEFAULT; // 0
    +    h264enc_params->rateControlParams.rcAlgo = IH264_RATECONTROL_PRC_LOW_DELAY; // 1
         h264enc_params->rateControlParams.qpI = 28;
         h264enc_params->rateControlParams.qpMaxI = 36;
         h264enc_params->rateControlParams.qpMinI = 10;
    @@ -453,8 +453,8 @@ static int init_h264_static_params(encoder *enc)
         h264enc_params->rateControlParams.removeExpensiveCoeff = 0;
         h264enc_params->rateControlParams.chromaQPIndexOffset = 0;
         h264enc_params->rateControlParams.IPQualityFactor = IH264_QUALITY_FACTOR_DEFAULT; // 0
    -    h264enc_params->rateControlParams.initialBufferLevel = 64000;
    -    h264enc_params->rateControlParams.HRDBufferSize = 64000;
    +    h264enc_params->rateControlParams.initialBufferLevel = enc->bps / 2;
    +    h264enc_params->rateControlParams.HRDBufferSize = enc->bps / 2;
         h264enc_params->rateControlParams.minPicSizeRatioI = 0;
         h264enc_params->rateControlParams.maxPicSizeRatioI = 20;
         h264enc_params->rateControlParams.minPicSizeRatioP = 0;
    

    I then encoded at 3 different bitrates:

    $ videnc2test 1280 720 500 in.yuv out-600.h264 30 600 h264 baseline 40 OMAPDRM
    $ videnc2test 1280 720 500 in.yuv out-1200.h264 30 1200 h264 baseline 40 OMAPDRM
    $ videnc2test 1280 720 500 in.yuv out-2500.h264 30 2500 h264 baseline 40 OMAPDRM

    However, the size of the output changes only very slightly:

    out-600.mp4: 8312398 bytes
    out-1200.mp4: 8312398 bytes
    out-2500.mp4: 8369783 bytes

    What do I need to do to get the actual output bitrate to match the desired bitrate?

  • Hi,

    Can you please try to apply the patch attached above and run the videnc2test with config file. The configuration settings can be done in run time.

  • The patch does not compile:

    videnc2test.c: In function 'encoder_init':
    videnc2test.c:1193:28: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
      dce_buf_lock(1, (size_t*) &(enc->outBufs->descs[0].buf));
                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    videnc2test.c:1202:29: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
       dce_buf_lock(1, (size_t*) &(enc->outBufs->descs[1].buf));
                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    videnc2test.c:1051:21: warning: variable 'err' set but not used [-Wunused-but-set-variable]
         XDAS_Int32      err;
                         ^~~
    videnc2test.c: In function 'encoder_deinit':
    videnc2test.c:1228:31: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
       dce_buf_unlock(1, (size_t*) &(enc->outBufs->descs[0].buf));
                                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    videnc2test.c:1234:31: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
       dce_buf_unlock(1, (size_t*) &(enc->outBufs->descs[1].buf));
                                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    videnc2test.c: In function 'main':
    videnc2test.c:1346:18: error: 'sig_handler' undeclared (first use in this function); did you mean 'sa_handler'?
      sa.sa_handler = sig_handler;
                      ^~~~~~~~~~~
                      sa_handler
    videnc2test.c:1346:18: note: each undeclared identifier is reported only once for each function it appears in
    videnc2test.c:1353:2: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
      XDAS_Int32      err;
      ^~~~~~~~~~
    videnc2test.c:1362:30: error: 'i' undeclared (first use in this function)
         int             eof = 0; i;
                                  ^
    videnc2test.c:1363:5: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
         int             bytesGenerated = 0;
         ^~~
    videnc2test.c:1366:10: error: 'encObj' undeclared (first use in this function)
      memset(&encObj, 0, sizeof(encoder));
              ^~~~~~
    videnc2test.c:1403:3: error: 'buf' undeclared (first use in this function)
       buf = drm_get_buffer(&encObj);
       ^~~
    videnc2test.c:1361:21: warning: unused variable 'in_cnt' [-Wunused-variable]
         int             in_cnt = 0, out_cnt = 0, iters = 0;
                         ^~~~~~

  • Hi,

    Can you use the modified source shared and try to compile and run at your side with config file?

  • Hi Prasanth, I was able to compile the files that you shared privately. Do you have a sample config file that I can use as a starting point for CBR encoding?

  • Hi John,

    Please use the shared config file. Modify the same as per your requirement. Refer user guide if needed.

  • Hi Prasanth,

    I made the following changes to the config file you shared because my input file is 1280x720:

    --- sample.cfg.0
    +++ sample.cfg
    @@ -6,10 +6,10 @@
    ##########################################################################################
    # Files
    ##########################################################################################
    -InputFile = "..\..\..\Test\TestVecs\Input\airshow_p176x144_nv12.yuv"
    -EncodedFile = "..\..\..\Test\TestVecs\Output\airshow_p176x144.264"
    -ReferenceFile = "..\..\..\Test\TestVecs\Reference\airshow_p176x144.264" #Reference file to bitmatch with encoded bit stream
    -waterMarkInputKeyFile = "..\..\..\Test\TestVecs\Config\waterMarkInputKeyFile.bin" # file name along with the path of water mark input key
    +InputFile = "in.yuv"
    +EncodedFile = "out.h264"
    +ReferenceFile = "" #Reference file to bitmatch with encoded bit stream
    +waterMarkInputKeyFile = "" # file name along with the path of water mark input key

    ##########################################################################################
    # Encoder Control
    @@ -19,7 +19,7 @@
    MaxInterFrameInterval = 1 # I to P frame distance. 1 indicates no B frames. Value >1 indicates presence of B frames.
    Profile = 100 # Encoding profile 100 => HP, 77 => MP, 66 => BP
    Level = 41 # Level IDC (e.g. 20 = level 2.0)
    -NumInputUnits = 300 # Total number of frames to encode
    +NumInputUnits = 500 # Total number of frames to encode
    MaxWidth = 1920 # Max Frame width should be multiple of 16
    MaxHeight = 1088 # Max Frame height should be multiple of 16
    InputChromaFormat = 9 # Input data chroma format, supports only DM_YUV_420SP format
    @@ -28,15 +28,15 @@
    OutputDataMode = 3 # Encode entire frame into a bitstream in single call. Only supported value is 3.
    NumOutputUnits = 1 # Number of units of output-data (ex. 1 Slice/Frame encoded stream).
    dataLayout = 0 # input data buffer layout 0=> interleaved, 1=> seprated. Applicable only for interlace content.
    -inputWidth = 352 # width of image
    -inputHeight = 288 # Height of image
    +inputWidth = 1280 # width of image
    +inputHeight = 720 # Height of image
    targetFrameRate = 30000 # Target frame rate in fps * 1000, => For 60 fields per second it should be 30000
    -targetBitRate = 512000 # Target Bit Rate in Bits per second.
    +targetBitRate = 600000 # Target Bit Rate in Bits per second.
    intraFrameInterval = 60 # Interval between two consecutive intra frames, 0 => Only first frame to be intra coded, 1 => All intra frames, N => One intra frame and N-1 inter frames, where N > 1
    interFrameInterval = 1 # M: Number of (M-1) B frames between two reference frames. 1 indicates no B frame.
    generateHeader = 0 # Header is not encoded seperately. The entire frame is encoded as an access unit alongwith the headers.
    -captureWidth = 352 # Image capture width
    -captureHeight = 288 # Image capture height
    +captureWidth = 1280 # Image capture width
    +captureHeight = 720 # Image capture height
    captureTopLeftx = 0 # Exact source position of the pixel to encode in input buffer X direction
    captureTopLefty = 0 # Exact source position of the pixel to encode in input buffer Y direction
    forceFrame = -1 # Frame type is not forced. It is as per the encoding behaviour.
    @@ -109,8 +109,8 @@
    qpMaxB = 51 # Maximum QP for B frames
    qpMinB = 10 # Minimum QP for B frames
    chromaQPIndexOffset = 0 # Specifies offset to be added to luma QP for addressing QPC values table for chroma components
    -initialBufferLevel = 1024000 # Initial Buffer level for HRD compliance, keep same as HRDBufferSize for best quality
    -HRDBufferSize = 1024000 # Hypothetical Reference Decoder Buffer Size in bits - 2*bitrate for VBR
    +initialBufferLevel = 300000 # Initial Buffer level for HRD compliance, keep same as HRDBufferSize for best quality
    +HRDBufferSize = 300000 # Hypothetical Reference Decoder Buffer Size in bits - 2*bitrate for VBR
    enablePartialFrameSkip = 0 # Control Flag to enable Partial Frame Skip, 0 => Disable, Non-Zero => Enable
    enablePRC = 1 # Control Flag to enable MB level Perceptual Rate Control, 0 => Disable, Non-Zero => Enable
    removeExpensiveCoeff = 0 # Flag to remove high frequency expensive coefficients, 0 => Disable, Non-Zero => Enable

    I am getting another error though:

    $ videnc2test in.yuv sample.cfg h264
    videnc2test.c:934: init_h264_dyn_params error: Codec_control returned err=-1, extendedError=0000c015
    videnc2test.c:1038: encoder_init error: H264 encoder dynamic parameter error

    Is this due to a change that I made?

    Thanks.

  • Hi John,

    The extended error says 0x0000c015,

    bits, 0, 2, 1, 14 & 15 are set. 

    As mentioned earlier can you please map it in interface file (ih264enc.h), you can find the meaning of each error bit in this enum IH264ENC_ErrorBit?

  • Hi Prasanth,

    Thanks for helping me decode the error bits. I see that 0x000c015 means:

    - IH264ENC_LEVEL_INCOMPLAINT_PARAMETER (bit 0)
    - IH264ENC_PROFILE_INCOMPLAINT_CONTENTTYPE (bit 1)
    - IH264ENC_PROFILE_INCOMPLAINT_FMO_SETTING (but 2)

    The IH264ENC_ErrorBit enum doesn't have values for bits 14 & 15.

    I'm not sure how to fix these errors. Would you be able to provide me with a working (without errors) config file that I can use as a starting point, and make changes to as needed?

  • Hi John,

    Please try with this below which is working at my side.

    # New Input File Format is as follows
    # ParameterName = ParameterValue # Comment
    #


    ##########################################################################################
    # Files
    ##########################################################################################
    InputFile = "..\..\..\Test\input\input_nv12.yuv"
    EncodedFile = "..\..\..\Test\output\output.264"

    ##########################################################################################
    # Encoder Control
    ##########################################################################################
    EncodingPreset = 3 # 0=> Default (see codec-specific document to understand the encoding behaviour).
    RateControlPreset = 5 # 1 => Low Delay, 2 => Storage, 3 => reserved, 4 => None, 5 => user defined
    MaxInterFrameInterval = 1 # I to P frame distance. 1 indicates no B frames. Value >1 indicates presence of B frames.
    Profile = 100 # Encoding profile 100 => HP, 77 => MP, 66 => BP
    Level = 40 # Level IDC (e.g. 20 = level 2.0)
    NumInputUnits = 500 # Total number of frames to encode
    MaxWidth = 1920 # Max Frame width should be multiple of 16
    MaxHeight = 1088 # Max Frame height should be multiple of 16
    InputChromaFormat = 9 # Input data chroma format, supports only DM_YUV_420SP format
    InputContentType = 0 # Input buffer content type, 0 -> Progressive Type, 1-> Interlaced
    InputDataMode = 3 # Process entire frame. Only supported value is 3.
    OutputDataMode = 3 # Encode entire frame into a bitstream in single call. Only supported value is 3.
    NumOutputUnits = 1 # Number of units of output-data (ex. 1 Slice/Frame encoded stream).
    dataLayout = 0 # input data buffer layout 0=> interleaved, 1=> seprated. Applicable only for interlace content.
    inputWidth = 1280 # width of image
    inputHeight = 720 # Height of image
    targetFrameRate = 30000 # Target frame rate in fps * 1000, => For 60 fields per second it should be 30000
    targetBitRate = 10000000 # Target Bit Rate in Bits per second.
    intraFrameInterval = 30 # Interval between two consecutive intra frames, 0 => Only first frame to be intra coded, 1 => All intra frames, N => One intra frame and N-1 inter frames, where N > 1
    interFrameInterval = 1 # M: Number of (M-1) B frames between two reference frames. 1 indicates no B frame.
    generateHeader = 0 # Header is not encoded seperately. The entire frame is encoded as an access unit alongwith the headers.
    captureWidth = 1280 # Image capture width
    captureHeight = 720 # Image capture height
    captureTopLeftx = 0 # Exact source position of the pixel to encode in input buffer X direction
    captureTopLefty = 0 # Exact source position of the pixel to encode in input buffer Y direction
    forceFrame = -1 # Frame type is not forced. It is as per the encoding behaviour.
    sampleAspectRatioHeight = 1 # Aspect Ratio Height
    sampleAspectRatioWidth = 1 # Aspect Ratio Width
    ignoreOutbufSizeFlag = 1 # Flag to inform for checking output buffer availability inside codec.

    ###########################################################################################
    # InterCoding Control
    ###########################################################################################
    interCodingPreset = 0 # Inter coding mode preset, 0 => deafult values, 1 => user defined
    searchRangeHorP = 144 # Horizontal Search Range for P frames in integer pixels, e.g. 144 -> this will make search range from (-144 to +144) offseted by GMV.x
    searchRangeVerP = 32 # Vertical Search Range for P frames in integer pixels
    searchRangeHorB = 144 # Horizontal Search Range for B frames in integer pixels
    searchRangeVerB = 16 # Vertical Search Range for B frames in integer pixels
    skipMVCodingBias = 1 # Bias control for having a macro block use skip MV or regular MV, 0 => Low biasing, 1 => Normal/Med biasing, 4 => Mild biasing, 5 => Adaptive biasing
    minBlockSizeP = 1 # minimum block size for P frames, 0 => 16x16 1 => 8x8
    minBlockSizeB = 1 # minimum block size for B frames, 0 => 16x16 1 => 8x8
    searchCenter_x = 32767 # Search center for Motion estimation i.e global motion vector in X dir. For best video quality, set this to 32767 so that Codec will set searchCenter_x and searchCenter_y at internally computed global offset.
    searchCenter_y = 0 # Search center for Motion estimation i.e global motion vector in Y dir
    mvAccuracy = 2 # Pixel accuracy of the motion vector, 0 => integer pel 2=> quarter pel

    ############################################################################################
    # IntraCoding Control
    ############################################################################################
    intraCodingPreset = 1 # Intra coding mode preset, 0 => deafult values, 1 => user defined
    lumaIntra4x4Enable = 0 # Enable the selected intra 4x4 modes (0-511) Order Of modes - HOR_UP|VERT_LEFT|HOR_DOWN|VERT_RIGHT|DIAG_DOWN_RIGHT|DIAG_DOWN_LEFT|DC|HOR|VER
    lumaIntra8x8Enable = 0 # Enable the selected intra 8x8 modes (0-511) Order Of modes - HOR_UP|VERT_LEFT|HOR_DOWN|VERT_RIGHT|DIAG_DOWN_RIGHT|DIAG_DOWN_LEFT|DC|HOR|VER
    lumaIntra16x16Enable = 15 # Enable the selected intra 16x16 modes (0-15) Order of modes - PLANE|DC|HOR|VER
    chromaIntra8x8Enable = 0 # Enable the selected chroma intra modes (0-15) Order of modes - PLANE|VER|HOR|DC
    intraRefreshRate = 0 # Rate at which intra MB Refresh is done. e.g. 10 indicates every 10th MB will coded as Intra in inter pictures.
    constrainedIntraPredEnable = 0 # Controls the intra macroblock coding in inter slices
    chromaComponentEnable = 1 # Controls the chroma Intra prediction search. 0: Cb+Cr,1: Cr only

    ############################################################################################
    # Loop Filter Control
    ############################################################################################
    loopfilterPreset = 0 # Preset value for loop filter operation parameters, 0 => deafult values, 1 => user defined
    loopfilterDisableIDC = 0 # Disable H.264 loop filter, (0=Filter, 1= NoFilter, 2 = No loop filter across slices)
    filterOffsetA = 0 # Alpha offset for loop filter
    filterOffsetB = 0 # Beta offset for loop filter

    ############################################################################################
    # Entropy Coding Mode
    ############################################################################################
    entropyCodingMode = 0 # Enropy coding type, (0 => CAVLC, 1 => CABAC)

    ############################################################################################
    # Slice Mode Configuration
    ############################################################################################
    sliceCodingPreset = 0 # Preset value for slice coding mode, 0 => deafult values, 1 => user defined
    sliceMode = 3 # Type of slice coding, (0 => slice coding mode is frame based, 1 => Slices are controlled based upon number of Macroblocks 2 => Slices are controlled based upon number of bytes (will be supported in future codec release)
    sliceStartOffset0 = 1
    sliceStartOffset1 = 45
    sliceStartOffset2 = 70
    sliceUnitSize = 0 # The meaning of this parameter depends upon sliceMode
    streamFormat = 0 # Type of bitstream to be encoded. Only value 0 is supprted (Byte stream format)

    ################################################################################
    # Rate Control Params
    ################################################################################
    rateControlParamPreset = 1 # Preset value for selecting rate control params, 0: default (other parameters in this category will be decided by Codec internally), 1: user defined
    scalingMatrixPreset = 0 # Scaling Matrix selection of encoder, 0: no scaling matrices, 1: normal, 2: noisy, 3 : standard default
    qpI = 10 # Initial QP for I/IDR frames, -1 indicates codec chosen
    qpP = -1 # Initial QP for P frames
    qpOffsetB = 4 # Offset of B frames QP from P frames
    rcAlgo = 0 # Rate control algorithm used, 0: Variable Bitrate, 1 : Constant bitrate (low dealy), Only applicable if RateControlPreset is set to 5 (user defined).
    qpMaxI = 40 # Maximum QP for I/IDR frames
    qpMinI = 8 # Minimum QP for I/IDR frames
    qpMaxP = 40 # Maximum QP for P frames
    qpMinP = 10 # Minimum QP for P frames
    qpMaxB = 40 # Maximum QP for B frames
    qpMinB = 10 # Minimum QP for B frames
    chromaQPIndexOffset = 0 # Specifies offset to be added to luma QP for addressing QPC values table for chroma components
    initialBufferLevel = 20000000 # Initial Buffer level for HRD compliance, keep same as HRDBufferSize for best quality
    HRDBufferSize = 20000000 # Hypothetical Reference Decoder Buffer Size in bits - 2*bitrate for VBR
    enablePartialFrameSkip = 0 # Control Flag to enable Partial Frame Skip, 0 => Disable, Non-Zero => Enable
    enablePRC = 1 # Control Flag to enable MB level Perceptual Rate Control, 0 => Disable, Non-Zero => Enable
    removeExpensiveCoeff = 0 # Flag to remove high frequency expensive coefficients, 0 => Disable, Non-Zero => Enable

    ################################################################################
    # VUI Control Params
    ################################################################################
    vuiCodingPreset = 0 # Preset value for VUI Control Params, 0 => deafult values, 1 => user defined
    aspectRatioInfoPresentFlag = 1 # Controls the insertion of aspect ratio information in VUI part of bit-stream
    aspectRatioIdc = 1 # Aspect ratio ID
    videoSignalTypePresentFlag = 0 # controls the insertion of video signal type in VUI part of bit-stream
    videoFormat = 2 # Video signal type
    videoFullRangeFlag = 0 # Flag to specigy Range of the pixels
    timingInfoPresentFlag = 1 # Controls the insertion of timing info related parameters in VUI part of bit-stream

    ################################################################################
    # NALU Control Params
    ################################################################################
    naluControlPreset = 0 # Preset value for NALU Control Params, 0 => deafult values, 1 => user defined
    naluPresentMaskStartOfSequence = 416 # Controls the insertion of different NALU at start of sequence
    naluPresentMaskIDRPicture = 416 # Controls the insertion of different NALU at IDR picture
    naluPresentMaskIntraPicture = 2 # Controls the insertion of different NALU at Intra picture(s)
    naluPresentMaskNonIntraPicture = 384 # Controls the insertion of different NALU at Non-intra pictures
    naluPresentMaskEndOfSequence = 3072 # Controls the insertion of different NALU at end of sequence

    ################################################################################
    # STEREO INFO Control Params
    ################################################################################
    stereoInfoPreset = 0 # Preset controls the Enable/Disable of Stereo Videoc Coding, 0 => Disable, 1 => Default Frame packing SEI parameters, 2 => User defined
    topFieldIsLeftViewFlag = 1 # Controls top field in video coded sequence as a left view or right view, 0 => Top field is Left View, Non-Zero => Top field is Right view
    viewSelfContainedFlag = 0 # Controls the Left/Right view should refer Left view or Right view, 0 => Leftview can refer to Rightview or Leftview & Rightview can refer to Rightview or Leftview, Non-Zero => Leftview can refer only to Leftview & Rightview can refer only to Rightview

    ################################################################################
    # Frame Packing SEI Params
    ################################################################################
    framePackingPreset = 0 # Preset controls the Enable/Disable of Frame packing SEI message encoding, 0 => Disable, 1 => Default Frame packing SEI parameters, 2 => User defined
    framePackingType = 3 # Indicates that frame packing arrangement type, 0 => Checker board arrangement of 2 views, 1 => Column interleaving arrangement of 2 views, 2 => Row interleaving arrangement of 2 views, 3 => Side by side arrangement of 2 views, 4=> Top-Bottom arrangement of 2 views
    frame0PositionX = 0 # Location of the upper left sample of frame 0(Left view) in horizontal direction
    frame0PositionY = 0 # Location of the upper left sample of frame 0(Left view) in vertical direction
    frame1PositionX = 0 # Location of the upper left sample of frame 1(Right view) in horizontal direction
    frame1PositionY = 0 # Location of the upper left sample of frame 1(Right view) in vertical direction
    reservedByte = 0 # Value of frame_packing_arrangement_reserved_byte syntax element

    ################################################################################
    # H-P Coding Control Params
    ################################################################################
    numTemporalLayer = 1 # 1 => 1layer , 2 => 2layers,3=> 3layers,4 => 4layers
    referencePicMarking = 1 # 0 =>Short-term referencing(Sliding Window),1=> Long term referencing(MMCO Commands)

    ################################################################################
    # MISC
    ################################################################################
    gopStructure = 0 # GOP structure, 0 => Open or Non uniform(IBBPBBP), 1 => Closed or Uniform (BBIBBPBB)
    IDRFrameInterval = 1 # Interval b/w two IDR frames
    bottomFieldIntra = 0 # 1 : Force bottom field of Intra frame as Intra field, 0: bottom field as inter (default)
    transformBlockSize = 2 # Tranform type, 0:4x4 only, 1: 8x8 only, 2:Adaptive (default)
    log2MaxFNumMinus4 = 8 # sliceParams::frame_num syntax element will be reset after every (1<< (log2MaxFNumMinus4 + 4)) frames
    picOrderCountType = 0 # Picture order count type, supported value 0,1 and 2
    topFieldFirstFlag = 1 # Flag to indicate field order in interlaced content
    interlaceCodingType = 3 # Interlced field coding type selection, 2 => MRF 3=> ARF 4=> SPF
    forceIDRPeriod = 100000 # ForceIDRPeriod specified by user to control encoding
    forceSKIPPeriod = 100000 # Skip frame interval
    enableLongTermRefFrame = 0 # Parameter is used to support long-term reference frame, 0 => Disable, Non-Zero => Enable
    enableWatermark = 0 # Flag to enable water marking
    maxPicSizeRatioI = 0

    ##########################################################################################
    # ROI Parameters
    ##########################################################################################
    enableROI = 0 # 0->disable ROI 1-> enable ROI
    ROIcfg = "..\..\..\Test\TestVecs\Config\roiInputParams.cfg"

  • Hi Prashanth,

    That config seems to work for VBR encoding, thank you.

    I tried the following modifications for 800 kbps CBR encoding:

    --- sample-2.cfg
    +++ sample-modified.cfg
    @@ -29,7 +29,7 @@
     inputWidth = 1280 # width of image
     inputHeight = 720 # Height of image
     targetFrameRate = 30000 # Target frame rate in fps * 1000, => For 60 fields per second it should be 30000
    -targetBitRate = 10000000 # Target Bit Rate in Bits per second.
    +targetBitRate = 800000 # Target Bit Rate in Bits per second.
     intraFrameInterval = 30 # Interval between two consecutive intra frames, 0 => Only first frame to be intra coded, 1 => All intra frames, N => One intra frame and N-1 inter frames, where N > 1
     interFrameInterval = 1 # M: Number of (M-1) B frames between two reference frames. 1 indicates no B frame.
     generateHeader = 0 # Header is not encoded seperately. The entire frame is encoded as an access unit alongwith the headers.
    @@ -101,7 +101,7 @@
     qpI = 10 # Initial QP for I/IDR frames, -1 indicates codec chosen
     qpP = -1 # Initial QP for P frames
     qpOffsetB = 4 # Offset of B frames QP from P frames
    -rcAlgo = 0 # Rate control algorithm used, 0: Variable Bitrate, 1 : Constant bitrate (low dealy), Only applicable if RateControlPreset is set to 5 (user defined).
    +rcAlgo = 1 # Rate control algorithm used, 0: Variable Bitrate, 1 : Constant bitrate (low dealy), Only applicable if RateControlPreset is set to 5 (user defined).
     qpMaxI = 40 # Maximum QP for I/IDR frames
     qpMinI = 8 # Minimum QP for I/IDR frames
     qpMaxP = 40 # Maximum QP for P frames
    @@ -109,8 +109,8 @@
     qpMaxB = 40 # Maximum QP for B frames
     qpMinB = 10 # Minimum QP for B frames
     chromaQPIndexOffset = 0 # Specifies offset to be added to luma QP for addressing QPC values table for chroma components
    -initialBufferLevel = 20000000 # Initial Buffer level for HRD compliance, keep same as HRDBufferSize for best quality
    -HRDBufferSize = 20000000 # Hypothetical Reference Decoder Buffer Size in bits - 2*bitrate for VBR
    +initialBufferLevel = 400000 # Initial Buffer level for HRD compliance, keep same as HRDBufferSize for best quality
    +HRDBufferSize = 400000 # Hypothetical Reference Decoder Buffer Size in bits - 2*bitrate for VBR
     enablePartialFrameSkip = 0 # Control Flag to enable Partial Frame Skip, 0 => Disable, Non-Zero => Enable
     enablePRC = 1 # Control Flag to enable MB level Perceptual Rate Control, 0 => Disable, Non-Zero => Enable
     removeExpensiveCoeff = 0 # Flag to remove high frequency expensive coefficients, 0 => Disable, Non-Zero => Enable
    

    The resulting H.264 output file is 8,148,321 bytes. The test video is 500 frames = 16.67 seconds long, so if my math is correct, that works out to 8,148,321*8 / 16.67 = 3,910,412 bits/second or 3910 kbps.

    Why might the bitrate of the resulting file be 3910 kbps instead of the 800 kbps I'm trying to achieve?

  • Hi John,

    Thank you for the update. Yes, your math is right.

    Can you try setting the below? 

    qpI          = -1    (Let codec decide the intial qp value for I frames)
    qpP         = -1   (Let codec decide the intial qp value for P frames)
    qpMaxI   = 40   (Upper boundary supported values 0 to 51 for I frames)
    qpMinI    = 20   (Lower boundary supported values 0 to 51 for I frames)
    qpMaxP  = 40   (Upper boundary supported values 0 to 51 for P frames)
    qpMinP   = 20   (Lower boundary supported values 0 to 51 for P frames)

    Lower the qp value better the quality and higher the bitrate. Higher the qp value lower the quality but the targetBitrate will be achieved. Can you play around(tune these values) the qpMax and qpMin for both I and P frames which suits your requirement? Supported values are 0 to 51.

    Always note that qpMin < qpMax value.