Re: [PATCH v4 1/1] libv4l: Add plugin support to libv4l
Hi Hans, Hans de Goede wrote: Hi, Sorry it took so long, but I've just merged the plugin support into v4l-utils git. I did make some minor mods / bugfixes before merging, see the commit message in git. Regards, Hans p.s. I think we should expand the plugin support with support for a output devices, iow add a write() dev_op. If you guys agree I can easily do so myself, we should do this asap before people start depending on the ABI (although there is no ABI stability promise until I release 0.10.x, see my message to the list wrt the start of the 0.9.x cycle). I think that it is a good point, you can add write() and reserved dev_ops. Thanks Yordan While on the subject of keeping the plugin ABI, I suggest that we add a number of extra dev_ops named reserved1 -- reserved8 for future use and a comment that these should all be set to NULL. Then we can easily add another op on the future while keeping compatibility with older plugins. On 05/03/2011 05:26 PM, Yordan Kamenov wrote: A libv4l2 plugin will sit in between libv4l2 itself and the actual /dev/video device node a fd refers to. It will be called each time libv4l2 wants to do an operation (read/write/ioctl) on the actual /dev/video node in question. Signed-off-by: Yordan Kamenov --- lib/include/libv4l2-plugin.h | 36 ++ lib/include/libv4lconvert.h|5 +- lib/libv4l2/Makefile |6 +- lib/libv4l2/libv4l2-priv.h | 10 ++ lib/libv4l2/libv4l2.c | 88 ++ lib/libv4l2/v4l2-plugin.c | 158 lib/libv4l2/v4l2convert.c |9 -- lib/libv4lconvert/control/libv4lcontrol-priv.h |4 + lib/libv4lconvert/control/libv4lcontrol.c | 35 -- lib/libv4lconvert/control/libv4lcontrol.h |5 +- lib/libv4lconvert/libv4lconvert-priv.h |2 + lib/libv4lconvert/libv4lconvert.c | 34 -- utils/qv4l2/qv4l2.cpp | 17 +++- utils/qv4l2/qv4l2.h|1 + 14 files changed, 347 insertions(+), 63 deletions(-) create mode 100644 lib/include/libv4l2-plugin.h create mode 100644 lib/libv4l2/v4l2-plugin.c diff --git a/lib/include/libv4l2-plugin.h b/lib/include/libv4l2-plugin.h new file mode 100644 index 000..158c0c2 --- /dev/null +++ b/lib/include/libv4l2-plugin.h @@ -0,0 +1,36 @@ +/* +* Copyright (C) 2010 Nokia Corporation + +* This program 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. +* +* This program 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 this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __LIBV4L2_PLUGIN_H +#define __LIBV4L2_PLUGIN_H + +#include + +/* Structure libv4l2_dev_ops holds the calls from libv4ls to video nodes. + They can be normal open/close/ioctl etc. or any of them may be replaced + with a callback by a loaded plugin. +*/ + +struct libv4l2_dev_ops { +void * (*init)(int fd); +void (*close)(void *dev_ops_priv); +int (*ioctl)(void *dev_ops_priv, int fd, unsigned long int request, void *arg); +ssize_t (*read)(void *dev_ops_priv, int fd, void *buffer, size_t n); +}; + +#endif diff --git a/lib/include/libv4lconvert.h b/lib/include/libv4lconvert.h index 0264290..351142e 100644 --- a/lib/include/libv4lconvert.h +++ b/lib/include/libv4lconvert.h @@ -38,6 +38,8 @@ #include +#include "libv4l2-plugin.h" + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -50,7 +52,8 @@ extern "C" { struct v4lconvert_data; -LIBV4L_PUBLIC struct v4lconvert_data *v4lconvert_create(int fd); +LIBV4L_PUBLIC struct v4lconvert_data *v4lconvert_create(int fd, +void *dev_ops_priv, struct libv4l2_dev_ops *dev_ops); LIBV4L_PUBLIC void v4lconvert_destroy(struct v4lconvert_data *data); /* When doing flipping / rotating / video-processing, only supported diff --git a/lib/libv4l2/Makefile b/lib/libv4l2/Makefile index d78632f..f8b3714 100644 --- a/lib/libv4l2/Makefile +++ b/lib/libv4l2/Makefile @@ -1,12 +1,12 @@ override CPPFLAGS += -I../include -fvisibility=hidden -LIBS_libv4l2 = -lpthread +LIBS_libv4l2 = -lpthread -ldl -V4L2_OBJS = libv4l2.o log.o +V4L2_OBJS = libv4l2.o v4l2-plugin.o log.o V4L2CONVERT = v4l2convert.so V4L2CONVERT_O = v4l2convert.o libv4l2.so TARGETS
Re: [libv4l-mcplugin PATCH 0/3] Media controller plugin for libv4l2
Hans de Goede wrote: Hi, Hi Hans, So judging from the directory layout, this is supposed to be a separate project, and not part of v4l-utils / libv4l, right? It is separate now, but I guess that at some point it would be good to have 'plugins' directory containing some generic plugins as part of libv4l. Regards Yordan WRT my merging plans for libv4l. I've recently done some much needed work to better support high-res usb cameras. I plan to do a 0.8.4 release with that work included real soon. Once that is done I'll change the version in the Make.rules to 0.9.0-test and merge the plugin. Then we'll have some 0.9.x releases followed by some 0.9.9x release (all testing releases) followed by a 0.10.0 which should be the first stable release with plugin support. Regards, Hans On 05/19/2011 02:36 PM, Yordan Kamenov wrote: Hi, This is the Media Controller plugin for libv4l. It uses libv4l2 plugin support which is accepted by Hans De Goede, but not yet included in mainline libv4l2: http://www.spinics.net/lists/linux-media/msg32017.html The plugin allows a traditional v4l2 applications to work with Media Controller framework. The plugin is loaded when application opens /dev/video0 and it configures the media controller and then all ioctl's by the applicatin are handled by the plugin. The plugin implements init, close and ioctl callbacks. The init callback checks it's input file descriptor and if it coresponds to /dev/video0, then the media controller is initialized and appropriate pipeline is created. The close callback deinitializes the pipeline, and closes the media device. The ioctl callback is responsible to handle ioctl calls from application by using the media controller pipeline. The plugin uses media-ctl library for media controller operations: http://git.ideasonboard.org/?p=media-ctl.git;a=summary The plugin is divided in three separate patches: * Media Controller pipelines initialization, configuration and destruction * v4l operations - uses some functionality from the first one * Plugin interface operations (init, close and ioctl) - uses functionality from first two Yordan Kamenov (3): Add files for media controller pipelines Add files for v4l operations Add libv4l2 media controller plugin interface files -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[libv4l-mcplugin PATCH 3/3] Add libv4l2 media controller plugin interface files
Add interface functions init(), close() and ioctl(), called by libv4l2. Signed-off-by: Yordan Kamenov --- libv4l2plugin-omap3mc.c | 241 +++ libv4l2plugin-omap3mc.h | 91 ++ 2 files changed, 332 insertions(+), 0 deletions(-) create mode 100644 libv4l2plugin-omap3mc.c create mode 100644 libv4l2plugin-omap3mc.h diff --git a/libv4l2plugin-omap3mc.c b/libv4l2plugin-omap3mc.c new file mode 100644 index 000..e5b5ef0 --- /dev/null +++ b/libv4l2plugin-omap3mc.c @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2011 Nokia Corporation + * + * Contact: Yordan Kamenov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libv4l2-plugin.h" +#include "libv4l2plugin-omap3mc.h" +#include "paths.h" +#include "operations.h" + +#if __GNUC__ >= 4 +#define PLUGIN_PUBLIC __attribute__ ((visibility("default"))) +#define PLUGIN_HIDDEN __attribute__ ((visibility("hidden"))) +#else +#define PLUGIN_PUBLIC +#define PLUGIN_HIDDEN +#endif + +/* Check if /dev/media0 is already open*/ +int media_in_use() +{ + int glob_ret, file, ret = 0; + glob_t globbuf; + ssize_t link_len; + char file_name[16]; + + glob_ret = glob("/proc/self/fd/*", 0, NULL, &globbuf); + + if (glob_ret == GLOB_NOSPACE) + return ret; + + if (glob_ret == GLOB_ABORTED || glob_ret == GLOB_NOMATCH) + goto leave; + + for (file = 0; file < globbuf.gl_pathc; file++) { + link_len = readlink(globbuf.gl_pathv[file], + file_name, strlen(MEDIA_DEVICE)); + if (link_len == strlen(MEDIA_DEVICE)) + file_name[link_len] = '\0'; + else + continue; + + if (!strncmp(file_name, MEDIA_DEVICE, strlen(MEDIA_DEVICE))) { + ret = 1; + break; + } + } + +leave: + globfree(&globbuf); + + return ret; +} + +PLUGIN_HIDDEN void * omap3mc_init(int fd) +{ + int ret = -1, primary; + struct omap3mcplugin *plugin; + const struct capture_pipeline *pipe = NULL; + struct sub_module *dst_sub_module = NULL; + char link_path[20]; + ssize_t link_len; + char file[VIDEO_NODE_LENGTH + 1]; + + /* Get filename from fd */ + sprintf(link_path, "/proc/self/fd/%d", fd); + link_len = readlink(link_path, file, VIDEO_NODE_LENGTH); + if (link_len == VIDEO_NODE_LENGTH) + link_path[link_len] = '\0'; + else + return NULL; + + /* FIXME: What we do if the application is aware of video nodes + and tries to open() real /dev/video0 (CSI2 capture) */ + if (strncmp(file, VIDEO_PRIMARY, strlen(VIDEO_PRIMARY)) == 0) + primary = 1; + else if (strncmp(file, VIDEO_SECONDARY, strlen(VIDEO_SECONDARY)) == 0) + primary = 0; + else + return NULL; + + if (media_in_use()) + return NULL; + + plugin = calloc(1, sizeof(*plugin)); + if (plugin == NULL) + return NULL; + + plugin->media = media_open(MEDIA_DEVICE, 1); + if (plugin->media == NULL) { + free(plugin); + return NULL; + } + + pipe = pipe_sensor_yuv(primary); + + if (pipe) + plugin->path = path_allocate(plugin->media, pipe); + + if (plugin->path) + dst_sub_module = path_destination_submodule(plugin->path); + + if (dst_sub_module) + ret = path_power_on(plugin->path, fd); + + if (ret == 0) + ret = path_connect_entities(plugin->media, plugin->path); + + plugin->fd = dst_sub_module->entity->fd; + + if (ret != 0) { + path_disconnect_entities(plugin->media, plugin->path); + path_power_off(plugin->path); + + media_close(plugin->media); + free(plugin); + plugin = NULL; + } + + return plugin; +} + +PLUGIN_HIDDEN void omap3mc_close
[libv4l-mcplugin PATCH 2/3] Add files for v4l operations
Add files with implementation of v4l ioctls. Signed-off-by: Yordan Kamenov --- operations.c | 611 ++ operations.h | 44 + 2 files changed, 655 insertions(+), 0 deletions(-) create mode 100644 operations.c create mode 100644 operations.h diff --git a/operations.c b/operations.c new file mode 100644 index 000..307785f --- /dev/null +++ b/operations.c @@ -0,0 +1,611 @@ +/* + * Copyright (C) 2011 Nokia Corporation + * + * Contact: Yordan Kamenov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "sl_list.h" +#include "operations.h" +#include "paths.h" + +#define CHECK_DST_SUBMODULE(dst_sm, error_msg) {\ + if ((dst_sm) == NULL) {\ + MC_PLUGIN_PRINTF(error_msg);\ + errno = EBADF;\ + return -1;\ + }\ +} + +int mc_vidioc_streamon(struct omap3mcplugin *plugin, unsigned long int request, ...) +{ + int ret = -1; + enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + struct sub_module *dst_sub_module = NULL; + + if (plugin->path) + dst_sub_module = path_destination_submodule(plugin->path); + + CHECK_DST_SUBMODULE(dst_sub_module, "streamon failed\n"); + + ret = SYS_IOCTL(dst_sub_module->entity->fd, VIDIOC_STREAMON, &type); + if (ret) { + int saved_err = errno; + MC_PLUGIN_PRINTF("streamon: %s\n", strerror(errno)); + errno = saved_err; + } + + return ret; +} + +int mc_vidioc_streamoff(struct omap3mcplugin *plugin, unsigned long int request, ...) +{ + int ret = -1; + enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + struct sub_module *dst_sub_module = NULL; + + if (plugin->path) + dst_sub_module = path_destination_submodule(plugin->path); + + CHECK_DST_SUBMODULE(dst_sub_module, "streamoff failed\n"); + + ret = SYS_IOCTL(dst_sub_module->entity->fd, VIDIOC_STREAMOFF, &type); + if (ret) { + int saved_err = errno; + MC_PLUGIN_PRINTF("streamoff: %s\n", strerror(errno)); + errno = saved_err; + } + + return ret; +} + +int mc_vidioc_s_fmt(struct omap3mcplugin *plugin, unsigned long int request, ...) +{ + int pix_count, res_count, found = 0, ret = -1; + enum mc_plugin_pixelformat src_pixfmt, dst_pixfmt, temp_pixfmt; + struct v4l2_rect src_res, dst_res; + const int max_rect = 10; + struct v4l2_rect res[max_rect]; + struct v4l2_format *arg; + va_list ap; + enum mc_plugin_pixelformat pixfmt; + + va_start(ap, request); + arg = va_arg(ap, struct v4l2_format *); + va_end(ap); + + pixfmt = pixel_v4l_to_mc_plugin(arg->fmt.pix.pixelformat); + + /* Check if destionation format is supported from pipeline */ + for (pix_count = 0; +MC_PLUGIN_PIX_FMT_INVALID != plugin->path->pipe->out_pixfmt[pix_count]; +pix_count++) + if (pixfmt == plugin->path->pipe->out_pixfmt[pix_count]) { + dst_pixfmt = pixfmt; + ret = 0; + break; + } + + if (ret < 0) { + MC_PLUGIN_PRINTF("Destination format not supported\n"); + errno = EINVAL; + return ret; + } + + for (pix_count = 0; +MC_PLUGIN_PIX_FMT_INVALID != plugin->path->pipe->in_pixfmt[pix_count]; +pix_count++) { + + memset(res, 0x0, sizeof(res)); + src_pixfmt = plugin->path->pipe->in_pixfmt[pix_count]; + temp_pixfmt = src_pixfmt; + + ret = path_enum_src_framesizes(plugin, &src_pixfmt, res, max_rect); + + /* Find Best capture resolution */ + for (res_count = 0; res_count < max_rect; res_count++) { + + src_res = res[res_count]; + dst_res.width = arg->fmt.pix.width; + dst_res.height = arg->fmt.pix.height; + +
[libv4l-mcplugin PATCH 1/3] Add files for media controller pipelines
Add Makefile. Add files for Media Controller pipelines initialization, configuration and destruction. Add file for list operations. Add config file. Signed-off-by: Yordan Kamenov --- Makefile | 30 ++ omap3-mc.conf | 82 + paths.c | 959 + paths.h | 64 sl_list.h | 65 5 files changed, 1200 insertions(+), 0 deletions(-) create mode 100644 Makefile create mode 100644 omap3-mc.conf create mode 100644 paths.c create mode 100644 paths.h create mode 100644 sl_list.h diff --git a/Makefile b/Makefile new file mode 100644 index 000..2b3b375 --- /dev/null +++ b/Makefile @@ -0,0 +1,30 @@ +ARCH ?= arm +KDIR ?= /usr/src/linux +LIBV4LINCDIR ?= ../../v4l-utils/lib/include/ +LIBMEDIACTLDIR ?= /usr/local/lib +CONF_INST_DIR := $(DESTDIR)/etc/libv4l2plugins +PLUGIN_INST_DIR := $(DESTDIR)/usr/lib/libv4l/plugins + +KINC := -I$(KDIR)/include -I$(KDIR)/arch/$(ARCH)/include +INC := -I$(LIBV4LINCDIR) $(KINC) +CC := $(CROSS_COMPILE)gcc + +LDFLAGS += -L$(LIBMEDIACTLDIR) -lmediactl + +CFLAGS += -O2 -Wall -fpic -I. $(INC) +OBJS = libv4l2plugin-omap3mc.o paths.o operations.o + +all: libv4l2plugin-omap3mc.so + +libv4l2plugin-omap3mc.so: $(OBJS) + $(CC) $(CFLAGS) -shared $(LDFLAGS) -o libv4l2plugin-omap3mc.so $(OBJS) +clean: + rm -f $(OBJS) libv4l2plugin-omap3mc.so + +install: libv4l2plugin-omap3mc.so + test -z "$(CONF_INST_DIR)" || mkdir -p "$(CONF_INST_DIR)" + install -m 666 omap3-mc.conf "$(CONF_INST_DIR)" + test -z "$(PLUGIN_INST_DIR)" || mkdir -p "$(PLUGIN_INST_DIR)" + install -m 755 libv4l2plugin-omap3mc.so "$(PLUGIN_INST_DIR)" + +.PHONY: clean all diff --git a/omap3-mc.conf b/omap3-mc.conf new file mode 100644 index 000..3b7947c --- /dev/null +++ b/omap3-mc.conf @@ -0,0 +1,82 @@ +# Configuration file for media controller plugin for libv4l +# +# +# Format: +# +# [primary|secondary]_path +# list of subdevice names +# end +# +# [primary|secondary]_in_pixfmt +# list of formats supported by input device +# end +# +# [primary|secondary]_out_pixfmt +# list of formats supported by output device +# end +# +# +# +# Sensors: +# jt8ev1, smiapp-001, smiapp-002, smiapp-003, smiapp-004, tcm8500md, vw6558 +# +# Subdevices: +# OMAP3 ISP CSI2a +# OMAP3 ISP CSI2a output +# OMAP3 ISP CCP2 +# OMAP3 ISP CCP2 input +# OMAP3 ISP CCDC +# OMAP3 ISP preview +# OMAP3 ISP preview output +# OMAP3 ISP resizer input +# OMAP3 ISP resizer +# OMAP3 ISP resizer output +# +# +# Formats: +# BAYER8_SBGGR, BAYER8_SGBRG, BAYER8_SGRBG, BAYER10_SGRBG, BAYER10_SRGGB, +# BAYER10_SBGGR, BAYER10_SGBRG, BAYER10DPCM8_SGRBG, YUYV, UYVY +# +# + + + +primary_path +jt8ev1 +OMAP3 ISP CSI2a +OMAP3 ISP CCDC +OMAP3 ISP preview +OMAP3 ISP resizer +OMAP3 ISP resizer output +end + +primary_in_pixfmt +BAYER10DPCM8_SGRBG +BAYER10_SGRBG +end + +primary_out_pixfmt +UYVY +end + + + +secondary_path +vw6558 +OMAP3 ISP CCP2 +OMAP3 ISP CCDC +OMAP3 ISP preview +OMAP3 ISP resizer +OMAP3 ISP resizer output +end + +secondary_in_pixfmt +BAYER10DPCM8_SGRBG +BAYER10_SGRBG +end + +secondary_out_pixfmt +UYVY +end + + diff --git a/paths.c b/paths.c new file mode 100644 index 000..bbc6cfd --- /dev/null +++ b/paths.c @@ -0,0 +1,959 @@ +/* + * Copyright (C) 2011 Nokia Corporation + * + * Contact: Yordan Kamenov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "sl_list.h" +#include "paths.h" + +#define CONFIG_FILE "/etc/libv4l2plugins/omap3-mc.conf" + +#define LINESIZE(256) +#define CHOMP(x)\ +do {\ +char *p;\ +int sz;\ +p = (x);\ +sz = strlen(p);\ +p += sz - 1;\ +if (sz) \ +while (isspace(*p)) *p-- = 0; \ +} while (0) + +/* Sections in configuration file */ +enum mc_plugin_config_sections { + CONFIG_S
[libv4l-mcplugin PATCH 0/3] Media controller plugin for libv4l2
Hi, This is the Media Controller plugin for libv4l. It uses libv4l2 plugin support which is accepted by Hans De Goede, but not yet included in mainline libv4l2: http://www.spinics.net/lists/linux-media/msg32017.html The plugin allows a traditional v4l2 applications to work with Media Controller framework. The plugin is loaded when application opens /dev/video0 and it configures the media controller and then all ioctl's by the applicatin are handled by the plugin. The plugin implements init, close and ioctl callbacks. The init callback checks it's input file descriptor and if it coresponds to /dev/video0, then the media controller is initialized and appropriate pipeline is created. The close callback deinitializes the pipeline, and closes the media device. The ioctl callback is responsible to handle ioctl calls from application by using the media controller pipeline. The plugin uses media-ctl library for media controller operations: http://git.ideasonboard.org/?p=media-ctl.git;a=summary The plugin is divided in three separate patches: * Media Controller pipelines initialization, configuration and destruction * v4l operations - uses some functionality from the first one * Plugin interface operations (init, close and ioctl) - uses functionality from first two Yordan Kamenov (3): Add files for media controller pipelines Add files for v4l operations Add libv4l2 media controller plugin interface files -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RESEND PATCH 1/1] libv4l2: Add plugin support to libv4l
A libv4l2 plugin will sit in between libv4l2 itself and the actual /dev/video device node a fd refers to. It will be called each time libv4l2 wants to do an operation (read/write/ioctl) on the actual /dev/video node in question. Signed-off-by: Yordan Kamenov --- lib/include/libv4l2-plugin.h | 36 ++ lib/include/libv4lconvert.h|5 +- lib/libv4l2/Makefile |6 +- lib/libv4l2/libv4l2-priv.h | 10 ++ lib/libv4l2/libv4l2.c | 88 ++ lib/libv4l2/v4l2-plugin.c | 158 lib/libv4l2/v4l2convert.c |9 -- lib/libv4lconvert/control/libv4lcontrol-priv.h |4 + lib/libv4lconvert/control/libv4lcontrol.c | 35 -- lib/libv4lconvert/control/libv4lcontrol.h |5 +- lib/libv4lconvert/libv4lconvert-priv.h |2 + lib/libv4lconvert/libv4lconvert.c | 34 -- utils/qv4l2/qv4l2.cpp | 17 +++- utils/qv4l2/qv4l2.h|1 + 14 files changed, 347 insertions(+), 63 deletions(-) create mode 100644 lib/include/libv4l2-plugin.h create mode 100644 lib/libv4l2/v4l2-plugin.c diff --git a/lib/include/libv4l2-plugin.h b/lib/include/libv4l2-plugin.h new file mode 100644 index 000..158c0c2 --- /dev/null +++ b/lib/include/libv4l2-plugin.h @@ -0,0 +1,36 @@ +/* +* Copyright (C) 2010 Nokia Corporation + +* This program 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. +* +* This program 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 this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __LIBV4L2_PLUGIN_H +#define __LIBV4L2_PLUGIN_H + +#include + +/* Structure libv4l2_dev_ops holds the calls from libv4ls to video nodes. + They can be normal open/close/ioctl etc. or any of them may be replaced + with a callback by a loaded plugin. +*/ + +struct libv4l2_dev_ops { +void * (*init)(int fd); +void (*close)(void *dev_ops_priv); +int (*ioctl)(void *dev_ops_priv, int fd, unsigned long int request, void *arg); +ssize_t (*read)(void *dev_ops_priv, int fd, void *buffer, size_t n); +}; + +#endif diff --git a/lib/include/libv4lconvert.h b/lib/include/libv4lconvert.h index 0264290..351142e 100644 --- a/lib/include/libv4lconvert.h +++ b/lib/include/libv4lconvert.h @@ -38,6 +38,8 @@ #include +#include "libv4l2-plugin.h" + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -50,7 +52,8 @@ extern "C" { struct v4lconvert_data; -LIBV4L_PUBLIC struct v4lconvert_data *v4lconvert_create(int fd); +LIBV4L_PUBLIC struct v4lconvert_data *v4lconvert_create(int fd, + void *dev_ops_priv, struct libv4l2_dev_ops *dev_ops); LIBV4L_PUBLIC void v4lconvert_destroy(struct v4lconvert_data *data); /* When doing flipping / rotating / video-processing, only supported diff --git a/lib/libv4l2/Makefile b/lib/libv4l2/Makefile index d78632f..f8b3714 100644 --- a/lib/libv4l2/Makefile +++ b/lib/libv4l2/Makefile @@ -1,12 +1,12 @@ override CPPFLAGS += -I../include -fvisibility=hidden -LIBS_libv4l2 = -lpthread +LIBS_libv4l2 = -lpthread -ldl -V4L2_OBJS = libv4l2.o log.o +V4L2_OBJS = libv4l2.o v4l2-plugin.o log.o V4L2CONVERT = v4l2convert.so V4L2CONVERT_O = v4l2convert.o libv4l2.so TARGETS = $(V4L2_LIB) libv4l2.pc -INCLUDES = ../include/libv4l2.h +INCLUDES = ../include/libv4l2.h ../include/libv4l2-plugin.h ifeq ($(LINKTYPE),static) V4L2_LIB = libv4l2.a diff --git a/lib/libv4l2/libv4l2-priv.h b/lib/libv4l2/libv4l2-priv.h index 46d6103..d06a508 100644 --- a/lib/libv4l2/libv4l2-priv.h +++ b/lib/libv4l2/libv4l2-priv.h @@ -85,8 +85,18 @@ struct v4l2_dev_info { /* buffer when doing conversion and using read() for read() */ int readbuf_size; unsigned char *readbuf; + struct libv4l2_dev_ops *dev_ops; + /* plugin info */ + void *plugin_library; + void *dev_ops_priv; }; +void v4l2_plugin_init(int fd, void **plugin_lib_ret, void **plugin_priv_ret, + struct libv4l2_dev_ops **dev_ops_ret); +void v4l2_plugin_cleanup(void *plugin_priv, void *plugin_lib, + struct libv4l2_dev_ops *dev_ops); + + /* From log.c */ void v4l2_log_ioctl(unsigned long int request, void *arg, int result); di
[PATCH v4 1/1] libv4l: Add plugin support to libv4l
A libv4l2 plugin will sit in between libv4l2 itself and the actual /dev/video device node a fd refers to. It will be called each time libv4l2 wants to do an operation (read/write/ioctl) on the actual /dev/video node in question. Signed-off-by: Yordan Kamenov --- lib/include/libv4l2-plugin.h | 36 ++ lib/include/libv4lconvert.h|5 +- lib/libv4l2/Makefile |6 +- lib/libv4l2/libv4l2-priv.h | 10 ++ lib/libv4l2/libv4l2.c | 88 ++ lib/libv4l2/v4l2-plugin.c | 158 lib/libv4l2/v4l2convert.c |9 -- lib/libv4lconvert/control/libv4lcontrol-priv.h |4 + lib/libv4lconvert/control/libv4lcontrol.c | 35 -- lib/libv4lconvert/control/libv4lcontrol.h |5 +- lib/libv4lconvert/libv4lconvert-priv.h |2 + lib/libv4lconvert/libv4lconvert.c | 34 -- utils/qv4l2/qv4l2.cpp | 17 +++- utils/qv4l2/qv4l2.h|1 + 14 files changed, 347 insertions(+), 63 deletions(-) create mode 100644 lib/include/libv4l2-plugin.h create mode 100644 lib/libv4l2/v4l2-plugin.c diff --git a/lib/include/libv4l2-plugin.h b/lib/include/libv4l2-plugin.h new file mode 100644 index 000..158c0c2 --- /dev/null +++ b/lib/include/libv4l2-plugin.h @@ -0,0 +1,36 @@ +/* +* Copyright (C) 2010 Nokia Corporation + +* This program 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. +* +* This program 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 this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __LIBV4L2_PLUGIN_H +#define __LIBV4L2_PLUGIN_H + +#include + +/* Structure libv4l2_dev_ops holds the calls from libv4ls to video nodes. + They can be normal open/close/ioctl etc. or any of them may be replaced + with a callback by a loaded plugin. +*/ + +struct libv4l2_dev_ops { +void * (*init)(int fd); +void (*close)(void *dev_ops_priv); +int (*ioctl)(void *dev_ops_priv, int fd, unsigned long int request, void *arg); +ssize_t (*read)(void *dev_ops_priv, int fd, void *buffer, size_t n); +}; + +#endif diff --git a/lib/include/libv4lconvert.h b/lib/include/libv4lconvert.h index 0264290..351142e 100644 --- a/lib/include/libv4lconvert.h +++ b/lib/include/libv4lconvert.h @@ -38,6 +38,8 @@ #include +#include "libv4l2-plugin.h" + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -50,7 +52,8 @@ extern "C" { struct v4lconvert_data; -LIBV4L_PUBLIC struct v4lconvert_data *v4lconvert_create(int fd); +LIBV4L_PUBLIC struct v4lconvert_data *v4lconvert_create(int fd, + void *dev_ops_priv, struct libv4l2_dev_ops *dev_ops); LIBV4L_PUBLIC void v4lconvert_destroy(struct v4lconvert_data *data); /* When doing flipping / rotating / video-processing, only supported diff --git a/lib/libv4l2/Makefile b/lib/libv4l2/Makefile index d78632f..f8b3714 100644 --- a/lib/libv4l2/Makefile +++ b/lib/libv4l2/Makefile @@ -1,12 +1,12 @@ override CPPFLAGS += -I../include -fvisibility=hidden -LIBS_libv4l2 = -lpthread +LIBS_libv4l2 = -lpthread -ldl -V4L2_OBJS = libv4l2.o log.o +V4L2_OBJS = libv4l2.o v4l2-plugin.o log.o V4L2CONVERT = v4l2convert.so V4L2CONVERT_O = v4l2convert.o libv4l2.so TARGETS = $(V4L2_LIB) libv4l2.pc -INCLUDES = ../include/libv4l2.h +INCLUDES = ../include/libv4l2.h ../include/libv4l2-plugin.h ifeq ($(LINKTYPE),static) V4L2_LIB = libv4l2.a diff --git a/lib/libv4l2/libv4l2-priv.h b/lib/libv4l2/libv4l2-priv.h index 46d6103..d06a508 100644 --- a/lib/libv4l2/libv4l2-priv.h +++ b/lib/libv4l2/libv4l2-priv.h @@ -85,8 +85,18 @@ struct v4l2_dev_info { /* buffer when doing conversion and using read() for read() */ int readbuf_size; unsigned char *readbuf; + struct libv4l2_dev_ops *dev_ops; + /* plugin info */ + void *plugin_library; + void *dev_ops_priv; }; +void v4l2_plugin_init(int fd, void **plugin_lib_ret, void **plugin_priv_ret, + struct libv4l2_dev_ops **dev_ops_ret); +void v4l2_plugin_cleanup(void *plugin_priv, void *plugin_lib, + struct libv4l2_dev_ops *dev_ops); + + /* From log.c */ void v4l2_log_ioctl(unsigned long int request, void *arg, int result); di
Froe 1678f1f41284ad9665de8717b7b8be117ddf9596 Mon Sep 17 00:00:00 2001
Hi Hans, here is the fourth version of plugin support for libv4l2. Changes in v4: * Make close() callback void * Move plugin clean up where the actual fd gets closed * Use SYS_FOO in default device operations instead of syscall() -- Changes in v3: * Pass opened fd to the plugin instead of filename * Plugin private data is returned by init call and is passed as argument in ioctl/read/close (remove libv4l2_set/get_plugindata functions) * Plugin do not handle mmap/munmap -- Changes in v2: * Remove calls of v4l2_plugin_foo functions in the beginning of coresponding v4l2_foo functions and instead replace SYS_FOO calls. * Add to v4l2_dev_info device operation structure which can hold plugin callbacks or dyrect syscall(SYS_foo, ...) calls. * Under libv4lconvert also replace SYS_FOO cals with device operations. This required also to add dev_ops field to v4lconvert_data and v4lcontrol_data. --- v1: Here is initial version of plugin support for libv4l, based on your RFC. It is provided by functions v4l2_plugin_[open,close,etc]. When open() is called libv4l dlopens files in /usr/lib/libv4l/plugins 1 at a time and call open() callback passing through the applications parameters unmodified. If a plugin is relevant for the specified device node, it can indicate so by returning a value other then -1 (the actual file descriptor). As soon as a plugin returns another value then -1 plugin loading stops and information about it (fd and corresponding library handle) is stored. For each function v4l2_[ioctl,read,close,etc] is called corresponding v4l2_plugin_* function which looks if there is loaded plugin for that file and call it's callbacks. v4l2_plugin_* functions indicate by their first argument if plugin was used, and if it was not then v4l2_* functions proceed Yordan Kamenov (1): Add plugin support to libv4l lib/include/libv4l2-plugin.h | 36 ++ lib/include/libv4lconvert.h|5 +- lib/libv4l2/Makefile |6 +- lib/libv4l2/libv4l2-priv.h | 10 ++ lib/libv4l2/libv4l2.c | 88 ++ lib/libv4l2/v4l2-plugin.c | 158 lib/libv4l2/v4l2convert.c |9 -- lib/libv4lconvert/control/libv4lcontrol-priv.h |4 + lib/libv4lconvert/control/libv4lcontrol.c | 35 -- lib/libv4lconvert/control/libv4lcontrol.h |5 +- lib/libv4lconvert/libv4lconvert-priv.h |2 + lib/libv4lconvert/libv4lconvert.c | 34 -- utils/qv4l2/qv4l2.cpp | 17 +++- utils/qv4l2/qv4l2.h|1 + 14 files changed, 347 insertions(+), 63 deletions(-) create mode 100644 lib/include/libv4l2-plugin.h create mode 100644 lib/libv4l2/v4l2-plugin.c -- 1.7.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/1 v3] libv4l: Add plugin support to libv4l
Hans de Goede wrote: Hi, Hi Hans, Thanks for your comments. First of all my apologies for taking so long to get around to reviewing this. Over all it looks good, I've put some small remarks inline, if you fix these I can merge this. I wonder though, given the recent limbo around Nokia's change of focus, if there are any plans to actually move forward with a plugin using this... ? The reason I'm asking is that adding the plugin framework if nothing is going to use it seems a bit senseless. We are working on a "media controller" plugin which allows a traditional v4l2 application to work with Media Controller framework. The idea is when the application opens /dev/video0, then the plugin initializes media controller and creates appropriate pipeline, after that the plugin redirects all ioctl's from the application to this pipeline and on close call the pipeline is deinitialized. Regards, Hans On 02/14/2011 12:02 PM, Yordan Kamenov wrote: [snip] diff --git a/lib/libv4l2/v4l2convert.c b/lib/libv4l2/v4l2convert.c index e251085..03f34ad 100644 --- a/lib/libv4l2/v4l2convert.c +++ b/lib/libv4l2/v4l2convert.c @@ -46,7 +46,6 @@ LIBV4L_PUBLIC int open(const char *file, int oflag, ...) { int fd; -struct v4l2_capability cap; int v4l_device = 0; /* check if we're opening a video4linux2 device */ @@ -76,14 +75,6 @@ LIBV4L_PUBLIC int open(const char *file, int oflag, ...) if (fd == -1 || !v4l_device) return fd; -/* check that this is an v4l2 device, libv4l2 only supports v4l2 devices */ -if (SYS_IOCTL(fd, VIDIOC_QUERYCAP,&cap)) -return fd; - -/* libv4l2 only adds functionality to capture capable devices */ -if (!(cap.capabilities& V4L2_CAP_VIDEO_CAPTURE)) -return fd; - /* Try to Register with libv4l2 (in case of failure pass the fd to the application as is) */ v4l2_fd_open(fd, 0); Hmm, why are you removing this check ? In case of above example of media controller plugin when the application opens /dev/video0, then this plugin should be used. But in media controller framework /dev/video0 file might correspond to a subdevice which is not a capture device and this fd will not be registered in libv4l2 at all. Regards Yordan -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/1 v3] libv4l: Add plugin support
Hi Hans, any comments on that? Regards Yordan Yordan Kamenov wrote: Hi Hans, here is third version of plugin support for libv4l2. Changes in v3: * Pass opened fd to the plugin instead of filename * Plugin private data is returned by init call and is passed as argument in ioctl/read/close (remove libv4l2_set/get_plugindata functions) * Plugin do not handle mmap/munmap -- Changes in v2: * Remove calls of v4l2_plugin_foo functions in the beginning of coresponding v4l2_foo functions and instead replace SYS_FOO calls. * Add to v4l2_dev_info device operation structure which can hold plugin callbacks or dyrect syscall(SYS_foo, ...) calls. * Under libv4lconvert also replace SYS_FOO cals with device operations. This required also to add dev_ops field to v4lconvert_data and v4lcontrol_data. --- v1: Here is initial version of plugin support for libv4l, based on your RFC. It is provided by functions v4l2_plugin_[open,close,etc]. When open() is called libv4l dlopens files in /usr/lib/libv4l/plugins 1 at a time and call open() callback passing through the applications parameters unmodified. If a plugin is relevant for the specified device node, it can indicate so by returning a value other then -1 (the actual file descriptor). As soon as a plugin returns another value then -1 plugin loading stops and information about it (fd and corresponding library handle) is stored. For each function v4l2_[ioctl,read,close,etc] is called corresponding v4l2_plugin_* function which looks if there is loaded plugin for that file and call it's callbacks. v4l2_plugin_* functions indicate by their first argument if plugin was used, and if it was not then v4l2_* functions proceed with their usual behavior. Yordan Kamenov (1): libv4l: Add plugin support to libv4l lib/include/libv4l2-plugin.h | 36 ++ lib/include/libv4lconvert.h|5 +- lib/libv4l2/Makefile |4 +- lib/libv4l2/libv4l2-priv.h | 10 ++ lib/libv4l2/libv4l2.c | 90 ++ lib/libv4l2/v4l2-plugin.c | 160 lib/libv4l2/v4l2convert.c |9 -- lib/libv4lconvert/control/libv4lcontrol-priv.h |4 + lib/libv4lconvert/control/libv4lcontrol.c | 35 -- lib/libv4lconvert/control/libv4lcontrol.h |5 +- lib/libv4lconvert/libv4lconvert-priv.h |2 + lib/libv4lconvert/libv4lconvert.c | 34 -- 12 files changed, 333 insertions(+), 61 deletions(-) create mode 100644 lib/include/libv4l2-plugin.h create mode 100644 lib/libv4l2/v4l2-plugin.c -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/1 v3] libv4l: Add plugin support to libv4l
A libv4l2 plugin will sit in between libv4l2 itself and the actual /dev/video device node a fd refers to. It will be called each time libv4l2 wants to do an operation (read/write/ioctl) on the actual /dev/video node in question. Signed-off-by: Yordan Kamenov --- lib/include/libv4l2-plugin.h | 36 ++ lib/include/libv4lconvert.h|5 +- lib/libv4l2/Makefile |4 +- lib/libv4l2/libv4l2-priv.h | 10 ++ lib/libv4l2/libv4l2.c | 90 ++ lib/libv4l2/v4l2-plugin.c | 160 lib/libv4l2/v4l2convert.c |9 -- lib/libv4lconvert/control/libv4lcontrol-priv.h |4 + lib/libv4lconvert/control/libv4lcontrol.c | 35 -- lib/libv4lconvert/control/libv4lcontrol.h |5 +- lib/libv4lconvert/libv4lconvert-priv.h |2 + lib/libv4lconvert/libv4lconvert.c | 34 -- 12 files changed, 333 insertions(+), 61 deletions(-) create mode 100644 lib/include/libv4l2-plugin.h create mode 100644 lib/libv4l2/v4l2-plugin.c diff --git a/lib/include/libv4l2-plugin.h b/lib/include/libv4l2-plugin.h new file mode 100644 index 000..5cb666a --- /dev/null +++ b/lib/include/libv4l2-plugin.h @@ -0,0 +1,36 @@ +/* +* Copyright (C) 2010 Nokia Corporation + +* This program 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. +* +* This program 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 this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __LIBV4L2_PLUGIN_H +#define __LIBV4L2_PLUGIN_H + +#include + +/* Structure libv4l2_dev_ops holds the calls from libv4ls to video nodes. + They can be normal open/close/ioctl etc. or any of them may be replaced + with a callback by a loaded plugin. +*/ + +struct libv4l2_dev_ops { +void * (*init)(int fd); +int (*close)(void *dev_ops_priv); +int (*ioctl)(void *dev_ops_priv, int fd, unsigned long int request, void *arg); +ssize_t (*read)(void *dev_ops_priv, int fd, void *buffer, size_t n); +}; + +#endif diff --git a/lib/include/libv4lconvert.h b/lib/include/libv4lconvert.h index 0264290..351142e 100644 --- a/lib/include/libv4lconvert.h +++ b/lib/include/libv4lconvert.h @@ -38,6 +38,8 @@ #include +#include "libv4l2-plugin.h" + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -50,7 +52,8 @@ extern "C" { struct v4lconvert_data; -LIBV4L_PUBLIC struct v4lconvert_data *v4lconvert_create(int fd); +LIBV4L_PUBLIC struct v4lconvert_data *v4lconvert_create(int fd, + void *dev_ops_priv, struct libv4l2_dev_ops *dev_ops); LIBV4L_PUBLIC void v4lconvert_destroy(struct v4lconvert_data *data); /* When doing flipping / rotating / video-processing, only supported diff --git a/lib/libv4l2/Makefile b/lib/libv4l2/Makefile index d78632f..eb1c019 100644 --- a/lib/libv4l2/Makefile +++ b/lib/libv4l2/Makefile @@ -1,8 +1,8 @@ override CPPFLAGS += -I../include -fvisibility=hidden -LIBS_libv4l2 = -lpthread +LIBS_libv4l2 = -lpthread -ldl -V4L2_OBJS = libv4l2.o log.o +V4L2_OBJS = libv4l2.o v4l2-plugin.o log.o V4L2CONVERT = v4l2convert.so V4L2CONVERT_O = v4l2convert.o libv4l2.so TARGETS = $(V4L2_LIB) libv4l2.pc diff --git a/lib/libv4l2/libv4l2-priv.h b/lib/libv4l2/libv4l2-priv.h index 46d6103..d06a508 100644 --- a/lib/libv4l2/libv4l2-priv.h +++ b/lib/libv4l2/libv4l2-priv.h @@ -85,8 +85,18 @@ struct v4l2_dev_info { /* buffer when doing conversion and using read() for read() */ int readbuf_size; unsigned char *readbuf; + struct libv4l2_dev_ops *dev_ops; + /* plugin info */ + void *plugin_library; + void *dev_ops_priv; }; +void v4l2_plugin_init(int fd, void **plugin_lib_ret, void **plugin_priv_ret, + struct libv4l2_dev_ops **dev_ops_ret); +void v4l2_plugin_cleanup(void *plugin_priv, void *plugin_lib, + struct libv4l2_dev_ops *dev_ops); + + /* From log.c */ void v4l2_log_ioctl(unsigned long int request, void *arg, int result); diff --git a/lib/libv4l2/libv4l2.c b/lib/libv4l2/libv4l2.c index ab85ea7..2b717a8 100644 --- a/lib/libv4l2/libv4l2.c +++ b/lib/libv4l2/libv4l2.c @@ -67,6 +67,7 @@ #include #include "libv4l2.h" #include "libv4l2-priv.h" +#include "libv4l2-plugin.h&quo
[PATCH 0/1 v3] libv4l: Add plugin support
Hi Hans, here is third version of plugin support for libv4l2. Changes in v3: * Pass opened fd to the plugin instead of filename * Plugin private data is returned by init call and is passed as argument in ioctl/read/close (remove libv4l2_set/get_plugindata functions) * Plugin do not handle mmap/munmap -- Changes in v2: * Remove calls of v4l2_plugin_foo functions in the beginning of coresponding v4l2_foo functions and instead replace SYS_FOO calls. * Add to v4l2_dev_info device operation structure which can hold plugin callbacks or dyrect syscall(SYS_foo, ...) calls. * Under libv4lconvert also replace SYS_FOO cals with device operations. This required also to add dev_ops field to v4lconvert_data and v4lcontrol_data. --- v1: Here is initial version of plugin support for libv4l, based on your RFC. It is provided by functions v4l2_plugin_[open,close,etc]. When open() is called libv4l dlopens files in /usr/lib/libv4l/plugins 1 at a time and call open() callback passing through the applications parameters unmodified. If a plugin is relevant for the specified device node, it can indicate so by returning a value other then -1 (the actual file descriptor). As soon as a plugin returns another value then -1 plugin loading stops and information about it (fd and corresponding library handle) is stored. For each function v4l2_[ioctl,read,close,etc] is called corresponding v4l2_plugin_* function which looks if there is loaded plugin for that file and call it's callbacks. v4l2_plugin_* functions indicate by their first argument if plugin was used, and if it was not then v4l2_* functions proceed with their usual behavior. Yordan Kamenov (1): libv4l: Add plugin support to libv4l lib/include/libv4l2-plugin.h | 36 ++ lib/include/libv4lconvert.h|5 +- lib/libv4l2/Makefile |4 +- lib/libv4l2/libv4l2-priv.h | 10 ++ lib/libv4l2/libv4l2.c | 90 ++ lib/libv4l2/v4l2-plugin.c | 160 lib/libv4l2/v4l2convert.c |9 -- lib/libv4lconvert/control/libv4lcontrol-priv.h |4 + lib/libv4lconvert/control/libv4lcontrol.c | 35 -- lib/libv4lconvert/control/libv4lcontrol.h |5 +- lib/libv4lconvert/libv4lconvert-priv.h |2 + lib/libv4lconvert/libv4lconvert.c | 34 -- 12 files changed, 333 insertions(+), 61 deletions(-) create mode 100644 lib/include/libv4l2-plugin.h create mode 100644 lib/libv4l2/v4l2-plugin.c -- 1.7.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/1 v2] libv4l: Add plugin support
Hi Hans, here is second version of plugin support for libv4l2. Changes in v2: * Remove calls of v4l2_plugin_foo functions in the beginning of coresponding v4l2_foo functions and instead replace SYS_FOO calls. * Add to v4l2_dev_info device operation structure which can hold plugin callbacks or dyrect syscall(SYS_foo, ...) calls. * Under libv4lconvert also replace SYS_FOO cals with device operations. This required also to add dev_ops field to v4lconvert_data and v4lcontrol_data. --- v1: Here is initial version of plugin support for libv4l, based on your RFC. It is provided by functions v4l2_plugin_[open,close,etc]. When open() is called libv4l dlopens files in /usr/lib/libv4l/plugins 1 at a time and call open() callback passing through the applications parameters unmodified. If a plugin is relevant for the specified device node, it can indicate so by returning a value other then -1 (the actual file descriptor). As soon as a plugin returns another value then -1 plugin loading stops and information about it (fd and corresponding library handle) is stored. For each function v4l2_[ioctl,read,close,etc] is called corresponding v4l2_plugin_* function which looks if there is loaded plugin for that file and call it's callbacks. v4l2_plugin_* functions indicate by their first argument if plugin was used, and if it was not then v4l2_* functions proceed with their usual behavior. Yordan Kamenov (1): Add plugin support to libv4l lib/include/libv4l2-plugin.h | 43 +++ lib/include/libv4l2.h |4 +- lib/include/libv4lconvert.h|5 +- lib/libv4l1/libv4l1.c |2 +- lib/libv4l2/Makefile |4 +- lib/libv4l2/libv4l2-priv.h | 24 ++ lib/libv4l2/libv4l2.c | 128 +++--- lib/libv4l2/v4l2-plugin.c | 344 lib/libv4l2/v4l2convert.c | 23 ++- lib/libv4lconvert/control/libv4lcontrol-priv.h |3 + lib/libv4lconvert/control/libv4lcontrol.c | 26 +- lib/libv4lconvert/control/libv4lcontrol.h |5 +- lib/libv4lconvert/libv4lconvert-priv.h |1 + lib/libv4lconvert/libv4lconvert.c | 25 +- 14 files changed, 573 insertions(+), 64 deletions(-) create mode 100644 lib/include/libv4l2-plugin.h create mode 100644 lib/libv4l2/v4l2-plugin.c -- 1.7.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/1 v2] Add plugin support to libv4l
A libv4l2 plugin will sit in between libv4l2 itself and the actual /dev/video device node a fd refers to. It will be called each time libv4l2 wants to do an operation (read/write/ioctl/mmap/munmap) on the actual /dev/video node in question. Signed-off-by: Yordan Kamenov --- lib/include/libv4l2-plugin.h | 43 +++ lib/include/libv4l2.h |4 +- lib/include/libv4lconvert.h|5 +- lib/libv4l1/libv4l1.c |2 +- lib/libv4l2/Makefile |4 +- lib/libv4l2/libv4l2-priv.h | 24 ++ lib/libv4l2/libv4l2.c | 128 +++--- lib/libv4l2/v4l2-plugin.c | 344 lib/libv4l2/v4l2convert.c | 23 ++- lib/libv4lconvert/control/libv4lcontrol-priv.h |3 + lib/libv4lconvert/control/libv4lcontrol.c | 26 +- lib/libv4lconvert/control/libv4lcontrol.h |5 +- lib/libv4lconvert/libv4lconvert-priv.h |1 + lib/libv4lconvert/libv4lconvert.c | 25 +- 14 files changed, 573 insertions(+), 64 deletions(-) create mode 100644 lib/include/libv4l2-plugin.h create mode 100644 lib/libv4l2/v4l2-plugin.c diff --git a/lib/include/libv4l2-plugin.h b/lib/include/libv4l2-plugin.h new file mode 100644 index 000..3971735 --- /dev/null +++ b/lib/include/libv4l2-plugin.h @@ -0,0 +1,43 @@ +/* +* Copyright (C) 2010 Nokia Corporation + +* This program 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. +* +* This program 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 this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __LIBV4L2_PLUGIN_H +#define __LIBV4L2_PLUGIN_H + +#include + +/* Structure libv4l2_dev_ops holds the calls from libv4ls to video nodes. + They can be normal open/clode/ioctl etc. or any of them may be replaced + with a callback by a loaded plugin. +*/ + +struct libv4l2_dev_ops { + int (*open)(const char *file, int oflag, mode_t mode); + int (*close)(int fd); + int (*ioctl)(int fd, unsigned long int request, void *arg); + ssize_t (*read)(int fd, void *buffer, size_t n); + void *(*mmap)(void *start, size_t length, int prot, int flags, + int fd, int64_t offset); + int (*munmap)(void *_start, size_t length); +}; + +/* Plugin utility functions */ +void libv4l2_set_plugindata(int fd, void *plugin_data); +void *libv4l2_get_plugindata(int fd); + +#endif diff --git a/lib/include/libv4l2.h b/lib/include/libv4l2.h index cc0ab4a..5db000f 100644 --- a/lib/include/libv4l2.h +++ b/lib/include/libv4l2.h @@ -22,6 +22,7 @@ #include #include #include +#include "libv4l2-plugin.h" #ifdef __cplusplus extern "C" { @@ -106,7 +107,8 @@ LIBV4L_PUBLIC int v4l2_get_control(int fd, int cid); Returns fd on success, -1 if the fd is not suitable for use through libv4l2 (note the fd is left open in this case). */ -LIBV4L_PUBLIC int v4l2_fd_open(int fd, int v4l2_flags); +LIBV4L_PUBLIC int v4l2_fd_open(int fd, struct libv4l2_dev_ops *dev_ops, + int v4l2_flags); #ifdef __cplusplus } diff --git a/lib/include/libv4lconvert.h b/lib/include/libv4lconvert.h index 0264290..f210b2d 100644 --- a/lib/include/libv4lconvert.h +++ b/lib/include/libv4lconvert.h @@ -38,6 +38,8 @@ #include +#include "libv4l2-plugin.h" + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -50,7 +52,8 @@ extern "C" { struct v4lconvert_data; -LIBV4L_PUBLIC struct v4lconvert_data *v4lconvert_create(int fd); +LIBV4L_PUBLIC struct v4lconvert_data *v4lconvert_create(int fd, + struct libv4l2_dev_ops *dev_ops); LIBV4L_PUBLIC void v4lconvert_destroy(struct v4lconvert_data *data); /* When doing flipping / rotating / video-processing, only supported diff --git a/lib/libv4l1/libv4l1.c b/lib/libv4l1/libv4l1.c index fee0fb7..180db0e 100644 --- a/lib/libv4l1/libv4l1.c +++ b/lib/libv4l1/libv4l1.c @@ -342,7 +342,7 @@ int v4l1_open(const char *file, int oflag, ...) /* Register with libv4l2, as we use that todo format conversion and read() emulation for us */ - if (v4l2_fd_open(fd, 0) == -1) { + if (v4l2_fd_open(fd, NULL, 0) == -1) { int saved_err = errno; SYS_CLOSE(fd); diff --git a/lib/libv4l2/Makefile b/lib/libv4l2/Makefi
Re: [PATCH 1/1] Add plugin support to libv4l
Hi Hans, Thanks for your comments. Hans de Goede wrote: Hi, First of all many thanks for working on this! I've several remarks which I would like to see addressed before merging this. Since most remarks are rather high level remarks I've opted to just make a bulleted list of them rather then inserting them inline. * The biggest problem with your current implementation is that for each existing libv4l2_foo function you check if there is a plugin attached to the fd passed in and if that plugin wants to handle the call. Now lets assume that there is a plugin and that it wants to handle all calls. That means that you've now effectively replaced all libv4l2_foo calls with calling the corresponding foo function from the plugin and returning its result. This means that for this fd / device you've achieved the same result as completely replacing libv4l2.so.0 with a new library containing the plugin code. IOW you've not placed then plugin between libv4l2 and the device (as intended) but completely short-circuited / replaced libv4l2. This means for example for a device which only supports yuv output, that libv4l2 will no longer do format emulation and conversion and an app which only supports devices which deliver rgb data will no longer work. To actually place the plugin between libv4l2 (and libv4lconvert) and the device, you should replace all the SYS_FOO calls in libv4l2. The SYS_FOO calls are the calls to the actual device, so be replacing those with calls to the plugin you actual place the plugin between libv4l and the device as intended. I agree with that, currently the plugin can replace the libv4l2, but if we replace SYS_FOO calls it will actually sit between library and the video node. I will do that. * Currently you add a loop much like the one in the v4l2_get_index function to each libv4l2_plugin function. Basically you add an array of v4l2_plugin_info structs in libv4l2-plugin. Which gets searched by fd, much like the v4l2_dev_info struct array. Including needing similar locking. I would like you to instead just store the plugin info for a certain fd directly into the v4l2_dev_info struct. This way the separate array, looping and locking can go away. I have put separate array, because the array of v4l2_dev_info is declared static in libv4l2.c and is not visible to v4l2-plugin.c (I did't want to change it's declaration). But with changes that you suggest below, there is no problem to add plugin data to v4l2_dev_info. * Next I would also like to see all the libv4l2_plugin_foo functions except for libv4l2_plugin_open go away. Instead libv4l2.c can call the plugin functions directly. Let me try to explain what I have in mind. Lets say we store the struct libv4l2_plugin_data pointer to the active plugin in the v4l2_dev_info struct and name it dev_ops (short for device operations). Then we can replace all SYS_FOO calls inside libv4l2 (except the ones were v4l2_get_index returns -1), with a call to the relevant devop functions, for example: result = SYS_IOCTL(devices[index].fd, VIDIOC_REQBUFS, req); Would become: result = devices[index].dev_ops->v4l2_plugin_ioctl( devices[index].fd, VIDIOC_REQBUFS, req); Note that the plugin_used parameter of the v4l2_plugin_ioctl is gone, it should simply do a normal SYS_IOCTL and return the return value of that if it is not interested in intercepting the ioctl (you could move the definition of the SYS_FOO macros to libv4l2-plugin.h to make them availables to plugins). Also I think it would be better to rename the function pointers inside the libv4l2_plugin_data struct from v4l2_plugin_foo to just foo, so that the above code would become: result = devices[index].dev_ops->v4l2_plugin_ioctl( devices[index].fd, VIDIOC_REQBUFS, req); * The above means that need to always have a dev_ops pointer, so we need to have a default_dev_ops struct to use when no plugin wants to talk to the device. Ok, I will replace SYS_FOO calls with dev_ops structure. * You've put the v4l2_plugin_foo functions (of which only v4l2_plugin_foo will remain in my vision) in lib/include/libv4l2.h I don't think these functions should be public, their prototypes should be moved to lib/libv4l2/libv4l2-priv.h, and they should not be declared LIBV4L_PUBLIC. * There is one special case in all this, files under libv4lconvert also use SYS_IOCTL in various places. Since this now need to go through the plugin we need to take some special measures here. There are 2 options: 1) Break the libv4lconvert ABI (very few programs use it) and pass a struct libv4l2_plugin_data pointer to the v4lconvert_create function. *And* export the default_dev_ops struct from libv4l2. 2) Add a libv4l2_raw_ioctl method, which just gets the index and then does devices[index].dev_ops->v4l2_plugin_ioctl Except that this is not really an option as libv4lconvert should not depend
[PATCH 1/1] Add plugin support to libv4l
A libv4l2 plugin will sit in between libv4l2 itself and the actual /dev/video device node a fd refers to. It will be called each time libv4l2 wants to do an operation (read/write/ioctl/mmap/munmap) on the actual /dev/video node in question. Signed-off-by: Yordan Kamenov --- lib/include/libv4l2-plugin.h | 74 lib/include/libv4l2.h| 15 ++ lib/libv4l2/Makefile |4 +- lib/libv4l2/libv4l2-priv.h |9 + lib/libv4l2/libv4l2.c| 56 ++- lib/libv4l2/v4l2-plugin.c| 399 ++ lib/libv4l2/v4l2convert.c| 20 ++- 7 files changed, 568 insertions(+), 9 deletions(-) create mode 100644 lib/include/libv4l2-plugin.h create mode 100644 lib/libv4l2/v4l2-plugin.c diff --git a/lib/include/libv4l2-plugin.h b/lib/include/libv4l2-plugin.h new file mode 100644 index 000..881b55d --- /dev/null +++ b/lib/include/libv4l2-plugin.h @@ -0,0 +1,74 @@ +/* +* Copyright (C) 2010 Nokia Corporation + +* This program 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. +* +* This program 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 this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __LIBV4L2_PLUGIN_H +#define __LIBV4L2_PLUGIN_H + +#include + +/* A libv4l2 plugin will sit in between libv4l2 itself and the + actual /dev/video device node a fd refers to. It will be called each time + libv4l2 wants to do an operation (read/write/ioctl/mmap/munmap) on the + actual /dev/video node in question. When called the plugin can then choose + to do one of the following: + 1. Pass the call unmodified to the fd, and return the return value unmodifed + 2. Modify some arguments in the call and pass it through + 3. Modify the return(ed) value(s) of a passed through call + 4. Not do any operation on the fd at all but instead completely fake it + (which opens the possibility for "fake" v4l devices) + + libv4l2 plugins should *never* use any global variables. All data should be + bound to the specific fd to which the plugin is bound. This ensures that for + example a plugin for a specific type of usb webcam will also work when 2 + identical cameras are plugged into a system (and both are used from the same + process). + + A libv4l2 plugin can register plugin private data using: + void libv4l2_set_plugindata(int fd, void *plugin_data); + + And can get this data out of libv4l2 again inside a callback using: + void *libv4l2_get_plugindata(int fd); + + Note that a plugin should call libv4l2_set_plugindata only once per fd ! + Calling it a second time will overwrite the previous value. The logical + place to use libv4l2_set_plugindata is from the plugin's open callback. +*/ + +/* Plugin callback function struct */ +struct libv4l2_plugin_data { + int (*open)(const char *file, int oflag, ...); + int (*close)(int fd); + int (*ioctl)(int fd, unsigned long int request, ...); + ssize_t (*read)(int fd, void *buffer, size_t n); + void *(*mmap)(void *start, size_t length, int prot, int flags, + int fd, int64_t offset); + /* Note as munmap has no fd argument, defining a callback for munmap + will result in it getting called for *any* call to v4l2_munmap. + So if a plugin defines a callback for munmap (because for + example it returns fake mmap buffers from its mmap callback). + Then it must keep track of the addresses at which these buffers + live and their size and check the munmap arguments to see if the + munmap call was meant for it. */ + int (*munmap)(void *_start, size_t length); +}; + +/* Plugin utility functions */ +void libv4l2_set_plugindata(int fd, void *plugin_data); +void *libv4l2_get_plugindata(int fd); + +#endif diff --git a/lib/include/libv4l2.h b/lib/include/libv4l2.h index cc0ab4a..2123546 100644 --- a/lib/include/libv4l2.h +++ b/lib/include/libv4l2.h @@ -22,6 +22,7 @@ #include #include #include +#include "libv4l2-plugin.h" #ifdef __cplusplus extern "C" { @@ -108,6 +109,20 @@ LIBV4L_PUBLIC int v4l2_get_control(int fd, int cid); (note the fd is left open in this case). */ LIBV4L_PUBLIC int v4l2_fd_open(int fd, int v4l2_flags); + +LIBV4L_PUBLIC int v4l2_plugin_open(int *plugin_used, const char *file, + int oflag, ...); +
[PATCH 0/1] libv4l: Add plugin support
Hi Hans, Here is initial version of plugin support for libv4l, based on your RFC. It is provided by functions v4l2_plugin_[open,close,etc]. When open() is called libv4l dlopens files in /usr/lib/libv4l/plugins 1 at a time and call open() callback passing through the applications parameters unmodified. If a plugin is relevant for the specified device node, it can indicate so by returning a value other then -1 (the actual file descriptor). As soon as a plugin returns another value then -1 plugin loading stops and information about it (fd and corresponding library handle) is stored. For each function v4l2_[ioctl,read,close,etc] is called corresponding v4l2_plugin_* function which looks if there is loaded plugin for that file and call it's callbacks. v4l2_plugin_* functions indicate by their first argument if plugin was used, and if it was not then v4l2_* functions proceed with their usual behavior. Yordan Kamenov (1): Add plugin support to libv4l lib/include/libv4l2-plugin.h | 74 lib/include/libv4l2.h| 15 ++ lib/libv4l2/Makefile |4 +- lib/libv4l2/libv4l2-priv.h |9 + lib/libv4l2/libv4l2.c| 56 ++- lib/libv4l2/v4l2-plugin.c| 399 ++ lib/libv4l2/v4l2convert.c| 20 ++- 7 files changed, 568 insertions(+), 9 deletions(-) create mode 100644 lib/include/libv4l2-plugin.h create mode 100644 lib/libv4l2/v4l2-plugin.c -- 1.7.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html