[FFmpeg-cvslog] Merge commit '3a165c187da7d74f46f6c1778294e8c5a3a7151f'
Clément Bœsch
git at videolan.org
Wed Mar 22 18:55:52 EET 2017
ffmpeg | branch: master | Clément Bœsch <u at pkh.me> | Wed Mar 22 17:55:18 2017 +0100| [b7336faa39b8ea26d01817cb6a7bf26a795d0580] | committer: Clément Bœsch
Merge commit '3a165c187da7d74f46f6c1778294e8c5a3a7151f'
* commit '3a165c187da7d74f46f6c1778294e8c5a3a7151f':
v4l2: convert to stdatomic
Merged-by: Clément Bœsch <u at pkh.me>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=b7336faa39b8ea26d01817cb6a7bf26a795d0580
---
libavdevice/v4l2-common.h | 1 -
libavdevice/v4l2.c | 16 +++++++++-------
2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/libavdevice/v4l2-common.h b/libavdevice/v4l2-common.h
index 40c7164..0cbaec8 100644
--- a/libavdevice/v4l2-common.h
+++ b/libavdevice/v4l2-common.h
@@ -35,7 +35,6 @@
#endif
#include <linux/videodev2.h>
#endif
-#include "libavutil/atomic.h"
#include "libavutil/avassert.h"
#include "libavutil/imgutils.h"
#include "libavutil/log.h"
diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
index dada8ce..1562975 100644
--- a/libavdevice/v4l2.c
+++ b/libavdevice/v4l2.c
@@ -30,6 +30,8 @@
* V4L2_PIX_FMT_* and AV_PIX_FMT_*
*/
+#include <stdatomic.h>
+
#include "v4l2-common.h"
#include <dirent.h>
@@ -78,7 +80,7 @@ struct video_data {
int64_t last_time_m;
int buffers;
- volatile int buffers_queued;
+ atomic_int buffers_queued;
void **buf_start;
unsigned int *buf_len;
char *standard;
@@ -402,7 +404,7 @@ static int enqueue_buffer(struct video_data *s, struct v4l2_buffer *buf)
res = AVERROR(errno);
av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", av_err2str(res));
} else {
- avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);
+ atomic_fetch_add(&s->buffers_queued, 1);
}
return res;
@@ -510,9 +512,9 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
av_log(ctx, AV_LOG_ERROR, "Invalid buffer index received.\n");
return AVERROR(EINVAL);
}
- avpriv_atomic_int_add_and_fetch(&s->buffers_queued, -1);
+ atomic_fetch_add(&s->buffers_queued, -1);
// always keep at least one buffer queued
- av_assert0(avpriv_atomic_int_get(&s->buffers_queued) >= 1);
+ av_assert0(atomic_load(&s->buffers_queued) >= 1);
#ifdef V4L2_BUF_FLAG_ERROR
if (buf.flags & V4L2_BUF_FLAG_ERROR) {
@@ -538,7 +540,7 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
}
/* Image is at s->buff_start[buf.index] */
- if (avpriv_atomic_int_get(&s->buffers_queued) == FFMAX(s->buffers / 8, 1)) {
+ if (atomic_load(&s->buffers_queued) == FFMAX(s->buffers / 8, 1)) {
/* when we start getting low on queued buffers, fall back on copying data */
res = av_new_packet(pkt, buf.bytesused);
if (res < 0) {
@@ -607,7 +609,7 @@ static int mmap_start(AVFormatContext *ctx)
return res;
}
}
- s->buffers_queued = s->buffers;
+ atomic_store(&s->buffers_queued, s->buffers);
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (v4l2_ioctl(s->fd, VIDIOC_STREAMON, &type) < 0) {
@@ -1000,7 +1002,7 @@ static int v4l2_read_close(AVFormatContext *ctx)
{
struct video_data *s = ctx->priv_data;
- if (avpriv_atomic_int_get(&s->buffers_queued) != s->buffers)
+ if (atomic_load(&s->buffers_queued) != s->buffers)
av_log(ctx, AV_LOG_WARNING, "Some buffers are still owned by the caller on "
"close.\n");
======================================================================
diff --cc libavdevice/v4l2-common.h
index 40c7164,0000000..0cbaec8
mode 100644,000000..100644
--- a/libavdevice/v4l2-common.h
+++ b/libavdevice/v4l2-common.h
@@@ -1,62 -1,0 +1,61 @@@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVDEVICE_V4L2_COMMON_H
+#define AVDEVICE_V4L2_COMMON_H
+
+#undef __STRICT_ANSI__ //workaround due to broken kernel headers
+#include "config.h"
+#include "libavformat/internal.h"
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#if HAVE_SYS_VIDEOIO_H
+#include <sys/videoio.h>
+#else
+#if HAVE_ASM_TYPES_H
+#include <asm/types.h>
+#endif
+#include <linux/videodev2.h>
+#endif
- #include "libavutil/atomic.h"
+#include "libavutil/avassert.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+#include "avdevice.h"
+#include "timefilter.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/time.h"
+#include "libavutil/avstring.h"
+
+struct fmt_map {
+ enum AVPixelFormat ff_fmt;
+ enum AVCodecID codec_id;
+ uint32_t v4l2_fmt;
+};
+
+extern const struct fmt_map ff_fmt_conversion_table[];
+
+uint32_t ff_fmt_ff2v4l(enum AVPixelFormat pix_fmt, enum AVCodecID codec_id);
+enum AVPixelFormat ff_fmt_v4l2ff(uint32_t v4l2_fmt, enum AVCodecID codec_id);
+enum AVCodecID ff_fmt_v4l2codec(uint32_t v4l2_fmt);
+
+#endif /* AVDEVICE_V4L2_COMMON_H */
diff --cc libavdevice/v4l2.c
index dada8ce,0479121..1562975
--- a/libavdevice/v4l2.c
+++ b/libavdevice/v4l2.c
@@@ -19,23 -27,31 +19,25 @@@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#undef __STRICT_ANSI__ //workaround due to broken kernel headers
-#include "config.h"
-#include "libavformat/avformat.h"
-#include "libavformat/internal.h"
-#include <unistd.h>
-#include <fcntl.h>
+/**
+ * @file
+ * Video4Linux2 grab interface
+ *
+ * Part of this file is based on the V4L2 video capture example
+ * (http://linuxtv.org/downloads/v4l-dvb-apis/capture-example.html)
+ *
+ * Thanks to Michael Niedermayer for providing the mapping between
+ * V4L2_PIX_FMT_* and AV_PIX_FMT_*
+ */
+
+ #include <stdatomic.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/time.h>
-#include <poll.h>
-#if HAVE_SYS_VIDEOIO_H
-#include <sys/videoio.h>
-#else
-#include <linux/videodev2.h>
++
+#include "v4l2-common.h"
+#include <dirent.h>
+
+#if CONFIG_LIBV4L2
+#include <libv4l2.h>
#endif
-#include "libavutil/avassert.h"
-#include "libavutil/imgutils.h"
-#include "libavutil/internal.h"
-#include "libavutil/log.h"
-#include "libavutil/opt.h"
-#include "libavutil/parseutils.h"
-#include "libavutil/pixdesc.h"
-#include "libavutil/avstring.h"
-#include "libavutil/mathematics.h"
static const int desired_video_buffers = 256;
@@@ -68,17 -62,15 +70,17 @@@
struct video_data {
AVClass *class;
int fd;
- int frame_format; /* V4L2_PIX_FMT_* */
+ int pixelformat; /* V4L2_PIX_FMT_* */
int width, height;
int frame_size;
- int timeout;
int interlaced;
int top_field_first;
+ int ts_mode;
+ TimeFilter *timefilter;
+ int64_t last_time_m;
int buffers;
- volatile int buffers_queued;
+ atomic_int buffers_queued;
void **buf_start;
unsigned int *buf_len;
char *standard;
@@@ -394,20 -421,6 +396,20 @@@ static int mmap_init(AVFormatContext *c
return 0;
}
+static int enqueue_buffer(struct video_data *s, struct v4l2_buffer *buf)
+{
+ int res = 0;
+
+ if (v4l2_ioctl(s->fd, VIDIOC_QBUF, buf) < 0) {
+ res = AVERROR(errno);
+ av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", av_err2str(res));
+ } else {
- avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);
++ atomic_fetch_add(&s->buffers_queued, 1);
+ }
+
+ return res;
+}
+
static void mmap_release_buffer(void *opaque, uint8_t *data)
{
struct v4l2_buffer buf = { 0 };
@@@ -510,31 -482,16 +512,31 @@@ static int mmap_read_frame(AVFormatCont
av_log(ctx, AV_LOG_ERROR, "Invalid buffer index received.\n");
return AVERROR(EINVAL);
}
- avpriv_atomic_int_add_and_fetch(&s->buffers_queued, -1);
+ atomic_fetch_add(&s->buffers_queued, -1);
// always keep at least one buffer queued
- av_assert0(avpriv_atomic_int_get(&s->buffers_queued) >= 1);
+ av_assert0(atomic_load(&s->buffers_queued) >= 1);
- if (s->frame_size > 0 && buf.bytesused != s->frame_size) {
- av_log(ctx, AV_LOG_ERROR,
- "The v4l2 frame is %d bytes, but %d bytes are expected\n",
- buf.bytesused, s->frame_size);
+#ifdef V4L2_BUF_FLAG_ERROR
+ if (buf.flags & V4L2_BUF_FLAG_ERROR) {
+ av_log(ctx, AV_LOG_WARNING,
+ "Dequeued v4l2 buffer contains corrupted data (%d bytes).\n",
+ buf.bytesused);
+ buf.bytesused = 0;
+ } else
+#endif
+ {
+ /* CPIA is a compressed format and we don't know the exact number of bytes
+ * used by a frame, so set it here as the driver announces it. */
+ if (ctx->video_codec_id == AV_CODEC_ID_CPIA)
+ s->frame_size = buf.bytesused;
- return AVERROR_INVALIDDATA;
+ if (s->frame_size > 0 && buf.bytesused != s->frame_size) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Dequeued v4l2 buffer contains %d bytes, but %d were expected. Flags: 0x%08X.\n",
+ buf.bytesused, s->frame_size, buf.flags);
+ enqueue_buffer(s, &buf);
+ return AVERROR_INVALIDDATA;
+ }
}
/* Image is at s->buff_start[buf.index] */
@@@ -600,21 -558,27 +602,21 @@@ static int mmap_start(AVFormatContext *
.memory = V4L2_MEMORY_MMAP
};
- res = ioctl(s->fd, VIDIOC_QBUF, &buf);
- if (res < 0) {
- err = AVERROR(errno);
- av_strerror(err, errbuf, sizeof(errbuf));
+ if (v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf) < 0) {
+ res = AVERROR(errno);
av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
- errbuf);
-
- return err;
+ av_err2str(res));
+ return res;
}
}
- s->buffers_queued = s->buffers;
+ atomic_store(&s->buffers_queued, s->buffers);
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- res = ioctl(s->fd, VIDIOC_STREAMON, &type);
- if (res < 0) {
- err = AVERROR(errno);
- av_strerror(err, errbuf, sizeof(errbuf));
+ if (v4l2_ioctl(s->fd, VIDIOC_STREAMON, &type) < 0) {
+ res = AVERROR(errno);
av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n",
- errbuf);
-
- return err;
+ av_err2str(res));
+ return res;
}
return 0;
@@@ -996,12 -877,12 +998,12 @@@ FF_ENABLE_DEPRECATION_WARNING
return pkt->size;
}
-static int v4l2_read_close(AVFormatContext *s1)
+static int v4l2_read_close(AVFormatContext *ctx)
{
- struct video_data *s = s1->priv_data;
+ struct video_data *s = ctx->priv_data;
- if (avpriv_atomic_int_get(&s->buffers_queued) != s->buffers)
+ if (atomic_load(&s->buffers_queued) != s->buffers)
- av_log(s1, AV_LOG_WARNING, "Some buffers are still owned by the caller on "
+ av_log(ctx, AV_LOG_WARNING, "Some buffers are still owned by the caller on "
"close.\n");
mmap_close(s);
More information about the ffmpeg-cvslog
mailing list