[FFmpeg-devel] [PATCH 2/6] lavc/v4l2-common: Add pack_flags to v4l2 conversion tables and extend the mapping function to use it.

Alexis Ballier aballier at gentoo.org
Thu Nov 20 17:51:53 CET 2014


It serves to distinguish if we will (de)packetize the format from an AVFrame or an AVPacket. We will need AVFrame support for v4l m2m and we can certainly not use as-is e.g. V4L2_PIX_FMT_YUV420 as AV_PIX_FMT_YUV420P since the former is pseudo-packed while the later is planar. Also, V4L multi planar formats cannot be packetized into raw video AVPackets.
---
 libavcodec/v4l2-common.c | 63 ++++++++++++++++++++++++------------------------
 libavcodec/v4l2-common.h |  7 +++++-
 libavdevice/v4l2.c       |  2 +-
 libavdevice/v4l2enc.c    |  2 +-
 4 files changed, 40 insertions(+), 34 deletions(-)

diff --git a/libavcodec/v4l2-common.c b/libavcodec/v4l2-common.c
index 884101d..815a5c4 100644
--- a/libavcodec/v4l2-common.c
+++ b/libavcodec/v4l2-common.c
@@ -19,49 +19,49 @@
 #include "v4l2-common.h"
 
 const struct v4l_fmt_map avpriv_v4l_fmt_conversion_table[] = {
-    //ff_fmt              codec_id              v4l2_fmt
-    { AV_PIX_FMT_YUV420P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV420  },
-    { AV_PIX_FMT_YUV420P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YVU420  },
-    { AV_PIX_FMT_YUV422P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV422P },
-    { AV_PIX_FMT_YUYV422, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUYV    },
-    { AV_PIX_FMT_UYVY422, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_UYVY    },
-    { AV_PIX_FMT_YUV411P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV411P },
-    { AV_PIX_FMT_YUV410P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV410  },
-    { AV_PIX_FMT_YUV410P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YVU410  },
-    { AV_PIX_FMT_RGB555LE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB555  },
-    { AV_PIX_FMT_RGB555BE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB555X },
-    { AV_PIX_FMT_RGB565LE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB565  },
-    { AV_PIX_FMT_RGB565BE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB565X },
-    { AV_PIX_FMT_BGR24,   AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_BGR24   },
-    { AV_PIX_FMT_RGB24,   AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB24   },
-    { AV_PIX_FMT_BGR0,    AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_BGR32   },
-    { AV_PIX_FMT_0RGB,    AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB32   },
-    { AV_PIX_FMT_GRAY8,   AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_GREY    },
+    //ff_fmt              codec_id              v4l2_fmt                  pack_flags
+    { AV_PIX_FMT_YUV420P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV420     , FF_V4L_PACK_AVPACKET },
+    { AV_PIX_FMT_YUV420P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YVU420     , FF_V4L_PACK_AVPACKET },
+    { AV_PIX_FMT_YUV422P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV422P    , FF_V4L_PACK_AVPACKET },
+    { AV_PIX_FMT_YUYV422, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUYV       , FF_V4L_PACK_AVPACKET | FF_V4L_PACK_AVFRAME },
+    { AV_PIX_FMT_UYVY422, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_UYVY       , FF_V4L_PACK_AVPACKET | FF_V4L_PACK_AVFRAME },
+    { AV_PIX_FMT_YUV411P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV411P    , FF_V4L_PACK_AVPACKET },
+    { AV_PIX_FMT_YUV410P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV410     , FF_V4L_PACK_AVPACKET },
+    { AV_PIX_FMT_YUV410P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YVU410     , FF_V4L_PACK_AVPACKET },
+    { AV_PIX_FMT_RGB555LE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB555     , FF_V4L_PACK_AVPACKET | FF_V4L_PACK_AVFRAME },
+    { AV_PIX_FMT_RGB555BE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB555X    , FF_V4L_PACK_AVPACKET | FF_V4L_PACK_AVFRAME },
+    { AV_PIX_FMT_RGB565LE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB565     , FF_V4L_PACK_AVPACKET | FF_V4L_PACK_AVFRAME },
+    { AV_PIX_FMT_RGB565BE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB565X    , FF_V4L_PACK_AVPACKET | FF_V4L_PACK_AVFRAME },
+    { AV_PIX_FMT_BGR24,   AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_BGR24      , FF_V4L_PACK_AVPACKET | FF_V4L_PACK_AVFRAME },
+    { AV_PIX_FMT_RGB24,   AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB24      , FF_V4L_PACK_AVPACKET | FF_V4L_PACK_AVFRAME },
+    { AV_PIX_FMT_BGR0,    AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_BGR32      , FF_V4L_PACK_AVPACKET | FF_V4L_PACK_AVFRAME },
+    { AV_PIX_FMT_0RGB,    AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB32      , FF_V4L_PACK_AVPACKET | FF_V4L_PACK_AVFRAME },
+    { AV_PIX_FMT_GRAY8,   AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_GREY       , FF_V4L_PACK_AVPACKET | FF_V4L_PACK_AVFRAME },
 #ifdef V4L2_PIX_FMT_Y16
-    { AV_PIX_FMT_GRAY16LE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_Y16     },
+    { AV_PIX_FMT_GRAY16LE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_Y16        , FF_V4L_PACK_AVPACKET | FF_V4L_PACK_AVFRAME },
 #endif
-    { AV_PIX_FMT_NV12,    AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_NV12    },
-    { AV_PIX_FMT_NONE,    AV_CODEC_ID_MJPEG,    V4L2_PIX_FMT_MJPEG   },
-    { AV_PIX_FMT_NONE,    AV_CODEC_ID_MJPEG,    V4L2_PIX_FMT_JPEG    },
+    { AV_PIX_FMT_NV12,    AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_NV12       , FF_V4L_PACK_AVPACKET },
+    { AV_PIX_FMT_NONE,    AV_CODEC_ID_MJPEG,    V4L2_PIX_FMT_MJPEG      , FF_V4L_PACK_AVPACKET },
+    { AV_PIX_FMT_NONE,    AV_CODEC_ID_MJPEG,    V4L2_PIX_FMT_JPEG       , FF_V4L_PACK_AVPACKET },
 #ifdef V4L2_PIX_FMT_H264
-    { AV_PIX_FMT_NONE,    AV_CODEC_ID_H264,     V4L2_PIX_FMT_H264    },
+    { AV_PIX_FMT_NONE,    AV_CODEC_ID_H264,     V4L2_PIX_FMT_H264       , FF_V4L_PACK_AVPACKET },
 #endif
 #ifdef V4L2_PIX_FMT_MPEG4
-    { AV_PIX_FMT_NONE,    AV_CODEC_ID_MPEG4,    V4L2_PIX_FMT_MPEG4   },
+    { AV_PIX_FMT_NONE,    AV_CODEC_ID_MPEG4,    V4L2_PIX_FMT_MPEG4      , FF_V4L_PACK_AVPACKET },
 #endif
 #ifdef V4L2_PIX_FMT_CPIA1
-    { AV_PIX_FMT_NONE,    AV_CODEC_ID_CPIA,     V4L2_PIX_FMT_CPIA1   },
+    { AV_PIX_FMT_NONE,    AV_CODEC_ID_CPIA,     V4L2_PIX_FMT_CPIA1      , FF_V4L_PACK_AVPACKET },
 #endif
 #ifdef V4L2_PIX_FMT_SRGGB8
-    { AV_PIX_FMT_BAYER_BGGR8, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_SBGGR8 },
-    { AV_PIX_FMT_BAYER_GBRG8, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_SGBRG8 },
-    { AV_PIX_FMT_BAYER_GRBG8, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_SGRBG8 },
-    { AV_PIX_FMT_BAYER_RGGB8, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_SRGGB8 },
+    { AV_PIX_FMT_BAYER_BGGR8, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_SBGGR8 , FF_V4L_PACK_AVPACKET | FF_V4L_PACK_AVFRAME },
+    { AV_PIX_FMT_BAYER_GBRG8, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_SGBRG8 , FF_V4L_PACK_AVPACKET | FF_V4L_PACK_AVFRAME },
+    { AV_PIX_FMT_BAYER_GRBG8, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_SGRBG8 , FF_V4L_PACK_AVPACKET | FF_V4L_PACK_AVFRAME },
+    { AV_PIX_FMT_BAYER_RGGB8, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_SRGGB8 , FF_V4L_PACK_AVPACKET | FF_V4L_PACK_AVFRAME },
 #endif
     { AV_PIX_FMT_NONE,    AV_CODEC_ID_NONE,     0                    },
 };
 
