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.

H264 level changing problem



Hi,

I am trying to change the H264 level to 1.3 for DM6446. I am using loopbackCombo.x64P which comes with dvsdk1.3.

My target is to configure the h264 encoder to baseline profile with level 1.2. But after I changed the encodedecode application with params.levelIdc = IH264_LEVEL_12 I saw

the sequence parameter set(SPS) has baseline profile and level 3 (not 1.2).  Here is my code segment. Could anyone tell me what am I missing. Also what should be the value for params.searchRange.

 


    IH264VENC_Params     params;
    VIDENC_Handle        hEncode;
    XDAS_Int32           status;

    params.videncParams.size                  = sizeof(IH264VENC_Params);
    params.videncParams.encodingPreset        = XDM_DEFAULT;
    params.videncParams.rateControlPreset     = bitrate < 0 ? IVIDEO_NONE : IVIDEO_LOW_DELAY;
    params.videncParams.maxFrameRate          = gblGetYFactor() == NTSCSTD ? 30000 : 25000;
    params.videncParams.maxBitRate            = bitrate < 0 ? 0 : bitrate;
    params.videncParams.dataEndianness        = XDM_BYTE;
    params.videncParams.maxInterFrameInterval = 0;
    params.videncParams.inputChromaFormat     = XDM_YUV_422ILE;
    params.videncParams.inputContentType      = IVIDEO_PROGRESSIVE;
    params.videncParams.maxHeight             = D1_HEIGHT;
    params.videncParams.maxWidth              = D1_WIDTH;

    params.profileIdc = 66;
    params.levelIdc = IH264_LEVEL_13;
    params.rcAlgo = 0;
    //params.searchRange = 16;

    /* Create H.264 encoder instance */
    hEncode = VIDENC_create(hEngine, "h264enc", (VIDENC_Params *)&params);

 

  • A few things -

     

    a) For Level 1.2,

    params.levelIdc = IH264_LEVEL_12;

    Currently, it is set to 1.3 - params.levelIdc = IH264_LEVEL_13;

     

    b) Further,as per link below, Level 1.2 of H.264 BP profile allows for max resolution of 352*288 (or 320*240) at 384Kbits max bit rate. Changing the level would likely require change in corresponding resolution /bitrate 

    http://en.wikipedia.org/wiki/H.264/MPEG-4_AVC#Levels

     

    c) params.searchRange can be anywhere between 0 and 64 - As per the codec user guide, it is Integer pel search around 16*16 blocks. Having greater value will likely imply better compression quality & greater complexity (more CPU consumption) and vice versa.

     

    Prateek

     

  • Thanks Bansal for your reply.

    We have two 3rd party phones. One of them supports H264 level 1.2 and other 1.3. So we want to work with both of them.

    a. We have tried to change the level using IH264_LEVEL_12 and IH264_LEVEL_13. And both cases the output level is 3.0 which we saw in the SPS packet.

    b. The resolution we have set is CIF
        params.videncParams.maxHeight             = 288;
        params.videncParams.maxWidth              = 352;
    c. The maximum bit rate we have set is 384000.
        params.videncParams.maxBitRate = 384000;

    After setting these values we still saw the output of the H264 encoder is level 3.0.

    Question: 1. Does DVSDK1.3 loopbackCombo.x64P support only level 3.0?

    2. Does DVSDK1.3 and DVSDK2.0 have same loopbackCombo.x64P in term of H264 library?

    3. Is there any TI document which describes the H264 parameters to change the level with example?

     

  •  Can TI provide us example code on how to set level 1.2 or level 1.3 for H264?

  • It would help to understand which DVSDK you are using. I am assuming you are using DVSDK v1.30. Please confirm. 

     

    DVSDK v1.30 has H.264 encoder v1.10 

    DVSDK v2.00 has H.264 encoder v2.00

     

    The difference between the two H.264 encoder v1.10 and v2.00 is 

    a) migration from XDM 0.9 version APIs to XDM v1.0 APIs as explained in https://docs.google.com/viewer?url=http://wiki.davincidsp.com/images/d/de/XDM_migration0_9to1_0_v05.pdf

    b) H.264 encoder v2.00 supports upto level 4.1 while encoder v1.10 supports upto level 3.0

    As such the loopbackCombo.x64P file shipped with DVSDK v1.30 and DVSDK v2.00 are different.

     

    As per page 45 of H.264 encoder v1.10 User Guide, the following fields of IVIDENC1_Params data structure are level

    dependent: 

    a) maxHeight

    b) maxWidth

    c) maxFrameRate

    d) maxBitRate

    &#56256;d)d) m maxBitRate

    To check the values supported for maxHeight and maxWidth use the

    following expression:

    maxFrameSizeinMbs >= (maxHeight*maxWidth) / 256;

     

    For level 1.2 based on wikipedia, maximum frame size in Macroblocks maxFrameSizeinMbs = 396

    So, maxHeight = 288 and maxWidth = 352 should satisfy the above condition.

     

    Now, for maxFrameRate, use the below expression  to check the supported maxFrameRate

    values for each level:

    maxFrameRate <= maxMbsPerSecond / FrameSizeinMbs;

    where FrameSizeinMbs = (inputHeight * inputWidth)/256

     

    maxMbsPerSecond = 6000 for level v1.2

                                         = 11880 for level v1.3

    This implies maxFrameRate <= 6000/396 (15.15fps) for level v1.2 

                                                           = 11880/396  (30fps) for level v1.3 

    With respect to bitRate, maxBitRate <= 384000 for level v1.2

                                                                       = 768000 for level v1.3

     

    If the above conditions do not work, I will have to check with our experts if they are any other extended parameter settings that are required. 

    It would help if you can provide both your creation time parameters and dynamic parameter configuration settings ie IVIDENC_Params, IH264VENC_Params and IVIDENC_DynamicParams, IH264ENC_DynamicParams configuration. It could be that we are missing something on dynamicParams settings.

     

    Prateek

     

  • As you wanted to know which DVSDK we are using, We are using DVSDK v1.3.

     

    Question:

    - Is it possible to configure H264 encoder at 1.2 (or 1.3) and decoder at 3.0 in loopbackCombo.x64P? Or, both of them (encoder and decoder) should be exactly same level?

  • The code we used to create H264 encoder using parameter is given below. Let us know if you find something to try.

    The output of the encoder still is level 3.0 using these parameters.

     

    static int videoEncodeAlgCreate(Engine_Handle hEngine,
                                    VIDENC_Handle *hEncodePtr,
                                    int width, int height, int bitrate)
    {
        DBG_TRACE_ENTER();

        IH264VENC_DynamicParams dynamicParams;

        VIDENC_Status        encStatus;

        IH264VENC_Params     params;

        VIDENC_Handle        hEncode;
        XDAS_Int32           status;

        params.videncParams.size                  = sizeof(IH264VENC_Params);
        params.videncParams.encodingPreset        = XDM_DEFAULT;
        params.videncParams.rateControlPreset     = bitrate < 0 ? IVIDEO_NONE : IVIDEO_LOW_DELAY;
        params.videncParams.maxFrameRate          = 15200;
        params.videncParams.maxBitRate            = 384000;
        params.videncParams.dataEndianness        = XDM_BYTE;
        params.videncParams.maxInterFrameInterval = 0;
        params.videncParams.inputChromaFormat     = XDM_YUV_422ILE;
        params.videncParams.inputContentType      = IVIDEO_PROGRESSIVE;

        //CIF 352x288
        params.videncParams.maxHeight             = 288;
        params.videncParams.maxWidth              = 352;

        //H264 baseline profile and level = 1.2
        params.profileIdc = 66;
        params.levelIdc = IH264_LEVEL_12;
        params.rcAlgo = 0;
        params.searchRange = 0;

        /* Create H.264 encoder instance */
        hEncode = VIDENC_create(hEngine, "h264enc", (VIDENC_Params *)&params);

        if (hEncode == NULL) {
            ERR("Can't open encode algorithm: %s\n", "h264");
            return FAILURE;
        }

        printf("frame size: width = %d, height = %d\n", width, height);

        dynamicParams.videncDynamicParams.size = sizeof(IH264VENC_DynamicParams);
        dynamicParams.videncDynamicParams.inputHeight        = height;
        dynamicParams.videncDynamicParams.inputWidth         = width;
        dynamicParams.videncDynamicParams.targetBitRate      = 384000;
        //This paramenter will control I-Frame
        dynamicParams.videncDynamicParams.intraFrameInterval = 30;
        dynamicParams.videncDynamicParams.generateHeader     = XDM_ENCODE_AU;
        dynamicParams.videncDynamicParams.captureWidth       = 0;
        dynamicParams.videncDynamicParams.forceIFrame        = 0;

        dynamicParams.maxMBsPerSlice = 396;
        dynamicParams.videncDynamicParams.targetFrameRate = 15200;
        dynamicParams.videncDynamicParams.refFrameRate = 15200;

        /* Set video encoder dynamic parameters */
        encStatus.size = sizeof(VIDENC_Status);
        status = VIDENC_control(hEncode, XDM_SETPARAMS, (VIDENC_DynamicParams *)&dynamicParams,
                                &encStatus);

        if (status != VIDENC_EOK) {
            ERR("XDM_SETPARAMS failed, status=%ld\n", status);
            return FAILURE;
        }

        *hEncodePtr = hEncode;
        DBG_TRACE_LEAVE();
        return SUCCESS;
    }

  • Hi David,

     

    I am assuming width and height is set for dynamicParams as per 352*288 resolution.  

        printf("frame size: width = %d, height = %d\n", width, height);

        dynamicParams.videncDynamicParams.size = sizeof(IH264VENC_DynamicParams);
        dynamicParams.videncDynamicParams.inputHeight        = height;
        dynamicParams.videncDynamicParams.inputWidth         = width;

     

    Also, there is no slice support in this encoder release as such maximum macro-blocks per slice might not be relevant to this release configuration. 

        dynamicParams.maxMBsPerSlice = 396;

     

    Otherwise, the parameter configuration above looks right to me. I am checking with our codecs team in India if there is additional configuration needed. 

     

  • Hi David,

     

    The server combo package loopbackCombo.x64P should not make a difference  - it is really the linux application that should. How are you testing this? I am assuming something similar to encode only application that is present on DVSDK.

     

    Prateek

     

     

     

  • Hi David,

     

    Here is the link to generating SPS and PPS header in middle of the sequence. I have copied the FAQ item below as well. Note this is for DM6467 device and not for DM6446 device - as such it is not clear if H.264 encoder v1.10 on DM6446 would be able to support it. I will check this with our codecs team however in the meantime if you have some time would be good to quickly try if the SPS/PPS header information in the middle of the sequence is different that the beginning of the sequence and has the right codec level (1.2, 1.3) information. 

    http://wiki.davincidsp.com/index.php/DaVinciHD_Codecs_FAQ#H264_Decoder_FAQs_.28Reference_Codec_Version_--_REL_200_V_H264AVC_D_HP_DM6467_1_10_012.29

     

    • TI encoder generates SPS/PPS headers only at the beginning of the sequence. Is there a way to insert the SPS/PPS headers in the middle of the sequence?

    Yes, you could insert SPS/PPS as required by your application. In the dynamicParams, set the generateHeader field as 1 and call the control API with XDM_SETPARAMS command. Now the next process call will generate the SPS/PPS. Note that this process call will not encode a picture; it will only generate the headers. Once the headers are generated, set generateHeader field as 0, and again call the control API with XDM_SETPARAMS. Now the process calls will actually encode the frames. This sequence can be repeated whenever the application requires the encoder to generate the SPS/PPS headers.

     

    Also, other things that we discussed in addition to one above - 

    a) Changing the frame rate from 15200 to 15000 - as the codec likely does not support fractional frame rates. 

    b) Changing the maxMBsperSlice from 396 to default say 0 and see if it has any effect

    c) Transcoding network stream from DM6446 and change SPS/PPS header information to reflect v1.2 o3 v1.3 rather than v3.0 and see if this makes any difference in decoding performance on two decoders. I understand you are currently able to run 1s or 2s clips on decoder #1 (supports upto v1.3 level only) while the other decoder #2 (supports upto v1.2 level only) shows lot of blocky artifacts when running DM6446 encoded stream.

    d) Send blocky artifacts images of decoder #2 and network stream data of decoder #1 to analyze SPS/PPS header information. I can analyze this on Wireshark v1.2 analyzer.

     

    I will check with our team if SPS/PPS header information can reflect the correct level as per the codec parameter settings. 

     

  • Thanks to our codecs team - it looks like they might have found the problem, please set encodingPreset inside static params to a non zero value.

     

    params.videncParams.encodingPreset = 3 (could be used)

     

    Following are the values that can be taken.

    3 -> User defined.

    2 -> XDM_HIGH_SPEED

    1 -> XDM_HIGH_QUALITY

    0 -> XDM_DEFAULT (This sets the levelIdc = 30)

     

    Let us know if this solves the issue?

  • Our issue is not resolved yet. We have set the value of params.videncParams.encodingPreset = 3 and found that the SPS paramater changes to level 1.2 which is one step better. After making couple of video calls with PolyCom and Nortel phone we found that result is same. PolyCom displays video for 2/4 seconds and then it stops displaying anything. Nortel phone still showing big mosaic macro block.

    We found that the FPS is 14 which is less than the maximum frame rate 15(expected). But the bitrate is very high(not expected), it crosses the maximum bitrate of 384kbps.
    The encoder bitrate is around 500kbps to 800kpbs(or up). We saw the receiving bitrate on PolyCom and GrandStream video phone. They display fps, bitrate.

    So it looks like the follow parameter which we have set into the H264 encoder does not have real effect.

    params.videncParams.maxBitRate            = 384000;

    Is there any other way to control the bit rate?

  • There is rateControlPreset parameter under videncParams that can be used to control the bit rate. The different values of rateControlPreset parameter can be found on page 36 of the User Guide.

     

     

  • Finally loopbackCombo.x64P produces CIF resolution with 384Kbps bit rate by using the following parameter values.

    For IH264VENC_Params structure
    --------------------------------
    params.videncParams.rateControlPreset     = IVIDEO_LOW_DELAY
    params.videncParams.encodingPreset        = 3;
    params.videncParams.maxHeight             = 288;
    params.videncParams.maxWidth              = 352;
    params.videncParams.maxFrameRate          = 15000;
    params.videncParams.maxBitRate            = 384000;

    params.profileIdc = 66;
    params.levelIdc = IH264_LEVEL_12;


    For VIDENC_DynamicParams structure
    -----------------------------------
    dynamicParams.inputHeight        = 288;
    dynamicParams.inputWidth         = 352;
    dynamicParams.targetBitRate      = 384000;
    dynamicParams.targetFrameRate = 15000;
    dynamicParams.refFrameRate = 15000;

    Though it is not compatible with Nortel and PolyCom H264 video phone for some reason.

  • Hi David,

     

    Good to hear that you were able to at least get v1.2 stream. 

    Regarding compliance with Nortel & Polycom phones, would it be possible to get sample encoded streams that works well with those phones. Comparing those compliant encoded streams with v1.2 compliant stream that you are generating would provide us with some insight into the difference between two. One thing I do know is that H.264 v1.10 encoder does not support multiple slices - while H.264 encoder v2.00 does support multiple slices. H.264 encoder v2.00 is part of the DVSDK v2.00 on DM6446. Would it be possible for you to try  DM6446 DVSDK v2.00 demo on the EVM, generate a test stream using DM6446 EVM and feed it to Nortel  Polycom phones to see if it works? Note, the EVM demos can only store the encoded contents in elementary stream format on HDD. 

     

     Prateek

  • HI,

    I am using H.264 encoder v2.0 and I want to set it to multiple slice mode.

    Which parameter should I use to do that?