AnsweredAssumed Answered

IPU: set input/output buffer

Question asked by Kirill Brilliantov on Nov 7, 2013

Hello!

I try use imx-lib, not GStreamer, for capture and encode video. Because my matrix have output data in YUV422 format I have to use IPU for prepare data for codec, convert YUV422 to YUV420.

 

Capture code:

typedef struct {

    __u32 offset;

    __u32 length;

    void *data;

} cap_buffer;

cap_buffer video_buffer[BUFFER_NUM];

for (i = 0; i < BUFFER_NUM; i++) {

        memset(&buf, 0, sizeof(buf));

        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

        buf.index = i;

 

        if (ioctl(fd, VIDIOC_QUERYBUF, &buf)) {

            daemon_error("Failed VIDIOC_QUERYBUF, errno %d (%s)",

                        errno, strerror(errno));

            return -1;

        }

 

        video_buffer[i].length = buf.length;

        video_buffer[i].offset = buf.m.offset;

        video_buffer[i].data = mmap(NULL, buf.length,

                                PROT_READ | PROT_WRITE, MAP_PRIVATE, fd,

                                (off_t)buf.m.offset);

        if (NULL == video_buffer[i].data) {

            daemon_error("Mmap failed, errno %d (%s)", errno, strerror(errno));

            return -1;

        }

    }

 

for (i = 0; i < BUFFER_NUM; i++) {

        memset(&buf, 0, sizeof(buf));

        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

        buf.memory = V4L2_MEMORY_MMAP;

        buf.index = i;

        buf.m.offset = video_buffer[i].offset;

 

        if (ioctl(fd, VIDIOC_QBUF, &buf)) {

            daemon_error("Failed VIDIOC_QBUF, errno %d (%s)",

                        errno, strerror(errno));

            return -1;

        }

    }

 

IPU configuration:

ipu_lib_input_param_t input;

ipu_lib_output_param_t output;

input.width = width;

input.height = height;

input.fmt = IPU_PIX_FMT_YUYV;

output.width = width;

output.height = height;

output.fmt = IPU_PIX_FMT_YVU420P;

mxc_ipu_lib_task_init(&input, NULL, &output, OP_NORMAL_MODE, ipu_handle);

 

And use it:

unsigned char out_ipu[1280 * 720 * 3 / 2] = {0};

while (1) {

struct v4l2_buffer v4l2_buf;

 

v4l2_get(&v4l2_buf);

cap_buffer *data = v4l2_data(v4l2_buf.index); //get pointer on v4l2 data

 

ipu_handle.inbuf_start[0] = data->data;

ipu_handle.outbuf_start[0] = out_ipu;

mxc_ipu_lib_task_buf_update(&ipu_handle, 0, 0, 0, NULL, NULL);

............

}

 

All work without error, but unfortunally output buffer unchanged, I write it to file.

I try use memcpy for fill ipu_handle.inbuf_start[0] and ipu_handle.outbuf_start[0], but this not solve problem.

 

How should I configure inbuf_start and outbuf_start?

Thank you and excuse my bad english.

 

Update:

Problem solved, I set V4L2 buffer offset as input buffer user_def_paddr[0]

Outcomes