select/poll is not working in block mode for camera capture

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

select/poll is not working in block mode for camera capture

Jump to solution
1,753 Views
titusstalin
Contributor V

Hello,

I've attached the v4l2 camera capture example code and am not getting any timeout when I use this example in poll/select method while using non-blocking method.

 

While opening the v4l2 device node in non-blocking mode, it should timeout if didn't receive any frames in given timeout.

But its not working as expected, but its working with UVC camera (USB webcam).

 

Application output log:

root@sabre:/#
root@sabre:/# ./poll /dev/video3 640 480 1
main
before open
after open fd : 3
get standard
set standard
query cap
capabilitioes
set format
get format
/dev/video3: 640x480 UYVY 30.00fps
request buffers
allocate buffers
buffers[n_buffers].start= 0x76dc1000     buffers[n_buffers].length=614400
buffers[n_buffers].start= 0x76d2b000     buffers[n_buffers].length=614400
buffers[n_buffers].start= 0x76c95000     buffers[n_buffers].length=614400
buffers[n_buffers].start= 0x76bff000     buffers[n_buffers].length=614400
queue buffers
start capture
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
Waiting at 'poll()'
 before process image
Processing Frame: 640x480 UYVY
[   0,   0] YUYV:0x0bfb0afc RGB:0x0313ffffffff
[ 250,   0] YUYV:0x16fd17ff RGB:0x131e10
red pixel count=0
 after process image
 before save frame
save frame
Wrote 614400 of 614400 bytes to frame1.raw
 before save frame

root@sabre:/#

 

Attached the dmesg (kernel log)

There you can see lot of DQBUF calls, but it should be.

 

Here is the log when I tried with USB webcam.

 

root@sabre:/#
root@sabre:/#
root@sabre:/# ./poll /dev/video4 640 480 1
main
before open
after open fd : 3
get standard
VIDIOC_G_STD: Inappropriate ioctl for device
set standard
VIDIOC_S_STD: Inappropriate ioctl for device
found NTSC TV decoder
found SECAM TV decoder
found PAL TV decoder
query cap
capabilitioes
VIDIOC_S_INPUT: Invalid argument
set format
get format
/dev/video4: 640x480 YUYV 5.00fps
request buffers
allocate buffers
buffers[n_buffers].start= 0x76dd1000     buffers[n_buffers].length=614400
buffers[n_buffers].start= 0x76d3b000     buffers[n_buffers].length=614400
buffers[n_buffers].start= 0x76ca5000     buffers[n_buffers].length=614400
buffers[n_buffers].start= 0x76c0f000     buffers[n_buffers].length=614400
queue buffers
start capture
Waiting at 'poll()'
Waiting at 'poll()'
 before process image
Processing Frame: 640x480 YUYV
[   0,   0] YUYV:0x7df87df8 RGB:0x71886e
[ 250,   0] YUYV:0x790e7d0f RGB:0x907295
red pixel count=0
 after process image
 before save frame
save frame
Wrote 614400 of 614400 bytes to frame1.raw
 before save frame

 

root@sabre:/#
root@sabre:/#
root@sabre:/#
root@sabre:/# dmesg
usb 1-1.1: reset high-speed USB device number 3 using ci_hdrc
UVC case VIDIOC_REQBUFS
vb2: Allocated 4 buffers, 1 plane(s) each
UVC case VIDIOC_QUERYBUF
UVC case VIDIOC_QUERYBUF
UVC case VIDIOC_QUERYBUF
UVC case VIDIOC_QUERYBUF
UVC case VIDIOC_QBUF
vb2: vb2_internal_qbuf() of buffer 0 succeeded
UVC case VIDIOC_QBUF
vb2: vb2_internal_qbuf() of buffer 1 succeeded
UVC case VIDIOC_QBUF
vb2: vb2_internal_qbuf() of buffer 2 succeeded
UVC case VIDIOC_QBUF
vb2: vb2_internal_qbuf() of buffer 3 succeeded
UVC case VIDIOC_STREAMON
UVC case VIDIOC_DQBUF
vb2: dqbuf of buffer 0, with state 0
UVC case VIDIOC_QBUF
vb2: vb2_internal_qbuf() of buffer 0 succeeded
UVC case VIDIOC_DQBUF
vb2: dqbuf of buffer 1, with state 0
UVC case VIDIOC_QBUF
vb2: vb2_internal_qbuf() of buffer 1 succeeded
UVC case VIDIOC_STREAMOFF
root@sabre:/#
root@sabre:/#

 

 

 

