From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Paulo Assis <pj.assis@gmail.com>
Cc: Linux Media Mailing List <linux-media@vger.kernel.org>
Subject: Re: uvcvideo fails on 3.16 and 3.17 kernels
Date: Wed, 01 Oct 2014 14:05:22 +0300 [thread overview]
Message-ID: <1782581.QHYlHgcnOV@avalon> (raw)
In-Reply-To: <CAPueXH5vbm_cSwA_EYyYJRiH3XFKuae9HAG1xGTNha5nB+q0uA@mail.gmail.com>
Hi Paulo,
On Wednesday 01 October 2014 11:48:26 Paulo Assis wrote:
> Laurent hi,
>
> 2014-09-30 23:31 GMT+01:00 Laurent Pinchart:
> > Hi Paulo,
> >
> > Thank you for investigation this.
> >
> > On Tuesday 30 September 2014 13:56:15 Paulo Assis wrote:
> >
> >> Ok,
> >> so I've set a workaround in guvcview, it now uses the length filed if
> >> bytesused is set to zero.
> >> Anyway I think this violates the v4l2 api:
> >> http://linuxtv.org/downloads/v4l-dvb-apis/buffer.html
> >>
> >> bytesused - ..., Drivers must set this field when type refers to an
> >> input stream, ...
> >>
> >> without this value we have no way of knowing the exact frame size for
> >> compressed formats.
> >>
> >> And this was working in uvcvideo up until 3.16, I don't know how many
> >> userspace apps rely on this value, but at least guvcview does, and
> >> it's currently broken for uvcvideo devices in the latest kernels.
> >
> > It took me some time to debug the problem, and I think the problem is
> > actually on guvcview's side. When dequeuing a video buffer, the
> > application requeues it immediately before processing the buffer's
> > contents. The VIDIOC_QBUF ioctl will reset the bytesused field to 0.
> >
> > While you could work around the problem by using a different struct
> > v4l2_buffer instance for the VIDIOC_QBUF call, the V4L2 doesn't allow
> > userspace application to access a queued buffer. You must process the
> > buffer before requeuing it.
>
> I though this was why we requested multiple buffers. If this is true
> then using just one buffer is enough, also using multiple threads to
> process frame data seems useless in this case, since we need to
> process the buffer before queueing the next one.
>
> I thought one could request 4 buffers for mmap and do:
>
> VIDIOC_DQBUF data->buf[0]
> VIDIOC_QBUF driver queues->buf[1]
>
> process buf[0]
>
> VIDIOC_DQBUF data->buf[1]
> VIDIOC_QBUF driver queues->buf[2]
>
> process buf[1]
>
> VIDIOC_DQBUF data->buf[2]
> VIDIOC_QBUF driver queues->buf[3]
>
> process buf[2]
>
> VIDIOC_DQBUF data->buf[3]
> VIDIOC_QBUF driver queues->buf[0]
>
> process buf[3]
That's certainly valid. However, if I'm not mistaken, after dequeuing buffer i
you immediately requeue the same buffer, not buffer i+1.
What you should do is queueing all buffers right before starting the stream (I
think you're doing fine there, but I haven't double-checked), and then, when a
buffer is available, perform the following sequence.
VIDIOC_DQBUF() -> returns buffer i
process buffer i
VIDIOC_QBUF(buffer i)
You can perform processing in a different thread if needed, the important part
being not to requeue the buffer before userspace is done with it.
The bug that caused guvcview to stop functioning is in v4l2_core.c.
memset(&vd->buf, 0, sizeof(struct v4l2_buffer));
vd->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
vd->buf.memory = V4L2_MEMORY_MMAP;
ret = xioctl(vd->fd, VIDIOC_DQBUF, &vd->buf);
if(!ret)
{
/*
* driver timestamp is unreliable
* use monotonic system time
*/
vd->timestamp = ns_time_monotonic();
/* queue the buffers */
ret = xioctl(vd->fd, VIDIOC_QBUF, &vd->buf);
...
}
The VIDIOC_DQBUF call will return the correct bytesused value in vd-
>buf.bytesused, but the VIDIOC_QBUF call then resets that value to 0.
As a quick workaround while you fix the buffer processing sequence, you can
copy vd->buf into a new local v4l2_buffer variable after calling VIDIOC_DQBUF,
and use that local variable in the VIDIOC_QBUF call. Note that you will still
violate the V4L2 API as you're not allowed to touch a buffer after requeuing
it, but it should hide the problem and get guvcview to display images again.
> Now if we need to process the buffer between VIDIOC_DQBUF and
> VIDIOC_QBUF, whats the point in using more than one buffer ?
--
Regards,
Laurent Pinchart
next prev parent reply other threads:[~2014-10-01 11:05 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-30 8:50 uvcvideo fails on 3.16 and 3.17 kernels Paulo Assis
2014-09-30 12:56 ` Paulo Assis
2014-09-30 22:31 ` Laurent Pinchart
2014-10-01 10:48 ` Paulo Assis
2014-10-01 11:05 ` Laurent Pinchart [this message]
2014-10-01 11:53 ` Paulo Assis
2014-10-01 12:07 ` Hans Verkuil
2014-09-30 13:12 ` Nicolas Dufresne
2014-09-30 13:29 ` Paulo Assis
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1782581.QHYlHgcnOV@avalon \
--to=laurent.pinchart@ideasonboard.com \
--cc=linux-media@vger.kernel.org \
--cc=pj.assis@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.