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.

H.264 B-frames in IPNC 3.5

We are using IPNC 3.5.0 on a DM8127.  Back in March of this year, I posted a question  (http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/716/t/252361.aspx) about B-frames and was told that they are not supported, apparently because the existing buffer handling cannot deal with the out-of-order frame generation that B-frames involve.  However, the documentation on the H.264 encoder itself (ti_tools/codecs-dm814x/REL.500.V.H264AVC.E.IVAHD.02.00.04.01/500.V.H264AVC.E.IVAHD.02.00/IVAHD_001/Docs/H264_Encoder_HDVICP2_UserGuide.pdf) explicitly says that B-frames are supported.  And indeed, if I set encPrm.chCreateParams[i].defaultDynamicParams.interFrameInterval to 2, I get an H.264 stream that contains B-frames.

However, there are a few mysteries: In the first GOP of the stream, the first B-frame is missing.  That is, the first GOP begins I, P, B, P instead of I, B, P, B, P, and is of size 15 instead of 16.  The structure of the subsequent GOPs is correct.  Also, the size of the encoded stream is more than twice as big as the same file encoded at the same bitrate without B-frames.  And, if I use ffmpeg to convert the encoded streams back to YUV and compare them to the original YUV file to determine the peak signal to noise ratio (PSNR), the PSNR of the stream that included B-frames is significantly worse (by about 5.5 dB) than that of the stream encoded without B-frames.  Finally, if I set the interframeInterval to 3, the call to System_linkCreate() for the encoder hangs.