-uint32_t avpriv_v4l_fmt_ff2v4l(enum AVPixelFormat pix_fmt, enum AVCodecID codec_id)
+uint32_t avpriv_v4l_fmt_ff2v4l(enum AVPixelFormat pix_fmt, enum AVCodecID codec_id, int pack_flags)
 {
     int i;
 
@@ -69,7 +69,8 @@ uint32_t avpriv_v4l_fmt_ff2v4l(enum AVPixelFormat pix_fmt, enum AVCodecID codec_
         if ((codec_id == AV_CODEC_ID_NONE ||
              avpriv_v4l_fmt_conversion_table[i].codec_id == codec_id) &&
             (pix_fmt == AV_PIX_FMT_NONE ||
-             avpriv_v4l_fmt_conversion_table[i].ff_fmt == pix_fmt)) {
+             avpriv_v4l_fmt_conversion_table[i].ff_fmt == pix_fmt) &&
+             (avpriv_v4l_fmt_conversion_table[i].pack_flags & pack_flags)) {
             return avpriv_v4l_fmt_conversion_table[i].v4l2_fmt;
         }
     }
diff --git a/libavcodec/v4l2-common.h b/libavcodec/v4l2-common.h
index 2528cd0..772edea 100644
--- a/libavcodec/v4l2-common.h
+++ b/libavcodec/v4l2-common.h
@@ -32,15 +32,20 @@
 #include "libavutil/pixfmt.h"
 #include "libavcodec/avcodec.h"
 
