Strides problem on the nvconverter

Hi all,

I have some problem setting the strides on the output plane in the nvVideoConverter.

I am using a nvbuffer on the output plane of the converter in YUV420M format with 720x405 resolution, if I don’t set any stride the converter automatically sets the luma stride at 720 and chromas at 360, but I need a stride in the chromas set at 368. I am setting that as follows:

memset(&v4l2_buf, 0, sizeof(v4l2_buf));
memset(planes, 0, sizeof(planes));
memset(&format, 0, sizeof(struct v4l2_format));

v4l2_buf.m.planes = planes;
v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
v4l2_buf.memory = V4L2_MEMORY_USERPTR;

if (nvidia_conv_->output_plane.dqBuffer(v4l2_buf, &buffer, NULL, 100) < 0)
{
    printf("ERROR while DQing buffer at conv0 output plane");
}

NvBuffer::NvBufferPlane &plane0 = buffer->planes[0];
NvBuffer::NvBufferPlane &plane1 = buffer->planes[1];
NvBuffer::NvBufferPlane &plane2 = buffer->planes[2];

plane0.fmt.stride=720;   
plane1.fmt.stride=368;
plane2.fmt.stride=368;

plane0.bytesused = plane0.fmt.stride * plane0.fmt.height;
plane1.bytesused = plane1.fmt.stride * plane1.fmt.height;
plane2.bytesused = plane2.fmt.stride * plane2.fmt.height;

That method doesn’t work for me. It looks like the stride is ignored. Does it require a special set format function or something alike?

Is there another way to change the chromas stride value before queuing the buffer on the converter output plane?

Hello ACervantes:

Stride is an attribute of our dmabuf, and when v4l2 component is initialized, the dmabuf is created according the color format & layout & size.
So we can’t change the stride value after dmabuf is created.

thanks
wayne zhu

Hi waynezhu,

Thanks for the information.

I was looking in the Multimedia API about how to set the stride on the initialization in the converter, but I didn’t find how do that, is there any way to do that?

I am trying to use the 07_video_converter of the tegra multimedia API samples to pass through the converter this video (link), the resolution is 720x405, the format is YUV420, the luma stride is 720 and the chromas stride is 368.

./video_convert test_720x405_video 720 405 YUV420M transformed-video-720x405-yuv420 720 405 YUV420M --input-raw --output-raw

video link:
https://drive.google.com/file/d/0Bx2fEbZl-3uUWXlGYktXR2Q5Q0U/view?usp=sharing

Also I am trying to set the strides in the NvVideoConverter.cpp as follows:

int
NvVideoConverter::setOutputPlaneFormat(uint32_t pixfmt, uint32_t width,
        uint32_t height, enum v4l2_nv_buffer_layout type)
{
    struct v4l2_format format;
    uint32_t num_bufferplanes;
    NvBuffer::NvBufferPlaneFormat planefmts[MAX_PLANES];

    if (setOutputPlaneBufferLayout(type) < 0)
    {
        return -1;
    }

    output_plane_pixfmt = pixfmt;
    NvBuffer::fill_buffer_plane_format(&num_bufferplanes, planefmts, width,
            height, pixfmt);
    output_plane.setBufferPlaneFormat(num_bufferplanes, planefmts);
    
    memset(&format, 0, sizeof(struct v4l2_format));
    format.type = output_plane.getBufType();
    format.fmt.pix_mp.width = width;
    format.fmt.pix_mp.height = height;
    format.fmt.pix_mp.pixelformat = pixfmt;
    format.fmt.pix_mp.num_planes = num_bufferplanes;
    format.fmt.pix_mp.plane_fmt[0].bytesperline=720;
    format.fmt.pix_mp.plane_fmt[1].bytesperline=368;
    format.fmt.pix_mp.plane_fmt[2].bytesperline=368;
    

    CHECK_V4L2_RETURN(output_plane.setFormat(format),
            "Setting output plane format");
}

But when the NvV4l2ElementPlane::setFormat function call the ioctl VIDIOC_S_FMT the strides was not set at the values desired, and the strides take the values for the luma=768 and the chromas=512.

Is there any way to process that video without the artifacts on the output file with the NvVideoConverter?

Thanks

Hi ACervantes:
On TX1, stride can’t be set for dmabuf in user side.
You can only set width, height, colorformat, layout, then we will calculate a stride for you.

Probably you need consider some other way to process your issue.

Hi waynezhu

Just confirming, is this a limitation in the TX2 as well? If so, are there plans to specify input strides in the near future?

Hi Michael:

Yes, till now on all tegra(TK1,Tx1/2) platform, dma_buf’s stride can’t be set by user.
I think we don’t have plan to support.

Hi waynezhu,

It is pretty common that in some cases, for hardware/performance constraints, an incoming video buffer (not necessary coming from the camera) has different stride and width values.

For example, if we have a 16-bytes alignment requirement, then a video frame of 720x405 will have a chroma plane width of 360, however, since this is not multiple of 16 the allocated memory for the frame has a stride of 368.

In some platforms, the codecs allow to properly handle those cases by specifying the width and the stride to the processing unit before it gets processed so the unit will automatically skip the padding.

If currently TX1 and TX2 do not support this setup, how do you recommend to efficiently handle an incoming buffer with different stride and width without copying the plane to a new buffer?

Regards,

Hello,
In Tx1&TX2, where is your buffer(with different stride) from?

If your buffer is from nvidia’s decode/camera, stride is fixed.

If your buffer be copied from other source, you need copy your buffer into dmabuf(in this case, copy can’t be avoided), during this copy, then you can align the stride.

Thanks
wayne zhu