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 HP encoder for C6678 with padded YUV buffers

Hello,

H.264 HP decoder generates YUV buffers that are padded to be of size multiple of 16. For example:

IVIDEO1_BufDesc.frameWidth = 854; // Non-multiple of 16

IVIDEO1_BufDesc.frameHeight = 480;

IVIDEO1_BufDesc.framePitch = 864; // Width with padding to be multiple of 16

I am trying to use this padded YUV buffers as input for H.264 HP encoder but with no luck - generated image is not correct. I did the following:

IVIDENC2_DynamicParams.captureWidth = 864;

IVIDENC2_DynamicParams.inputWidth = 854;

IVIDENC2_DynamicParams.inputHeight = 480;

IVIDEO2_BufDesc.planeDesc[N].buf = IVIDEO1_BufDesc.bufDesc[N].buf;

IVIDEO2_BufDesc.planeDesc[N].bufSize.bytes = IVIDEO1_BufDesc.bufDesc[N].bufSize;

IVIDEO2_BufDesc.inEncoderBufferDescriptor.imagePitch[N] = IVIDEO1_BufDesc.framePitch;

IVIDENC2_DynamicParams - encoder dynamic parameters.

IVIDEO1_BufDesc - output buffer descriptor from decoder.

IVIDEO2_BufDesc - input buffer descriptor to encoder.

When width is multiple of 16 generated image is correct.

Can you advise how to pass padded YUV buffers from H.264 HP decoder to encoder?

Regards,

Andrey Lisnevich

  • Actually I do not understand decoder behaviour:

    Input is 854x480

    IVIDDEC2_DynamicParams.maxWidth = 864;

    IVIDDEC2_DynamicParams.maxHeight = 480;

    IVIDDEC2_DynamicParams.displayWidth = 0; // I.e. pitch = input width

    Decoder requests:

    minInBufSize[0] 622080
    minOutBufSize[0] 506240
    minOutBufSize[1] 126560
    minOutBufSize[2] 126560


    Buffers are bigger than result YUV, but it is Ok

    But as output I get:

    displayBuffer->framePitch = 864; // Why if IVIDDEC2_DynamicParams.displayWidth = 0 ?
    displayBuffer->frameWidth = 854; // Ok

    displayBuffer->frameHeight = 480; // Ok
    displayBuffer->bufDesc[0].bufSize =409920; // 854*480 = 409920. Means that Y component size is not based on pitch (i.e. lines not padded)
    displayBuffer->bufDesc[1].bufSize =102480; // The same
    displayBuffer->bufDesc[2].bufSize =102480 // The same

    So I am confused and do not understand is output from decoder is based on pitch or input width?

    But in both cases I can't get correct image when encoding this YUV data with H.264 HP encoder (with multiple of 16 resolutions result image is correct).

  • Hi Andrey,

    If input width is non-multiple of 16, encoder will pad it appropriately to the next multiple of 16 internally and encodes it.

    Encoder doesnot use the field captureWidth.

    Here padded input is given to encoder with inputWidth = 854. So encoder will take this width as reference and will pad the rest to get the next multiple of 16 internally. Then the next bits in input, it will treat as next row.

    Since you are using already padded yuv, that width you can specify as inputWidth ie 864.

    Thanks and regards

    Sudheesh

  • Hi Sudheesh,


    I did additional investigation and have few questions.

    1) First is regarding MPEG-2 decoder (latest for C6678). When I use as input 854x480 stream it produces the following result:

    IVIDDEC2_Status.outputWidth and IVIDDEC2_Status.outputHeight is 864x480 // Not correct should be 854x480

    IVIDEO1_BufDesc.bufDesc[0].bufSize = 414720; // Buffer size is for 864x480 resolution, i.e. pitch is 864
    IVIDEO1_BufDesc.bufDesc[1].bufSize = 103680;
    IVIDEO1_BufDescbufDesc[2].bufSize = 103680;
    IVIDEO1_BufDesc.frameWidth and IVIDEO1_BufDesc.frameHeight is again 864x480 // Not correct should be 854x480

    IVIDEO1_BufDesc.framePitch =  864;

    Generated YUV in this case is incorrect if I treat it 864x480. Only few frames are correct. See mpeg2 directory in attached archive.

    As I see MPEG-2 encoder does not report correct width (854) at all. According to documentation it should report 854 in IVIDEO1_BufDesc.frameWidth and IVIDDEC2_Status.outputWidth. Why is it so? Can you please check and correct me if I am mistaken.

    2) Second is regarding H.264 HP decoder (latest for C6678). When I use as input 854x480 stream the same code produces the following result::

    IVIDDEC2_Status.outputWidth and IVIDDEC2_Status.outputHeight is 854x480 // Correct

    IVIDEO1_BufDesc.bufDesc[0].bufSize = 409920; // Buffer size is incorrect because it should be 414720 for pitch = 864.
    IVIDEO1_BufDesc.bufDesc[1].bufSize = 102480; // Incorrect
    IVIDEO1_BufDescbufDesc[2].bufSize = 102480; // Incorrect
    IVIDEO1_BufDesc.frameWidth and IVIDEO1_BufDesc.frameHeight is again 854x480 // Correct

    IVIDEO1_BufDesc.framePitch =  864; // Pitch is not in correspondance with bufSize variables

    Generated YUV in this case is correct if I treat it as 864x480 (i.e. save more data then specified in bufSize variables). See h264hp directory.

    Can you please explain this behaviour?

    Regards,

    Andrey Lisnevich

    results.zip
  • One more question: does H.264 HP encoder respects YUV with pitch != width? Is there any way to input YUV 854x480 with pitch 864 and get encoded frames of size 854x480?

  • Hi Andrey,

    H264HP encoder does not honor pitch != width. Application has to make sure no padding is present between rows. Codec internally pads and encodes.

    We are not sure about the decoder behavior.

    Best regards

    Rama

     

  • Thanks Rama,

    I got the point regarding encoder. It will be good if someone can explain MPEG2/H.264 decoder behaviour also. Numbers in result structures of the decoders looks incorrect.

    Regards,

    Andrey Lisnevich

  • Hi Andrey,

    H264 HP Decoder returns actual size of the frame decoded, not the padded frame i.e IVIDEO1_BufDesc.bufDesc[0].bufSize = 409920; is the number of bytes you have to read from the output buffer to extract the frame.

    If width=pitch, you can directly use the output buffer to the next stage.

    If witdh!=pitch, you need to extract the frame from the output buffer.

    Refer to function TestApp_WriteOutputData() between lines 1917-1963 in TestAppDecoder.c to see how this is done.

    Thanks,

    Praveen

  • Hi Praveen,

    I got your point. I still believe bufSize should be buffer size as in documentation:

    typedef struct XDM1_SingleBufDesc {
        XDAS_Int8   *buf;       /**< Pointer to a buffer address. */
        XDAS_Int32  bufSize;    /**< Size of @c buf in 8-bit bytes. */

    Treating bufSize as "the number of bytes you have to read from the output buffer to extract the frame" is not obvious and not documented.

    Regards,

    Andrey Lisnevich