+/* for v4l_fmt_map.pack_flags */
+#define FF_V4L_PACK_AVPACKET (1 << 0)
+#define FF_V4L_PACK_AVFRAME  (1 << 1)
+
 struct v4l_fmt_map {
     enum AVPixelFormat ff_fmt;
     enum AVCodecID codec_id;
     uint32_t v4l2_fmt;
+    int pack_flags;
 };
 
 extern const struct v4l_fmt_map avpriv_v4l_fmt_conversion_table[];
 
-uint32_t avpriv_v4l_fmt_ff2v4l(enum AVPixelFormat pix_fmt, enum AVCodecID codec_id);
+uint32_t avpriv_v4l_fmt_ff2v4l(enum AVPixelFormat pix_fmt, enum AVCodecID codec_id, int pack_flags);
 enum AVPixelFormat avpriv_v4l_fmt_v4l2ff(uint32_t v4l2_fmt, enum AVCodecID codec_id);
 enum AVCodecID avpriv_v4l_fmt_v4l2codec(uint32_t v4l2_fmt);
 
diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
index 95fcf5e..8e4e141 100644
--- a/libavdevice/v4l2.c
+++ b/libavdevice/v4l2.c
@@ -784,7 +784,7 @@ static int device_try_init(AVFormatContext *ctx,
 {
     int ret, i;
 
-    *desired_format = avpriv_v4l_fmt_ff2v4l(pix_fmt, ctx->video_codec_id);
+    *desired_format = avpriv_v4l_fmt_ff2v4l(pix_fmt, ctx->video_codec_id, FF_V4L_PACK_AVPACKET);
 
     if (*desired_format) {
         ret = device_init(ctx, width, height, *desired_format);
diff --git a/libavdevice/v4l2enc.c b/libavdevice/v4l2enc.c
index 5d9b7f5..e8c2ab3 100644
--- a/libavdevice/v4l2enc.c
+++ b/libavdevice/v4l2enc.c
@@ -64,7 +64,7 @@ static av_cold int write_header(AVFormatContext *s1)
 
     enc_ctx = s1->streams[0]->codec;
 
-    v4l2_pixfmt = avpriv_v4l_fmt_ff2v4l(enc_ctx->pix_fmt, AV_CODEC_ID_RAWVIDEO);
+    v4l2_pixfmt = avpriv_v4l_fmt_ff2v4l(enc_ctx->pix_fmt, AV_CODEC_ID_RAWVIDEO, FF_V4L_PACK_AVPACKET);
     if (!v4l2_pixfmt) { // XXX: try to force them one by one?
         av_log(s1, AV_LOG_ERROR, "Unknown V4L2 pixel format equivalent for %s\n",
                av_get_pix_fmt_name(enc_ctx->pix_fmt));
-- 
2.1.3



More information about the ffmpeg-devel mailing list