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 encoder - Motion Vector Access

Other Parts Discussed in Thread: OMAP3530

Hi,

I'm trying to take advantage of the Motion Vector Access API in the H.264 Encoder for the OMAP35. It is supposed to supply an array containing the motion vectors that the encoder found while encoding the frame. However, it simply doesn't work.

The codec I'm using is named H.264 Baseline Profile Encoder, Build ID 2.01.013, and is located within the DVSDK at the path:
dvsdk_3_00_02_44/cs1omap3530_1_00_01/packages/ti/sdo/codecs/h264enc .

The Motion Vector Access API is detailed thoroughly in Appendix A of the included User Guide. However, when trying to activate it, none of the expected outcomes described there actually occur. That is, when setting dynParams.mvDataEnable = 1, the number of requested output buffers (from the codec) is supposed to change from 1 to 2 but it does not. Even if ignoring that problem and giving the encoder two buffers, the encoder process call does not fill the second buffer with vector data.

I have tried upgrading to the latest version of the codec from the TI website, 2.02.00. With that version the number of buffers still does not change correctly, but if I ignore that, and give the encoder two buffers anyway, then I do get some numbers - but they don't look correct. For example, the first 10 vectors received appear as follows:

(0,-2)(0,0)(1429,0)(5,3)(0,0)(4603,0)(5,3)(0,66)(8556,0)(4,2)

Note the large numbers every 3 pairs.

Also for some unknown reason this new codec (which is for the DM6446 and is supposed to work with the OMAP3530) runs extremely slowly, at about half realtime speed (approx 80 msec per PAL D1 frame as opposed to ~40 with the current version). I only replaced the codec directory with the new one, the files determining memory layout etc. were not changed.

Thanks for any help,

-itay

  • Itay,

    Are you using extended class for dynamic parameters as mvDataEnable is an extended parameter?

    If base class for dynamic parameters is used, then mvDataEnable will not be activated and by default codec will work as base class dynamic parameters input.

    Please check and confirm that you are using extended class for dynamic parameters.

    Regards,

    Jaydeep

  • Jaydeep,

    Yes, I am using the IH264VENC_DynamicParams structure and setting the size parameter accordingly. I am filling all the additional dynamic parameters according to the defaults present in the structure H264VENC_TI_DYNAMICPARAMS, with the exception of mvDataEnable which I am setting to 1.

    Thanks,

    -itay

  • Itay,

    Please share input yuv stream used for H.264 encoder along with configuration settings. I will check on stand-alone codec to verify this issue.

    Regards,

    Jaydeep

  • Jaydeep,

    There is no need (at this point) to share the input yuv stream, as the first thing I expect when setting mvDataEnable to 1 is that the number of output buffers will change to 2 (one for the bitstream, one for the motion vectors). This is according to the user manual, page A-3. However the value remains at 1, i.e. the codec doesn't even declare that it will be outputting motion vectors. The following code demonstrates this (the final assertion fails on my system).

    Thanks,

    -itay

    --
    // this struct manually copied from DSP side lib.
    IH264VENC_DynamicParams H264VENC_TI_DYNAMICPARAMS =
    {
        { sizeof(IH264VENC_DynamicParams), 480, 720, 30000, 30000, 4000000,
                0,0,0,-1,0,0 },
        24,24,51,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,
        NULL, NULL, 0,
        { 0,0,0,0,0,0,0,0 },
        0,0,0,0,0,
        { 0,0,0,0,0,0,0,0 }
    };

    IH264VENC_Params h264_videncParams;
    IH264VENC_DynamicParams h264_dynParams = H264VENC_TI_DYNAMICPARAMS;

    h264_videncParams.videncParams.size = sizeof(IH264VENC_Params);
    h264_videncParams.videncParams.encodingPreset = XDM_DEFAULT;
    h264_videncParams.videncParams.rateControlPreset = IVIDEO_LOW_DELAY;
    h264_videncParams.videncParams.maxHeight = 576;
    h264_videncParams.videncParams.maxWidth = 720;
    h264_videncParams.videncParams.maxFrameRate = 30000;
    h264_videncParams.videncParams.maxBitRate = MAX_BITRATE;
    h264_videncParams.videncParams.dataEndianness = XDM_BYTE;
    h264_videncParams.videncParams.maxInterFrameInterval = 1;
    h264_videncParams.videncParams.inputContentType = IVIDEO_PROGRESSIVE;
    h264_videncParams.videncParams.inputChromaFormat = XDM_YUV_422ILE;
    h264_videncParams.videncParams.reconChromaFormat = XDM_CHROMA_NA;
    h264_videncParams.profileIdc = 66;
    h264_videncParams.levelIdc = IH264_LEVEL_30;
    h264_videncParams.rcAlgo = 0;
    h264_videncParams.searchRange = 64;

    VIDENC1_Handle hVidenc = VIDENC1_create(hEngine, "h264enc", (IVIDENC1_Params*)&h264_videncParams);

    h264_dynParams.videncDynamicParams.size = sizeof(IH264VENC_DynamicParams);
    h264_dynParams.videncDynamicParams.inputWidth = 720; // Image width in Pels
    h264_dynParams.videncDynamicParams.inputHeight = 576; // Image height in Pels
    h264_dynParams.videncDynamicParams.targetFrameRate = 25000; // Frame Rate per second*1000
    h264_dynParams.videncDynamicParams.targetBitRate = 4000000; // Bitrate(bps)
    h264_dynParams.videncDynamicParams.intraFrameInterval = 30; // Period of I-Frames
    h264_dynParams.videncDynamicParams.generateHeader = XDM_ENCODE_AU;
    h264_dynParams.videncDynamicParams.captureWidth = 0;
    h264_dynParams.videncDynamicParams.forceFrame = -1;
    h264_dynParams.videncDynamicParams.mbDataFlag = 0;
    h264_dynParams.videncDynamicParams.interFrameInterval = 1;
    h264_dynParams.videncDynamicParams.refFrameRate = h264_dynParams.videncDynamicParams.targetFrameRate;
    h264_dynParams.mvDataEnable = 1;

    IH264VENC_Status h264_status;
    h264_status.videncStatus.size = sizeof(IH264VENC_Status);
    h264_status.videncStatus.data.buf = NULL;

    // set dynamic params
    r = VIDENC1_control(hVidenc, XDM_SETPARAMS, (VIDENC1_DynamicParams*)&h264_dynParams, (VIDENC1_Status*)&h264_status);
    if (r != VIDENC1_EOK)
        exit(0);

    // Get buffer requirements
    r = VIDENC1_control(hVidenc, XDM_GETBUFINFO, (VIDENC1_DynamicParams*)&h264_dynParams, (VIDENC1_Status*)&h264_status);
    if (r != VIDENC1_EOK)
        exit(0);

    assert(h264_status.videncStatus.bufInfo.minNumInBufs == 1); // passes
    assert(h264_status.videncStatus.bufInfo.minNumOutBufs == 2); // fails! == 1 when should be 2!

  • Itay,

    Please use encoder preset setting as follows,

    h264_videncParams.videncParams.encodingPreset = XDM_USER_DEFINED;

    and then enable mvDataEnable flag.

    Regards,

    Jaydeep

  • Thanks, it works now. I've now noticed that this requirement actually is mentioned in the manual, but is located where it could easily be overlooked.

    A second issue is that in order to get the vectors an additional status call (VIDENC1_control with the command IH264VENC_GETSTATUS) must be performed after the frame encode call. This is not mentioned in the manual but I found it in the manual for the newer codec version.

    Thanks for your help,

    -itay