[FFmpeg-devel] v4l2: bug #1570 and possible solution
Michael Niedermayer
michaelni at gmx.at
Tue Feb 12 15:02:40 CET 2013
On Tue, Feb 12, 2013 at 12:40:21PM +0100, Giorgio Vazzana wrote:
> 2013/2/12 Michael Niedermayer <michaelni at gmx.at>:
> > If i understand the problem correctly then i would suggest to switch
> > to copying frames into normally allocated packets whenever there is
> > just 1 buffer left available
>
> This sounds like a good idea. See attached patch (tested and seems to
> work okay).
> v4l2.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++-------------------
> 1 file changed, 48 insertions(+), 19 deletions(-)
> 02634d9155fb732e79bc389383efbb59a9a40f04 0001-lavd-v4l2-copy-frames-into-normally-allocated-packet.patch
> From 3e5c057ec73c67944960edd66abf912354449331 Mon Sep 17 00:00:00 2001
> From: Giorgio Vazzana <mywing81 at gmail.com>
> Date: Tue, 12 Feb 2013 12:24:53 +0100
> Subject: [PATCH] lavd/v4l2: copy frames into normally allocated packets whenever there is just one buffer left available
>
> This will avoid the possibility that we dequeue more buffers than we
> have obtained from the v4l2 driver.
>
> Fixes ticket #1570
> ---
> libavdevice/v4l2.c | 67 +++++++++++++++++++++++++++++++++++++--------------
> 1 files changed, 48 insertions(+), 19 deletions(-)
>
> diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
> index 4c43e37..13cc47d 100644
> --- a/libavdevice/v4l2.c
> +++ b/libavdevice/v4l2.c
> @@ -111,6 +111,7 @@ struct video_data {
> int buffers;
> void **buf_start;
> unsigned int *buf_len;
> + int buffers_dequeued;
> char *standard;
> v4l2_std_id std_id;
> int channel;
> @@ -123,6 +124,8 @@ struct video_data {
> struct buff_data {
> int index;
> int fd;
> + int *buffers_dequeued;
> + int buffer_copied;
> };
>
> struct fmt_map {
> @@ -466,25 +469,37 @@ static int mmap_init(AVFormatContext *ctx)
> return 0;
> }
>
> -static void mmap_release_buffer(AVPacket *pkt)
> +static int enqueue_buffer(int fd, int index)
> {
> + int res;
> struct v4l2_buffer buf = { 0 };
> - int res, fd;
> - struct buff_data *buf_descriptor = pkt->priv;
> -
> - if (pkt->data == NULL)
> - return;
>
> - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
> + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
> buf.memory = V4L2_MEMORY_MMAP;
> - buf.index = buf_descriptor->index;
> - fd = buf_descriptor->fd;
> - av_free(buf_descriptor);
> + buf.index = index;
>
> if (v4l2_ioctl(fd, VIDIOC_QBUF, &buf) < 0) {
> res = AVERROR(errno);
> av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", av_err2str(res));
> + return res;
> }
> + return 0;
> +}
> +
> +static void mmap_release_buffer(AVPacket *pkt)
> +{
> + struct buff_data *buf_descriptor = pkt->priv;
> +
> + if (pkt->data == NULL)
> + return;
> +
> + if (buf_descriptor->buffer_copied) {
> + av_free(pkt->data);
> + } else {
> + if (!enqueue_buffer(buf_descriptor->fd, buf_descriptor->index))
> + (*buf_descriptor->buffers_dequeued)--;
the deallocation of packets could happen from different thread(s)
so i think this needs either a mutex, an atomic decrement or some
lockless algorithm to achive the same
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
The real ebay dictionary, page 3
"Rare item" - "Common item with rare defect or maybe just a lie"
"Professional" - "'Toy' made in china, not functional except as doorstop"
"Experts will know" - "The seller hopes you are not an expert"
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20130212/0dbeef3a/attachment.asc>
More information about the ffmpeg-devel
mailing list