Are B-frames still considered unsupported?  If so, can anyone provide advice on how I could overcome the problems noted above?  Thanks.

  • The first mystery seems to be solved.  The encoder is using open GOPs, so the first B-frame of a GOP is predicted from a reference frame in the previous GOP.  That first B-frame is missing from the first GOP because there's no previous GOP from which to predict it.  However, I'm still confused about why the encoded file size goes up and the PSNR goes down when I enable B-frames.

  • Dave Beal,

    Could you please share the encoder configurations used here? ~5db PSNR deviation is too much, there should be something fishy in parameter settings or buffer handling.

    Also mention the video encoder release integrated to this application. 

    Thanks.

  • Hello  Santosh -

    Thanks in advance for your help!

    The encoder is REL.500.V.H264AVC.E.IVAHD.02.00.04.01.

    Here are my encoder params:

            inter = 1;    // or 2 for B-frames

            encPrm.chCreateParams[0].defaultDynamicParams.inputFrameRate = 30;
            encPrm.chCreateParams[0].defaultDynamicParams.intraFrameInterval = 16;
            encPrm.chCreateParams[0].defaultDynamicParams.targetBitRate = 3000000;
            encPrm.chCreateParams[0].format =IVIDEO_H264HP ;
            encPrm.chCreateParams[0].profile                 = VENC_CHN_HIGH_PROFILE;
            encPrm.chCreateParams[0].dataLayout              = IVIDEO_PROGRESSIVE;
            encPrm.chCreateParams[0].fieldMergeEncodeEnable  = FALSE;
            encPrm.chCreateParams[0].enableAnalyticinfo      = FALSE;
            encPrm.chCreateParams[0].maxBitRate              = 6000000;
            encPrm.chCreateParams[0].encodingPreset          = XDM_DEFAULT;
            encPrm.chCreateParams[0].rateControlPreset       = IVIDEO_USER_DEFINED;
            encPrm.chCreateParams[0].enableHighSpeed         = FALSE;
            encPrm.chCreateParams[0].enableWaterMarking      = FALSE;

            rateCntrlTi = VENC_RATE_CTRL_CBR;
            if (inter > 1) {
                rateCntrlTi = VENC_RATE_CTRL_VBR;  // Can't do low delay RC if B frames enabled???
                encPrm.chCreateParams[0].StreamPreset = ALG_VID_ENC_PRESET_HIGHQUALITY;
            } else {
                encPrm.chCreateParams[0].StreamPreset = ALG_VID_ENC_PRESET_AUTO;
            }
            encPrm.chCreateParams[0].enableAnalyticinfo = 0;
            encPrm.chCreateParams[0].defaultDynamicParams.interFrameInterval = inter;
            encPrm.chCreateParams[0].defaultDynamicParams.mvAccuracy = IVIDENC2_MOTIONVECTOR_QUARTERPEL;
            encPrm.chCreateParams[0].defaultDynamicParams.rcAlg            = rateCntrlTi;
            encPrm.chCreateParams[0].defaultDynamicParams.qpMin            = 5;
            encPrm.chCreateParams[0].defaultDynamicParams.qpMax            = 50;
            encPrm.chCreateParams[0].defaultDynamicParams.qpInit           = -1;
            encPrm.chCreateParams[0].defaultDynamicParams.vbrDuration      = 8;
            encPrm.chCreateParams[0].defaultDynamicParams.vbrSensitivity   = 0;
            encPrm.numBufPerCh[0] = 30;
            encPrm.numFullBufPerCh[0] = 3;
            encPrm.bufBytesPerCh[0] = 2250000;

    For a 739-frame YUV stream of 1920x1080, I get these encoded file sizes and PSNR values:

    interframeInterval = 1, CBR:  4,659,759 bytes, 26.30 dB

    interframeInterval = 1, VBR: 5,648,671 bytes, 27.00 dB

    interframeInterval = 2, VBR: 10,007,368 bytes, 20.87 dB

    The YUV file is about 2.3GB.  If you need it, I'll try compressing it.

  • One more fact that seems to explain the size difference between encoded files containing B-frames and those that don't:  At the beginning of the encoded files that contain B-frames, the B-frames are approximately the same size as the P-frames (both about 5500 bytes) .  However, the B-frames quickly become bigger.  By the end of the 739 frame sequence, the B-frames are at least 4 times bigger than the P-frames (22000 byte B-frames vs. 4600 byte P-frames).

  • Dave Beal,

    Okay, H.264 encoder release 02.00.04.01 supports encoding 'B' Frames. 

    The encoder settings you have shared are not the complete set, with only these parameters(shared) we will not be able test at our end. I hope full set of encoder parameters are programmed somewhere down the layer at application side. We basically need all those parameters. Alternatively, encoder parameters set can be known by doing an encoder control call for XDM_GETSTATUS. Please do this exercise and share full set of parameters.

    As of now we  don't  need raw video content, so don't share .

    FYI,  Sample Encoder settings to enable 'B' frames are as follows,

    STATIC/CREATE:

    ((gCodecParams).codec_params).params = {...}
    videnc2Params = {...}
    size = 0x00000138
    encodingPreset = 0x00000003
    rateControlPreset = 0x00000005
    maxHeight = 0x00000438
    maxWidth = 0x00000780
    dataEndianness = 0x00000001
    maxInterFrameInterval = 0x00000002
    maxBitRate = 0xFFFFFFC0
    minBitRate = 256000
    inputChromaFormat = 0x00000009
    inputContentType = 0x00000000
    operatingMode = 0x00000001
    profile = 0x00000064
    level = 0x00000029
    inputDataMode = 0x00000003
    outputDataMode = 0x00000003
    numInputDataUnits = 0x00000001
    numOutputDataUnits = 0x00000001
    metadataType = 0x00400BAC
    [0] = 0x00000100
    [1] = 0xFFFFFFFF
    [2] = 0xFFFFFFFF
    rateControlParams = {...}
    rateControlParamsPreset = 0x01
    scalingMatrixPreset = 0x02
    rcAlgo = 0x00
    qpI = 0x1E
    qpMaxI = 0x29
    qpMinI = 0x14
    qpP = 0x1E
    qpMaxP = 0x29
    qpMinP = 0x14
    qpOffsetB = 0x04
    qpMaxB = 0x29
    qpMinB = 0x14
    allowFrameSkip = 0x00
    removeExpensiveCoeff = 0x00
    chromaQPIndexOffset = 0x00
    IPQualityFactor = 0x00
    initialBufferLevel = 0x002FAF08
    HRDBufferSize = 0x017D7840
    minPicSizeRatioI = 0x0000
    maxPicSizeRatioI = 0x0000
    minPicSizeRatioP = 0x0000
    maxPicSizeRatioP = 0x0000
    minPicSizeRatioB = 0x0000
    maxPicSizeRatioB = 0x0000
    enablePRC = 0x01
    enablePartialFrameSkip = 0x01
    discardSavedBits = 0x00
    reserved = 0x00
    VBRDuration = 0x00000008
    VBRsensitivity = 0x00
    skipDistributionWindowLength = 0x0000
    numSkipInDistributionWindow = 0x0000
    enableHRDComplianceMode = 0x01
    frameSkipThMulQ5 = 0x00000000
    vbvUseLevelThQ5 = 0x00000000
    reservedRC = 0x00400BF4
    [0] = 0x00000000
    [1] = 0x00000000
    [2] = 0x00000000
    interCodingParams = {...}
    interCodingPreset = 0x01
    searchRangeHorP = 0x0090
    searchRangeVerP = 0x0020
    searchRangeHorB = 0x0090
    searchRangeVerB = 0x0010
    interCodingBias = 0x01
    skipMVCodingBias = 0x01
    minBlockSizeP = 0x00
    minBlockSizeB = 0x00
    meAlgoMode = 0x00
    intraCodingParams = {...}
    intraCodingPreset = 0x01
    lumaIntra4x4Enable = 0x0000
    lumaIntra8x8Enable = 0x00FF
    lumaIntra16x16Enable = 0x0F
    chromaIntra8x8Enable = 0x0F
    chromaComponentEnable = 0x01
    intraRefreshMethod = 0x00
    intraRefreshRate = 0x0000
    gdrOverlapRowsBtwFrames = 0x0000
    constrainedIntraPredEnable = 0x0000
    intraCodingBias = 0x00
    nalUnitControlParams = {...}
    naluControlPreset = 0x0001
    naluPresentMaskStartOfSequence = 0x63C0
    naluPresentMaskIDRPicture = 0x4240
    naluPresentMaskIntraPicture = 0x4240
    naluPresentMaskNonIntraPicture = 0x4240
    naluPresentMaskEndOfSequence = 0x4E40
    sliceCodingParams = {...}
    sliceCodingPreset = 0x00
    sliceMode = 0x0000
    sliceUnitSize = 0x0000
    sliceStartOffset = 0x00400C34
    [0] = 0x00
    [1] = 0x00
    [2] = 0x00
    streamFormat = 0x00
    loopFilterParams = {...}
    loopfilterPreset = 0x01
    loopfilterDisableIDC = 0x00
    filterOffsetA = 0x00
    filterOffsetB = 0x00
    fmoCodingParams = {...}
    fmoCodingPreset = 0x00
    numSliceGroups = 0x01
    sliceGroupMapType = 0x04
    sliceGroupChangeDirectionFlag = 0x00
    sliceGroupChangeRate = 0x00
    sliceGroupChangeCycle = 0x0000
    sliceGroupParams = 0x00400C44
    [0] = 0x0000
    [1] = 0x0000
    vuiCodingParams = {...}
    vuiCodingPreset = 0x01
    aspectRatioInfoPresentFlag = 0x01
    aspectRatioIdc = 0x01
    videoSignalTypePresentFlag = 0x00
    videoFormat = 0x02
    videoFullRangeFlag = 0x01
    timingInfoPresentFlag = 0x01
    hrdParamsPresentFlag = 0x01
    numUnitsInTicks = 0x000003E8
    stereoInfoParams = {...}
    stereoInfoPreset = 0x00
    topFieldIsLeftViewFlag = 0x00
    viewSelfContainedFlag = 0x00
    framePackingSEIParams = {...}
    framePackingPreset = 0x00
    framePackingType = 0x00
    frame0PositionX = 0x00
    frame0PositionY = 0x00
    frame1PositionX = 0x00
    frame1PositionY = 0x00
    reservedByte = 0x00
    svcCodingParams = {...}
    svcExtensionFlag = 0x00
    dependencyID = 0x00
    qualityID = 0x00
    enhancementProfileID = 0x00
    layerIndex = 0x00
    refLayerDQId = 0x00
    interlaceCodingType = 0x03
    bottomFieldIntra = 0x00
    gopStructure = 0x01
    entropyCodingMode = 0x01
    transformBlockSize = 0x02
    log2MaxFNumMinus4 = 0x08
    picOrderCountType = 0x01
    enableWatermark = 0x00
    IDRFrameInterval = 0x00000001
    pConstantMemory = 0x00000000
    maxIntraFrameInterval = 0x00000010
    debugTraceLevel = 0x00000001
    lastNFramesToLog = 0x00000000
    enableAnalyticinfo = 0x00
    enableGMVSei = 0x00
    constraintSetFlags = 0x00
    enableRCDO = 0x00
    enableLongTermRefFrame = 0x00000000
    LTRPPeriod = 0xFFFFFFFF
    numTemporalLayer = 0x01
    referencePicMarking = 0x01
    reservedParams = 0x00400C90
    [0] = 0x00000000
    [1] = 0x0000001F
    [2] = 0x00000000


    DYNAMIC:

    ((gCodecParams).codec_params).dynamicParams = {...}
    videnc2DynamicParams = {...}
    size = 0x000000EC
    inputHeight = 0x00000438
    inputWidth = 0x00000780
    refFrameRate = 0x00007530
    targetFrameRate = 0x00007530
    targetBitRate = 0x017D7840
    intraFrameInterval = 0x00000010
    generateHeader = 0x00000000
    captureWidth = 0x00000780
    forceFrame = 0xFFFFFFFF
    interFrameInterval = 0x00000002
    mvAccuracy = 0x00000002
    sampleAspectRatioHeight = 0x00000001
    sampleAspectRatioWidth = 0x00000001
    ignoreOutbufSizeFlag = 0x00000001
    putDataFxn = 0x9FDC6A39
    putDataHandle = 0x00000000
    getDataFxn = 0x9FDC7715
    getDataHandle = 0x9FD9B628
    getBufferFxn = 0x9FDC618D
    getBufferHandle = 0x00000000
    lateAcquireArg = 0x00000100
    rateControlParams = {...}
    rateControlParamsPreset = 0x01
    scalingMatrixPreset = 0x02
    rcAlgo = 0x00
    qpI = 0x1E
    qpMaxI = 0x29
    qpMinI = 0x14
    qpP = 0x1E
    qpMaxP = 0x29
    qpMinP = 0x14
    qpOffsetB = 0x04
    qpMaxB = 0x29
    qpMinB = 0x14
    allowFrameSkip = 0x00
    removeExpensiveCoeff = 0x00
    chromaQPIndexOffset = 0x00
    IPQualityFactor = 0x00
    initialBufferLevel = 0x002FAF08
    HRDBufferSize = 0x017D7840
    minPicSizeRatioI = 0x0000
    maxPicSizeRatioI = 0x0000
    minPicSizeRatioP = 0x0000
    maxPicSizeRatioP = 0x0000
    minPicSizeRatioB = 0x0000
    maxPicSizeRatioB = 0x0000
    enablePRC = 0x01
    enablePartialFrameSkip = 0x01
    discardSavedBits = 0x00
    reserved = 0x00
    VBRDuration = 0x00000008
    VBRsensitivity = 0x00
    skipDistributionWindowLength = 0x0000
    numSkipInDistributionWindow = 0x0000
    enableHRDComplianceMode = 0x01
    frameSkipThMulQ5 = 0x00000000
    vbvUseLevelThQ5 = 0x00000000
    reservedRC = 0x00400D30
    [0] = 0x00000000
    [1] = 0x00000000
    [2] = 0x00000000
    interCodingParams = {...}
    interCodingPreset = 0x01
    searchRangeHorP = 0x0090
    searchRangeVerP = 0x0020
    searchRangeHorB = 0x0090
    searchRangeVerB = 0x0010
    interCodingBias = 0x01
    skipMVCodingBias = 0x01
    minBlockSizeP = 0x00
    minBlockSizeB = 0x00
    meAlgoMode = 0x00
    intraCodingParams = {...}
    intraCodingPreset = 0x01
    lumaIntra4x4Enable = 0x0000
    lumaIntra8x8Enable = 0x00FF
    lumaIntra16x16Enable = 0x0F
    chromaIntra8x8Enable = 0x0F
    chromaComponentEnable = 0x01
    intraRefreshMethod = 0x00
    intraRefreshRate = 0x0000
    gdrOverlapRowsBtwFrames = 0x0000
    constrainedIntraPredEnable = 0x0000
    intraCodingBias = 0x00
    sliceCodingParams = {...}
    sliceCodingPreset = 0x00
    sliceMode = 0x0000
    sliceUnitSize = 0x0000
    sliceStartOffset = 0x00400D64
    [0] = 0x00
    [1] = 0x00
    [2] = 0x00
    streamFormat = 0x00
    sliceGroupChangeCycle = 0x00000000
    searchCenter = {...}
    x = 0x00007FFF
    y = 0x00007FFF
    enableStaticMBCount = 0x00
    enableROI = 0x00000000
    reservedDynParams = 0x00400D7C
    [0] = 0x6942676E
    [1] = 0x3D007361
    [2] = 0x6D003100

    Thanks.

  • Encoder output with the above settings and bits consumed for respective frame types are as expected.

    Frame No // Frame Type// Bits

    #0 : IVIDEO_NA_FRAME : Bits : 0
    #1 : IVIDEO_IDR_FRAME : Bits : 536072
    #2 : IVIDEO_B_FRAME : Bits : 93584
    #3 : IVIDEO_P_FRAME : Bits : 32832
    #4 : IVIDEO_B_FRAME : Bits : 11928
    #5 : IVIDEO_P_FRAME : Bits : 51392
    #6 : IVIDEO_B_FRAME : Bits : 17864
    #7 : IVIDEO_P_FRAME : Bits : 47216
    #8 : IVIDEO_B_FRAME : Bits : 12856
    #9 : IVIDEO_P_FRAME : Bits : 42520
    #10 : IVIDEO_B_FRAME : Bits : 11560
    #11 : IVIDEO_P_FRAME : Bits : 49608
    #12 : IVIDEO_B_FRAME : Bits : 13800
    #13 : IVIDEO_P_FRAME : Bits : 45336
    #14 : IVIDEO_B_FRAME : Bits : 15880
    #15 : IVIDEO_P_FRAME : Bits : 43352
    #16 : IVIDEO_B_FRAME : Bits : 31224
    #17 : IVIDEO_IDR_FRAME : Bits : 345384
    #18 : IVIDEO_B_FRAME : Bits : 31104
    #19 : IVIDEO_P_FRAME : Bits : 75176
    #20 : IVIDEO_B_FRAME : Bits : 29384
    #21 : IVIDEO_P_FRAME : Bits : 111024
    #22 : IVIDEO_B_FRAME : Bits : 35656
    #23 : IVIDEO_P_FRAME : Bits : 130648
    #24 : IVIDEO_B_FRAME : Bits : 52640
    #25 : IVIDEO_P_FRAME : Bits : 167264
    #26 : IVIDEO_B_FRAME : Bits : 85768
    #27 : IVIDEO_P_FRAME : Bits : 195096
    #28 : IVIDEO_B_FRAME : Bits : 92088
    #29 : IVIDEO_P_FRAME : Bits : 232800
    #30 : IVIDEO_B_FRAME : Bits : 110888
    #31 : IVIDEO_P_FRAME : Bits : 233168
    #32 : IVIDEO_B_FRAME : Bits : 125136
    #33 : IVIDEO_IDR_FRAME : Bits : 485192
    #34 : IVIDEO_B_FRAME : Bits : 140432
    #35 : IVIDEO_P_FRAME : Bits : 219384
    #36 : IVIDEO_B_FRAME : Bits : 111312
    #37 : IVIDEO_P_FRAME : Bits : 203648
    #38 : IVIDEO_B_FRAME : Bits : 111712
    #39 : IVIDEO_P_FRAME : Bits : 216208
    #40 : IVIDEO_B_FRAME : Bits : 102360
    #41 : IVIDEO_P_FRAME : Bits : 214224
    #42 : IVIDEO_B_FRAME : Bits : 96480
    #43 : IVIDEO_P_FRAME : Bits : 204312
    #44 : IVIDEO_B_FRAME : Bits : 102672
    #45 : IVIDEO_P_FRAME : Bits : 223064
    #46 : IVIDEO_B_FRAME : Bits : 109072
    #47 : IVIDEO_P_FRAME : Bits : 203912
    #48 : IVIDEO_B_FRAME : Bits : 89360
    #49 : IVIDEO_IDR_FRAME : Bits : 518504
    #50 : IVIDEO_B_FRAME : Bits : 107064
    #51 : IVIDEO_P_FRAME : Bits : 145448
    #52 : IVIDEO_B_FRAME : Bits : 75592
    #53 : IVIDEO_P_FRAME : Bits : 179056
    #54 : IVIDEO_B_FRAME : Bits : 76896
    #55 : IVIDEO_P_FRAME : Bits : 196920
    #56 : IVIDEO_B_FRAME : Bits : 118472
    #57 : IVIDEO_P_FRAME : Bits : 216872
    #58 : IVIDEO_B_FRAME : Bits : 102768
    #59 : IVIDEO_P_FRAME : Bits : 199216
    #60 : IVIDEO_B_FRAME : Bits : 106816
    #61 : IVIDEO_P_FRAME : Bits : 192616
    #62 : IVIDEO_B_FRAME : Bits : 115576
    #63 : IVIDEO_P_FRAME : Bits : 206064
    #64 : IVIDEO_B_FRAME : Bits : 94328
    #65 : IVIDEO_IDR_FRAME : Bits : 525360
    #66 : IVIDEO_B_FRAME : Bits : 106600
    #67 : IVIDEO_P_FRAME : Bits : 167792
    #68 : IVIDEO_B_FRAME : Bits : 84352
    #69 : IVIDEO_P_FRAME : Bits : 203176
    #70 : IVIDEO_B_FRAME : Bits : 84184
    #71 : IVIDEO_P_FRAME : Bits : 228192
    #72 : IVIDEO_B_FRAME : Bits : 100552
    #73 : IVIDEO_P_FRAME : Bits : 218760
    #74 : IVIDEO_B_FRAME : Bits : 101360
    #75 : IVIDEO_P_FRAME : Bits : 186064
    #76 : IVIDEO_B_FRAME : Bits : 77632
    #77 : IVIDEO_P_FRAME : Bits : 188608
    #78 : IVIDEO_B_FRAME : Bits : 79448
    #79 : IVIDEO_P_FRAME : Bits : 213520
    #80 : IVIDEO_B_FRAME : Bits : 127424
    #81 : IVIDEO_IDR_FRAME : Bits : 565712
    #82 : IVIDEO_B_FRAME : Bits : 148016
    #83 : IVIDEO_P_FRAME : Bits : 254176
    #84 : IVIDEO_B_FRAME : Bits : 132608
    #85 : IVIDEO_P_FRAME : Bits : 227632
    #86 : IVIDEO_B_FRAME : Bits : 142864
    #87 : IVIDEO_P_FRAME : Bits : 220488
    #88 : IVIDEO_B_FRAME : Bits : 137304
    #89 : IVIDEO_P_FRAME : Bits : 248480
    #90 : IVIDEO_B_FRAME : Bits : 130680
    #91 : IVIDEO_P_FRAME : Bits : 235888
    #92 : IVIDEO_B_FRAME : Bits : 122440
    #93 : IVIDEO_P_FRAME : Bits : 238928
    #94 : IVIDEO_B_FRAME : Bits : 103048
    #95 : IVIDEO_P_FRAME : Bits : 245064
    #96 : IVIDEO_B_FRAME : Bits : 119336
    #97 : IVIDEO_IDR_FRAME : Bits : 560960
    #98 : IVIDEO_B_FRAME : Bits : 133288
    #99 : IVIDEO_P_FRAME : Bits : 204040

    Thanks.

  • Hi Santosh -

    I've managed to use the XDM_GETSTATUS call to get the IH264ENC_Status data from the encoder, but the IH264ENC_DynamicParams data comes back all zeroes.  I don't know why.  (I have set the size fields at the beginning of both structs.)  Here is the Status data:

    status.videnc2Status.size = 804
    status.videnc2Status.extendedError = 0
    status.videnc2Status.data.buf = (nil)
    status.videnc2Status.data.bufSize = 0
    status.videnc2Status.data.accessMask = 0
    status.videnc2Status.encodingPreset = 3
    status.videnc2Status.rateControlPreset = 5
    status.videnc2Status.maxInterFrameInterval = 4
    status.videnc2Status.inputChromaFormat = 9
    status.videnc2Status.inputContentType = 0
    status.videnc2Status.operatingMode = 1
    status.videnc2Status.profile = 100
    status.videnc2Status.level = 50
    status.videnc2Status.inputDataMode = 3
    status.videnc2Status.outputDataMode = 3
    status.videnc2Status.numInputDataUnits = 1
    status.videnc2Status.numOutputDataUnits = 1
    status.videnc2Status.configurationID = 1271
    status.videnc2Status.bufInfo.minNumInBufs = 0
    status.videnc2Status.bufInfo.minNumOutBufs = 0
    status.videnc2Status.bufInfo.minNumBufSets = 0
    status.videnc2Status.metadataType[] = [ -1 -1 -1 ]
    status.videnc2Status.encDynamicParams.size = 236
    status.videnc2Status.encDynamicParams.inputHeight = 1080
    status.videnc2Status.encDynamicParams.inputWidth = 1920
    status.videnc2Status.encDynamicParams.refFrameRate = 60000
    status.videnc2Status.encDynamicParams.targetFrameRate = 60000
    status.videnc2Status.encDynamicParams.targetBitRate = 3000000
    status.videnc2Status.encDynamicParams.intraFrameInterval = 16
    status.videnc2Status.encDynamicParams.generateHeader = 0
    status.videnc2Status.encDynamicParams.captureWidth = 1920
    status.videnc2Status.encDynamicParams.forceFrame = -1
    status.videnc2Status.encDynamicParams.interFrameInterval = 2
    status.videnc2Status.encDynamicParams.mvAccuracy = 2
    status.videnc2Status.encDynamicParams.sampleAspectRatioHeight = 1080
    status.videnc2Status.encDynamicParams.sampleAspectRatioWidth = 1920
    status.videnc2Status.encDynamicParams.ignoreOutbufSizeFlag = 1
    status.videnc2Status.encDynamicParams.putDataFxn = (nil)
    status.videnc2Status.encDynamicParams.putDataHandle = (nil)
    status.videnc2Status.encDynamicParams.getDataFxn = (nil)
    status.videnc2Status.encDynamicParams.getDataHandle = (nil)
    status.videnc2Status.encDynamicParams.getBufferFxn = 0x8d8796ed
    status.videnc2Status.encDynamicParams.getBufferHandle = (nil)
    status.videnc2Status.encDynamicParams.lateAcquireArg = -1
    status.rateControlParams.rateControlParamsPreset = 1
    status.rateControlParams.scalingMatrixPreset = 1
    status.rateControlParams.rcAlgo = 0
    status.rateControlParams.qpI = 255
    status.rateControlParams.qpMaxI = 50
    status.rateControlParams.qpMinI = 5
    status.rateControlParams.qpP = 255
    status.rateControlParams.qpMaxP = 50
    status.rateControlParams.qpMinP = 5
    status.rateControlParams.qpOffsetB = 4
    status.rateControlParams.qpMaxB = 44
    status.rateControlParams.qpMinB = 10
    status.rateControlParams.allowFrameSkip = 0
    status.rateControlParams.removeExpensiveCoeff = 0
    status.rateControlParams.chromaQPIndexOffset = 0
    status.rateControlParams.IPQualityFactor = 0
    status.rateControlParams.initialBufferLevel = 6000000
    status.rateControlParams.HRDBufferSize = 6000000
    status.rateControlParams.minPicSizeRatioI = 0
    status.rateControlParams.maxPicSizeRatioI = 640
    status.rateControlParams.minPicSizeRatioP = 0
    status.rateControlParams.maxPicSizeRatioP = 0
    status.rateControlParams.minPicSizeRatioB = 0
    status.rateControlParams.maxPicSizeRatioB = 0
    status.rateControlParams.enablePRC = 1
    status.rateControlParams.enablePartialFrameSkip = 0
    status.rateControlParams.discardSavedBits = 1
    status.rateControlParams.reserved = 0
    status.rateControlParams.VBRDuration = 8
    status.rateControlParams.VBRsensitivity = 0
    status.rateControlParams.skipDistributionWindowLength = 5
    status.rateControlParams.numSkipInDistributionWindow = 1
    status.rateControlParams.enableHRDComplianceMode = 1
    status.rateControlParams.frameSkipThMulQ5 = 0
    status.rateControlParams.vbvUseLevelThQ5 = 0
    status.rateControlParams.reservedRC[] = [ 0  0 0 ]
    status.interCodingParams.interCodingPreset = 0
    status.interCodingParams.searchRangeHorP = 144
    status.interCodingParams.searchRangeVerP = 32
    status.interCodingParams.searchRangeHorB = 144
    status.interCodingParams.searchRangeVerB = 16
    status.interCodingParams.interCodingBias = 1
    status.interCodingParams.skipMVCodingBias = 1
    status.interCodingParams.minBlockSizeP = 0
    status.interCodingParams.minBlockSizeB = 0
    status.interCodingParams.meAlgoMode = 0
    status.intraCodingParams.intraCodingPreset = 0
    status.intraCodingParams.lumaIntra4x4Enable = 0
    status.intraCodingParams.lumaIntra8x8Enable = 255
    status.intraCodingParams.lumaIntra16x16Enable = 15
    status.intraCodingParams.chromaIntra8x8Enable = 15
    status.intraCodingParams.chromaComponentEnable = 1
    status.intraCodingParams.intraRefreshMethod = 0
    status.intraCodingParams.intraRefreshRate = 0
    status.intraCodingParams.gdrOverlapRowsBtwFrames = 0
    status.intraCodingParams.constrainedIntraPredEnable = 0
    status.intraCodingParams.intraCodingBias = 0
    status.nalUnitControlParams.naluControlPreset = 1
    status.nalUnitControlParams.naluPresentMaskStartOfSequence = 8608
    status.nalUnitControlParams.naluPresentMaskIDRPicture = 8608
    status.nalUnitControlParams.naluPresentMaskIntraPicture = 8450
    status.nalUnitControlParams.naluPresentMaskNonIntraPicture = 2
    status.nalUnitControlParams.naluPresentMaskEndOfSequence = 3072
    status.sliceCodingParams.sliceCodingPreset = 1
    status.sliceCodingParams.sliceMode = 0
    status.sliceCodingParams.sliceUnitSize = 0
    status.sliceCodingParams.sliceStartOffset[] = [ 0 0 0 ]
    status.sliceCodingParams.streamFormat = 0
    status.loopFilterParams.loopfilterPreset = 0
    status.loopFilterParams.loopfilterDisableIDC = 0
    status.loopFilterParams.filterOffsetA = 0
    status.loopFilterParams.filterOffsetB = 0
    status.fmoCodingParams.fmoCodingPreset = 0
    status.fmoCodingParams.numSliceGroups = 1
    status.fmoCodingParams.sliceGroupMapType = 4
    status.fmoCodingParams.sliceGroupChangeDirectionFlag = 0
    status.fmoCodingParams.sliceGroupChangeRate = 0
    status.fmoCodingParams.sliceGroupChangeCycle = 0
    status.fmoCodingParams.sliceGroupParams[] = [ 0 0 ]
    status.vuiCodingParams.vuiCodingPreset = 1
    status.vuiCodingParams.aspectRatioInfoPresentFlag = 0
    status.vuiCodingParams.aspectRatioIdc = 255
    status.vuiCodingParams.videoSignalTypePresentFlag = 0
    status.vuiCodingParams.videoFormat = 5
    status.vuiCodingParams.videoFullRangeFlag = 1
    status.vuiCodingParams.timingInfoPresentFlag = 1
    status.vuiCodingParams.hrdParamsPresentFlag = 1
    status.vuiCodingParams.numUnitsInTicks = 1000
    status.stereoInfoParams.stereoInfoPreset = 0
    status.stereoInfoParams.topFieldIsLeftViewFlag = 1
    status.stereoInfoParams.viewSelfContainedFlag = 0
    status.framePackingSEIParams.framePackingPreset = 0
    status.framePackingSEIParams.framePackingType = 3
    status.framePackingSEIParams.frame0PositionX = 0
    status.framePackingSEIParams.frame0PositionY = 0
    status.framePackingSEIParams.frame1PositionX = 0
    status.framePackingSEIParams.frame1PositionY = 0
    status.framePackingSEIParams.reservedByte = 0
    status.svcCodingParams.svcExtensionFlag = 0
    status.svcCodingParams.dependencyID = 0
    status.svcCodingParams.qualityID = 0
    status.svcCodingParams.enhancementProfileID = 0
    status.svcCodingParams.layerIndex = 0
    status.svcCodingParams.refLayerDQId = 0
    status.interlaceCodingType = 3
    status.bottomFieldIntra = 0
    status.gopStructure = 0
    status.entropyCodingMode = 1
    status.transformBlockSize = 2
    status.log2MaxFNumMinus4 = 10
    status.picOrderCountType = 0
    status.enableWatermark = 0
    status.IDRFrameInterval = 1
    status.maxIntraFrameInterval = 300
    status.debugTraceLevel = 1
    status.lastNFramesToLog = 31
    status.enableAnalyticinfo = 0
    status.enableGMVSei = 0
    status.constraintSetFlags = 0
    status.enableRCDO = 0
    status.enableLongTermRefFrame = 0
    status.LTRPPeriod = 0
    status.searchCenter = 32767,32767
    status.enableStaticMBCount = 0
    status.extMemoryDebugTraceAddr = 0xb0c49480
    status.numTemporalLayer = 1
    status.referencePicMarking = 1
    status.extMemoryDebugTraceSize = 43008
    status.enableROI = 0

  • Hi Santosh -

    I'm still having no luck getting dynamic parameters from the H.264 encoder.  I make the enclink_h264_control(handle, XDM_GETSTATUS, params, status) call and it returns XDM_EOK.  The status structure is filled in with reasonable looking values (shown above), but the params structure is not filled in at all; bogus values I inserted before the call are still there.  I set  params->videnc2DynamicParams.size to sizeof(IH264ENC_DynamicParams) before the call.  I've tried making the call after the encoder is configured but before I send it any frames.  I've also tried making the call after I've sent 100 frames.  Same result both ways.

    Looking through the existing code, I don't see any call to XDM_GETSTATUS where the params structure is used after the call, only the status structure.  Does XDM_GETSTATUS actually fill in the dynamic params?

  • Hi Dave Beal,

    Sorry for the delayed response! I was on vacation.

    And you go it correct,

    • control call for encoder status doesn't modify user input dynamic parameter structure.
    • For status of encoder's dynamic parameters you can look into status.videnc2Status.encDynamicParams 
    I will verify these shared parameters in our stand alone encoder setup and get back to you. Meanwhile could you please increase the Qp range of 'B' frames and test at your end too? For P frames QpMax,QpMin = [ 50, 5] but for B frames it is set as QpMax,QpMin = [ 44, 10]  . So please enlarge the Qp range for B and test it. i.e., For B frames 
    rateControlParams.qpMaxB =  44  50            
    rateControlParams.qpMinB  =  10  5
    Thanks.
  • Hi Santosh -

    No need to apologize - I hope you had an enjoyable vacation!

    I've added code to set the B-frame QP parameters as you suggested.  In the EncLinkH264_algCreate() function, I make these assignments:

        hObj->staticParams.rateControlParams.qpMaxB = 50;
        hObj->staticParams.rateControlParams.qpMinB = 5;
        hObj->dynamicParams.rateControlParams.qpMaxB = 50;
        hObj->dynamicParams.rateControlParams.qpMinB = 5;

    then, later in the same function, I make the same assignments again, just before enclink_h264_control(XDM_SETPARAMS) is called.  I immediately read back the values via enclink_h264_control(XDM_GETPARAMS), and they are as I set them.

    Then, soon after I send the first frames to the encoder, I again call enclink_h264_control(XDM_GETPARAMS) and the values have changed to

    status.rateControlParams.qpMaxB = 44
    status.rateControlParams.qpMinB = 10

    I don't understand why the values change.  I didn't write most of the application code that I'm using, so I suppose it's possible that there's some application code that's changing the values, but I haven't been able to find any such code.

    Is the encoder capable of changing these parameters on its own?

  • Hi Santosh -

    I found and fixed the call that was setting my B-frame QP limits back to the default; it was due to Enclink_h264EncodeFrameBatch() calling EncLinkH264_algSetConfig().  Now, setting qpMaxB to 50 and qpMinB to 5 causes the size of the encoded file to decrease substantially compared to 44 and 10.  However, it is still somewhat larger than the same file encoded at the same bitrate without B-frames, and its PSNR is still 5 to 6 dB worse.  Here are my results for a 739-frame 1920x1080 YUV input stream:

    Intra=16, inter=1, VBR: encoded file size = 5,648,671 bytes, PSNR = 27.00 dB

    Intra=16, inter=1, CBR: encoded file size = 4,659,759 bytes, PSNR = 26.30 dB

    Intra=16, inter=2, VBR, BQP 10-44: encoded file size = 10,005,164 bytes, PSNR = 20.87 dB

    Intra=16, inter=2, VBR, BQP 5-50: encoded file size = 5,860,640 bytes, PSNR = 21.06 dB

    In all cases, target bitrate = 3Mbps, max bit rate = 6Mbps.

  • HI Dave Beal,

    This is not the expected behaviour. We shall verify the encoder configurations and get back to you.

    But can you please make sure that the 'input buffer handling' is properly implemented in you case for 'B' frame cases? You can refer to section 3.2 Frame Buffer Management - H264_Encoder_HDVICP2_UserGuide.pdf. Also you can refer the sample test application/client that is available in the release package.

    Thanks.

  • Hi Dave Beal,

    Few suggestions from our experts

    1. Make sure they are using delta qp=4 btw P and B.
    2. B frames need not always help, sometimes it can degrade PSNR (ex: fast moving sequence)
    3. I think stream is required if none of the above two help to solve his doubt.
    4. Please share the encoded bit stream, encoder configuration, and raw video content.
    5. For sharing raw video - You can encode the raw content with high bitrate and IPPPP.. sequence and share the bit stream. This should be nearer to the original video raw.
    Thanks.
  • Hi Santosh -

    I've attached an encoded version of my video as an H.264 elementary stream.  The encoder was configured as intra=16, inter=1, CBR, target bitrate=12Mbps, max bitrate=25Mbps.  This was the highest bitrate of this video that would fit in the website's maximum file size.

    Also, I don't understand what is meant by "Make sure they are using delta qp=4 btw P and B."  I am setting status.rateControlParams.qpOffsetB = 4.  Is this what you mean?

    I will be out of the office beginning tomorrow, returning next Wednesday (8/28).  I will try to check for updates while I am out.

    Centre_fast_1920x1080p60_12M_25M_16_1_CBR.dat
  • Hi Dave Beal,

    Your understanding for Qp delta/ QpOffsetB is correct. It is 4 as I have had a look to your encoder configuration.

    1. Reason for IBPBP... file size more than IPPPP.. file size : You had set [QpMinP,QpMaxP] =  [5,50] & [QpMinB,QpMaxB] =  [10,44] and bitrate as 3MBPS for full HD resolution. So because of this low bitrate for HD resolution, our encoder always tries to code with possible high Qp. And since you had restricted 'B' frame Qp not to go beyond 44, the size of 'B' frames were more than that of 'P' frames. We could reproduce such a observation at our setup(using your encoder configuration] and above given reason is right for this behaviour.
    2. Reason for bad PSNR for IBPBP.. sequence compared to IPPPP.. sequence : As said earlier in this thread that 'B' frames always shall not improve the PSNR, sometime (fast moving scenes) they may degrade too.In case of fast moving scenes 'B' frames has to code lot of motion information and hence need more bits. If bits are not available(less bitrate cases ) then our encoder starts coding the information with less quality to meet the network bit rate and hence less quality video.
    So the behaviour is as expected in your application from codec perspective.
    Few more tips from our experts
    1. Increase the bit rate if your application allow.
    2. Decrease the Qp range for P frames i.e., [QpMinP,QpMaxP] =  [10,40] 
    Thanks
  • Hi Santosh -

    Your suggestions have solved my B-frame mystery.  As you suggested, increasing the B-frame QP range from [10-44] to [5-50] resolved the encoded file size problem, and I've now verified that fixing the code in src_bios6/links_m3video/iva_enc/encLink_h264.c to return input buffers for release only when indicated by outArgs->videnc2OutArgs.freeBufID[] solved the PSNR problem.

    When I enable B-frames by increasing interframeInterval from 1 to 2, I now get an encoded file size that is slightly smaller and a PSNR value that is very slightly better than without B-frames.  Thanks for your help!

  • Dave Beal, 

    Good to hear it!! 


    Thanks and Regards,

    Santoshkumar S K