[PATCH 1/2] Implement av_log_error() and use it in v4l2.c for the macro LOG_ERRNO.

Stefano Sabatini stefano.sabatini-lala
Sat Apr 24 16:31:05 CEST 2010


Increase consistency and robustness, as av_log_error() uses
av_strerror() rather than strerror(), which is not thread-safe.
---
 libavdevice/v4l2.c |   25 +++++++++++++------------
 libavutil/log.c    |   17 +++++++++++++++++
 libavutil/log.h    |   14 ++++++++++++++
 3 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
index 8142739..7044664 100644
--- a/libavdevice/v4l2.c
+++ b/libavdevice/v4l2.c
@@ -149,6 +149,9 @@ static struct fmt_map fmt_conversion_table[] = {
     },
 };
 
+#define LOG_ERRNO(log_ctx, ...) \
+    av_log_error(log_ctx, AV_LOG_ERROR, AVERROR(errno), __VA_ARGS__)
+
 static int device_open(AVFormatContext *ctx, uint32_t *capabilities)
 {
     struct v4l2_capability cap;
@@ -161,8 +164,7 @@ static int device_open(AVFormatContext *ctx, uint32_t *capabilities)
     }
     fd = open(ctx->filename, flags, 0);
     if (fd < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s : %s\n",
-                 ctx->filename, strerror(errno));
+        LOG_ERRNO(ctx, "Cannot open video device %s", ctx->filename);
 
         return AVERROR(errno);
     }
@@ -171,14 +173,13 @@ static int device_open(AVFormatContext *ctx, uint32_t *capabilities)
     // ENOIOCTLCMD definition only availble on __KERNEL__
     if (res < 0 && errno == 515)
     {
-        av_log(ctx, AV_LOG_ERROR, "QUERYCAP not implemented, probably V4L device but not supporting V4L2\n");
+        LOG_ERRNO(ctx, "QUERYCAP not implemented, probably V4L device but not supporting V4L2\n");
         close(fd);
 
         return AVERROR(errno);
     }
     if (res < 0) {
-        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n",
-                 strerror(errno));
+        LOG_ERRNO(ctx, "ioctl(VIDIOC_QUERYCAP)");
         close(fd);
 
         return AVERROR(errno);
@@ -296,7 +297,7 @@ static int mmap_init(AVFormatContext *ctx)
         if (errno == EINVAL) {
             av_log(ctx, AV_LOG_ERROR, "Device does not support mmap\n");
         } else {
-            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_REQBUFS)\n");
+            LOG_ERRNO(ctx, "ioctl(VIDIOC_REQBUFS)");
         }
 
         return AVERROR(errno);
@@ -331,7 +332,7 @@ static int mmap_init(AVFormatContext *ctx)
         buf.index = i;
         res = ioctl (s->fd, VIDIOC_QUERYBUF, &buf);
         if (res < 0) {
-            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYBUF)\n");
+            LOG_ERRNO(ctx, "ioctl(VIDIOC_QUERYBUF)");
 
             return AVERROR(errno);
         }
@@ -345,7 +346,7 @@ static int mmap_init(AVFormatContext *ctx)
         s->buf_start[i] = mmap (NULL, buf.length,
                         PROT_READ | PROT_WRITE, MAP_SHARED, s->fd, buf.m.offset);
         if (s->buf_start[i] == MAP_FAILED) {
-            av_log(ctx, AV_LOG_ERROR, "mmap: %s\n", strerror(errno));
+            LOG_ERRNO(ctx, "mmap");
 
             return AVERROR(errno);
         }
@@ -378,7 +379,7 @@ static void mmap_release_buffer(AVPacket *pkt)
 
     res = ioctl (fd, VIDIOC_QBUF, &buf);
     if (res < 0) {
-        av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF)\n");
+        LOG_ERRNO(NULL, "ioctl(VIDIOC_QBUF)");
     }
     pkt->data = NULL;
     pkt->size = 0;
@@ -403,7 +404,7 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
 
             return AVERROR(EAGAIN);
         }
-        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n", strerror(errno));
+        LOG_ERRNO(ctx, "ioctl(VIDIOC_DQBUF)");
 
         return AVERROR(errno);
     }
@@ -457,7 +458,7 @@ static int mmap_start(AVFormatContext *ctx)
 
         res = ioctl (s->fd, VIDIOC_QBUF, &buf);
         if (res < 0) {
-            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", strerror(errno));
+            LOG_ERRNO(ctx, "ioctl(VIDIOC_QBUF)");
 
             return AVERROR(errno);
         }
@@ -466,7 +467,7 @@ static int mmap_start(AVFormatContext *ctx)
     type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
     res = ioctl (s->fd, VIDIOC_STREAMON, &type);
     if (res < 0) {
-        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n", strerror(errno));
+        LOG_ERRNO(ctx, "ioctl(VIDIOC_STREAMON)");
 
         return AVERROR(errno);
     }
diff --git a/libavutil/log.c b/libavutil/log.c
index 9a8b66e..2034000 100644
--- a/libavutil/log.c
+++ b/libavutil/log.c
@@ -114,3 +114,20 @@ void av_log_set_callback(void (*callback)(void*, int, const char*, va_list))
 {
     av_log_callback = callback;
 }
+
+void av_vlog_error(void *log_ctx, int level, int error, const char *fmt, va_list vl)
+{
+    char errbuf[128];
+
+    av_strerror(error, errbuf, sizeof(errbuf));
+    av_vlog(log_ctx, level, fmt, vl);
+    av_log(log_ctx, level, ": %s\n", errbuf);
+}
+
+void av_log_error(void *log_ctx, int level, int error, const char *fmt, ...)
+{
+    va_list vl;
+    va_start(vl, fmt);
+    av_vlog_error(log_ctx, level, error, fmt, vl);
+    va_end(vl);
+}
diff --git a/libavutil/log.h b/libavutil/log.h
index b0a1493..3ed6a8d 100644
--- a/libavutil/log.h
+++ b/libavutil/log.h
@@ -112,4 +112,18 @@ void av_log_set_level(int);
 void av_log_set_callback(void (*)(void*, int, const char*, va_list));
 void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl);
 
+/**
+ * Logs the template in fmt, followed by ": " and the description of
+ * the error corresponding to the AVERROR code in error.
+ *
+ * @param level the importance level of the message, lower values
+ * signifying higher importance.
+ */
+void av_vlog_error(void *log_ctx, int level, int error, const char *fmt, va_list vl);
+
+/**
+ * @see av_vlog_error()
+ */
+void av_log_error(void *log_ctx, int level, int error, const char *fmt, ...);
+
 #endif /* AVUTIL_LOG_H */
-- 
1.7.0


--+HP7ph2BbKc20aGI--



More information about the ffmpeg-devel mailing list