As you can see, kernel has limited DQBUF calls.

The same issue am getting if I try "select" method, you can check the attached code.

FYI: I'm using default kernel and OV5640 MIPI camera.

 

Can you please help me on this issue ?

Any insight/pointers pls ?

 

Thanks for your help.

 

Regards,

Titus S.

Original Attachment has been moved to: dmesg_log.txt.zip

Original Attachment has been moved to: application_camera.c.zip

Labels (5)
0 Kudos
1 Solution
1,220 Views
titusstalin
Contributor V

Hi Joan,

Thanks for your reply.

I'm afraid that you had read my question/problem or not.

Because, I'm able to receive the frames from camera with blocking and non-blocking mode but select/poll feature is not working. (also this issue comes from OV5640 default camera and pre-built kernel)

Using select/poll feature, application will call DQBUF when camera buffer is filled with frames which is not working with imx driver.

I've modified the imx driver and it worked now.

Here is the code for other customers if they face issue like this.

static unsigned int mxc_poll(struct file *file, struct poll_table_struct *wait)
{
    struct video_device *dev = video_devdata(file);
    cam_data *cam = video_get_drvdata(dev);
    wait_queue_head_t *queue = NULL;
    struct mxc_v4l_frame *done_frame;
    int res = 0;

    pr_debug("%s:%d\n", __func__,__LINE__);


    if (down_interruptible(&cam->busy_lock))
        return -EINTR;

    queue = &cam->enc_queue;
    poll_wait(file, queue, wait);


//Titus :  Needed for 'select' and 'poll'
    if (!list_empty(&cam->done_q))
        done_frame = list_entry(&cam->done_q, struct mxc_v4l_frame, queue);
    else {
        LNT_TRACE("DONE QUEUE is empty\n");
        up(&cam->busy_lock);
        return res;
    }

//    if (done_frame && (done_frame->buffer.flags & V4L2_BUF_FLAG_DONE))
    if (cam->enc_counter > 0) {
        up(&cam->busy_lock);
        LNT_TRACE("Ready for DQUEUE\n");
        return POLLIN | POLLRDNORM;
    }

    up(&cam->busy_lock);
    return res;
}

View solution in original post

0 Kudos
2 Replies
1,220 Views
joanxie
NXP TechSupport
NXP TechSupport

for how to debug the mipi camera, pls refer to the enclosed file.

0 Kudos
1,221 Views
titusstalin
Contributor V

Hi Joan,

Thanks for your reply.

I'm afraid that you had read my question/problem or not.

Because, I'm able to receive the frames from camera with blocking and non-blocking mode but select/poll feature is not working. (also this issue comes from OV5640 default camera and pre-built kernel)

Using select/poll feature, application will call DQBUF when camera buffer is filled with frames which is not working with imx driver.

I've modified the imx driver and it worked now.

Here is the code for other customers if they face issue like this.

static unsigned int mxc_poll(struct file *file, struct poll_table_struct *wait)
{
    struct video_device *dev = video_devdata(file);
    cam_data *cam = video_get_drvdata(dev);
    wait_queue_head_t *queue = NULL;
    struct mxc_v4l_frame *done_frame;
    int res = 0;

    pr_debug("%s:%d\n", __func__,__LINE__);


    if (down_interruptible(&cam->busy_lock))
        return -EINTR;

    queue = &cam->enc_queue;
    poll_wait(file, queue, wait);


//Titus :  Needed for 'select' and 'poll'
    if (!list_empty(&cam->done_q))
        done_frame = list_entry(&cam->done_q, struct mxc_v4l_frame, queue);
    else {
        LNT_TRACE("DONE QUEUE is empty\n");
        up(&cam->busy_lock);
        return res;
    }

//    if (done_frame && (done_frame->buffer.flags & V4L2_BUF_FLAG_DONE))
    if (cam->enc_counter > 0) {
        up(&cam->busy_lock);
        LNT_TRACE("Ready for DQUEUE\n");
        return POLLIN | POLLRDNORM;
    }

    up(&cam->busy_lock);
    return res;
}

0 Kudos