From 8eec655320f5ea48fe63dbfb8611dfdec1cf0c83 Mon Sep 17 00:00:00 2001 From: Clément Bœsch Date: Sun, 19 May 2013 23:35:07 +0200 Subject: lavd/v4l2: move pixel format conversion code to a separate place. This will be shared with the output device. --- libavdevice/Makefile | 2 +- libavdevice/v4l2-common.c | 96 ++++++++++++++++++++++++++++++++++ libavdevice/v4l2-common.h | 62 ++++++++++++++++++++++ libavdevice/v4l2.c | 130 ++++------------------------------------------ 4 files changed, 170 insertions(+), 120 deletions(-) create mode 100644 libavdevice/v4l2-common.c create mode 100644 libavdevice/v4l2-common.h diff --git a/libavdevice/Makefile b/libavdevice/Makefile index efffa8bbcd..dfde768d34 100644 --- a/libavdevice/Makefile +++ b/libavdevice/Makefile @@ -32,7 +32,7 @@ OBJS-$(CONFIG_PULSE_INDEV) += pulse.o OBJS-$(CONFIG_SDL_OUTDEV) += sdl.o OBJS-$(CONFIG_SNDIO_INDEV) += sndio_common.o sndio_dec.o OBJS-$(CONFIG_SNDIO_OUTDEV) += sndio_common.o sndio_enc.o -OBJS-$(CONFIG_V4L2_INDEV) += v4l2.o timefilter.o +OBJS-$(CONFIG_V4L2_INDEV) += v4l2.o v4l2-common.o timefilter.o OBJS-$(CONFIG_V4L_INDEV) += v4l.o OBJS-$(CONFIG_VFWCAP_INDEV) += vfwcap.o OBJS-$(CONFIG_X11GRAB_INDEV) += x11grab.o diff --git a/libavdevice/v4l2-common.c b/libavdevice/v4l2-common.c new file mode 100644 index 0000000000..572f0ed36b --- /dev/null +++ b/libavdevice/v4l2-common.c @@ -0,0 +1,96 @@ +/* + * 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 + */ + +#include "v4l2-common.h" + +const struct fmt_map avpriv_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 }, +#ifdef V4L2_PIX_FMT_Y16 + { AV_PIX_FMT_GRAY16LE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_Y16 }, +#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 }, +#ifdef V4L2_PIX_FMT_H264 + { AV_PIX_FMT_NONE, AV_CODEC_ID_H264, V4L2_PIX_FMT_H264 }, +#endif +#ifdef V4L2_PIX_FMT_CPIA1 + { AV_PIX_FMT_NONE, AV_CODEC_ID_CPIA, V4L2_PIX_FMT_CPIA1 }, +#endif + { AV_PIX_FMT_NONE, AV_CODEC_ID_NONE, 0 }, +}; + +uint32_t avpriv_fmt_ff2v4l(enum AVPixelFormat pix_fmt, enum AVCodecID codec_id) +{ + int i; + + for (i = 0; avpriv_fmt_conversion_table[i].codec_id != AV_CODEC_ID_NONE; i++) { + if ((codec_id == AV_CODEC_ID_NONE || + avpriv_fmt_conversion_table[i].codec_id == codec_id) && + (pix_fmt == AV_PIX_FMT_NONE || + avpriv_fmt_conversion_table[i].ff_fmt == pix_fmt)) { + return avpriv_fmt_conversion_table[i].v4l2_fmt; + } + } + + return 0; +} + +enum AVPixelFormat avpriv_fmt_v4l2ff(uint32_t v4l2_fmt, enum AVCodecID codec_id) +{ + int i; + + for (i = 0; avpriv_fmt_conversion_table[i].codec_id != AV_CODEC_ID_NONE; i++) { + if (avpriv_fmt_conversion_table[i].v4l2_fmt == v4l2_fmt && + avpriv_fmt_conversion_table[i].codec_id == codec_id) { + return avpriv_fmt_conversion_table[i].ff_fmt; + } + } + + return AV_PIX_FMT_NONE; +} + +enum AVCodecID avpriv_fmt_v4l2codec(uint32_t v4l2_fmt) +{ + int i; + + for (i = 0; avpriv_fmt_conversion_table[i].codec_id != AV_CODEC_ID_NONE; i++) { + if (avpriv_fmt_conversion_table[i].v4l2_fmt == v4l2_fmt) { + return avpriv_fmt_conversion_table[i].codec_id; + } + } + + return AV_CODEC_ID_NONE; +} diff --git a/libavdevice/v4l2-common.h b/libavdevice/v4l2-common.h new file mode 100644 index 0000000000..8aef2349ae --- /dev/null +++ b/libavdevice/v4l2-common.h @@ -0,0 +1,62 @@ +/* + * 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 +#include +#include +#include +#include +#if HAVE_SYS_VIDEOIO_H +#include +#else +#if HAVE_ASM_TYPES_H +#include +#endif +#include +#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 av_export const struct fmt_map avpriv_fmt_conversion_table[]; + +uint32_t avpriv_fmt_ff2v4l(enum AVPixelFormat pix_fmt, enum AVCodecID codec_id); +enum AVPixelFormat avpriv_fmt_v4l2ff(uint32_t v4l2_fmt, enum AVCodecID codec_id); +enum AVCodecID avpriv_fmt_v4l2codec(uint32_t v4l2_fmt); + +#endif /* AVDEVICE_V4L2_COMMON_H */ diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c index 7c6c1bcc45..90985e35f3 100644 --- a/libavdevice/v4l2.c +++ b/libavdevice/v4l2.c @@ -30,33 +30,7 @@ * V4L2_PIX_FMT_* and AV_PIX_FMT_* */ -#undef __STRICT_ANSI__ //workaround due to broken kernel headers -#include "config.h" -#include "libavformat/internal.h" -#include -#include -#include -#include -#include -#if HAVE_SYS_VIDEOIO_H -#include -#else -#if HAVE_ASM_TYPES_H -#include -#endif -#include -#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" +#include "v4l2-common.h" #if CONFIG_LIBV4L2 #include @@ -128,45 +102,6 @@ struct buff_data { int index; }; -struct fmt_map { - enum AVPixelFormat ff_fmt; - enum AVCodecID codec_id; - uint32_t v4l2_fmt; -}; - -static struct fmt_map 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 }, -#ifdef V4L2_PIX_FMT_Y16 - { AV_PIX_FMT_GRAY16LE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_Y16 }, -#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 }, -#ifdef V4L2_PIX_FMT_H264 - { AV_PIX_FMT_NONE, AV_CODEC_ID_H264, V4L2_PIX_FMT_H264 }, -#endif -#ifdef V4L2_PIX_FMT_CPIA1 - { AV_PIX_FMT_NONE, AV_CODEC_ID_CPIA, V4L2_PIX_FMT_CPIA1 }, -#endif -}; - static int device_open(AVFormatContext *ctx) { struct v4l2_capability cap; @@ -275,49 +210,6 @@ static int first_field(int fd) return 1; } -static uint32_t fmt_ff2v4l(enum AVPixelFormat pix_fmt, enum AVCodecID codec_id) -{ - int i; - - for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) { - if ((codec_id == AV_CODEC_ID_NONE || - fmt_conversion_table[i].codec_id == codec_id) && - (pix_fmt == AV_PIX_FMT_NONE || - fmt_conversion_table[i].ff_fmt == pix_fmt)) { - return fmt_conversion_table[i].v4l2_fmt; - } - } - - return 0; -} - -static enum AVPixelFormat fmt_v4l2ff(uint32_t v4l2_fmt, enum AVCodecID codec_id) -{ - int i; - - for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) { - if (fmt_conversion_table[i].v4l2_fmt == v4l2_fmt && - fmt_conversion_table[i].codec_id == codec_id) { - return fmt_conversion_table[i].ff_fmt; - } - } - - return AV_PIX_FMT_NONE; -} - -static enum AVCodecID fmt_v4l2codec(uint32_t v4l2_fmt) -{ - int i; - - for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) { - if (fmt_conversion_table[i].v4l2_fmt == v4l2_fmt) { - return fmt_conversion_table[i].codec_id; - } - } - - return AV_CODEC_ID_NONE; -} - #if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE static void list_framesizes(AVFormatContext *ctx, int fd, uint32_t pixelformat) { @@ -349,8 +241,8 @@ static void list_formats(AVFormatContext *ctx, int fd, int type) struct v4l2_fmtdesc vfd = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE }; while(!v4l2_ioctl(fd, VIDIOC_ENUM_FMT, &vfd)) { - enum AVCodecID codec_id = fmt_v4l2codec(vfd.pixelformat); - enum AVPixelFormat pix_fmt = fmt_v4l2ff(vfd.pixelformat, codec_id); + enum AVCodecID codec_id = avpriv_fmt_v4l2codec(vfd.pixelformat); + enum AVPixelFormat pix_fmt = avpriv_fmt_v4l2ff(vfd.pixelformat, codec_id); vfd.index++; @@ -825,7 +717,7 @@ static int device_try_init(AVFormatContext *s1, { int ret, i; - *desired_format = fmt_ff2v4l(pix_fmt, s1->video_codec_id); + *desired_format = avpriv_fmt_ff2v4l(pix_fmt, s1->video_codec_id); if (*desired_format) { ret = device_init(s1, width, height, *desired_format); @@ -837,14 +729,14 @@ static int device_try_init(AVFormatContext *s1, } if (!*desired_format) { - for (i = 0; ivideo_codec_id == AV_CODEC_ID_NONE || - fmt_conversion_table[i].codec_id == s1->video_codec_id) { + avpriv_fmt_conversion_table[i].codec_id == s1->video_codec_id) { av_log(s1, AV_LOG_DEBUG, "Trying to set codec:%s pix_fmt:%s\n", - avcodec_get_name(fmt_conversion_table[i].codec_id), - (char *)av_x_if_null(av_get_pix_fmt_name(fmt_conversion_table[i].ff_fmt), "none")); + avcodec_get_name(avpriv_fmt_conversion_table[i].codec_id), + (char *)av_x_if_null(av_get_pix_fmt_name(avpriv_fmt_conversion_table[i].ff_fmt), "none")); - *desired_format = fmt_conversion_table[i].v4l2_fmt; + *desired_format = avpriv_fmt_conversion_table[i].v4l2_fmt; ret = device_init(s1, width, height, *desired_format); if (ret >= 0) break; @@ -863,7 +755,7 @@ static int device_try_init(AVFormatContext *s1, } } - *codec_id = fmt_v4l2codec(*desired_format); + *codec_id = avpriv_fmt_v4l2codec(*desired_format); av_assert0(*codec_id != AV_CODEC_ID_NONE); return ret; } @@ -986,7 +878,7 @@ static int v4l2_read_header(AVFormatContext *s1) if ((res = v4l2_set_parameters(s1)) < 0) return res; - st->codec->pix_fmt = fmt_v4l2ff(desired_format, codec_id); + st->codec->pix_fmt = avpriv_fmt_v4l2ff(desired_format, codec_id); s->frame_size = avpicture_get_size(st->codec->pix_fmt, s->width, s->height); -- cgit v1.2.3