diff --git a/ChangeLog b/ChangeLog index fab946a6bb..27a0ae5c32 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2006-10-03 Thomas Vander Stichele + + * configure.ac: + * sys/Makefile.am: + * sys/v4l2/Makefile.am: + * sys/v4l2/README: + * sys/v4l2/gstv4l2.c: + * sys/v4l2/gstv4l2colorbalance.c: + * sys/v4l2/gstv4l2colorbalance.h: + * sys/v4l2/gstv4l2object.c: + * sys/v4l2/gstv4l2object.h: + * sys/v4l2/gstv4l2src.c: + * sys/v4l2/gstv4l2src.h: + * sys/v4l2/gstv4l2tuner.c: + * sys/v4l2/gstv4l2tuner.h: + * sys/v4l2/gstv4l2vidorient.c: + * sys/v4l2/gstv4l2vidorient.h: + * sys/v4l2/gstv4l2xoverlay.c: + * sys/v4l2/gstv4l2xoverlay.h: + * sys/v4l2/v4l2_calls.c: + * sys/v4l2/v4l2_calls.h: + * sys/v4l2/v4l2src_calls.c: + * sys/v4l2/v4l2src_calls.h: + moved to gst-plugins-good + 2006-10-03 Thomas Vander Stichele * sys/v4l2/gstv4l2object.c: diff --git a/configure.ac b/configure.ac index cc0cc96f58..a8d877727c 100644 --- a/configure.ac +++ b/configure.ac @@ -266,63 +266,6 @@ GST_CHECK_FEATURE(X, [X libraries and plugins], CPPFLAGS="$ac_cppflags_save" ]) -dnl *** Video 4 Linux 2 *** -dnl for information about the header/define, see sys/v4l2/gstv4l2element.h -dnl renamed to GST_V4L2 because of some conflict with kernel headers -translit(dnm, m, l) AM_CONDITIONAL(USE_GST_V4L2, true) -GST_CHECK_FEATURE(GST_V4L2, [Video 4 Linux 2], v4l2src, [ - AC_MSG_CHECKING([Checking for uptodate v4l2 installation]) - AC_TRY_COMPILE([ -#include -#include -#define _LINUX_TIME_H -#define __user -#include -#if defined(V4L2_MAJOR_VERSION) || defined(V4L2_MINOR_VERSION) -#error too early v4l2 version or no v4l2 at all -#endif - ], [ -return 0; - ], [ - HAVE_GST_V4L2="yes" - AC_MSG_RESULT(yes) - ], [ - HAVE_GST_V4L2="no" - AC_MSG_RESULT(no) - AC_CHECK_HEADER(linux/videodev2.h, - [ - AC_MSG_WARN([video4linux2 headers were found, but they're old.]) - AC_MSG_WARN([Please update v4l2 to compile the v4l2 plugins]) - ], [ - AC_MSG_WARN([video4linux2 was not found]) - ]) - ]) - - if [ test x$HAVE_GST_V4L2 = xyes ]; then - dnl check for missing v4l2_buffer declaration (see #135919) - MISSING_DECL=0 - AC_MSG_CHECKING(struct v4l2_buffer declaration) - AC_TRY_COMPILE([ -#include -#include -#define _LINUX_TIME_H -#define __user -#include - ],[ -struct v4l2_buffer buf; -buf.index = 0; -return 0; - ], [ AC_MSG_RESULT(yes) ], [ MISSING_DECL=1 && AC_MSG_RESULT(no) ]) - if [ test x$MISSING_DECL = x1 ]; then - AC_DEFINE(GST_V4L2_MISSING_BUFDECL, 1, [struct v4l2_buffer missing]) - fi - - dnl check for XOverlay libraries - GST_CHECK_XV - fi -]) -AM_CONDITIONAL(USE_XVIDEO, test "x$HAVE_XVIDEO" = "xyes") - dnl *** ext plug-ins *** dnl keep this list sorted alphabetically ! @@ -855,7 +798,6 @@ gst-libs/Makefile gst-libs/gst/Makefile sys/Makefile sys/glsink/Makefile -sys/v4l2/Makefile examples/Makefile examples/directfb/Makefile ext/amrwb/amrwb-code/Makefile diff --git a/sys/Makefile.am b/sys/Makefile.am index ceacb8e972..5944a45eb0 100644 --- a/sys/Makefile.am +++ b/sys/Makefile.am @@ -10,12 +10,6 @@ # QCAM_DIR= # endif -if USE_GST_V4L2 -V4L2_DIR=v4l2 -else -V4L2_DIR= -endif - # if USE_VCD # VCD_DIR=vcd # else @@ -34,6 +28,6 @@ else GL_DIR= endif -SUBDIRS = $(GL_DIR) $(V4L2_DIR) +SUBDIRS = $(GL_DIR) -DIST_SUBDIRS = glsink v4l2 +DIST_SUBDIRS = glsink diff --git a/sys/v4l2/Makefile.am b/sys/v4l2/Makefile.am deleted file mode 100644 index 82e2ff3324..0000000000 --- a/sys/v4l2/Makefile.am +++ /dev/null @@ -1,37 +0,0 @@ -plugin_LTLIBRARIES = libgstvideo4linux2.la - -if USE_XVIDEO -xv_source = gstv4l2xoverlay.c -xv_libs = $(X_LIBS) $(XVIDEO_LIBS) -else -xv_source = -xv_libs = -endif - -libgstvideo4linux2_la_SOURCES = gstv4l2.c \ - gstv4l2colorbalance.c \ - gstv4l2object.c \ - gstv4l2src.c \ - gstv4l2tuner.c \ - gstv4l2vidorient.c \ - v4l2_calls.c \ - v4l2src_calls.c \ - $(xv_source) - -libgstvideo4linux2_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) \ - $(GST_BASE_CFLAGS) \ - $(GST_CFLAGS) \ - $(X_CFLAGS) - -libgstvideo4linux2_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) - -libgstvideo4linux2_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) \ - $(GST_BASE_LIBS) \ - -lgstinterfaces-$(GST_MAJORMINOR) \ - $(GST_LIBS) \ - $(xv_libs) - -noinst_HEADERS = gstv4l2object.h v4l2_calls.h \ - gstv4l2src.h v4l2src_calls.h \ - gstv4l2tuner.h gstv4l2xoverlay.h \ - gstv4l2colorbalance.h gstv4l2vidorient.h diff --git a/sys/v4l2/README b/sys/v4l2/README index bf90939b75..dc81f4f564 100644 --- a/sys/v4l2/README +++ b/sys/v4l2/README @@ -1,28 +1 @@ -v4l2 plugins -============ - -The idea is a bit the same as the idea for the v4l1 plugins. We want -one generic v4l2element, and a few child objects (probably only two: -v4l2src and v4l2sink): - - /-------- v4l2src -v4l2element ---= - \-------- v4l2sink - -Both v4l2src and v4l2sink have a uncompressed and a compressed -recording-/playback-mode. Since this is all part of v4l2, the 'client' -of these elements, i.e. an application using v4l2src/v4l2sink, will -hardly notice this. All capsnego stuff is done inside, and the plugin -knows which formats are compressed and which are not. - -Please note that the v4l1 and the v4l2 plugins are *not* compatible -concerning properties. Naming has been kept the same where possible, -but in some cases, properties had to be removed or added to make -full use of v4l2. - -V4L2 API: http://linux.bytesex.org/v4l2/. - http://v4l2spec.bytesex.org/ - /usr/include/linux/videodev2.h or - -Kernel patches available from - http://dl.bytesex.org/patches/. +moved to gst-plugins-good diff --git a/sys/v4l2/gstv4l2.c b/sys/v4l2/gstv4l2.c deleted file mode 100644 index a65f7c1627..0000000000 --- a/sys/v4l2/gstv4l2.c +++ /dev/null @@ -1,68 +0,0 @@ -/* GStreamer - * - * Copyright (C) 2001-2002 Ronald Bultje - * 2006 Edgard Lima - * - * gstv4l2.c: plugin for v4l2 elements - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gst/gst-i18n-plugin.h" - -#include - -#include "gstv4l2object.h" -#include "gstv4l2src.h" -/* #include "gstv4l2jpegsrc.h" */ -/* #include "gstv4l2mjpegsrc.h" */ -/* #include "gstv4l2mjpegsink.h" */ - -/* used in v4l2_calls.c and v4l2src_calls.c */ -GST_DEBUG_CATEGORY (v4l2_debug); - -static gboolean -plugin_init (GstPlugin * plugin) -{ - GST_DEBUG_CATEGORY_INIT (v4l2_debug, "v4l2", 0, "V4L2 API calls"); - - if (!gst_element_register (plugin, "v4l2src", GST_RANK_NONE, - GST_TYPE_V4L2SRC)) - /* !gst_element_register (plugin, "v4l2jpegsrc", */ - /* GST_RANK_NONE, GST_TYPE_V4L2JPEGSRC) || */ - /* !gst_element_register (plugin, "v4l2mjpegsrc", */ - /* GST_RANK_NONE, GST_TYPE_V4L2MJPEGSRC) || */ - /* !gst_element_register (plugin, "v4l2mjpegsink", */ - /* GST_RANK_NONE, GST_TYPE_V4L2MJPEGSINK)) */ - return FALSE; - -#ifdef ENABLE_NLS - setlocale (LC_ALL, ""); - bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); -#endif /* ENABLE_NLS */ - - return TRUE; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "video4linux2", - "elements for Video 4 Linux", - plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) diff --git a/sys/v4l2/gstv4l2colorbalance.c b/sys/v4l2/gstv4l2colorbalance.c deleted file mode 100644 index f5cde096f4..0000000000 --- a/sys/v4l2/gstv4l2colorbalance.c +++ /dev/null @@ -1,106 +0,0 @@ -/* GStreamer - * - * Copyright (C) 2003 Ronald Bultje - * 2006 Edgard Lima - * - * gstv4l2colorbalance.c: color balance interface implementation for V4L2 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "gstv4l2colorbalance.h" -#include "gstv4l2object.h" - -GST_BOILERPLATE (GstV4l2ColorBalanceChannel, - gst_v4l2_color_balance_channel, - GstColorBalanceChannel, GST_TYPE_COLOR_BALANCE_CHANNEL); - -static void -gst_v4l2_color_balance_channel_base_init (gpointer g_class) -{ -} - -static void -gst_v4l2_color_balance_channel_class_init (GstV4l2ColorBalanceChannelClass * - klass) -{ -} - -static void -gst_v4l2_color_balance_channel_init (GstV4l2ColorBalanceChannel * channel, - GstV4l2ColorBalanceChannelClass * klass) -{ - channel->id = (guint32) - 1; -} - -static G_GNUC_UNUSED gboolean -gst_v4l2_color_balance_contains_channel (GstV4l2Object * v4l2object, - GstV4l2ColorBalanceChannel * v4l2channel) -{ - const GList *item; - - for (item = v4l2object->colors; item != NULL; item = item->next) - if (item->data == v4l2channel) - return TRUE; - - return FALSE; -} - -const GList * -gst_v4l2_color_balance_list_channels (GstV4l2Object * v4l2object) -{ - return v4l2object->colors; -} - -void -gst_v4l2_color_balance_set_value (GstV4l2Object * v4l2object, - GstColorBalanceChannel * channel, gint value) -{ - - GstV4l2ColorBalanceChannel *v4l2channel = - GST_V4L2_COLOR_BALANCE_CHANNEL (channel); - - /* assert that we're opened and that we're using a known item */ - g_return_if_fail (GST_V4L2_IS_OPEN (v4l2object)); - g_return_if_fail (gst_v4l2_color_balance_contains_channel (v4l2object, - v4l2channel)); - - gst_v4l2_set_attribute (v4l2object, v4l2channel->id, value); -} - -gint -gst_v4l2_color_balance_get_value (GstV4l2Object * v4l2object, - GstColorBalanceChannel * channel) -{ - GstV4l2ColorBalanceChannel *v4l2channel = - GST_V4L2_COLOR_BALANCE_CHANNEL (channel); - gint value; - - /* assert that we're opened and that we're using a known item */ - g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2object), 0); - g_return_val_if_fail (gst_v4l2_color_balance_contains_channel (v4l2object, - v4l2channel), 0); - - if (!gst_v4l2_get_attribute (v4l2object, v4l2channel->id, &value)) - return 0; - - return value; -} diff --git a/sys/v4l2/gstv4l2colorbalance.h b/sys/v4l2/gstv4l2colorbalance.h deleted file mode 100644 index ecd0111dd2..0000000000 --- a/sys/v4l2/gstv4l2colorbalance.h +++ /dev/null @@ -1,104 +0,0 @@ -/* GStreamer - * - * Copyright (C) 2003 Ronald Bultje - * 2006 Edgard Lima - * - * gstv4l2colorbalance.h: color balance interface implementation for V4L2 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_V4L2_COLOR_BALANCE_H__ -#define __GST_V4L2_COLOR_BALANCE_H__ - -#include -#include -#include "v4l2_calls.h" - -G_BEGIN_DECLS - -#define GST_TYPE_V4L2_COLOR_BALANCE_CHANNEL \ - (gst_v4l2_color_balance_channel_get_type ()) -#define GST_V4L2_COLOR_BALANCE_CHANNEL(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_V4L2_COLOR_BALANCE_CHANNEL, \ - GstV4l2ColorBalanceChannel)) -#define GST_V4L2_COLOR_BALANCE_CHANNEL_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_V4L2_COLOR_BALANCE_CHANNEL, \ - GstV4l2ColorBalanceChannelClass)) -#define GST_IS_V4L2_COLOR_BALANCE_CHANNEL(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_V4L2_COLOR_BALANCE_CHANNEL)) -#define GST_IS_V4L2_COLOR_BALANCE_CHANNEL_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_V4L2_COLOR_BALANCE_CHANNEL)) - -typedef struct _GstV4l2ColorBalanceChannel { - GstColorBalanceChannel parent; - - guint32 id; -} GstV4l2ColorBalanceChannel; - -typedef struct _GstV4l2ColorBalanceChannelClass { - GstColorBalanceChannelClass parent; -} GstV4l2ColorBalanceChannelClass; - -GType gst_v4l2_color_balance_channel_get_type (void); - -const GList * gst_v4l2_color_balance_list_channels (GstV4l2Object * v4l2object); - -void gst_v4l2_color_balance_set_value (GstV4l2Object * v4l2object, - GstColorBalanceChannel * channel, - gint value); - -gint gst_v4l2_color_balance_get_value (GstV4l2Object * v4l2object, - GstColorBalanceChannel * channel); - -#define GST_IMPLEMENT_V4L2_COLOR_BALANCE_METHODS(Type, interface_as_function) \ - \ -static const GList * \ -interface_as_function ## _color_balance_list_channels (GstColorBalance * balance) \ -{ \ - Type *this = (Type*) balance; \ - return gst_v4l2_color_balance_list_channels(this->v4l2object); \ -} \ - \ -static void \ -interface_as_function ## _color_balance_set_value (GstColorBalance * balance, \ - GstColorBalanceChannel * channel, \ - gint value) \ -{ \ - Type *this = (Type*) balance; \ - return gst_v4l2_color_balance_set_value(this->v4l2object, channel, value); \ -} \ - \ -static gint \ -interface_as_function ## _color_balance_get_value (GstColorBalance * balance, \ - GstColorBalanceChannel * channel) \ -{ \ - Type *this = (Type*) balance; \ - return gst_v4l2_color_balance_get_value(this->v4l2object, channel); \ -} \ - \ -void \ -interface_as_function ## _color_balance_interface_init (GstColorBalanceClass * klass) \ -{ \ - GST_COLOR_BALANCE_TYPE (klass) = GST_COLOR_BALANCE_HARDWARE; \ - \ - /* default virtual functions */ \ - klass->list_channels = interface_as_function ## _color_balance_list_channels; \ - klass->set_value = interface_as_function ## _color_balance_set_value; \ - klass->get_value = interface_as_function ## _color_balance_get_value; \ -} \ - -#endif /* __GST_V4L2_COLOR_BALANCE_H__ */ diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c deleted file mode 100644 index 3ed211df53..0000000000 --- a/sys/v4l2/gstv4l2object.c +++ /dev/null @@ -1,509 +0,0 @@ -/* GStreamer - * - * Copyright (C) 2001-2002 Ronald Bultje - * 2006 Edgard Lima - * - * gstv4l2object.c: base class for V4L2 elements - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as published - * by the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. This library 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 Library General Public License for more details. - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include - -#include "v4l2_calls.h" -#include "gstv4l2tuner.h" -#ifdef HAVE_XVIDEO -#include "gstv4l2xoverlay.h" -#endif -#include "gstv4l2colorbalance.h" - -#define DEFAULT_PROP_DEVICE "/dev/video0" -#define DEFAULT_PROP_DEVICE_NAME NULL -#define DEFAULT_PROP_FLAGS 0 -#define DEFAULT_PROP_NORM NULL -#define DEFAULT_PROP_CHANNEL NULL -#define DEFAULT_PROP_FREQUENCY 0 - -enum -{ - PROP_0, - V4L2_STD_OBJECT_PROPS, -}; - -const GList * -gst_v4l2_probe_get_properties (GstPropertyProbe * probe) -{ - GObjectClass *klass = G_OBJECT_GET_CLASS (probe); - static GList *list = NULL; - - /* well, not perfect, but better than no locking at all. - * In the worst case we leak a list node, so who cares? */ - GST_CLASS_LOCK (GST_OBJECT_CLASS (klass)); - - if (!list) { - list = g_list_append (NULL, g_object_class_find_property (klass, "device")); - } - - GST_CLASS_UNLOCK (GST_OBJECT_CLASS (klass)); - - return list; -} - -static gboolean -gst_v4l2_class_probe_devices (GstElementClass * klass, gboolean check, - GList ** klass_devices) -{ - static gboolean init = FALSE; - static GList *devices = NULL; - - if (!init && !check) { - const gchar *dev_base[] = { "/dev/video", "/dev/v4l2/video", NULL }; - gint base, n, fd; - - while (devices) { - GList *item = devices; - gchar *device = item->data; - - devices = g_list_remove (devices, item); - g_free (device); - } - - /* - * detect /dev entries - */ - for (n = 0; n < 64; n++) { - for (base = 0; dev_base[base] != NULL; base++) { - struct stat s; - gchar *device = g_strdup_printf ("%s%d", - dev_base[base], - n); - - /* - * does the /dev/ entry exist at all? - */ - if (stat (device, &s) == 0) { - /* - * yes: is a device attached? - */ - if (S_ISCHR (s.st_mode)) { - - if ((fd = open (device, O_RDWR | O_NONBLOCK)) > 0 || errno == EBUSY) { - if (fd > 0) - close (fd); - - devices = g_list_append (devices, device); - break; - } - } - } - g_free (device); - } - } - init = TRUE; - } - - *klass_devices = devices; - - return init; -} - -void -gst_v4l2_probe_probe_property (GstPropertyProbe * probe, - guint prop_id, const GParamSpec * pspec, GList ** klass_devices) -{ - GstElementClass *klass = GST_ELEMENT_GET_CLASS (probe); - - switch (prop_id) { - case PROP_DEVICE: - gst_v4l2_class_probe_devices (klass, FALSE, klass_devices); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec); - break; - } -} - -gboolean -gst_v4l2_probe_needs_probe (GstPropertyProbe * probe, - guint prop_id, const GParamSpec * pspec, GList ** klass_devices) -{ - GstElementClass *klass = GST_ELEMENT_GET_CLASS (probe); - gboolean ret = FALSE; - - switch (prop_id) { - case PROP_DEVICE: - ret = !gst_v4l2_class_probe_devices (klass, TRUE, klass_devices); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec); - break; - } - return ret; -} - -static GValueArray * -gst_v4l2_class_list_devices (GstElementClass * klass, GList ** klass_devices) -{ - GValueArray *array; - GValue value = { 0 }; - GList *item; - - if (!*klass_devices) - return NULL; - - array = g_value_array_new (g_list_length (*klass_devices)); - item = *klass_devices; - g_value_init (&value, G_TYPE_STRING); - while (item) { - gchar *device = item->data; - - g_value_set_string (&value, device); - g_value_array_append (array, &value); - - item = item->next; - } - g_value_unset (&value); - - return array; -} - -GValueArray * -gst_v4l2_probe_get_values (GstPropertyProbe * probe, - guint prop_id, const GParamSpec * pspec, GList ** klass_devices) -{ - GstElementClass *klass = GST_ELEMENT_GET_CLASS (probe); - GValueArray *array = NULL; - - switch (prop_id) { - case PROP_DEVICE: - array = gst_v4l2_class_list_devices (klass, klass_devices); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec); - break; - } - - return array; -} - -#define GST_TYPE_V4L2_DEVICE_FLAGS (gst_v4l2_device_get_type ()) -GType -gst_v4l2_device_get_type (void) -{ - static GType v4l2_device_type = 0; - - if (v4l2_device_type == 0) { - static const GFlagsValue values[] = { - {V4L2_CAP_VIDEO_CAPTURE, "Device supports video capture", "capture"}, - {V4L2_CAP_VIDEO_OUTPUT, "Device supports video playback", "output"}, - {V4L2_CAP_VIDEO_OVERLAY, "Device supports video overlay", "overlay"}, - - {V4L2_CAP_VBI_CAPTURE, "Device supports the VBI capture", "vbi-capture"}, - {V4L2_CAP_VBI_OUTPUT, "Device supports the VBI output", "vbi-output"}, - - {V4L2_CAP_TUNER, "Device has a tuner or modulator", "tuner"}, - {V4L2_CAP_AUDIO, "Device has audio inputs or outputs", "audio"}, - - {0, NULL, NULL} - }; - - v4l2_device_type = - g_flags_register_static ("GstV4l2DeviceTypeFlags", values); - } - - return v4l2_device_type; -} - -void -gst_v4l2_object_install_properties_helper (GObjectClass * gobject_class) -{ - g_object_class_install_property (gobject_class, PROP_DEVICE, - g_param_spec_string ("device", "Device", "Device location", - DEFAULT_PROP_DEVICE, G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, PROP_DEVICE_NAME, - g_param_spec_string ("device-name", "Device name", - "Name of the device", DEFAULT_PROP_DEVICE_NAME, G_PARAM_READABLE)); - g_object_class_install_property (gobject_class, PROP_FLAGS, - g_param_spec_flags ("flags", "Flags", "Device type flags", - GST_TYPE_V4L2_DEVICE_FLAGS, DEFAULT_PROP_FLAGS, G_PARAM_READABLE)); -/* FIXME norm, channel, frequency are part of the tuner interface, so they - should be removed from the properties - g_object_class_install_property (gobject_class, PROP_NORM, - g_param_spec_string ("norm", "Norm", "Standard norm to use", - DEFAULT_PROP_NORM, G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, PROP_CHANNEL, - g_param_spec_string ("channel", "Channel", - "Input/output channel to switch to", DEFAULT_PROP_CHANNEL, - G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, PROP_FREQUENCY, - g_param_spec_ulong ("frequency", "Frequency", - "Frequency to tune to (in Hz)", 0, G_MAXULONG, DEFAULT_PROP_FREQUENCY, - G_PARAM_READWRITE)); -*/ -} - -GstV4l2Object * -gst_v4l2_object_new (GstElement * element, - GstV4l2GetInOutFunction get_in_out_func, - GstV4l2SetInOutFunction set_in_out_func, - GstV4l2UpdateFpsFunction update_fps_func) -{ - GstV4l2Object *v4l2object; - - /* - * some default values - */ - v4l2object = g_new0 (GstV4l2Object, 1); - - v4l2object->element = element; - v4l2object->get_in_out_func = get_in_out_func; - v4l2object->set_in_out_func = set_in_out_func; - v4l2object->update_fps_func = update_fps_func; - - v4l2object->video_fd = -1; - v4l2object->buffer = NULL; - v4l2object->videodev = g_strdup (DEFAULT_PROP_DEVICE); - - v4l2object->norms = NULL; - v4l2object->channels = NULL; - v4l2object->colors = NULL; - - v4l2object->xwindow_id = 0; - - return v4l2object; -} - -void -gst_v4l2_object_destroy (GstV4l2Object ** v4l2object) -{ - if (*v4l2object) { - if ((*v4l2object)->videodev) { - g_free ((*v4l2object)->videodev); - (*v4l2object)->videodev = NULL; - } - - g_free (*v4l2object); - *v4l2object = NULL; - } -} - -gboolean -gst_v4l2_object_set_property_helper (GstV4l2Object * v4l2object, - guint prop_id, const GValue * value, GParamSpec * pspec) -{ - switch (prop_id) { - case PROP_DEVICE: - g_free (v4l2object->videodev); - v4l2object->videodev = g_value_dup_string (value); - break; - case PROP_NORM: - if (GST_V4L2_IS_OPEN (v4l2object)) { - GstTuner *tuner = GST_TUNER (v4l2object->element); - GstTunerNorm *norm = gst_tuner_find_norm_by_name (tuner, - (gchar *) g_value_get_string (value)); - - if (norm) { - /* like gst_tuner_set_norm (tuner, norm) - without g_object_notify */ - gst_v4l2_tuner_set_norm (v4l2object, norm); - } - } else { - g_free (v4l2object->norm); - v4l2object->norm = g_value_dup_string (value); - } - break; - case PROP_CHANNEL: - if (GST_V4L2_IS_OPEN (v4l2object)) { - GstTuner *tuner = GST_TUNER (v4l2object->element); - GstTunerChannel *channel = gst_tuner_find_channel_by_name (tuner, - (gchar *) g_value_get_string (value)); - - if (channel) { - /* like gst_tuner_set_channel (tuner, channel) - without g_object_notify */ - gst_v4l2_tuner_set_channel (v4l2object, channel); - } - } else { - g_free (v4l2object->channel); - v4l2object->channel = g_value_dup_string (value); - } - break; - case PROP_FREQUENCY: - if (GST_V4L2_IS_OPEN (v4l2object)) { - GstTuner *tuner = GST_TUNER (v4l2object->element); - GstTunerChannel *channel = gst_tuner_get_channel (tuner); - - if (channel && - GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)) { - /* like - gst_tuner_set_frequency (tuner, channel, g_value_get_ulong (value)) - without g_object_notify */ - gst_v4l2_tuner_set_frequency (v4l2object, channel, - g_value_get_ulong (value)); - } - } else { - v4l2object->frequency = g_value_get_ulong (value); - } - break; - default: - return FALSE; - break; - } - return TRUE; -} - - -gboolean -gst_v4l2_object_get_property_helper (GstV4l2Object * v4l2object, - guint prop_id, GValue * value, GParamSpec * pspec) -{ - switch (prop_id) { - case PROP_DEVICE: - g_value_set_string (value, v4l2object->videodev); - break; - case PROP_DEVICE_NAME: - { - const guchar *new = NULL; - - if (GST_V4L2_IS_OPEN (v4l2object)) { - new = v4l2object->vcap.card; - } else if (gst_v4l2_open (v4l2object)) { - new = v4l2object->vcap.card; - gst_v4l2_close (v4l2object); - } - g_value_set_string (value, (gchar *) new); - break; - } - case PROP_FLAGS: - { - guint flags = 0; - - if (GST_V4L2_IS_OPEN (v4l2object)) { - flags |= v4l2object->vcap.capabilities & - (V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_VIDEO_OUTPUT | - V4L2_CAP_VIDEO_OVERLAY | - V4L2_CAP_VBI_CAPTURE | - V4L2_CAP_VBI_OUTPUT | V4L2_CAP_TUNER | V4L2_CAP_AUDIO); - } - g_value_set_flags (value, flags); - break; - } - case PROP_NORM: - g_value_set_string (value, v4l2object->norm); - break; - case PROP_CHANNEL: - g_value_set_string (value, v4l2object->channel); - break; - case PROP_FREQUENCY: - g_value_set_ulong (value, v4l2object->frequency); - break; - default: - return FALSE; - break; - } - return TRUE; -} - -static void -gst_v4l2_set_defaults (GstV4l2Object * v4l2object) -{ - GstTunerNorm *norm = NULL; - GstTunerChannel *channel = NULL; - GstTuner *tuner = GST_TUNER (v4l2object->element); - - if (v4l2object->norm) - norm = gst_tuner_find_norm_by_name (tuner, v4l2object->norm); - if (norm) { - gst_tuner_set_norm (tuner, norm); - } else { - norm = - GST_TUNER_NORM (gst_tuner_get_norm (GST_TUNER (v4l2object->element))); - if (norm) { - g_free (v4l2object->norm); - v4l2object->norm = g_strdup (norm->label); - gst_tuner_norm_changed (tuner, norm); -/* FIXME: remove - g_object_notify (G_OBJECT (v4l2object->element), "norm"); -*/ - } - } - - if (v4l2object->channel) - channel = gst_tuner_find_channel_by_name (tuner, v4l2object->channel); - if (channel) { - gst_tuner_set_channel (tuner, channel); - } else { - channel = - GST_TUNER_CHANNEL (gst_tuner_get_channel (GST_TUNER (v4l2object-> - element))); - g_free (v4l2object->channel); - v4l2object->channel = g_strdup (channel->label); - gst_tuner_channel_changed (tuner, channel); -/* FIXME: remove - g_object_notify (G_OBJECT (v4l2object->element), "channel"); -*/ - } - - if (GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)) { - if (v4l2object->frequency != 0) { - gst_tuner_set_frequency (tuner, channel, v4l2object->frequency); - } else { - v4l2object->frequency = gst_tuner_get_frequency (tuner, channel); - if (v4l2object->frequency == 0) { - /* guess */ - gst_tuner_set_frequency (tuner, channel, 1000); - } else { -/* FIXME: remove - g_object_notify (G_OBJECT (v4l2object->element), "frequency"); -*/ - } - } - } -} - -gboolean -gst_v4l2_object_start (GstV4l2Object * v4l2object) -{ - if (gst_v4l2_open (v4l2object)) - gst_v4l2_set_defaults (v4l2object); - else - return FALSE; - -#ifdef HAVE_XVIDEO - gst_v4l2_xoverlay_start (v4l2object); -#endif - - return TRUE; -} - -gboolean -gst_v4l2_object_stop (GstV4l2Object * v4l2object) -{ -#ifdef HAVE_XVIDEO - gst_v4l2_xoverlay_stop (v4l2object); -#endif - - if (!gst_v4l2_close (v4l2object)) - return FALSE; - - return TRUE; -} diff --git a/sys/v4l2/gstv4l2object.h b/sys/v4l2/gstv4l2object.h deleted file mode 100644 index 34470739cd..0000000000 --- a/sys/v4l2/gstv4l2object.h +++ /dev/null @@ -1,195 +0,0 @@ -/* GStreamer - * - * Copyright (C) 2001-2002 Ronald Bultje - * 2006 Edgard Lima - * - * gstv4l2object.h: base class for V4L2 elements - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_V4L2_OBJECT_H__ -#define __GST_V4L2_OBJECT_H__ - -/* Because of some really cool feature in video4linux1, also known as - * 'not including sys/types.h and sys/time.h', we had to include it - * ourselves. In all their intelligence, these people decided to fix - * this in the next version (video4linux2) in such a cool way that it - * breaks all compilations of old stuff... - * The real problem is actually that linux/time.h doesn't use proper - * macro checks before defining types like struct timeval. The proper - * fix here is to either fuck the kernel header (which is what we do - * by defining _LINUX_TIME_H, an innocent little hack) or by fixing it - * upstream, which I'll consider doing later on. If you get compiler - * errors here, check your linux/time.h && sys/time.h header setup. - */ -#include -#include -#define _LINUX_TIME_H -#define __user -#include - -#include -#include - -#include - -G_BEGIN_DECLS - -#define GST_V4L2_OBJECT(obj) (GstV4l2Object *)(obj) - -typedef struct _GstV4l2Object GstV4l2Object; -typedef struct _GstV4l2ObjectClassHelper GstV4l2ObjectClassHelper; -typedef struct _GstV4l2Xv GstV4l2Xv; - -typedef gboolean (*GstV4l2GetInOutFunction) (GstV4l2Object * v4l2object, gint * input); -typedef gboolean (*GstV4l2SetInOutFunction) (GstV4l2Object * v4l2object, gint input); -typedef gboolean (*GstV4l2UpdateFpsFunction) (GstV4l2Object * v4l2object); - -struct _GstV4l2Object { - GstElement * element; - - /* the video device */ - char *videodev; - - /* the video-device's file descriptor */ - gint video_fd; - - /* the video buffer (mmap()'ed) */ - guint8 **buffer; - - /* the video device's capabilities */ - struct v4l2_capability vcap; - - /* the video device's window properties */ - struct v4l2_window vwin; - - /* some more info about the current input's capabilities */ - struct v4l2_input vinput; - - /* lists... */ - GList *colors; - GList *norms; - GList *channels; - - /* properties */ - gchar *norm; - gchar *channel; - gulong frequency; - - /* X-overlay */ - GstV4l2Xv *xv; - gulong xwindow_id; - - /* funcs */ - GstV4l2GetInOutFunction get_in_out_func; - GstV4l2SetInOutFunction set_in_out_func; - GstV4l2UpdateFpsFunction update_fps_func; -}; - -struct _GstV4l2ObjectClassHelper { - /* probed devices */ - GList *devices; -}; - -GType gst_v4l2_object_get_type(void); - -#define V4L2_STD_OBJECT_PROPS \ - PROP_DEVICE, \ - PROP_DEVICE_NAME, \ - PROP_FLAGS, \ - PROP_NORM, \ - PROP_CHANNEL, \ - PROP_FREQUENCY - - -/* create/destroy */ -GstV4l2Object * gst_v4l2_object_new (GstElement * element, - GstV4l2GetInOutFunction get_in_out_func, - GstV4l2SetInOutFunction set_in_out_func, - GstV4l2UpdateFpsFunction update_fps_func); -void gst_v4l2_object_destroy (GstV4l2Object ** v4l2object); - -/* properties */ -void gst_v4l2_object_install_properties_helper (GObjectClass *gobject_class); - -gboolean gst_v4l2_object_set_property_helper (GstV4l2Object *v4l2object, - guint prop_id, const GValue * value, - GParamSpec * pspec); -gboolean gst_v4l2_object_get_property_helper (GstV4l2Object *v4l2object, - guint prop_id, GValue * value, - GParamSpec * pspec); -/* starting/stopping */ -gboolean gst_v4l2_object_start (GstV4l2Object *v4l2object); -gboolean gst_v4l2_object_stop (GstV4l2Object *v4l2object); - -/* probing */ -const GList* gst_v4l2_probe_get_properties (GstPropertyProbe * probe); - -void gst_v4l2_probe_probe_property (GstPropertyProbe * probe, guint prop_id, - const GParamSpec * pspec, - GList ** klass_devices); -gboolean gst_v4l2_probe_needs_probe (GstPropertyProbe * probe, guint prop_id, - const GParamSpec * pspec, - GList ** klass_devices); -GValueArray* gst_v4l2_probe_get_values (GstPropertyProbe * probe, guint prop_id, - const GParamSpec * pspec, - GList ** klass_devices); - -#define GST_IMPLEMENT_V4L2_PROBE_METHODS(Type_Class, interface_as_function) \ - \ -static void \ -interface_as_function ## _probe_probe_property (GstPropertyProbe * probe, \ - guint prop_id, \ - const GParamSpec * pspec) \ -{ \ - Type_Class *this_class = (Type_Class*) probe; \ - gst_v4l2_probe_probe_property (probe, prop_id, pspec, \ - &this_class->v4l2_class_devices); \ -} \ - \ -static gboolean \ -interface_as_function ## _probe_needs_probe (GstPropertyProbe * probe, \ - guint prop_id, \ - const GParamSpec * pspec) \ -{ \ - Type_Class *this_class = (Type_Class*) probe; \ - return gst_v4l2_probe_needs_probe (probe, prop_id, pspec, \ - &this_class->v4l2_class_devices); \ -} \ - \ -static GValueArray * \ -interface_as_function ## _probe_get_values (GstPropertyProbe * probe, \ - guint prop_id, \ - const GParamSpec * pspec) \ -{ \ - Type_Class *this_class = (Type_Class*) probe; \ - return gst_v4l2_probe_get_values (probe, prop_id, pspec, \ - &this_class->v4l2_class_devices); \ -} \ - \ -static void \ -interface_as_function ## _property_probe_interface_init (GstPropertyProbeInterface * iface) \ -{ \ - iface->get_properties = gst_v4l2_probe_get_properties; \ - iface->probe_property = interface_as_function ## _probe_probe_property; \ - iface->needs_probe = interface_as_function ## _probe_needs_probe; \ - iface->get_values = interface_as_function ## _probe_get_values; \ -} - -G_END_DECLS - -#endif /* __GST_V4L2_OBJECT_H__ */ diff --git a/sys/v4l2/gstv4l2src.c b/sys/v4l2/gstv4l2src.c deleted file mode 100644 index d17852579b..0000000000 --- a/sys/v4l2/gstv4l2src.c +++ /dev/null @@ -1,987 +0,0 @@ -/* GStreamer - * - * Copyright (C) 2001-2002 Ronald Bultje - * 2006 Edgard Lima - * - * gstv4l2src.c: Video4Linux2 source element - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION:element-v4l2src - * - * - * v4l2src can be used to capture video from v4l2 devices, like webcams and tv cards. - * Example launch line - * - * - * gst-launch v4l2src ! xvimagesink - * - * This pipeline shows the video captured from /dev/video0 tv card and for - * webcams. - * - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include "v4l2src_calls.h" -#include - -#include "gstv4l2colorbalance.h" -#include "gstv4l2tuner.h" -#include "gstv4l2xoverlay.h" -#include "gstv4l2vidorient.h" - -static const GstElementDetails gst_v4l2src_details = -GST_ELEMENT_DETAILS ("Video (video4linux2/raw) Source", - "Source/Video", - "Reads raw frames from a video4linux2 (BT8x8) device", - "Ronald Bultje ," - " Edgard Lima "); - - -GST_DEBUG_CATEGORY (v4l2src_debug); -#define GST_CAT_DEFAULT v4l2src_debug - -enum -{ - PROP_0, - V4L2_STD_OBJECT_PROPS, -}; - -static const guint32 gst_v4l2_formats[] = { - /* from Linux 2.6.15 videodev2.h */ - V4L2_PIX_FMT_RGB332, - V4L2_PIX_FMT_RGB555, - V4L2_PIX_FMT_RGB565, - V4L2_PIX_FMT_RGB555X, - V4L2_PIX_FMT_RGB565X, - V4L2_PIX_FMT_BGR24, - V4L2_PIX_FMT_RGB24, - V4L2_PIX_FMT_BGR32, - V4L2_PIX_FMT_RGB32, - V4L2_PIX_FMT_GREY, - V4L2_PIX_FMT_YVU410, - V4L2_PIX_FMT_YVU420, - V4L2_PIX_FMT_YUYV, - V4L2_PIX_FMT_UYVY, - V4L2_PIX_FMT_YUV422P, - V4L2_PIX_FMT_YUV411P, - V4L2_PIX_FMT_Y41P, - - /* two planes -- one Y, one Cr + Cb interleaved */ - V4L2_PIX_FMT_NV12, - V4L2_PIX_FMT_NV21, - - /* The following formats are not defined in the V4L2 specification */ - V4L2_PIX_FMT_YUV410, - V4L2_PIX_FMT_YUV420, - V4L2_PIX_FMT_YYUV, - V4L2_PIX_FMT_HI240, - - /* see http://www.siliconimaging.com/RGB%20Bayer.htm */ -#ifdef V4L2_PIX_FMT_SBGGR8 - V4L2_PIX_FMT_SBGGR8, -#endif - - /* compressed formats */ - V4L2_PIX_FMT_MJPEG, - V4L2_PIX_FMT_JPEG, - V4L2_PIX_FMT_DV, - V4L2_PIX_FMT_MPEG, - - /* Vendor-specific formats */ - V4L2_PIX_FMT_WNVA, - -#ifdef V4L2_PIX_FMT_SN9C10X - V4L2_PIX_FMT_SN9C10X, -#endif -#ifdef V4L2_PIX_FMT_PWC1 - V4L2_PIX_FMT_PWC1, -#endif -#ifdef V4L2_PIX_FMT_PWC2 - V4L2_PIX_FMT_PWC2, -#endif -}; - -#define GST_V4L2_FORMAT_COUNT (G_N_ELEMENTS (gst_v4l2_formats)) - -GST_IMPLEMENT_V4L2_PROBE_METHODS (GstV4l2SrcClass, gst_v4l2src); -GST_IMPLEMENT_V4L2_COLOR_BALANCE_METHODS (GstV4l2Src, gst_v4l2src); -GST_IMPLEMENT_V4L2_TUNER_METHODS (GstV4l2Src, gst_v4l2src); -#ifdef HAVE_XVIDEO -GST_IMPLEMENT_V4L2_XOVERLAY_METHODS (GstV4l2Src, gst_v4l2src); -#endif -GST_IMPLEMENT_V4L2_VIDORIENT_METHODS (GstV4l2Src, gst_v4l2src); - -static gboolean -gst_v4l2src_iface_supported (GstImplementsInterface * iface, GType iface_type) -{ - GstV4l2Object *v4l2object = GST_V4L2SRC (iface)->v4l2object; - -#ifdef HAVE_XVIDEO - g_assert (iface_type == GST_TYPE_TUNER || - iface_type == GST_TYPE_X_OVERLAY || - iface_type == GST_TYPE_COLOR_BALANCE || - iface_type == GST_TYPE_VIDEO_ORIENTATION); -#else - g_assert (iface_type == GST_TYPE_TUNER || - iface_type == GST_TYPE_COLOR_BALANCE || - iface_type == GST_TYPE_VIDEO_ORIENTATION); -#endif - - if (v4l2object->video_fd == -1) - return FALSE; - -#ifdef HAVE_XVIDEO - if (iface_type == GST_TYPE_X_OVERLAY && !GST_V4L2_IS_OVERLAY (v4l2object)) - return FALSE; -#endif - - return TRUE; -} - -static void -gst_v4l2src_interface_init (GstImplementsInterfaceClass * klass) -{ - /* - * default virtual functions - */ - klass->supported = gst_v4l2src_iface_supported; -} - -void -gst_v4l2src_init_interfaces (GType type) -{ - static const GInterfaceInfo v4l2iface_info = { - (GInterfaceInitFunc) gst_v4l2src_interface_init, - NULL, - NULL, - }; - static const GInterfaceInfo v4l2_tuner_info = { - (GInterfaceInitFunc) gst_v4l2src_tuner_interface_init, - NULL, - NULL, - }; -#ifdef HAVE_XVIDEO - static const GInterfaceInfo v4l2_xoverlay_info = { - (GInterfaceInitFunc) gst_v4l2src_xoverlay_interface_init, - NULL, - NULL, - }; -#endif - static const GInterfaceInfo v4l2_colorbalance_info = { - (GInterfaceInitFunc) gst_v4l2src_color_balance_interface_init, - NULL, - NULL, - }; - static const GInterfaceInfo v4l2_videoorientation_info = { - (GInterfaceInitFunc) gst_v4l2src_video_orientation_interface_init, - NULL, - NULL, - }; - static const GInterfaceInfo v4l2_propertyprobe_info = { - (GInterfaceInitFunc) gst_v4l2src_property_probe_interface_init, - NULL, - NULL, - }; - - g_type_add_interface_static (type, - GST_TYPE_IMPLEMENTS_INTERFACE, &v4l2iface_info); - g_type_add_interface_static (type, GST_TYPE_TUNER, &v4l2_tuner_info); -#ifdef HAVE_XVIDEO - g_type_add_interface_static (type, GST_TYPE_X_OVERLAY, &v4l2_xoverlay_info); -#endif - g_type_add_interface_static (type, - GST_TYPE_COLOR_BALANCE, &v4l2_colorbalance_info); - g_type_add_interface_static (type, - GST_TYPE_VIDEO_ORIENTATION, &v4l2_videoorientation_info); - g_type_add_interface_static (type, GST_TYPE_PROPERTY_PROBE, - &v4l2_propertyprobe_info); -} - -GST_BOILERPLATE_FULL (GstV4l2Src, gst_v4l2src, GstPushSrc, GST_TYPE_PUSH_SRC, - gst_v4l2src_init_interfaces); - -static void gst_v4l2src_dispose (GObject * object); - -/* basesrc methods */ -static gboolean gst_v4l2src_start (GstBaseSrc * src); -static gboolean gst_v4l2src_stop (GstBaseSrc * src); -static gboolean gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps); -static GstCaps *gst_v4l2src_get_caps (GstBaseSrc * src); -static GstFlowReturn gst_v4l2src_create (GstPushSrc * src, GstBuffer ** out); - -static void gst_v4l2src_fixate (GstPad * pad, GstCaps * caps); - -static void gst_v4l2src_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_v4l2src_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -static GstCaps *gst_v4l2src_get_all_caps (void); - -static void -gst_v4l2src_base_init (gpointer g_class) -{ - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); - GstV4l2SrcClass *gstv4l2src_class = GST_V4L2SRC_CLASS (g_class); - - gstv4l2src_class->v4l2_class_devices = NULL; - - GST_DEBUG_CATEGORY_INIT (v4l2src_debug, "v4l2src", 0, "V4L2 source element"); - - gst_element_class_set_details (gstelement_class, &gst_v4l2src_details); - - gst_element_class_add_pad_template - (gstelement_class, - gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - gst_v4l2src_get_all_caps ())); -} - -static void -gst_v4l2src_class_init (GstV4l2SrcClass * klass) -{ - GObjectClass *gobject_class; - GstBaseSrcClass *basesrc_class; - GstPushSrcClass *pushsrc_class; - - gobject_class = G_OBJECT_CLASS (klass); - basesrc_class = GST_BASE_SRC_CLASS (klass); - pushsrc_class = GST_PUSH_SRC_CLASS (klass); - - gobject_class->dispose = gst_v4l2src_dispose; - gobject_class->set_property = gst_v4l2src_set_property; - gobject_class->get_property = gst_v4l2src_get_property; - - gst_v4l2_object_install_properties_helper (gobject_class); - - basesrc_class->get_caps = gst_v4l2src_get_caps; - basesrc_class->set_caps = gst_v4l2src_set_caps; - basesrc_class->start = gst_v4l2src_start; - basesrc_class->stop = gst_v4l2src_stop; - - pushsrc_class->create = gst_v4l2src_create; -} - -static void -gst_v4l2src_init (GstV4l2Src * v4l2src, GstV4l2SrcClass * klass) -{ - v4l2src->v4l2object = gst_v4l2_object_new (GST_ELEMENT (v4l2src), - gst_v4l2_get_input, gst_v4l2_set_input, gst_v4l2src_update_fps); - - v4l2src->breq.count = 0; - - v4l2src->formats = NULL; - - /* fps */ - v4l2src->fps_n = 0; - v4l2src->fps_d = 1; - - v4l2src->is_capturing = FALSE; - - gst_pad_set_fixatecaps_function (GST_BASE_SRC_PAD (v4l2src), - gst_v4l2src_fixate); - - gst_base_src_set_format (GST_BASE_SRC (v4l2src), GST_FORMAT_TIME); - gst_base_src_set_live (GST_BASE_SRC (v4l2src), TRUE); -} - - -static void -gst_v4l2src_dispose (GObject * object) -{ - GstV4l2Src *v4l2src = GST_V4L2SRC (object); - - if (v4l2src->formats) { - gst_v4l2src_clear_format_list (v4l2src); - } - - G_OBJECT_CLASS (parent_class)->dispose (object); -} - - -static void -gst_v4l2src_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec) -{ - GstV4l2Src *v4l2src; - - g_return_if_fail (GST_IS_V4L2SRC (object)); - v4l2src = GST_V4L2SRC (object); - - if (!gst_v4l2_object_set_property_helper (v4l2src->v4l2object, - prop_id, value, pspec)) { - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - } -} - - -static void -gst_v4l2src_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec) -{ - GstV4l2Src *v4l2src; - - g_return_if_fail (GST_IS_V4L2SRC (object)); - v4l2src = GST_V4L2SRC (object); - - if (!gst_v4l2_object_get_property_helper (v4l2src->v4l2object, - prop_id, value, pspec)) { - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - } -} - - -/* this function is a bit of a last resort */ -static void -gst_v4l2src_fixate (GstPad * pad, GstCaps * caps) -{ - GstStructure *structure; - gint i; - G_GNUC_UNUSED gchar *caps_str; - - caps_str = gst_caps_to_string (caps); - GST_DEBUG_OBJECT (GST_PAD_PARENT (pad), "fixating caps %s", caps_str); - g_free (caps_str); - - for (i = 0; i < gst_caps_get_size (caps); ++i) { - structure = gst_caps_get_structure (caps, i); - const GValue *v; - - /* FIXME such sizes? we usually fixate to something in the 320x200 - * range... */ - /* We are fixating to greater possble size (limited to GST_V4L2_MAX_SIZE) - and framarate closer to 15/2 that is common in web-cams */ - gst_structure_fixate_field_nearest_int (structure, "width", - GST_V4L2_MAX_SIZE); - gst_structure_fixate_field_nearest_int (structure, "height", - GST_V4L2_MAX_SIZE); - gst_structure_fixate_field_nearest_fraction (structure, "framerate", 15, 2); - - v = gst_structure_get_value (structure, "format"); - if (v && G_VALUE_TYPE (v) != GST_TYPE_FOURCC) { - guint32 fourcc; - - g_return_if_fail (G_VALUE_TYPE (v) == GST_TYPE_LIST); - - fourcc = gst_value_get_fourcc (gst_value_list_get_value (v, 0)); - gst_structure_set (structure, "format", GST_TYPE_FOURCC, fourcc, NULL); - } - } -} - -static GstStructure * -gst_v4l2src_v4l2fourcc_to_caps (guint32 fourcc) -{ - GstStructure *structure = NULL; - - switch (fourcc) { - case V4L2_PIX_FMT_MJPEG: /* Motion-JPEG */ - case V4L2_PIX_FMT_JPEG: /* JFIF JPEG */ - structure = gst_structure_new ("image/jpeg", NULL); - break; - case V4L2_PIX_FMT_RGB332: - case V4L2_PIX_FMT_RGB555: - case V4L2_PIX_FMT_RGB555X: - case V4L2_PIX_FMT_RGB565: - case V4L2_PIX_FMT_RGB565X: - case V4L2_PIX_FMT_RGB24: - case V4L2_PIX_FMT_BGR24: - case V4L2_PIX_FMT_RGB32: - case V4L2_PIX_FMT_BGR32:{ - guint depth = 0, bpp = 0; - gint endianness = 0; - guint32 r_mask = 0, b_mask = 0, g_mask = 0; - - switch (fourcc) { - case V4L2_PIX_FMT_RGB332: - bpp = depth = 8; - endianness = G_BYTE_ORDER; /* 'like, whatever' */ - r_mask = 0xe0; - g_mask = 0x1c; - b_mask = 0x03; - break; - case V4L2_PIX_FMT_RGB555: - case V4L2_PIX_FMT_RGB555X: - bpp = 16; - depth = 15; - endianness = - fourcc == V4L2_PIX_FMT_RGB555X ? G_BIG_ENDIAN : G_LITTLE_ENDIAN; - r_mask = 0x7c00; - g_mask = 0x03e0; - b_mask = 0x001f; - break; - case V4L2_PIX_FMT_RGB565: - case V4L2_PIX_FMT_RGB565X: - bpp = depth = 16; - endianness = - fourcc == V4L2_PIX_FMT_RGB565X ? G_BIG_ENDIAN : G_LITTLE_ENDIAN; - r_mask = 0xf800; - g_mask = 0x07e0; - b_mask = 0x001f; - break; - case V4L2_PIX_FMT_RGB24: - bpp = depth = 24; - endianness = G_BIG_ENDIAN; - r_mask = 0xff0000; - g_mask = 0x00ff00; - b_mask = 0x0000ff; - break; - case V4L2_PIX_FMT_BGR24: - bpp = depth = 24; - endianness = G_BIG_ENDIAN; - r_mask = 0x0000ff; - g_mask = 0x00ff00; - b_mask = 0xff0000; - break; - case V4L2_PIX_FMT_RGB32: - bpp = depth = 32; - endianness = G_BIG_ENDIAN; - r_mask = 0xff000000; - g_mask = 0x00ff0000; - b_mask = 0x0000ff00; - break; - case V4L2_PIX_FMT_BGR32: - bpp = depth = 32; - endianness = G_BIG_ENDIAN; - r_mask = 0x000000ff; - g_mask = 0x0000ff00; - b_mask = 0x00ff0000; - break; - default: - g_assert_not_reached (); - break; - } - structure = gst_structure_new ("video/x-raw-rgb", - "bpp", G_TYPE_INT, bpp, - "depth", G_TYPE_INT, depth, - "red_mask", G_TYPE_INT, r_mask, - "green_mask", G_TYPE_INT, g_mask, - "blue_mask", G_TYPE_INT, b_mask, - "endianness", G_TYPE_INT, endianness, NULL); - break; - } - case V4L2_PIX_FMT_GREY: /* 8 Greyscale */ - case V4L2_PIX_FMT_NV12: /* 12 Y/CbCr 4:2:0 */ - case V4L2_PIX_FMT_NV21: /* 12 Y/CrCb 4:2:0 */ - case V4L2_PIX_FMT_YYUV: /* 16 YUV 4:2:2 */ - case V4L2_PIX_FMT_HI240: /* 8 8-bit color */ - /* FIXME: get correct fourccs here */ - break; - case V4L2_PIX_FMT_YVU410: - case V4L2_PIX_FMT_YUV410: - case V4L2_PIX_FMT_YUV420: /* I420/IYUV */ - case V4L2_PIX_FMT_YUYV: - case V4L2_PIX_FMT_YVU420: - case V4L2_PIX_FMT_UYVY: - case V4L2_PIX_FMT_Y41P: - case V4L2_PIX_FMT_YUV422P: - case V4L2_PIX_FMT_YUV411P:{ - guint32 fcc = 0; - - switch (fourcc) { - case V4L2_PIX_FMT_YVU410: - fcc = GST_MAKE_FOURCC ('Y', 'V', 'U', '9'); - break; - case V4L2_PIX_FMT_YUV410: - fcc = GST_MAKE_FOURCC ('Y', 'U', 'V', '9'); - break; - case V4L2_PIX_FMT_YUV420: - fcc = GST_MAKE_FOURCC ('I', '4', '2', '0'); - break; - case V4L2_PIX_FMT_YUYV: - fcc = GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'); - break; - case V4L2_PIX_FMT_YVU420: - fcc = GST_MAKE_FOURCC ('Y', 'V', '1', '2'); - break; - case V4L2_PIX_FMT_UYVY: - fcc = GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'); - break; - case V4L2_PIX_FMT_Y41P: - fcc = GST_MAKE_FOURCC ('Y', '4', '1', 'P'); - break; - case V4L2_PIX_FMT_YUV411P: - fcc = GST_MAKE_FOURCC ('Y', '4', '1', 'B'); - break; - case V4L2_PIX_FMT_YUV422P: - fcc = GST_MAKE_FOURCC ('Y', '4', '2', 'B'); - break; - default: - g_assert_not_reached (); - break; - } - structure = gst_structure_new ("video/x-raw-yuv", - "format", GST_TYPE_FOURCC, fcc, NULL); - break; - } - case V4L2_PIX_FMT_DV: - structure = - gst_structure_new ("video/x-dv", "systemstream", G_TYPE_BOOLEAN, TRUE, - NULL); - break; - case V4L2_PIX_FMT_MPEG: /* MPEG */ - /* someone figure out the MPEG format used... */ - break; - case V4L2_PIX_FMT_WNVA: /* Winnov hw compres */ - break; - default: - GST_DEBUG ("Unknown fourcc 0x%08x %" GST_FOURCC_FORMAT, - fourcc, GST_FOURCC_ARGS (fourcc)); - break; - } - - return structure; -} - -static guint32 -gst_v4l2_fourcc_from_structure (GstStructure * structure) -{ - guint32 fourcc = 0; - const gchar *mimetype = gst_structure_get_name (structure); - - if (!strcmp (mimetype, "video/x-raw-yuv")) { - gst_structure_get_fourcc (structure, "format", &fourcc); - - switch (fourcc) { - case GST_MAKE_FOURCC ('I', '4', '2', '0'): - case GST_MAKE_FOURCC ('I', 'Y', 'U', 'V'): - fourcc = V4L2_PIX_FMT_YUV420; - break; - case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'): - fourcc = V4L2_PIX_FMT_YUYV; - break; - case GST_MAKE_FOURCC ('Y', '4', '1', 'P'): - fourcc = V4L2_PIX_FMT_Y41P; - break; - case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'): - fourcc = V4L2_PIX_FMT_UYVY; - break; - case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): - fourcc = V4L2_PIX_FMT_YVU420; - break; - case GST_MAKE_FOURCC ('Y', '4', '1', 'B'): - fourcc = V4L2_PIX_FMT_YUV411P; - break; - case GST_MAKE_FOURCC ('Y', '4', '2', 'B'): - fourcc = V4L2_PIX_FMT_YUV422P; - break; - } - } else if (!strcmp (mimetype, "video/x-raw-rgb")) { - gint depth, endianness, r_mask; - - gst_structure_get_int (structure, "depth", &depth); - gst_structure_get_int (structure, "endianness", &endianness); - gst_structure_get_int (structure, "red_mask", &r_mask); - - switch (depth) { - case 8: - fourcc = V4L2_PIX_FMT_RGB332; - break; - case 15: - fourcc = (endianness == G_LITTLE_ENDIAN) ? - V4L2_PIX_FMT_RGB555 : V4L2_PIX_FMT_RGB555X; - break; - case 16: - fourcc = (endianness == G_LITTLE_ENDIAN) ? - V4L2_PIX_FMT_RGB565 : V4L2_PIX_FMT_RGB565X; - break; - case 24: - fourcc = (r_mask == 0xFF) ? V4L2_PIX_FMT_BGR24 : V4L2_PIX_FMT_RGB24; - break; - case 32: - fourcc = (r_mask == 0xFF) ? V4L2_PIX_FMT_BGR32 : V4L2_PIX_FMT_RGB32; - break; - } - } else if (strcmp (mimetype, "video/x-dv") == 0) { - fourcc = V4L2_PIX_FMT_DV; - } else if (strcmp (mimetype, "image/jpeg") == 0) { - fourcc = V4L2_PIX_FMT_JPEG; - } - - return fourcc; -} - -static struct v4l2_fmtdesc * -gst_v4l2src_get_format_from_fourcc (GstV4l2Src * v4l2src, guint32 fourcc) -{ - struct v4l2_fmtdesc *fmt; - GSList *walk; - - if (fourcc == 0) - return NULL; - - walk = v4l2src->formats; - while (walk) { - fmt = (struct v4l2_fmtdesc *) walk->data; - if (fmt->pixelformat == fourcc) - return fmt; - /* special case for jpeg */ - if ((fmt->pixelformat == V4L2_PIX_FMT_MJPEG && fourcc == V4L2_PIX_FMT_JPEG) - || (fmt->pixelformat == V4L2_PIX_FMT_JPEG - && fourcc == V4L2_PIX_FMT_MJPEG)) { - return fmt; - } - walk = g_slist_next (walk); - } - - return NULL; -} - -static struct v4l2_fmtdesc * -gst_v4l2_caps_to_v4l2fourcc (GstV4l2Src * v4l2src, GstStructure * structure) -{ - return gst_v4l2src_get_format_from_fourcc (v4l2src, - gst_v4l2_fourcc_from_structure (structure)); -} - -static GstCaps * -gst_v4l2src_get_all_caps (void) -{ - static GstCaps *caps = NULL; - - if (caps == NULL) { - GstStructure *structure; - guint i; - - caps = gst_caps_new_empty (); - for (i = 0; i < GST_V4L2_FORMAT_COUNT; i++) { - structure = gst_v4l2src_v4l2fourcc_to_caps (gst_v4l2_formats[i]); - if (structure) { - gst_structure_set (structure, - "width", GST_TYPE_INT_RANGE, 1, GST_V4L2_MAX_SIZE, - "height", GST_TYPE_INT_RANGE, 1, GST_V4L2_MAX_SIZE, - "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, 100, 1, NULL); - gst_caps_append_structure (caps, structure); - } - } - } - - return caps; -} - -static GstCaps * -gst_v4l2src_get_caps (GstBaseSrc * src) -{ - GstV4l2Src *v4l2src = GST_V4L2SRC (src); - GstCaps *caps; - struct v4l2_fmtdesc *format; - int min_w, max_w, min_h, max_h; - GSList *walk; - GstStructure *structure; - guint fps_n, fps_d; - - if (!GST_V4L2_IS_OPEN (v4l2src->v4l2object)) { - return - gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD - (v4l2src))); - } - - if (!v4l2src->formats) - gst_v4l2src_fill_format_list (v4l2src); - - /* build our own capslist */ - caps = gst_caps_new_empty (); - walk = v4l2src->formats; - if (!gst_v4l2src_get_fps (v4l2src, &fps_n, &fps_d)) { - GST_DEBUG_OBJECT (v4l2src, "frame rate is unknown."); - fps_n = 0; - fps_d = 1; - } - while (walk) { - format = (struct v4l2_fmtdesc *) walk->data; - walk = g_slist_next (walk); - - /* get size delimiters */ - if (!gst_v4l2src_get_size_limits (v4l2src, format, - &min_w, &max_w, &min_h, &max_h)) { - continue; - } - /* template, FIXME, why limit if the device reported correct results? */ - /* we are doing it right now to avoid unexpected results */ - min_w = CLAMP (min_w, 1, GST_V4L2_MAX_SIZE); - min_h = CLAMP (min_h, 1, GST_V4L2_MAX_SIZE); - max_w = CLAMP (max_w, min_w, GST_V4L2_MAX_SIZE); - max_h = CLAMP (max_h, min_h, GST_V4L2_MAX_SIZE); - - /* add to list */ - structure = gst_v4l2src_v4l2fourcc_to_caps (format->pixelformat); - - if (structure) { - gst_structure_set (structure, - "width", GST_TYPE_INT_RANGE, min_w, max_w, - "height", GST_TYPE_INT_RANGE, min_h, max_h, NULL); - - /* FIXME, why random range? */ - /* AFAIK: in v4l2 standard we still don't have a good way to enum - for a range. Currently it is on discussion on v4l2 forum. - Currently, something more smart could be done for tvcard devices. - The maximum value could be determined by 'v4l2_standard.frameperiod' - and minimum also to the same if V4L2_CAP_TIMEPERFRAME is not set. */ - /* another approach for web-cams would be to try to set a very - high(100/1) and low(1/1) FPSs and get the values returned */ - gst_structure_set (structure, "framerate", GST_TYPE_FRACTION_RANGE, - 0, 1, 100, 1, NULL); - - gst_caps_append_structure (caps, structure); - } - } - - return caps; -} - -static gboolean -gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps) -{ - GstV4l2Src *v4l2src; - gint w, h; - GstStructure *structure; - struct v4l2_fmtdesc *format; - const GValue *framerate; - guint fps_n, fps_d; - - v4l2src = GST_V4L2SRC (src); - - /* if we're not open, punt -- we'll get setcaps'd later via negotiate */ - if (!GST_V4L2_IS_OPEN (v4l2src->v4l2object)) - return FALSE; - - /* make sure we stop capturing and dealloc buffers */ - if (GST_V4L2_IS_ACTIVE (v4l2src->v4l2object)) { - if (!gst_v4l2src_capture_stop (v4l2src)) - return FALSE; - if (!gst_v4l2src_capture_deinit (v4l2src)) - return FALSE; - } - - structure = gst_caps_get_structure (caps, 0); - - /* we want our own v4l2 type of fourcc codes */ - if (!(format = gst_v4l2_caps_to_v4l2fourcc (v4l2src, structure))) { - return FALSE; - } - - gst_structure_get_int (structure, "width", &w); - gst_structure_get_int (structure, "height", &h); - framerate = gst_structure_get_value (structure, "framerate"); - - GST_DEBUG_OBJECT (v4l2src, "trying to set_capture %dx%d, format %s", - w, h, format->description); - - if (framerate) { - fps_n = gst_value_get_fraction_numerator (framerate); - fps_d = gst_value_get_fraction_denominator (framerate); - } else { - fps_n = 0; - fps_d = 1; - } - - if (!gst_v4l2src_set_capture (v4l2src, format, &w, &h, &fps_n, &fps_d)) { - GST_WARNING_OBJECT (v4l2src, "could not set_capture %dx%d, format %s", - w, h, format->description); - return FALSE; - } - - if (fps_n) { - gst_structure_set (structure, - "width", G_TYPE_INT, w, - "height", G_TYPE_INT, h, - "framerate", GST_TYPE_FRACTION, fps_n, fps_d, NULL); - } else { - gst_structure_set (structure, - "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL); - } - - if (!gst_v4l2src_capture_init (v4l2src)) - return FALSE; - - if (!gst_v4l2src_capture_start (v4l2src)) - return FALSE; - - if (v4l2src->fps_n != fps_n || v4l2src->fps_d != fps_d) { - GST_WARNING_OBJECT (v4l2src, - "framerate changed after start capturing from %u/%u to %u/%u", fps_n, - fps_d, v4l2src->fps_n, v4l2src->fps_d); - if (fps_n) { - gst_structure_set (structure, - "width", G_TYPE_INT, w, - "height", G_TYPE_INT, h, - "framerate", GST_TYPE_FRACTION, v4l2src->fps_n, v4l2src->fps_d, NULL); - } - } - return TRUE; -} - -/* start and stop are not symmetric -- start will open the device, but not start - * capture. it's setcaps that will start capture, which is called via basesrc's - * negotiate method. stop will both stop capture and close the device. - */ -static gboolean -gst_v4l2src_start (GstBaseSrc * src) -{ - GstV4l2Src *v4l2src = GST_V4L2SRC (src); - - if (!gst_v4l2_object_start (v4l2src->v4l2object)) - return FALSE; - - v4l2src->offset = 0; - - return TRUE; -} - -static gboolean -gst_v4l2src_stop (GstBaseSrc * src) -{ - GstV4l2Src *v4l2src = GST_V4L2SRC (src); - - if (GST_V4L2_IS_ACTIVE (v4l2src->v4l2object) - && !gst_v4l2src_capture_stop (v4l2src)) - return FALSE; - - if (v4l2src->v4l2object->buffer != NULL) { - if (!gst_v4l2src_capture_deinit (v4l2src)) - return FALSE; - } - - if (!gst_v4l2_object_stop (v4l2src->v4l2object)) - return FALSE; - - return TRUE; -} - -static GstFlowReturn -gst_v4l2src_get_read (GstV4l2Src * v4l2src, GstBuffer ** buf) -{ - gint amount; - gint buffersize; - - buffersize = v4l2src->format.fmt.pix.sizeimage; - - do { - *buf = gst_v4l2src_buffer_new (v4l2src, buffersize, NULL, NULL); - - amount = - read (v4l2src->v4l2object->video_fd, GST_BUFFER_DATA (*buf), - buffersize); - if (amount == buffersize) { - break; - } else if (amount == -1) { - if (errno == EAGAIN || errno == EINTR) { - continue; - } else - goto read_error; - } else - goto short_read; - } while (TRUE); - - return GST_FLOW_OK; - - /* ERRORS */ -read_error: - { - GST_ELEMENT_ERROR (v4l2src, RESOURCE, SYNC, - (_("Error read()ing %d bytes on device %s."), - buffersize, v4l2src->v4l2object->videodev), GST_ERROR_SYSTEM); - gst_buffer_unref (*buf); - return GST_FLOW_ERROR; - } -short_read: - { - GST_ELEMENT_ERROR (v4l2src, RESOURCE, SYNC, (NULL), - ("Error read()ing a buffer on device %s: got only %d bytes instead of expected %d.", - v4l2src->v4l2object->videodev, amount, buffersize)); - gst_buffer_unref (*buf); - return GST_FLOW_ERROR; - } -} - -static GstFlowReturn -gst_v4l2src_get_mmap (GstV4l2Src * v4l2src, GstBuffer ** buf) -{ - gint i, num; - - /* grab a frame from the device, post an error */ - num = gst_v4l2src_grab_frame (v4l2src); - if (num == -1) - goto grab_failed; - - i = v4l2src->format.fmt.pix.sizeimage; - - /* check if this is the last buffer in the queue. If so do a memcpy to put it back asap - to avoid framedrops and deadlocks because of stupid elements */ - if (g_atomic_int_get (&v4l2src->pool->refcount) == v4l2src->breq.count) { - GST_LOG_OBJECT (v4l2src, "using memcpy'd buffer"); - - *buf = gst_v4l2src_buffer_new (v4l2src, i, NULL, NULL); - memcpy (GST_BUFFER_DATA (*buf), v4l2src->pool->buffers[num].start, i); - - /* posts an error message if something went wrong */ - if (!gst_v4l2src_queue_frame (v4l2src, num)) - goto queue_failed; - } else { - GST_LOG_OBJECT (v4l2src, "using mmap'd buffer"); - *buf = - gst_v4l2src_buffer_new (v4l2src, i, v4l2src->pool->buffers[num].start, - &v4l2src->pool->buffers[num]); - - /* no need to be careful here, both are > 0, because the element uses them */ - g_atomic_int_inc (&v4l2src->pool->buffers[num].refcount); - g_atomic_int_inc (&v4l2src->pool->refcount); - } - return GST_FLOW_OK; - - /* ERRORS */ -grab_failed: - { - GST_DEBUG_OBJECT (v4l2src, "failed to grab a frame"); - return GST_FLOW_ERROR; - } -queue_failed: - { - GST_DEBUG_OBJECT (v4l2src, "failed to queue frame"); - gst_buffer_unref (*buf); - return GST_FLOW_ERROR; - } -} - -static GstFlowReturn -gst_v4l2src_create (GstPushSrc * src, GstBuffer ** buf) -{ - GstV4l2Src *v4l2src = GST_V4L2SRC (src); - GstFlowReturn ret; - - if (v4l2src->breq.memory == V4L2_MEMORY_MMAP) { - ret = gst_v4l2src_get_mmap (v4l2src, buf); - } else { - ret = gst_v4l2src_get_read (v4l2src, buf); - } - return ret; -} diff --git a/sys/v4l2/gstv4l2src.h b/sys/v4l2/gstv4l2src.h deleted file mode 100644 index 87923e4ee9..0000000000 --- a/sys/v4l2/gstv4l2src.h +++ /dev/null @@ -1,117 +0,0 @@ -/* GStreamer - * - * Copyright (C) 2001-2002 Ronald Bultje - * 2006 Edgard Lima - * - * gstv4l2src.h: BT8x8/V4L2 source element - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_V4L2SRC_H__ -#define __GST_V4L2SRC_H__ - -#include - -GST_DEBUG_CATEGORY_EXTERN (v4l2src_debug); - -#define GST_V4L2_MAX_BUFFERS 16 -#define GST_V4L2_MIN_BUFFERS 2 -#define GST_V4L2_MAX_SIZE (1<<15) /* 2^15 == 32768 */ - -G_BEGIN_DECLS - -#define GST_TYPE_V4L2SRC \ - (gst_v4l2src_get_type()) -#define GST_V4L2SRC(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_V4L2SRC,GstV4l2Src)) -#define GST_V4L2SRC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_V4L2SRC,GstV4l2SrcClass)) -#define GST_IS_V4L2SRC(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_V4L2SRC)) -#define GST_IS_V4L2SRC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_V4L2SRC)) - -typedef struct _GstV4l2BufferPool GstV4l2BufferPool; -typedef struct _GstV4l2Buffer GstV4l2Buffer; -typedef struct _GstV4l2Src GstV4l2Src; -typedef struct _GstV4l2SrcClass GstV4l2SrcClass; - - -/* global info */ -struct _GstV4l2BufferPool -{ - gint refcount; /* number of users: 1 for every buffer, 1 for element */ - gint video_fd; - guint buffer_count; - GstV4l2Buffer *buffers; -}; - -struct _GstV4l2Buffer -{ - struct v4l2_buffer buffer; - guint8 *start; - guint length; - gint refcount; /* add 1 if in use by element, add 1 if in use by GstBuffer */ - GstV4l2BufferPool *pool; -}; - -/** - * GstV4l2Src: - * @pushsrc: parent #GstPushSrc. - * - * Opaque object. - */ -struct _GstV4l2Src -{ - GstPushSrc pushsrc; - - /*< private >*/ - GstV4l2Object * v4l2object; - - /* pads */ - GstPad *srcpad; - - /* internal lists */ - GSList *formats; /* list of available capture formats */ - - /* buffers */ - GstV4l2BufferPool *pool; - - struct v4l2_requestbuffers breq; - struct v4l2_format format; - - /* True if we want to stop */ - gboolean quit, is_capturing; - - guint64 offset; - - /* how are we going to push buffers? */ - guint fps_n, fps_d; -}; - -struct _GstV4l2SrcClass -{ - GstPushSrcClass parent_class; - - GList *v4l2_class_devices; -}; - -GType gst_v4l2src_get_type (void); - -G_END_DECLS - -#endif /* __GST_V4L2SRC_H__ */ diff --git a/sys/v4l2/gstv4l2tuner.c b/sys/v4l2/gstv4l2tuner.c deleted file mode 100644 index 5eb7877681..0000000000 --- a/sys/v4l2/gstv4l2tuner.c +++ /dev/null @@ -1,341 +0,0 @@ -/* GStreamer - * - * Copyright (C) 2003 Ronald Bultje - * 2006 Edgard Lima - * - * gstv4l2tuner.c: tuner interface implementation for V4L2 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "gstv4l2tuner.h" -#include "gstv4l2object.h" -#include "v4l2_calls.h" -#include "v4l2src_calls.h" - -static void gst_v4l2_tuner_channel_class_init (GstV4l2TunerChannelClass * - klass); -static void gst_v4l2_tuner_channel_init (GstV4l2TunerChannel * channel); - -static void gst_v4l2_tuner_norm_class_init (GstV4l2TunerNormClass * klass); -static void gst_v4l2_tuner_norm_init (GstV4l2TunerNorm * norm); - -static GstTunerNormClass *norm_parent_class = NULL; -static GstTunerChannelClass *channel_parent_class = NULL; - -GType -gst_v4l2_tuner_channel_get_type (void) -{ - static GType gst_v4l2_tuner_channel_type = 0; - - if (!gst_v4l2_tuner_channel_type) { - static const GTypeInfo v4l2_tuner_channel_info = { - sizeof (GstV4l2TunerChannelClass), - NULL, - NULL, - (GClassInitFunc) gst_v4l2_tuner_channel_class_init, - NULL, - NULL, - sizeof (GstV4l2TunerChannel), - 0, - (GInstanceInitFunc) gst_v4l2_tuner_channel_init, - NULL - }; - - gst_v4l2_tuner_channel_type = - g_type_register_static (GST_TYPE_TUNER_CHANNEL, - "GstV4l2TunerChannel", &v4l2_tuner_channel_info, 0); - } - - return gst_v4l2_tuner_channel_type; -} - -static void -gst_v4l2_tuner_channel_class_init (GstV4l2TunerChannelClass * klass) -{ - channel_parent_class = g_type_class_peek_parent (klass); -} - -static void -gst_v4l2_tuner_channel_init (GstV4l2TunerChannel * channel) -{ - channel->index = (guint32) - 1; - channel->tuner = (guint32) - 1; - channel->audio = (guint32) - 1; -} - -GType -gst_v4l2_tuner_norm_get_type (void) -{ - static GType gst_v4l2_tuner_norm_type = 0; - - if (!gst_v4l2_tuner_norm_type) { - static const GTypeInfo v4l2_tuner_norm_info = { - sizeof (GstV4l2TunerNormClass), - NULL, - NULL, - (GClassInitFunc) gst_v4l2_tuner_norm_class_init, - NULL, - NULL, - sizeof (GstV4l2TunerNorm), - 0, - (GInstanceInitFunc) gst_v4l2_tuner_norm_init, - NULL - }; - - gst_v4l2_tuner_norm_type = - g_type_register_static (GST_TYPE_TUNER_NORM, - "GstV4l2TunerNorm", &v4l2_tuner_norm_info, 0); - } - - return gst_v4l2_tuner_norm_type; -} - -static void -gst_v4l2_tuner_norm_class_init (GstV4l2TunerNormClass * klass) -{ - norm_parent_class = g_type_class_peek_parent (klass); -} - -static void -gst_v4l2_tuner_norm_init (GstV4l2TunerNorm * norm) -{ - norm->index = 0; -} - -static G_GNUC_UNUSED gboolean -gst_v4l2_tuner_contains_channel (GstV4l2Object * v4l2object, - GstV4l2TunerChannel * v4l2channel) -{ - const GList *item; - - for (item = v4l2object->channels; item != NULL; item = item->next) - if (item->data == v4l2channel) - return TRUE; - - return FALSE; -} - -const GList * -gst_v4l2_tuner_list_channels (GstV4l2Object * v4l2object) -{ - return v4l2object->channels; -} - -void -gst_v4l2_tuner_set_channel_and_notify (GstV4l2Object * v4l2object, - GstTunerChannel * channel) -{ - if (gst_v4l2_tuner_set_channel (v4l2object, channel)) { - g_object_notify (G_OBJECT (v4l2object->element), "channel"); - } -} - -gboolean -gst_v4l2_tuner_set_channel (GstV4l2Object * v4l2object, - GstTunerChannel * channel) -{ - GstV4l2TunerChannel *v4l2channel = GST_V4L2_TUNER_CHANNEL (channel); - - /* assert that we're opened and that we're using a known item */ - g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2object), FALSE); - g_return_val_if_fail (gst_v4l2_tuner_contains_channel (v4l2object, - v4l2channel), FALSE); - - if (v4l2object->set_in_out_func (v4l2object, v4l2channel->index)) { - gst_tuner_channel_changed (GST_TUNER (v4l2object->element), channel); - v4l2object->update_fps_func (v4l2object); - return TRUE; - } - - return FALSE; - -} - -GstTunerChannel * -gst_v4l2_tuner_get_channel (GstV4l2Object * v4l2object) -{ - GList *item; - gint channel; - - /* assert that we're opened and that we're using a known item */ - g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2object), NULL); - - v4l2object->get_in_out_func (v4l2object, &channel); - - for (item = v4l2object->channels; item != NULL; item = item->next) { - if (channel == GST_V4L2_TUNER_CHANNEL (item->data)->index) - return (GstTunerChannel *) item->data; - } - - return NULL; -} - -static G_GNUC_UNUSED gboolean -gst_v4l2_tuner_contains_norm (GstV4l2Object * v4l2object, - GstV4l2TunerNorm * v4l2norm) -{ - const GList *item; - - for (item = v4l2object->norms; item != NULL; item = item->next) - if (item->data == v4l2norm) - return TRUE; - - return FALSE; -} - -const GList * -gst_v4l2_tuner_list_norms (GstV4l2Object * v4l2object) -{ - return v4l2object->norms; -} - -void -gst_v4l2_tuner_set_norm_and_notify (GstV4l2Object * v4l2object, - GstTunerNorm * norm) -{ - if (gst_v4l2_tuner_set_norm (v4l2object, norm)) { - g_object_notify (G_OBJECT (v4l2object->element), "norm"); - } -} - -gboolean -gst_v4l2_tuner_set_norm (GstV4l2Object * v4l2object, GstTunerNorm * norm) -{ - GstV4l2TunerNorm *v4l2norm = GST_V4L2_TUNER_NORM (norm); - - /* assert that we're opened and that we're using a known item */ - g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2object), FALSE); - g_return_val_if_fail (gst_v4l2_tuner_contains_norm (v4l2object, v4l2norm), - FALSE); - - if (gst_v4l2_set_norm (v4l2object, v4l2norm->index)) { - gst_tuner_norm_changed (GST_TUNER (v4l2object->element), norm); - v4l2object->update_fps_func (v4l2object); - return TRUE; - } - - return FALSE; - -} - -GstTunerNorm * -gst_v4l2_tuner_get_norm (GstV4l2Object * v4l2object) -{ - GList *item; - v4l2_std_id norm; - - /* assert that we're opened and that we're using a known item */ - g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2object), NULL); - - gst_v4l2_get_norm (v4l2object, &norm); - - for (item = v4l2object->norms; item != NULL; item = item->next) { - if (norm == GST_V4L2_TUNER_NORM (item->data)->index) - return (GstTunerNorm *) item->data; - } - - return NULL; -} - -void -gst_v4l2_tuner_set_frequency_and_notify (GstV4l2Object * v4l2object, - GstTunerChannel * channel, gulong frequency) -{ - if (gst_v4l2_tuner_set_frequency (v4l2object, channel, frequency)) { - g_object_notify (G_OBJECT (v4l2object->element), "frequency"); - } -} - -gboolean -gst_v4l2_tuner_set_frequency (GstV4l2Object * v4l2object, - GstTunerChannel * channel, gulong frequency) -{ - GstV4l2TunerChannel *v4l2channel = GST_V4L2_TUNER_CHANNEL (channel); - gint chan; - - /* assert that we're opened and that we're using a known item */ - g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2object), FALSE); - g_return_val_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel, - GST_TUNER_CHANNEL_FREQUENCY), FALSE); - g_return_val_if_fail (gst_v4l2_tuner_contains_channel (v4l2object, - v4l2channel), FALSE); - - v4l2object->get_in_out_func (v4l2object, &chan); - if (chan == GST_V4L2_TUNER_CHANNEL (channel)->index && - GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)) { - if (gst_v4l2_set_frequency (v4l2object, v4l2channel->tuner, frequency)) { - gst_tuner_frequency_changed (GST_TUNER (v4l2object->element), channel, - frequency); - return TRUE; - } - } - return FALSE; -} - -gulong -gst_v4l2_tuner_get_frequency (GstV4l2Object * v4l2object, - GstTunerChannel * channel) -{ - GstV4l2TunerChannel *v4l2channel = GST_V4L2_TUNER_CHANNEL (channel); - gint chan; - gulong frequency = 0; - - /* assert that we're opened and that we're using a known item */ - g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2object), 0); - g_return_val_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel, - GST_TUNER_CHANNEL_FREQUENCY), 0); - g_return_val_if_fail (gst_v4l2_tuner_contains_channel (v4l2object, - v4l2channel), 0); - - v4l2object->get_in_out_func (v4l2object, &chan); - if (chan == GST_V4L2_TUNER_CHANNEL (channel)->index && - GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)) { - gst_v4l2_get_frequency (v4l2object, v4l2channel->tuner, &frequency); - } - - return frequency; -} - -gint -gst_v4l2_tuner_signal_strength (GstV4l2Object * v4l2object, - GstTunerChannel * channel) -{ - GstV4l2TunerChannel *v4l2channel = GST_V4L2_TUNER_CHANNEL (channel); - gint chan; - gulong signal = 0; - - /* assert that we're opened and that we're using a known item */ - g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2object), 0); - g_return_val_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel, - GST_TUNER_CHANNEL_FREQUENCY), 0); - g_return_val_if_fail (gst_v4l2_tuner_contains_channel (v4l2object, - v4l2channel), 0); - - v4l2object->get_in_out_func (v4l2object, &chan); - if (chan == GST_V4L2_TUNER_CHANNEL (channel)->index && - GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)) { - gst_v4l2_signal_strength (v4l2object, v4l2channel->tuner, &signal); - } - - return signal; -} diff --git a/sys/v4l2/gstv4l2tuner.h b/sys/v4l2/gstv4l2tuner.h deleted file mode 100644 index 40d2e1fc4c..0000000000 --- a/sys/v4l2/gstv4l2tuner.h +++ /dev/null @@ -1,195 +0,0 @@ -/* GStreamer - * - * Copyright (C) 2003 Ronald Bultje - * 2006 Edgard Lima - * - * gstv4l2tuner.h: tuner interface implementation for V4L2 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_V4L2_TUNER_H__ -#define __GST_V4L2_TUNER_H__ - -#include -#include - -#include "gstv4l2object.h" - -G_BEGIN_DECLS - -#define GST_TYPE_V4L2_TUNER_CHANNEL \ - (gst_v4l2_tuner_channel_get_type ()) -#define GST_V4L2_TUNER_CHANNEL(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_V4L2_TUNER_CHANNEL, \ - GstV4l2TunerChannel)) -#define GST_V4L2_TUNER_CHANNEL_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_V4L2_TUNER_CHANNEL, \ - GstV4l2TunerChannelClass)) -#define GST_IS_V4L2_TUNER_CHANNEL(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_V4L2_TUNER_CHANNEL)) -#define GST_IS_V4L2_TUNER_CHANNEL_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_V4L2_TUNER_CHANNEL)) - -typedef struct _GstV4l2TunerChannel { - GstTunerChannel parent; - - guint32 index; - guint32 tuner; - guint32 audio; -} GstV4l2TunerChannel; - -typedef struct _GstV4l2TunerChannelClass { - GstTunerChannelClass parent; -} GstV4l2TunerChannelClass; - -#define GST_TYPE_V4L2_TUNER_NORM \ - (gst_v4l2_tuner_norm_get_type ()) -#define GST_V4L2_TUNER_NORM(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_V4L2_TUNER_NORM, \ - GstV4l2TunerNorm)) -#define GST_V4L2_TUNER_NORM_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_V4L2_TUNER_NORM, \ - GstV4l2TunerNormClass)) -#define GST_IS_V4L2_TUNER_NORM(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_V4L2_TUNER_NORM)) -#define GST_IS_V4L2_TUNER_NORM_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_V4L2_TUNER_NORM)) - -typedef struct _GstV4l2TunerNorm { - GstTunerNorm parent; - - v4l2_std_id index; -} GstV4l2TunerNorm; - -typedef struct _GstV4l2TunerNormClass { - GstTunerNormClass parent; -} GstV4l2TunerNormClass; - -GType gst_v4l2_tuner_channel_get_type (void); -GType gst_v4l2_tuner_norm_get_type (void); - -/* channels */ -const GList* gst_v4l2_tuner_list_channels (GstV4l2Object * v4l2object); -void gst_v4l2_tuner_set_channel_and_notify (GstV4l2Object * v4l2object, - GstTunerChannel * channel); -GstTunerChannel* gst_v4l2_tuner_get_channel (GstV4l2Object * v4l2object); -gboolean gst_v4l2_tuner_set_channel (GstV4l2Object * v4l2object, - GstTunerChannel * channel); -/* norms */ -const GList* gst_v4l2_tuner_list_norms (GstV4l2Object * v4l2object); -void gst_v4l2_tuner_set_norm_and_notify (GstV4l2Object * v4l2object, - GstTunerNorm * norm); -GstTunerNorm* gst_v4l2_tuner_get_norm (GstV4l2Object * v4l2object); -gboolean gst_v4l2_tuner_set_norm (GstV4l2Object * v4l2object, - GstTunerNorm * norm); -/* frequency */ -void gst_v4l2_tuner_set_frequency_and_notify (GstV4l2Object * v4l2object, - GstTunerChannel * channel, - gulong frequency); -gint gst_v4l2_tuner_signal_strength (GstV4l2Object * v4l2object, - GstTunerChannel * channel); -gulong gst_v4l2_tuner_get_frequency (GstV4l2Object * v4l2object, - GstTunerChannel * channel); -gboolean gst_v4l2_tuner_set_frequency (GstV4l2Object * v4l2object, - GstTunerChannel * channel, - gulong frequency); - -#define GST_IMPLEMENT_V4L2_TUNER_METHODS(Type, interface_as_function) \ - \ -static const GList * \ -interface_as_function ## _tuner_list_channels (GstTuner * mixer) \ -{ \ - Type *this = (Type*) mixer; \ - return gst_v4l2_tuner_list_channels (this->v4l2object); \ -} \ - \ -static void \ -interface_as_function ## _tuner_set_channel_and_notify (GstTuner * mixer, \ - GstTunerChannel * channel) \ -{ \ - Type *this = (Type*) mixer; \ - gst_v4l2_tuner_set_channel_and_notify (this->v4l2object, channel); \ -} \ -static GstTunerChannel * \ -interface_as_function ## _tuner_get_channel (GstTuner * mixer) \ -{ \ - Type *this = (Type*) mixer; \ - return gst_v4l2_tuner_get_channel (this->v4l2object); \ -} \ -static const GList * \ -interface_as_function ## _tuner_list_norms (GstTuner * mixer) \ -{ \ - Type *this = (Type*) mixer; \ - return gst_v4l2_tuner_list_norms (this->v4l2object); \ -} \ -static void \ -interface_as_function ## _tuner_set_norm_and_notify (GstTuner * mixer, \ - GstTunerNorm * norm) \ -{ \ - Type *this = (Type*) mixer; \ - gst_v4l2_tuner_set_norm_and_notify (this->v4l2object, norm); \ -} \ -static GstTunerNorm * \ -interface_as_function ## _tuner_get_norm (GstTuner * mixer) \ -{ \ - Type *this = (Type*) mixer; \ - return gst_v4l2_tuner_get_norm (this->v4l2object); \ -} \ - \ -static void \ -interface_as_function ## _tuner_set_frequency_and_notify (GstTuner * mixer, \ - GstTunerChannel * channel, \ - gulong frequency) \ -{ \ - Type *this = (Type*) mixer; \ - gst_v4l2_tuner_set_frequency_and_notify (this->v4l2object, channel, frequency); \ -} \ - \ -static gulong \ -interface_as_function ## _tuner_get_frequency (GstTuner * mixer, \ - GstTunerChannel * channel) \ -{ \ - Type *this = (Type*) mixer; \ - return gst_v4l2_tuner_get_frequency (this->v4l2object, channel); \ -} \ - \ -static gint \ -interface_as_function ## _tuner_signal_strength (GstTuner * mixer, \ - GstTunerChannel * channel) \ -{ \ - Type *this = (Type*) mixer; \ - return gst_v4l2_tuner_signal_strength (this->v4l2object, channel); \ -} \ - \ -void \ -interface_as_function ## _tuner_interface_init (GstTunerClass * klass) \ -{ \ - /* default virtual functions */ \ - klass->list_channels = interface_as_function ## _tuner_list_channels; \ - klass->set_channel = interface_as_function ## _tuner_set_channel_and_notify; \ - klass->get_channel = interface_as_function ## _tuner_get_channel; \ - \ - klass->list_norms = interface_as_function ## _tuner_list_norms; \ - klass->set_norm = interface_as_function ## _tuner_set_norm_and_notify; \ - klass->get_norm = interface_as_function ## _tuner_get_norm; \ - \ - klass->set_frequency = interface_as_function ## _tuner_set_frequency_and_notify; \ - klass->get_frequency = interface_as_function ## _tuner_get_frequency; \ - klass->signal_strength = interface_as_function ## _tuner_signal_strength; \ -} \ - -#endif /* __GST_V4L2_TUNER_H__ */ diff --git a/sys/v4l2/gstv4l2vidorient.c b/sys/v4l2/gstv4l2vidorient.c deleted file mode 100644 index 07ac412bb2..0000000000 --- a/sys/v4l2/gstv4l2vidorient.c +++ /dev/null @@ -1,96 +0,0 @@ -/* GStreamer - * - * Copyright (C) 2006 Edgard Lima - * - * gstv4l2vidorient.c: video orientation interface implementation for V4L2 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "gstv4l2vidorient.h" -#include "gstv4l2object.h" -#include "v4l2_calls.h" -#include "v4l2src_calls.h" - -GST_DEBUG_CATEGORY_STATIC (v4l2vo_debug); -#define GST_CAT_DEFAULT v4l2vo_debug - -void -gst_v4l2_video_orientation_interface_init (GstVideoOrientationInterface * klass) -{ - GST_DEBUG_CATEGORY_INIT (v4l2vo_debug, "v4l2vo", 0, - "V4L2 VideoOrientation interface debugging"); -} - - -gboolean -gst_v4l2_video_orientation_get_hflip (GstV4l2Object * v4l2object, - gboolean * flip) -{ - - return gst_v4l2_get_attribute (v4l2object, V4L2_CID_HFLIP, flip); -} - -gboolean -gst_v4l2_video_orientation_get_vflip (GstV4l2Object * v4l2object, - gboolean * flip) -{ - return gst_v4l2_get_attribute (v4l2object, V4L2_CID_VFLIP, flip); -} - -gboolean -gst_v4l2_video_orientation_get_hcenter (GstV4l2Object * v4l2object, - gint * center) -{ - return gst_v4l2_get_attribute (v4l2object, V4L2_CID_HCENTER, center); -} - -gboolean -gst_v4l2_video_orientation_get_vcenter (GstV4l2Object * v4l2object, - gint * center) -{ - return gst_v4l2_get_attribute (v4l2object, V4L2_CID_VCENTER, center); -} - -gboolean -gst_v4l2_video_orientation_set_hflip (GstV4l2Object * v4l2object, gboolean flip) -{ - return gst_v4l2_set_attribute (v4l2object, V4L2_CID_HFLIP, flip); -} - -gboolean -gst_v4l2_video_orientation_set_vflip (GstV4l2Object * v4l2object, gboolean flip) -{ - return gst_v4l2_set_attribute (v4l2object, V4L2_CID_VFLIP, flip); -} - -gboolean -gst_v4l2_video_orientation_set_hcenter (GstV4l2Object * v4l2object, gint center) -{ - return gst_v4l2_set_attribute (v4l2object, V4L2_CID_HCENTER, center); -} - -gboolean -gst_v4l2_video_orientation_set_vcenter (GstV4l2Object * v4l2object, gint center) -{ - return gst_v4l2_set_attribute (v4l2object, V4L2_CID_VCENTER, center); -} diff --git a/sys/v4l2/gstv4l2vidorient.h b/sys/v4l2/gstv4l2vidorient.h deleted file mode 100644 index 965fc05972..0000000000 --- a/sys/v4l2/gstv4l2vidorient.h +++ /dev/null @@ -1,117 +0,0 @@ -/* GStreamer - * - * Copyright (C) 2006 Edgard Lima - * - * gstv4l2vidorient.h: video orientation interface implementation for V4L2 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_V4L2_VIDORIENT_H__ -#define __GST_V4L2_VIDORIENT_H__ - -#include -#include - -#include "gstv4l2object.h" - -G_BEGIN_DECLS - -void gst_v4l2_video_orientation_interface_init (GstVideoOrientationInterface * klass); - -gboolean gst_v4l2_video_orientation_get_hflip (GstV4l2Object *v4l2object, gboolean *flip); -gboolean gst_v4l2_video_orientation_get_vflip (GstV4l2Object *v4l2object, gboolean *flip); -gboolean gst_v4l2_video_orientation_get_hcenter (GstV4l2Object *v4l2object, gint *center); -gboolean gst_v4l2_video_orientation_get_vcenter (GstV4l2Object *v4l2object, gint *center); - -gboolean gst_v4l2_video_orientation_set_hflip (GstV4l2Object *v4l2object, gboolean flip); -gboolean gst_v4l2_video_orientation_set_vflip (GstV4l2Object *v4l2object, gboolean flip); -gboolean gst_v4l2_video_orientation_set_hcenter (GstV4l2Object *v4l2object, gint center); -gboolean gst_v4l2_video_orientation_set_vcenter (GstV4l2Object *v4l2object, gint center); - -#define GST_IMPLEMENT_V4L2_VIDORIENT_METHODS(Type, interface_as_function) \ - \ - static gboolean \ - interface_as_function ## _video_orientation_get_hflip (GstVideoOrientation *vo, gboolean *flip) \ - { \ - Type *this = (Type*) vo; \ - return gst_v4l2_video_orientation_get_hflip (this->v4l2object, flip); \ - } \ - \ - static gboolean \ - interface_as_function ## _video_orientation_get_vflip (GstVideoOrientation *vo, gboolean *flip) \ - { \ - Type *this = (Type*) vo; \ - return gst_v4l2_video_orientation_get_vflip (this->v4l2object, flip); \ - } \ - \ - static gboolean \ - interface_as_function ## _video_orientation_get_hcenter (GstVideoOrientation *vo, gint *center) \ - { \ - Type *this = (Type*) vo; \ - return gst_v4l2_video_orientation_get_hcenter (this->v4l2object, center); \ - } \ - \ - static gboolean \ - interface_as_function ## _video_orientation_get_vcenter (GstVideoOrientation *vo, gint *center) \ - { \ - Type *this = (Type*) vo; \ - return gst_v4l2_video_orientation_get_vcenter (this->v4l2object, center); \ - } \ - \ - static gboolean \ - interface_as_function ## _video_orientation_set_hflip (GstVideoOrientation *vo, gboolean flip) \ - { \ - Type *this = (Type*) vo; \ - return gst_v4l2_video_orientation_set_hflip (this->v4l2object, flip); \ - } \ - \ - static gboolean \ - interface_as_function ## _video_orientation_set_vflip (GstVideoOrientation *vo, gboolean flip) \ - { \ - Type *this = (Type*) vo; \ - return gst_v4l2_video_orientation_set_vflip (this->v4l2object, flip); \ - } \ - \ - static gboolean \ - interface_as_function ## _video_orientation_set_hcenter (GstVideoOrientation *vo, gint center) \ - { \ - Type *this = (Type*) vo; \ - return gst_v4l2_video_orientation_set_hcenter (this->v4l2object, center); \ - } \ - \ - static gboolean \ - interface_as_function ## _video_orientation_set_vcenter (GstVideoOrientation *vo, gint center) \ - { \ - Type *this = (Type*) vo; \ - return gst_v4l2_video_orientation_set_vcenter (this->v4l2object, center); \ - } \ - \ - void \ - interface_as_function ## _video_orientation_interface_init (GstVideoOrientationInterface * klass) \ - { \ - /* default virtual functions */ \ - klass->get_hflip = interface_as_function ## _video_orientation_get_hflip; \ - klass->get_vflip = interface_as_function ## _video_orientation_get_vflip; \ - klass->get_hcenter = interface_as_function ## _video_orientation_get_hcenter; \ - klass->get_vcenter = interface_as_function ## _video_orientation_get_vcenter; \ - klass->set_hflip = interface_as_function ## _video_orientation_set_hflip; \ - klass->set_vflip = interface_as_function ## _video_orientation_set_vflip; \ - klass->set_hcenter = interface_as_function ## _video_orientation_set_hcenter; \ - klass->set_vcenter = interface_as_function ## _video_orientation_set_vcenter; \ - } - -#endif /* __GST_V4L2_VIDORIENT_H__ */ diff --git a/sys/v4l2/gstv4l2xoverlay.c b/sys/v4l2/gstv4l2xoverlay.c deleted file mode 100644 index 5a07e510a4..0000000000 --- a/sys/v4l2/gstv4l2xoverlay.c +++ /dev/null @@ -1,251 +0,0 @@ -/* GStreamer - * - * Copyright (C) 2003 Ronald Bultje - * 2006 Edgard Lima - * - * gstv4l2xoverlay.c: X-based overlay interface implementation for V4L2 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include "gstv4l2xoverlay.h" -#include "gstv4l2object.h" -#include "v4l2_calls.h" - -struct _GstV4l2Xv -{ - Display *dpy; - gint port, idle_id; - GMutex *mutex; -}; - -GST_DEBUG_CATEGORY_STATIC (v4l2xv_debug); -#define GST_CAT_DEFAULT v4l2xv_debug - -static void gst_v4l2_xoverlay_set_xwindow_id (GstV4l2Object * v4l2object, - XID xwindow_id); - - - -void -gst_v4l2_xoverlay_interface_init (GstXOverlayClass * klass) -{ - GST_DEBUG_CATEGORY_INIT (v4l2xv_debug, "v4l2xv", 0, - "V4L2 XOverlay interface debugging"); -} - -static void -gst_v4l2_xoverlay_open (GstV4l2Object * v4l2object) -{ - struct stat s; - GstV4l2Xv *v4l2xv; - const gchar *name = g_getenv ("DISPLAY"); - unsigned int ver, rel, req, ev, err, anum; - int i, id = 0, first_id = 0, min; - XvAdaptorInfo *ai; - Display *dpy; - - /* we need a display, obviously */ - if (!name || !(dpy = XOpenDisplay (name))) { - GST_WARNING_OBJECT (v4l2object->element, - "No $DISPLAY set or failed to open - no overlay"); - return; - } - - /* First let's check that XVideo extension is available */ - if (!XQueryExtension (dpy, "XVideo", &i, &i, &i)) { - GST_WARNING_OBJECT (v4l2object->element, - "Xv extension not available - no overlay"); - XCloseDisplay (dpy); - return; - } - - /* find port that belongs to this device */ - if (XvQueryExtension (dpy, &ver, &rel, &req, &ev, &err) != Success) { - GST_WARNING_OBJECT (v4l2object->element, - "Xv extension not supported - no overlay"); - XCloseDisplay (dpy); - return; - } - if (XvQueryAdaptors (dpy, DefaultRootWindow (dpy), &anum, &ai) != Success) { - GST_WARNING_OBJECT (v4l2object->element, "Failed to query Xv adaptors"); - XCloseDisplay (dpy); - return; - } - if (fstat (v4l2object->video_fd, &s) < 0) { - GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND, - (_("Cannot identify device '%s'."), v4l2object->videodev), - GST_ERROR_SYSTEM); - XCloseDisplay (dpy); - return; - } - min = s.st_rdev & 0xff; - for (i = 0; i < anum; i++) { - if (!strcmp (ai[i].name, "video4linux2")) { - if (first_id == 0) - first_id = ai[i].base_id; - - /* hmm... */ - if (first_id != 0 && ai[i].base_id == first_id + min) - id = ai[i].base_id; - } - } - XvFreeAdaptorInfo (ai); - - if (id == 0) { - GST_WARNING_OBJECT (v4l2object->element, - "Did not find XvPortID for device - no overlay"); - XCloseDisplay (dpy); - return; - } - - v4l2xv = g_new0 (GstV4l2Xv, 1); - v4l2xv->dpy = dpy; - v4l2xv->port = id; - v4l2xv->mutex = g_mutex_new (); - v4l2xv->idle_id = 0; - v4l2object->xv = v4l2xv; - - if (v4l2object->xwindow_id) { - gst_v4l2_xoverlay_set_xwindow_id (v4l2object, v4l2object->xwindow_id); - } -} - -static void -gst_v4l2_xoverlay_close (GstV4l2Object * v4l2object) -{ - GstV4l2Xv *v4l2xv = v4l2object->xv; - - if (!v4l2object->xv) - return; - - if (v4l2object->xwindow_id) { - gst_v4l2_xoverlay_set_xwindow_id (v4l2object, 0); - } - - XCloseDisplay (v4l2xv->dpy); - g_mutex_free (v4l2xv->mutex); - if (v4l2xv->idle_id) - g_source_remove (v4l2xv->idle_id); - g_free (v4l2xv); - v4l2object->xv = NULL; -} - -void -gst_v4l2_xoverlay_start (GstV4l2Object * v4l2object) -{ - if (v4l2object->xwindow_id) { - gst_v4l2_xoverlay_open (v4l2object); - } -} - -void -gst_v4l2_xoverlay_stop (GstV4l2Object * v4l2object) -{ - gst_v4l2_xoverlay_close (v4l2object); -} - -static gboolean -idle_refresh (gpointer data) -{ - GstV4l2Object *v4l2object = GST_V4L2_OBJECT (data); - GstV4l2Xv *v4l2xv = v4l2object->xv; - XWindowAttributes attr; - - if (v4l2xv) { - g_mutex_lock (v4l2xv->mutex); - - XGetWindowAttributes (v4l2xv->dpy, v4l2object->xwindow_id, &attr); - XvPutVideo (v4l2xv->dpy, v4l2xv->port, v4l2object->xwindow_id, - DefaultGC (v4l2xv->dpy, DefaultScreen (v4l2xv->dpy)), - 0, 0, attr.width, attr.height, 0, 0, attr.width, attr.height); - - v4l2xv->idle_id = 0; - g_mutex_unlock (v4l2xv->mutex); - } - - /* once */ - return FALSE; -} - -static void -gst_v4l2_xoverlay_set_xwindow_id (GstV4l2Object * v4l2object, XID xwindow_id) -{ - GstV4l2Xv *v4l2xv; - XWindowAttributes attr; - gboolean change = (v4l2object->xwindow_id != xwindow_id); - - GST_LOG_OBJECT (v4l2object->element, "Setting XID to %lx", - (gulong) xwindow_id); - - if (!v4l2object->xv && GST_V4L2_IS_OPEN (v4l2object)) - gst_v4l2_xoverlay_open (v4l2object); - - v4l2xv = v4l2object->xv; - - if (v4l2xv) - g_mutex_lock (v4l2xv->mutex); - - if (change) { - if (v4l2object->xwindow_id && v4l2xv) { - GST_DEBUG_OBJECT (v4l2object->element, - "Deactivating old port %lx", v4l2object->xwindow_id); - - XvSelectPortNotify (v4l2xv->dpy, v4l2xv->port, 0); - XvSelectVideoNotify (v4l2xv->dpy, v4l2object->xwindow_id, 0); - XvStopVideo (v4l2xv->dpy, v4l2xv->port, v4l2object->xwindow_id); - } - - v4l2object->xwindow_id = xwindow_id; - } - - if (!v4l2xv || xwindow_id == 0) { - if (v4l2xv) - g_mutex_unlock (v4l2xv->mutex); - return; - } - - if (change) { - GST_DEBUG_OBJECT (v4l2object->element, "Activating new port %lx", - xwindow_id); - - /* draw */ - XvSelectPortNotify (v4l2xv->dpy, v4l2xv->port, 1); - XvSelectVideoNotify (v4l2xv->dpy, v4l2object->xwindow_id, 1); - } - - XGetWindowAttributes (v4l2xv->dpy, v4l2object->xwindow_id, &attr); - XvPutVideo (v4l2xv->dpy, v4l2xv->port, v4l2object->xwindow_id, - DefaultGC (v4l2xv->dpy, DefaultScreen (v4l2xv->dpy)), - 0, 0, attr.width, attr.height, 0, 0, attr.width, attr.height); - - if (v4l2xv->idle_id) - g_source_remove (v4l2xv->idle_id); - v4l2xv->idle_id = g_idle_add (idle_refresh, v4l2object); - g_mutex_unlock (v4l2xv->mutex); -} diff --git a/sys/v4l2/gstv4l2xoverlay.h b/sys/v4l2/gstv4l2xoverlay.h deleted file mode 100644 index 8eac0e2c7b..0000000000 --- a/sys/v4l2/gstv4l2xoverlay.h +++ /dev/null @@ -1,62 +0,0 @@ -/* GStreamer - * - * Copyright (C) 2003 Ronald Bultje - * 2006 Edgard Lima - * - * gstv4l2xoverlay.h: tv mixer interface implementation for V4L2 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_V4L2_X_OVERLAY_H__ -#define __GST_V4L2_X_OVERLAY_H__ - -#include - -#include -#include - -#include "gstv4l2object.h" - -G_BEGIN_DECLS - -void gst_v4l2_xoverlay_start (GstV4l2Object *v4l2object); -void gst_v4l2_xoverlay_stop (GstV4l2Object *v4l2object); - -void gst_v4l2_xoverlay_interface_init (GstXOverlayClass * klass); - -#define GST_IMPLEMENT_V4L2_XOVERLAY_METHODS(Type, interface_as_function) \ - \ -static void \ -interface_as_function ## _xoverlay_set_xwindow_id (GstXOverlay * xoverlay, \ - XID xwindow_id) \ -{ \ - Type *this = (Type*) xoverlay; \ - gst_v4l2_xoverlay_set_xwindow_id (this->v4l2object, xwindow_id); \ -} \ - \ -static void \ -interface_as_function ## _xoverlay_interface_init (GstXOverlayClass * klass) \ -{ \ - /* default virtual functions */ \ - klass->set_xwindow_id = interface_as_function ## _xoverlay_set_xwindow_id; \ - \ - gst_v4l2_xoverlay_interface_init(GstXOverlayClass * klass); \ -} \ - \ - - -#endif /* __GST_V4L2_X_OVERLAY_H__ */ diff --git a/sys/v4l2/v4l2_calls.c b/sys/v4l2/v4l2_calls.c deleted file mode 100644 index 96188450cf..0000000000 --- a/sys/v4l2/v4l2_calls.c +++ /dev/null @@ -1,748 +0,0 @@ -/* GStreamer - * - * Copyright (C) 2002 Ronald Bultje - * 2006 Edgard Lima - * - * v4l2_calls.c - generic V4L2 calls handling - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include "v4l2_calls.h" -#include "gstv4l2tuner.h" -#include "gstv4l2xoverlay.h" -#include "gstv4l2colorbalance.h" - -#include "gstv4l2src.h" - -GST_DEBUG_CATEGORY_EXTERN (v4l2_debug); -#define GST_CAT_DEFAULT v4l2_debug - -/****************************************************** - * gst_v4l2_get_capabilities(): - * get the device's capturing capabilities - * return value: TRUE on success, FALSE on error - ******************************************************/ -gboolean -gst_v4l2_get_capabilities (GstV4l2Object * v4l2object) -{ - GST_DEBUG_OBJECT (v4l2object->element, "getting capabilities"); - - if (!GST_V4L2_IS_OPEN (v4l2object)) - return FALSE; - - if (ioctl (v4l2object->video_fd, VIDIOC_QUERYCAP, &v4l2object->vcap) < 0) - goto cap_failed; - - return TRUE; - - /* ERRORS */ -cap_failed: - { - GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS, - (_("Error getting capabilities for device '%s': " - "It isn't a v4l2 driver. Check if it is a v4l1 driver."), - v4l2object->videodev), GST_ERROR_SYSTEM); - return FALSE; - } -} - - -/****************************************************** - * gst_v4l2_empty_lists() and gst_v4l2_fill_lists(): - * fill/empty the lists of enumerations - * return value: TRUE on success, FALSE on error - ******************************************************/ -static gboolean -gst_v4l2_fill_lists (GstV4l2Object * v4l2object) -{ - gint n; - - GST_DEBUG_OBJECT (v4l2object->element, "getting enumerations"); - GST_V4L2_CHECK_OPEN (v4l2object); - - GST_DEBUG_OBJECT (v4l2object->element, " channels"); - /* and now, the channels */ - for (n = 0;; n++) { - struct v4l2_input input; - GstV4l2TunerChannel *v4l2channel; - GstTunerChannel *channel; - - input.index = n; - if (ioctl (v4l2object->video_fd, VIDIOC_ENUMINPUT, &input) < 0) { - if (errno == EINVAL) - break; /* end of enumeration */ - else { - GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS, - (_("Failed to get %d in channel enumeration for %s."), - n, v4l2object->videodev), GST_ERROR_SYSTEM); - return FALSE; - } - } - - GST_DEBUG_OBJECT (v4l2object->element, " '%s'", input.name); - - v4l2channel = g_object_new (GST_TYPE_V4L2_TUNER_CHANNEL, NULL); - channel = GST_TUNER_CHANNEL (v4l2channel); - channel->label = g_strdup ((const gchar *) input.name); - channel->flags = GST_TUNER_CHANNEL_INPUT; - v4l2channel->index = n; - if (input.type == V4L2_INPUT_TYPE_TUNER) { - struct v4l2_tuner vtun; - - v4l2channel->tuner = input.tuner; - channel->flags |= GST_TUNER_CHANNEL_FREQUENCY; - - vtun.index = input.tuner; - if (ioctl (v4l2object->video_fd, VIDIOC_G_TUNER, &vtun) < 0) { - GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS, - (_("Failed to get tuner %d settings on %s."), - input.tuner, v4l2object->videodev), GST_ERROR_SYSTEM); - g_object_unref (G_OBJECT (channel)); - return FALSE; - } - channel->freq_multiplicator = - 62.5 * ((vtun.capability & V4L2_TUNER_CAP_LOW) ? 1 : 1000); - channel->min_frequency = vtun.rangelow * channel->freq_multiplicator; - channel->max_frequency = vtun.rangehigh * channel->freq_multiplicator; - channel->min_signal = 0; - channel->max_signal = 0xffff; - } - if (input.audioset) { - /* we take the first. We don't care for - * the others for now */ - while (!(input.audioset & (1 << v4l2channel->audio))) - v4l2channel->audio++; - channel->flags |= GST_TUNER_CHANNEL_AUDIO; - } - - v4l2object->channels = - g_list_append (v4l2object->channels, (gpointer) channel); - } - - GST_DEBUG_OBJECT (v4l2object->element, " norms"); - /* norms... */ - for (n = 0;; n++) { - struct v4l2_standard standard; - GstV4l2TunerNorm *v4l2norm; - GstTunerNorm *norm; - - /* fill in defaults */ - standard.frameperiod.denominator = 0; - standard.frameperiod.numerator = 1; - standard.index = n; - if (ioctl (v4l2object->video_fd, VIDIOC_ENUMSTD, &standard) < 0) { - if (errno == EINVAL) - break; /* end of enumeration */ - else { - GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS, - (_("Failed to get %d in norm enumeration for %s."), - n, v4l2object->videodev), GST_ERROR_SYSTEM); - return FALSE; - } - } - - GST_DEBUG_OBJECT (v4l2object->element, " '%s', fps: %d/%d", - standard.name, standard.frameperiod.denominator, - standard.frameperiod.numerator); - - v4l2norm = g_object_new (GST_TYPE_V4L2_TUNER_NORM, NULL); - norm = GST_TUNER_NORM (v4l2norm); - norm->label = g_strdup ((const gchar *) standard.name); - gst_value_set_fraction (&norm->framerate, - standard.frameperiod.denominator, standard.frameperiod.numerator); - v4l2norm->index = standard.id; - - v4l2object->norms = g_list_append (v4l2object->norms, (gpointer) norm); - } - - GST_DEBUG_OBJECT (v4l2object->element, " controls+menus"); - /* and lastly, controls+menus (if appropriate) */ - for (n = V4L2_CID_BASE;; n++) { - struct v4l2_queryctrl control; - GstV4l2ColorBalanceChannel *v4l2channel; - GstColorBalanceChannel *channel; - - /* when we reached the last official CID, continue with private CIDs */ - if (n == V4L2_CID_LASTP1) { - GST_DEBUG_OBJECT (v4l2object->element, "checking private CIDs"); - n = V4L2_CID_PRIVATE_BASE; - /* FIXME: We are still not handling private controls. We need a new GstInterface - to export those controls */ - break; - } - - control.id = n; - if (ioctl (v4l2object->video_fd, VIDIOC_QUERYCTRL, &control) < 0) { - if (errno == EINVAL) { - if (n < V4L2_CID_PRIVATE_BASE) - /* continue so that we also check private controls */ - continue; - else - break; - } else { - GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS, - (_("Failed to get %d in control enumeration for %s."), - n, v4l2object->videodev), GST_ERROR_SYSTEM); - return FALSE; - } - } - if (control.flags & V4L2_CTRL_FLAG_DISABLED) - continue; - - switch (n) { - case V4L2_CID_BRIGHTNESS: - case V4L2_CID_CONTRAST: - case V4L2_CID_SATURATION: - case V4L2_CID_HUE: - case V4L2_CID_BLACK_LEVEL: - case V4L2_CID_AUTO_WHITE_BALANCE: - case V4L2_CID_DO_WHITE_BALANCE: - case V4L2_CID_RED_BALANCE: - case V4L2_CID_BLUE_BALANCE: - case V4L2_CID_GAMMA: - case V4L2_CID_EXPOSURE: - case V4L2_CID_AUTOGAIN: - case V4L2_CID_GAIN: - /* we only handle these for now (why?) */ - break; - case V4L2_CID_HFLIP: - case V4L2_CID_VFLIP: - case V4L2_CID_HCENTER: - case V4L2_CID_VCENTER: - /* not handled here, handled by VideoOrientation interface */ - control.id++; - break; - case V4L2_CID_AUDIO_VOLUME: - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - case V4L2_CID_AUDIO_MUTE: - case V4L2_CID_AUDIO_LOUDNESS: - /* FIXME: We should implement GstMixer interface */ - /* fall through */ - default: - GST_DEBUG_OBJECT (v4l2object->element, - "ControlID %s (%x) unhandled, FIXME", control.name, n); - control.id++; - break; - } - if (n != control.id) - continue; - - GST_DEBUG_OBJECT (v4l2object->element, - "Adding ControlID %s (%x)", control.name, n); - v4l2channel = g_object_new (GST_TYPE_V4L2_COLOR_BALANCE_CHANNEL, NULL); - channel = GST_COLOR_BALANCE_CHANNEL (v4l2channel); - channel->label = g_strdup ((const gchar *) control.name); - v4l2channel->id = n; - -#if 0 /* FIXME: it will be need just when handling private controls - (currently none of base controls are of this type) */ - if (control.type == V4L2_CTRL_TYPE_MENU) { - struct v4l2_querymenu menu, *mptr; - int i; - - menu.id = n; - for (i = 0;; i++) { - menu.index = i; - if (ioctl (v4l2object->video_fd, VIDIOC_QUERYMENU, &menu) < 0) { - if (errno == EINVAL) - break; /* end of enumeration */ - else { - GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS, - (_("Failed to get %d in menu enumeration for %s"), - n, v4l2object->videodev), GST_ERROR_SYSTEM); - return FALSE; - } - } - mptr = g_malloc (sizeof (menu)); - memcpy (mptr, &menu, sizeof (menu)); - menus = g_list_append (menus, mptr); - } - } - v4l2object->menus = g_list_append (v4l2object->menus, menus); -#endif - - switch (control.type) { - case V4L2_CTRL_TYPE_INTEGER: - channel->min_value = control.minimum; - channel->max_value = control.maximum; - break; - case V4L2_CTRL_TYPE_BOOLEAN: - channel->min_value = FALSE; - channel->max_value = TRUE; - break; - default: - /* FIXME we should find out how to handle V4L2_CTRL_TYPE_BUTTON. - BUTTON controls like V4L2_CID_DO_WHITE_BALANCE can just be set (1) or - unset (0), but can't be queried */ - GST_DEBUG_OBJECT (v4l2object->element, - "Control with non supported type %s (%x), type=%d", - control.name, n, control.type); - channel->min_value = channel->max_value = 0; - break; - } - - v4l2object->colors = g_list_append (v4l2object->colors, (gpointer) channel); - } - - GST_DEBUG_OBJECT (v4l2object->element, "done"); - return TRUE; -} - - -static void -gst_v4l2_empty_lists (GstV4l2Object * v4l2object) -{ - GST_DEBUG_OBJECT (v4l2object->element, "deleting enumerations"); - - g_list_foreach (v4l2object->channels, (GFunc) g_object_unref, NULL); - g_list_free (v4l2object->channels); - v4l2object->channels = NULL; - - g_list_foreach (v4l2object->norms, (GFunc) g_object_unref, NULL); - g_list_free (v4l2object->norms); - v4l2object->norms = NULL; - - g_list_foreach (v4l2object->colors, (GFunc) g_object_unref, NULL); - g_list_free (v4l2object->colors); - v4l2object->colors = NULL; -} - -/****************************************************** - * gst_v4l2_open(): - * open the video device (v4l2object->videodev) - * return value: TRUE on success, FALSE on error - ******************************************************/ -gboolean -gst_v4l2_open (GstV4l2Object * v4l2object) -{ - struct stat st; - - GST_DEBUG_OBJECT (v4l2object->element, "Trying to open device %s", - v4l2object->videodev); - - GST_V4L2_CHECK_NOT_OPEN (v4l2object); - GST_V4L2_CHECK_NOT_ACTIVE (v4l2object); - - /* be sure we have a device */ - if (!v4l2object->videodev) - v4l2object->videodev = g_strdup ("/dev/video"); - - /* check if it is a device */ - if (stat (v4l2object->videodev, &st) == -1) - goto stat_failed; - - if (!S_ISCHR (st.st_mode)) - goto no_device; - - /* open the device */ - v4l2object->video_fd = - open (v4l2object->videodev, O_RDWR /* | O_NONBLOCK */ ); - - if (!GST_V4L2_IS_OPEN (v4l2object)) - goto not_open; - - /* get capabilities, error will be posted */ - if (!gst_v4l2_get_capabilities (v4l2object)) - goto error; - - /* do we need to be a capture device? */ - if (GST_IS_V4L2SRC (v4l2object) && - !(v4l2object->vcap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) - goto not_capture; - - /* create enumerations, posts errors. */ - if (!gst_v4l2_fill_lists (v4l2object)) - goto error; - - GST_INFO_OBJECT (v4l2object->element, - "Opened device '%s' (%s) successfully", - v4l2object->vcap.card, v4l2object->videodev); - - return TRUE; - - /* ERRORS */ -stat_failed: - { - GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND, - (_("Cannot identify device '%s'."), v4l2object->videodev), - GST_ERROR_SYSTEM); - goto error; - } -no_device: - { - GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND, - (_("This isn't a device '%s'."), v4l2object->videodev), - GST_ERROR_SYSTEM); - goto error; - } -not_open: - { - GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, OPEN_READ_WRITE, - (_("Could not open device \"%s\" for reading and writing."), - v4l2object->videodev), GST_ERROR_SYSTEM); - goto error; - } -not_capture: - { - GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND, - (_("Device \"%s\" is not a capture device."), - v4l2object->videodev), - ("Capabilities: 0x%x", v4l2object->vcap.capabilities)); - goto error; - } -error: - { - if (GST_V4L2_IS_OPEN (v4l2object)) { - /* close device */ - close (v4l2object->video_fd); - v4l2object->video_fd = -1; - } - /* empty lists */ - gst_v4l2_empty_lists (v4l2object); - - return FALSE; - } -} - - -/****************************************************** - * gst_v4l2_close(): - * close the video device (v4l2object->video_fd) - * return value: TRUE on success, FALSE on error - ******************************************************/ -gboolean -gst_v4l2_close (GstV4l2Object * v4l2object) -{ - GST_DEBUG_OBJECT (v4l2object->element, "Trying to close %s", - v4l2object->videodev); - - GST_V4L2_CHECK_OPEN (v4l2object); - GST_V4L2_CHECK_NOT_ACTIVE (v4l2object); - - /* close device */ - close (v4l2object->video_fd); - v4l2object->video_fd = -1; - - /* empty lists */ - gst_v4l2_empty_lists (v4l2object); - - return TRUE; -} - - -/****************************************************** - * gst_v4l2_get_norm() - * Get the norm of the current device - * return value: TRUE on success, FALSE on error - ******************************************************/ -gboolean -gst_v4l2_get_norm (GstV4l2Object * v4l2object, v4l2_std_id * norm) -{ - GST_DEBUG_OBJECT (v4l2object->element, "getting norm"); - - if (!GST_V4L2_IS_OPEN (v4l2object)) - return FALSE; - - if (ioctl (v4l2object->video_fd, VIDIOC_G_STD, norm) < 0) - goto std_failed; - - return TRUE; - - /* ERRORS */ -std_failed: - { - GST_DEBUG ("Failed to get the current norm for device %s", - v4l2object->videodev); - return FALSE; - } -} - - -/****************************************************** - * gst_v4l2_set_norm() - * Set the norm of the current device - * return value: TRUE on success, FALSE on error - ******************************************************/ -gboolean -gst_v4l2_set_norm (GstV4l2Object * v4l2object, v4l2_std_id norm) -{ - GST_DEBUG_OBJECT (v4l2object->element, "trying to set norm to %llx", norm); - - if (!GST_V4L2_IS_OPEN (v4l2object)) - return FALSE; - - if (ioctl (v4l2object->video_fd, VIDIOC_S_STD, &norm) < 0) - goto std_failed; - - return TRUE; - - /* ERRORS */ -std_failed: - { - GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, SETTINGS, - (_("Failed to set norm 0x%llx for device %s: %s."), - norm, v4l2object->videodev), GST_ERROR_SYSTEM); - return FALSE; - } -} - -/****************************************************** - * gst_v4l2_get_frequency(): - * get the current frequency - * return value: TRUE on success, FALSE on error - ******************************************************/ -gboolean -gst_v4l2_get_frequency (GstV4l2Object * v4l2object, - gint tunernum, gulong * frequency) -{ - struct v4l2_frequency freq; - GstTunerChannel *channel; - - GST_DEBUG_OBJECT (v4l2object->element, "getting current tuner frequency"); - - if (!GST_V4L2_IS_OPEN (v4l2object)) - return FALSE; - - channel = gst_tuner_get_channel (GST_TUNER (v4l2object->element)); - - freq.tuner = tunernum; - if (ioctl (v4l2object->video_fd, VIDIOC_G_FREQUENCY, &freq) < 0) - goto freq_failed; - - *frequency = freq.frequency * channel->freq_multiplicator; - - return TRUE; - - /* ERRORS */ -freq_failed: - { - GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, SETTINGS, - (_("Failed to get current tuner frequency for device %s."), - v4l2object->videodev), GST_ERROR_SYSTEM); - return FALSE; - } -} - - -/****************************************************** - * gst_v4l2_set_frequency(): - * set frequency - * return value: TRUE on success, FALSE on error - ******************************************************/ -gboolean -gst_v4l2_set_frequency (GstV4l2Object * v4l2object, - gint tunernum, gulong frequency) -{ - struct v4l2_frequency freq; - GstTunerChannel *channel; - - GST_DEBUG_OBJECT (v4l2object->element, - "setting current tuner frequency to %lu", frequency); - - if (!GST_V4L2_IS_OPEN (v4l2object)) - return FALSE; - - channel = gst_tuner_get_channel (GST_TUNER (v4l2object->element)); - - freq.tuner = tunernum; - /* fill in type - ignore error */ - ioctl (v4l2object->video_fd, VIDIOC_G_FREQUENCY, &freq); - freq.frequency = frequency / channel->freq_multiplicator; - - if (ioctl (v4l2object->video_fd, VIDIOC_S_FREQUENCY, &freq) < 0) - goto freq_failed; - - return TRUE; - - /* ERRORS */ -freq_failed: - { - GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, SETTINGS, - (_("Failed to set current tuner frequency for device %s to %lu."), - v4l2object->videodev, frequency), GST_ERROR_SYSTEM); - return FALSE; - } -} - -/****************************************************** - * gst_v4l2_signal_strength(): - * get the strength of the signal on the current input - * return value: TRUE on success, FALSE on error - ******************************************************/ -gboolean -gst_v4l2_signal_strength (GstV4l2Object * v4l2object, - gint tunernum, gulong * signal_strength) -{ - struct v4l2_tuner tuner; - - GST_DEBUG_OBJECT (v4l2object->element, "trying to get signal strength"); - - if (!GST_V4L2_IS_OPEN (v4l2object)) - return FALSE; - - tuner.index = tunernum; - if (ioctl (v4l2object->video_fd, VIDIOC_G_TUNER, &tuner) < 0) - goto tuner_failed; - - *signal_strength = tuner.signal; - - return TRUE; - - /* ERRORS */ -tuner_failed: - { - GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, SETTINGS, - (_("Failed to get signal strength for device %s."), - v4l2object->videodev), GST_ERROR_SYSTEM); - return FALSE; - } -} - -/****************************************************** - * gst_v4l2_get_attribute(): - * try to get the value of one specific attribute - * return value: TRUE on success, FALSE on error - ******************************************************/ -gboolean -gst_v4l2_get_attribute (GstV4l2Object * v4l2object, - int attribute_num, int *value) -{ - struct v4l2_control control; - - GST_DEBUG_OBJECT (v4l2object->element, "getting value of attribute %d", - attribute_num); - - if (!GST_V4L2_IS_OPEN (v4l2object)) - return FALSE; - - control.id = attribute_num; - - if (ioctl (v4l2object->video_fd, VIDIOC_G_CTRL, &control) < 0) - goto ctrl_failed; - - *value = control.value; - - return TRUE; - - /* ERRORS */ -ctrl_failed: - { - GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, SETTINGS, - (_("Failed to get value for control %d on device %s."), - attribute_num, v4l2object->videodev), GST_ERROR_SYSTEM); - return FALSE; - } -} - - -/****************************************************** - * gst_v4l2_set_attribute(): - * try to set the value of one specific attribute - * return value: TRUE on success, FALSE on error - ******************************************************/ -gboolean -gst_v4l2_set_attribute (GstV4l2Object * v4l2object, - int attribute_num, const int value) -{ - struct v4l2_control control; - - GST_DEBUG_OBJECT (v4l2object->element, "setting value of attribute %d to %d", - attribute_num, value); - - if (!GST_V4L2_IS_OPEN (v4l2object)) - return FALSE; - - control.id = attribute_num; - control.value = value; - if (ioctl (v4l2object->video_fd, VIDIOC_S_CTRL, &control) < 0) - goto ctrl_failed; - - return TRUE; - - /* ERRORS */ -ctrl_failed: - { - GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, SETTINGS, - (_("Failed to set value %d for control %d on device %s."), - value, attribute_num, v4l2object->videodev), GST_ERROR_SYSTEM); - return FALSE; - } -} - -gboolean -gst_v4l2_get_input (GstV4l2Object * v4l2object, gint * input) -{ - gint n; - - GST_DEBUG_OBJECT (v4l2object->element, "trying to get input"); - - if (!GST_V4L2_IS_OPEN (v4l2object)) - return FALSE; - - if (ioctl (v4l2object->video_fd, VIDIOC_G_INPUT, &n) < 0) - goto input_failed; - - *input = n; - - return TRUE; - - /* ERRORS */ -input_failed: - { - GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, SETTINGS, - (_("Failed to get current input on device %s."), - v4l2object->videodev), GST_ERROR_SYSTEM); - return FALSE; - } -} - -gboolean -gst_v4l2_set_input (GstV4l2Object * v4l2object, gint input) -{ - GST_DEBUG_OBJECT (v4l2object->element, "trying to set input to %d", input); - - if (!GST_V4L2_IS_OPEN (v4l2object)) - return FALSE; - - if (ioctl (v4l2object->video_fd, VIDIOC_S_INPUT, &input) < 0) - goto input_failed; - - return TRUE; - - /* ERRORS */ -input_failed: - { - GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, SETTINGS, - (_("Failed to set input %d on device %s."), - input, v4l2object->videodev), GST_ERROR_SYSTEM); - return FALSE; - } -} diff --git a/sys/v4l2/v4l2_calls.h b/sys/v4l2/v4l2_calls.h deleted file mode 100644 index 5000cf2141..0000000000 --- a/sys/v4l2/v4l2_calls.h +++ /dev/null @@ -1,129 +0,0 @@ -/* GStreamer - * - * Copyright (C) 2002 Ronald Bultje - * 2006 Edgard Lima - * - * v4l2_calls.h - generic V4L2 calls handling - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __V4L2_CALLS_H__ -#define __V4L2_CALLS_H__ - -#include "gstv4l2object.h" -#include "gst/gst-i18n-plugin.h" - - -/* simple check whether the device is open */ -#define GST_V4L2_IS_OPEN(v4l2object) \ - (v4l2object->video_fd > 0) - -/* check whether the device is 'active' */ -#define GST_V4L2_IS_ACTIVE(v4l2object) \ - (v4l2object->buffer != NULL) - -#define GST_V4L2_IS_OVERLAY(v4l2object) \ - (v4l2object->vcap.capabilities & V4L2_CAP_VIDEO_OVERLAY) - -/* checks whether the current v4lv4l2object has already been open()'ed or not */ -#define GST_V4L2_CHECK_OPEN(v4l2object) \ - if (!GST_V4L2_IS_OPEN(v4l2object)) \ - { \ - GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS, \ - (_("Device is not open.")), (NULL)); \ - return FALSE; \ - } - -/* checks whether the current v4lv4l2object is close()'ed or whether it is still open */ -#define GST_V4L2_CHECK_NOT_OPEN(v4l2object) \ - if (GST_V4L2_IS_OPEN(v4l2object)) \ - { \ - GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS, \ - (_("Device is open.")), (NULL)); \ - return FALSE; \ - } - -/* checks whether the current v4lv4l2object does video overlay */ -#define GST_V4L2_CHECK_OVERLAY(v4l2object) \ - if (!GST_V4L2_IS_OVERLAY(v4l2object)) \ - { \ - GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS, \ - (NULL), ("Device cannot handle overlay")); \ - return FALSE; \ - } - -/* checks whether we're in capture mode or not */ -#define GST_V4L2_CHECK_ACTIVE(v4l2object) \ - if (!GST_V4L2_IS_ACTIVE(v4l2object)) \ - { \ - GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS, \ - (NULL), ("Device is not in streaming mode")); \ - return FALSE; \ - } - -/* checks whether we're out of capture mode or not */ -#define GST_V4L2_CHECK_NOT_ACTIVE(v4l2object) \ - if (GST_V4L2_IS_ACTIVE(v4l2object)) \ - { \ - GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS, \ - (NULL), ("Device is in streaming mode")); \ - return FALSE; \ - } - - -/* open/close the device */ -gboolean gst_v4l2_open (GstV4l2Object *v4l2object); -gboolean gst_v4l2_close (GstV4l2Object *v4l2object); - -/* norm/input/output */ -gboolean gst_v4l2_get_norm (GstV4l2Object *v4l2object, - v4l2_std_id *norm); -gboolean gst_v4l2_set_norm (GstV4l2Object *v4l2object, - v4l2_std_id norm); -gboolean gst_v4l2_get_input (GstV4l2Object * v4l2object, - gint * input); -gboolean gst_v4l2_set_input (GstV4l2Object * v4l2object, - gint input); -#if 0 /* output not handled by now */ -gboolean gst_v4l2_get_output (GstV4l2Object *v4l2object, - gint *output); -gboolean gst_v4l2_set_output (GstV4l2Object *v4l2object, - gint output); -#endif /* #if 0 - output not handled by now */ - -/* frequency control */ -gboolean gst_v4l2_get_frequency (GstV4l2Object *v4l2object, - gint tunernum, - gulong *frequency); -gboolean gst_v4l2_set_frequency (GstV4l2Object *v4l2object, - gint tunernum, - gulong frequency); -gboolean gst_v4l2_signal_strength (GstV4l2Object *v4l2object, - gint tunernum, - gulong *signal); - -/* attribute control */ -gboolean gst_v4l2_get_attribute (GstV4l2Object *v4l2object, - int attribute, - int *value); -gboolean gst_v4l2_set_attribute (GstV4l2Object *v4l2object, - int attribute, - const int value); - -gboolean gst_v4l2_get_capabilities (GstV4l2Object * v4l2object); - -#endif /* __V4L2_CALLS_H__ */ diff --git a/sys/v4l2/v4l2src_calls.c b/sys/v4l2/v4l2src_calls.c deleted file mode 100644 index 64a1acac2d..0000000000 --- a/sys/v4l2/v4l2src_calls.c +++ /dev/null @@ -1,977 +0,0 @@ -/* GStreamer - * - * Copyright (C) 2002 Ronald Bultje - * 2006 Edgard Lima - * - * v4l2src.c - system calls - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include "v4l2src_calls.h" -#include -#include - -#include "gstv4l2tuner.h" - -GST_DEBUG_CATEGORY_EXTERN (v4l2src_debug); -#define GST_CAT_DEFAULT v4l2src_debug - -/* lalala... */ -#define GST_V4L2_SET_ACTIVE(element) (element)->buffer = GINT_TO_POINTER (-1) -#define GST_V4L2_SET_INACTIVE(element) (element)->buffer = NULL - -#define DEBUG(format, args...) \ - GST_CAT_DEBUG_OBJECT (\ - v4l2src_debug, v4l2src, \ - "V4L2SRC: " format, ##args) - -/* On some systems MAP_FAILED seems to be missing */ -#ifndef MAP_FAILED -#define MAP_FAILED ((caddr_t) -1) -#endif - -/****************************************************** - * gst_v4l2src_fill_format_list(): - * create list of supported capture formats - * return value: TRUE on success, FALSE on error - ******************************************************/ -gboolean -gst_v4l2src_fill_format_list (GstV4l2Src * v4l2src) -{ - gint n; - struct v4l2_fmtdesc *format; - - GST_DEBUG_OBJECT (v4l2src, "getting src format enumerations"); - - /* format enumeration */ - for (n = 0;; n++) { - format = g_new (struct v4l2_fmtdesc, 1); - - format->index = n; - format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_ENUM_FMT, format) < 0) { - if (errno == EINVAL) { - break; /* end of enumeration */ - } else - goto failed; - } - GST_LOG_OBJECT (v4l2src, "got format %" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS (format->pixelformat)); - - v4l2src->formats = g_slist_prepend (v4l2src->formats, format); - } - return TRUE; - - /* ERRORS */ -failed: - { - GST_ELEMENT_ERROR (v4l2src, RESOURCE, SETTINGS, - (_("Failed to get number %d in pixelformat enumeration for %s."), - n, v4l2src->v4l2object->videodev), GST_ERROR_SYSTEM); - g_free (format); - return FALSE; - } -} - -/****************************************************** - * gst_v4l2src_clear_format_list(): - * free list of supported capture formats - * return value: TRUE on success, FALSE on error - ******************************************************/ -gboolean -gst_v4l2src_clear_format_list (GstV4l2Src * v4l2src) -{ - g_slist_foreach (v4l2src->formats, (GFunc) g_free, NULL); - g_slist_free (v4l2src->formats); - v4l2src->formats = NULL; - - return TRUE; -} - - -/****************************************************** - * gst_v4l2src_queue_frame(): - * queue a frame for capturing - * return value: TRUE on success, FALSE on error - ******************************************************/ -gboolean -gst_v4l2src_queue_frame (GstV4l2Src * v4l2src, guint i) -{ - GST_LOG_OBJECT (v4l2src, "queueing frame %u", i); - - if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_QBUF, - &v4l2src->pool->buffers[i].buffer) < 0) - goto failed; - - return TRUE; - - /* ERRORS */ -failed: - { - GST_ELEMENT_ERROR (v4l2src, RESOURCE, WRITE, - (_("Could not write to device '%s'."), - v4l2src->v4l2object->videodev), - ("Error queueing buffer %u on device %s. system error: %s", i, - v4l2src->v4l2object->videodev, g_strerror (errno))); - return FALSE; - } -} - -/****************************************************** - * gst_v4l2src_grab_frame (): - * grab a frame for capturing - * return value: The captured frame number or -1 on error. - ******************************************************/ -gint -gst_v4l2src_grab_frame (GstV4l2Src * v4l2src) -{ - struct v4l2_buffer buffer; - gint32 trials = 100; - - memset (&buffer, 0x00, sizeof (buffer)); - buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - buffer.memory = v4l2src->breq.memory; - while (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_DQBUF, &buffer) < 0) { - /* if the sync() got interrupted, we can retry */ - switch (errno) { - case EAGAIN: - GST_DEBUG_OBJECT (v4l2src, - "Non-blocking I/O has been selected using O_NONBLOCK and" - " no buffer was in the outgoing queue. device %s", - v4l2src->v4l2object->videodev); - break; - case EINVAL: - goto einval; - case ENOMEM: - goto nomem; - case EIO: - GST_DEBUG_OBJECT (v4l2src, - "VIDIOC_DQBUF failed due to an internal error." - " Can also indicate temporary problems like signal loss." - " Note the driver might dequeue an (empty) buffer despite" - " returning an error, or even stop capturing." - " device %s", v4l2src->v4l2object->videodev); - break; - case EINTR: - GST_DEBUG_OBJECT (v4l2src, - "could not sync on a buffer on device %s", - v4l2src->v4l2object->videodev); - break; - default: - GST_ELEMENT_WARNING (v4l2src, RESOURCE, FAILED, - (_("Grabbing frame got interrupted on %s. No expected reason."), - v4l2src->v4l2object->videodev), GST_ERROR_SYSTEM); - break; - } - - if (--trials == -1) { - goto too_many_trials; - } else { - ioctl (v4l2src->v4l2object->video_fd, VIDIOC_QBUF, &buffer); - memset (&buffer, 0x00, sizeof (buffer)); - buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - buffer.memory = v4l2src->breq.memory; - } - } - - GST_LOG_OBJECT (v4l2src, "grabbed frame %d", buffer.index); - - return buffer.index; - - /* ERRORS */ -einval: - { - GST_ELEMENT_ERROR (v4l2src, RESOURCE, FAILED, - (_("Failed trying to get frames from device %s."), - v4l2src->v4l2object->videodev), - (_("The buffer type is not supported, or the index is out of bounds," - " or no buffers have been allocated yet, or the userptr" - " or length are invalid. device %s"), - v4l2src->v4l2object->videodev)); - return -1; - } -nomem: - { - GST_ELEMENT_ERROR (v4l2src, RESOURCE, FAILED, - (_("Failed trying to get frames from device %s. Not enough memory."), - v4l2src->v4l2object->videodev), - (_("insufficient memory to enqueue a user pointer buffer. device %s."), - v4l2src->v4l2object->videodev)); - return -1; - } -too_many_trials: - { - GST_ELEMENT_ERROR (v4l2src, RESOURCE, FAILED, - (_("Failed trying to get frames from device %s."), - v4l2src->v4l2object->videodev), - (_("Failed after 100 tries. device %s."), - v4l2src->v4l2object->videodev)); - return -1; - } -} - - -/****************************************************** - * gst_v4l2src_get_capture(): - * get capture parameters - * return value: TRUE on success, FALSE on error - ******************************************************/ -gboolean -gst_v4l2src_get_capture (GstV4l2Src * v4l2src) -{ - DEBUG ("Getting capture format"); - - GST_V4L2_CHECK_OPEN (v4l2src->v4l2object); - - memset (&v4l2src->format, 0, sizeof (struct v4l2_format)); - v4l2src->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_G_FMT, &v4l2src->format) < 0) - goto fmt_failed; - - return TRUE; - - /* ERRORS */ -fmt_failed: - { - GST_ELEMENT_ERROR (v4l2src, RESOURCE, SETTINGS, - (_("Failed to get pixelformat for device %s."), - v4l2src->v4l2object->videodev), GST_ERROR_SYSTEM); - return FALSE; - } -} - - -/****************************************************** - * gst_v4l2src_set_capture(): - * set capture parameters - * return value: TRUE on success, FALSE on error - ******************************************************/ -gboolean -gst_v4l2src_set_capture (GstV4l2Src * v4l2src, - struct v4l2_fmtdesc * fmt, gint * width, gint * height, - guint * fps_n, guint * fps_d) -{ - guint new_fps_n = *fps_n; - guint new_fps_d = *fps_d; - - DEBUG ("Setting capture format to %dx%d, format %s", - *width, *height, fmt->description); - - GST_V4L2_CHECK_OPEN (v4l2src->v4l2object); - GST_V4L2_CHECK_NOT_ACTIVE (v4l2src->v4l2object); - - /* error was posted */ - if (!gst_v4l2src_get_capture (v4l2src)) - goto fail; - - v4l2src->format.fmt.pix.width = *width; - v4l2src->format.fmt.pix.height = *height; - v4l2src->format.fmt.pix.pixelformat = fmt->pixelformat; - v4l2src->format.fmt.pix.field = V4L2_FIELD_INTERLACED; - v4l2src->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_S_FMT, &v4l2src->format) < 0) - goto fmt_failed; - - if (*width != v4l2src->format.fmt.pix.width || - *height != v4l2src->format.fmt.pix.height) { - DEBUG ("Updating size from %dx%d to %dx%d, format %s", - *width, *height, v4l2src->format.fmt.pix.width, - v4l2src->format.fmt.pix.height, fmt->description); - } - - /* update internal info, posted error */ - if (!gst_v4l2src_get_capture (v4l2src)) - goto fail; - - if (fmt->pixelformat != v4l2src->format.fmt.pix.pixelformat) - goto pixfmt_failed; - - if (*fps_n) { - if (gst_v4l2src_set_fps (v4l2src, &new_fps_n, &new_fps_d)) { - if (new_fps_n != *fps_n || new_fps_d != *fps_d) { - DEBUG ("Updating framerate from %u/%u to %u%u", - *fps_n, *fps_d, new_fps_n, new_fps_d); - *fps_n = new_fps_n; - *fps_d = new_fps_d; - } - } - } else { - if (gst_v4l2src_get_fps (v4l2src, &new_fps_n, &new_fps_d)) { - DEBUG ("framerate is %u/%u", new_fps_n, new_fps_d); - *fps_n = new_fps_n; - *fps_d = new_fps_d; - } - } - - *width = v4l2src->format.fmt.pix.width; - *height = v4l2src->format.fmt.pix.height; - - return TRUE; - - /* ERRORS */ -fmt_failed: - { - GST_ELEMENT_ERROR (v4l2src, RESOURCE, SETTINGS, - (_("Failed to set pixelformat to %s @ %dx%d for device %s: %s."), - fmt->description, *width, *height, v4l2src->v4l2object->videodev), - GST_ERROR_SYSTEM); - return FALSE; - } -pixfmt_failed: - { - GST_ELEMENT_ERROR (v4l2src, RESOURCE, SETTINGS, - (_("Failed to set pixelformat to %s @ %dx%d for device %s: %s."), - fmt->description, *width, *height, v4l2src->v4l2object->videodev), - GST_ERROR_SYSTEM); - return FALSE; - } -fail: - { - /* ERROR was posted */ - return FALSE; - } -} - -/****************************************************** - * gst_v4l2src_capture_init(): - * initialize the capture system - * return value: TRUE on success, FALSE on error - ******************************************************/ -gboolean -gst_v4l2src_capture_init (GstV4l2Src * v4l2src) -{ - gint n; - guint buffers; - GstV4l2Buffer *buffer; - - GST_DEBUG_OBJECT (v4l2src, "initting the capture system"); - - GST_V4L2_CHECK_OPEN (v4l2src->v4l2object); - GST_V4L2_CHECK_NOT_ACTIVE (v4l2src->v4l2object); - - /* request buffer info */ - buffers = v4l2src->breq.count; - - if (v4l2src->breq.count > GST_V4L2_MAX_BUFFERS) - v4l2src->breq.count = GST_V4L2_MAX_BUFFERS; - else if (v4l2src->breq.count < GST_V4L2_MIN_BUFFERS) - v4l2src->breq.count = GST_V4L2_MIN_BUFFERS; - - v4l2src->breq.type = v4l2src->format.type; - if (v4l2src->v4l2object->vcap.capabilities & V4L2_CAP_STREAMING) { - v4l2src->breq.memory = V4L2_MEMORY_MMAP; - if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_REQBUFS, - &v4l2src->breq) < 0) - goto reqbufs_failed; - - GST_LOG_OBJECT (v4l2src, "using default mmap method"); - } else if (v4l2src->v4l2object->vcap.capabilities & V4L2_CAP_READWRITE) { - v4l2src->breq.memory = 0; - GST_INFO_OBJECT (v4l2src, "using fallback read method"); - } else - goto broken_driver; - - /* Determine the device's framerate */ - if (!gst_v4l2src_update_fps (v4l2src->v4l2object)) { - GST_DEBUG_OBJECT (v4l2src, "frame rate is unknown."); - v4l2src->fps_d = 1; - v4l2src->fps_n = 0; - } - - if (v4l2src->breq.memory > 0) { - if (v4l2src->breq.count < GST_V4L2_MIN_BUFFERS) - goto no_buffers; - - if (v4l2src->breq.count != buffers) - g_object_notify (G_OBJECT (v4l2src), "num_buffers"); - - GST_INFO_OBJECT (v4l2src, - "Got %d buffers (%" GST_FOURCC_FORMAT ") of size %d KB", - v4l2src->breq.count, - GST_FOURCC_ARGS (v4l2src->format.fmt.pix.pixelformat), - v4l2src->format.fmt.pix.sizeimage / 1024); - - /* Map the buffers */ - GST_LOG_OBJECT (v4l2src, "initiating buffer pool"); - - v4l2src->pool = g_new (GstV4l2BufferPool, 1); - gst_atomic_int_set (&v4l2src->pool->refcount, 1); - v4l2src->pool->video_fd = v4l2src->v4l2object->video_fd; - v4l2src->pool->buffer_count = v4l2src->breq.count; - v4l2src->pool->buffers = g_new0 (GstV4l2Buffer, v4l2src->breq.count); - - for (n = 0; n < v4l2src->breq.count; n++) { - buffer = &v4l2src->pool->buffers[n]; - - gst_atomic_int_set (&buffer->refcount, 1); - buffer->pool = v4l2src->pool; - memset (&buffer->buffer, 0x00, sizeof (buffer->buffer)); - buffer->buffer.index = n; - buffer->buffer.type = v4l2src->breq.type; - buffer->buffer.memory = v4l2src->breq.memory; - - if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_QUERYBUF, - &buffer->buffer) < 0) - goto querybuf_failed; - - buffer->start = - mmap (0, buffer->buffer.length, PROT_READ | PROT_WRITE, MAP_SHARED, - v4l2src->v4l2object->video_fd, buffer->buffer.m.offset); - - if (buffer->start == MAP_FAILED) - goto mmap_failed; - - buffer->length = buffer->buffer.length; - if (!gst_v4l2src_queue_frame (v4l2src, n)) - goto queue_failed; - } - } else { - GST_LOG_OBJECT (v4l2src, "no buffer pool used"); - v4l2src->pool = NULL; - } - - GST_V4L2_SET_ACTIVE (v4l2src->v4l2object); - - return TRUE; - - /* ERRORS */ -reqbufs_failed: - { - GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ, - (_("Could not get buffers from device '%s'."), - v4l2src->v4l2object->videodev), - ("error requesting %d buffers. system error: %s", - v4l2src->breq.count, g_strerror (errno))); - return FALSE; - } -broken_driver: - { - GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ, - (_("The driver of device '%s' is broken."), - v4l2src->v4l2object->videodev), - ("no supported read capability from %s", - v4l2src->v4l2object->videodev)); - return FALSE; - } -no_buffers: - { - GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ, - (_("Could not get enough buffers from device '%s'."), - v4l2src->v4l2object->videodev), - ("we received %d, we want at least %d", - v4l2src->breq.count, GST_V4L2_MIN_BUFFERS)); - v4l2src->breq.count = buffers; - return FALSE; - } -querybuf_failed: - { - GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ, - (_("Could not get buffer properties of buffer %d."), n), - GST_ERROR_SYSTEM); - gst_v4l2src_capture_deinit (v4l2src); - return FALSE; - } -mmap_failed: - { - GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ, - (_("Could not mmap video buffer %d."), n), GST_ERROR_SYSTEM); - gst_v4l2src_capture_deinit (v4l2src); - buffer->start = 0; - return FALSE; - } -queue_failed: - { - gst_v4l2src_capture_deinit (v4l2src); - return FALSE; - } -} - - -/****************************************************** - * gst_v4l2src_capture_start(): - * start streaming capture - * return value: TRUE on success, FALSE on error - ******************************************************/ -gboolean -gst_v4l2src_capture_start (GstV4l2Src * v4l2src) -{ - gint type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - GST_DEBUG_OBJECT (v4l2src, "starting the capturing"); - - GST_V4L2_CHECK_OPEN (v4l2src->v4l2object); - GST_V4L2_CHECK_ACTIVE (v4l2src->v4l2object); - - v4l2src->quit = FALSE; - - if (v4l2src->breq.memory != 0) { - if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_STREAMON, &type) < 0) - goto streamon_failed; - } - - v4l2src->is_capturing = TRUE; - - return TRUE; - - /* ERRORS */ -streamon_failed: - { - GST_ELEMENT_ERROR (v4l2src, RESOURCE, OPEN_READ, - (_("Error starting streaming capture from device %s."), - v4l2src->v4l2object->videodev), GST_ERROR_SYSTEM); - return FALSE; - } -} - -/****************************************************** - * gst_v4l2src_capture_stop(): - * stop streaming capture - * return value: TRUE on success, FALSE on error - ******************************************************/ -gboolean -gst_v4l2src_capture_stop (GstV4l2Src * v4l2src) -{ - gint type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - GST_DEBUG_OBJECT (v4l2src, "stopping capturing"); - - GST_V4L2_CHECK_OPEN (v4l2src->v4l2object); - GST_V4L2_CHECK_ACTIVE (v4l2src->v4l2object); - - if (v4l2src->breq.memory != 0) { - /* we actually need to sync on all queued buffers but not - * on the non-queued ones */ - if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_STREAMOFF, &type) < 0) - goto streamoff_failed; - } - - /* make an optional pending wait stop */ - v4l2src->quit = TRUE; - v4l2src->is_capturing = FALSE; - - return TRUE; - - /* ERRORS */ -streamoff_failed: - { - GST_ELEMENT_ERROR (v4l2src, RESOURCE, CLOSE, - (_("Error stopping streaming capture from device %s."), - v4l2src->v4l2object->videodev), GST_ERROR_SYSTEM); - return FALSE; - } -} - -static void -gst_v4l2src_buffer_pool_free (GstV4l2BufferPool * pool, gboolean do_close) -{ - guint i; - - for (i = 0; i < pool->buffer_count; i++) { - gst_atomic_int_set (&pool->buffers[i].refcount, 0); - munmap (pool->buffers[i].start, pool->buffers[i].length); - } - g_free (pool->buffers); - gst_atomic_int_set (&pool->refcount, 0); - if (do_close) - close (pool->video_fd); - g_free (pool); -} - -/****************************************************** - * gst_v4l2src_capture_deinit(): - * deinitialize the capture system - * return value: TRUE on success, FALSE on error - ******************************************************/ -gboolean -gst_v4l2src_capture_deinit (GstV4l2Src * v4l2src) -{ - gint i; - gboolean try_reinit = FALSE; - - GST_DEBUG_OBJECT (v4l2src, "deinitting capture system"); - - GST_V4L2_CHECK_OPEN (v4l2src->v4l2object); - GST_V4L2_CHECK_ACTIVE (v4l2src->v4l2object); - - if (v4l2src->pool) { - /* free the buffers */ - for (i = 0; i < v4l2src->breq.count; i++) { - if (g_atomic_int_dec_and_test (&v4l2src->pool->buffers[i].refcount)) { - if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_DQBUF, - &v4l2src->pool->buffers[i].buffer) < 0) - GST_DEBUG_OBJECT (v4l2src, - "Could not dequeue buffer on uninitialization." - "system error: %s. Will try reinit instead", g_strerror (errno)); - try_reinit = TRUE; - } - } - if (g_atomic_int_dec_and_test (&v4l2src->pool->refcount)) { - /* we're last thing that used all this */ - gst_v4l2src_buffer_pool_free (v4l2src->pool, FALSE); - } - v4l2src->pool = NULL; - /* This is our second try to get the buffers dequeued. - * Since buffers are normally dequeued automatically when capturing is - * stopped, but may be enqueued before capturing has started, you get - * a problem when you abort before capturing started but have enqueued - * the buffers. We avoid that by starting/stopping capturing once so - * they get auto-dequeued. - */ - if (try_reinit) { - if (!gst_v4l2src_capture_start (v4l2src) || - !gst_v4l2src_capture_stop (v4l2src)) { - GST_DEBUG_OBJECT (v4l2src, "failed reinit device"); - return FALSE; - } - } - } - - GST_V4L2_SET_INACTIVE (v4l2src->v4l2object); - - return TRUE; -} - -/* - */ -gboolean -gst_v4l2src_get_size_limits (GstV4l2Src * v4l2src, - struct v4l2_fmtdesc * format, - gint * min_w, gint * max_w, gint * min_h, gint * max_h) -{ - - struct v4l2_format fmt; - - GST_LOG_OBJECT (v4l2src, - "getting size limits with format %" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS (format->pixelformat)); - - /* get size delimiters */ - memset (&fmt, 0, sizeof (fmt)); - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - fmt.fmt.pix.width = 0; - fmt.fmt.pix.height = 0; - fmt.fmt.pix.pixelformat = format->pixelformat; - fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; - if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_TRY_FMT, &fmt) < 0) { - GST_DEBUG_OBJECT (v4l2src, "failed to get min size: %s", - g_strerror (errno)); - return FALSE; - } - - if (min_w) - *min_w = fmt.fmt.pix.width; - if (min_h) - *min_h = fmt.fmt.pix.height; - - GST_LOG_OBJECT (v4l2src, - "got min size %dx%d", fmt.fmt.pix.width, fmt.fmt.pix.height); - - fmt.fmt.pix.width = GST_V4L2_MAX_SIZE; - fmt.fmt.pix.height = GST_V4L2_MAX_SIZE; - if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_TRY_FMT, &fmt) < 0) { - GST_DEBUG_OBJECT (v4l2src, "failed to get max size: %s", - g_strerror (errno)); - return FALSE; - } - - if (max_w) - *max_w = fmt.fmt.pix.width; - if (max_h) - *max_h = fmt.fmt.pix.height; - - GST_LOG_OBJECT (v4l2src, - "got max size %dx%d", fmt.fmt.pix.width, fmt.fmt.pix.height); - - return TRUE; -} - -gboolean -gst_v4l2src_update_fps (GstV4l2Object * v4l2object) -{ - GstV4l2Src *v4l2src = GST_V4L2SRC (v4l2object->element); - - return gst_v4l2src_get_fps (v4l2src, &v4l2src->fps_n, &v4l2src->fps_d); -} - - -gboolean -gst_v4l2src_set_fps (GstV4l2Src * v4l2src, guint * fps_n, guint * fps_d) -{ - GstV4l2Object *v4l2object = v4l2src->v4l2object; - struct v4l2_streamparm stream; - - GST_LOG_OBJECT (v4l2src, "setting fps %d, %d", *fps_n, *fps_d); - - memset (&stream, 0x00, sizeof (struct v4l2_streamparm)); - stream.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (ioctl (v4l2object->video_fd, VIDIOC_G_PARM, &stream) < 0) - goto gparm_failed; - - if (!(stream.parm.capture.capability & V4L2_CAP_TIMEPERFRAME)) - goto no_timeperframe; - - stream.parm.capture.timeperframe.denominator = *fps_n; - stream.parm.capture.timeperframe.numerator = *fps_d; - - if (ioctl (v4l2object->video_fd, VIDIOC_S_PARM, &stream) < 0) - goto sparm_failed; - - *fps_n = stream.parm.capture.timeperframe.denominator; - *fps_d = stream.parm.capture.timeperframe.numerator; - - GST_LOG_OBJECT (v4l2src, "fps set to %d, %d", *fps_n, *fps_d); - - return TRUE; - - /* ERRORS */ -gparm_failed: - { - GST_DEBUG_OBJECT (v4l2src, "failed to get PARM: %s", g_strerror (errno)); - return FALSE; - } -no_timeperframe: - { - GST_DEBUG_OBJECT (v4l2src, "no V4L2_CAP_TIMEPERFRAME"); - return FALSE; - } -sparm_failed: - { - GST_DEBUG_OBJECT (v4l2src, "failed to set PARM: %s", g_strerror (errno)); - return FALSE; - } -} - -gboolean -gst_v4l2src_get_fps (GstV4l2Src * v4l2src, guint * fps_n, guint * fps_d) -{ - GstV4l2Object *v4l2object = v4l2src->v4l2object; - v4l2_std_id norm; - struct v4l2_streamparm stream; - const GList *item; - gboolean found; - - if (!GST_V4L2_IS_OPEN (v4l2object)) - return FALSE; - - /* Try to get the frame rate directly from the device using VIDIOC_G_PARM */ - memset (&stream, 0x00, sizeof (struct v4l2_streamparm)); - stream.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - if (ioctl (v4l2object->video_fd, VIDIOC_G_PARM, &stream) < 0) { - GST_DEBUG_OBJECT (v4l2src, "failed to get PARM: %s", g_strerror (errno)); - goto try_stds; - } - - if (!(stream.parm.capture.capability & V4L2_CAP_TIMEPERFRAME)) { - GST_DEBUG_OBJECT (v4l2src, "no V4L2_CAP_TIMEPERFRAME"); - goto try_stds; - } - - /* Note: V4L2 gives us the frame interval, we need the frame rate */ - *fps_n = stream.parm.capture.timeperframe.denominator; - *fps_d = stream.parm.capture.timeperframe.numerator; - - GST_DEBUG_OBJECT (v4l2src, - "frame rate returned by G_PARM: %d/%d fps", *fps_n, *fps_d); - /* and we are done now */ - goto done; - -try_stds: - /* If G_PARM failed, try to get the same information from the video standard */ - if (!gst_v4l2_get_norm (v4l2object, &norm)) - return FALSE; - - found = FALSE; - for (item = v4l2object->norms; item != NULL; item = item->next) { - GstV4l2TunerNorm *v4l2norm = item->data; - - if (v4l2norm->index == norm) { - GValue *framerate = &GST_TUNER_NORM (v4l2norm)->framerate; - - *fps_n = gst_value_get_fraction_numerator (framerate); - *fps_d = gst_value_get_fraction_denominator (framerate); - - GST_DEBUG_OBJECT (v4l2src, - "frame rate returned by get_norm: %d/%d fps", *fps_n, *fps_d); - found = TRUE; - break; - } - } - /* nothing found, that's an error */ - if (!found) - goto failed; - -done: - return TRUE; - - /* ERRORS */ -failed: - { - GST_DEBUG_OBJECT (v4l2src, "failed to get framerate"); - return FALSE; - } -} - -#define GST_TYPE_V4L2SRC_BUFFER (gst_v4l2src_buffer_get_type()) -#define GST_IS_V4L2SRC_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_V4L2SRC_BUFFER)) -#define GST_V4L2SRC_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_V4L2SRC_BUFFER, GstV4l2SrcBuffer)) - -typedef struct _GstV4l2SrcBuffer -{ - GstBuffer buffer; - - GstV4l2Buffer *buf; -} GstV4l2SrcBuffer; - -static void gst_v4l2src_buffer_class_init (gpointer g_class, - gpointer class_data); -static void gst_v4l2src_buffer_init (GTypeInstance * instance, - gpointer g_class); -static void gst_v4l2src_buffer_finalize (GstV4l2SrcBuffer * v4l2src_buffer); - -GType -gst_v4l2src_buffer_get_type (void) -{ - static GType _gst_v4l2src_buffer_type; - - if (G_UNLIKELY (_gst_v4l2src_buffer_type == 0)) { - static const GTypeInfo v4l2src_buffer_info = { - sizeof (GstBufferClass), - NULL, - NULL, - gst_v4l2src_buffer_class_init, - NULL, - NULL, - sizeof (GstV4l2SrcBuffer), - 0, - gst_v4l2src_buffer_init, - NULL - }; - _gst_v4l2src_buffer_type = g_type_register_static (GST_TYPE_BUFFER, - "GstV4l2SrcBuffer", &v4l2src_buffer_info, 0); - } - return _gst_v4l2src_buffer_type; -} - -static void -gst_v4l2src_buffer_class_init (gpointer g_class, gpointer class_data) -{ - GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class); - - mini_object_class->finalize = (GstMiniObjectFinalizeFunction) - gst_v4l2src_buffer_finalize; -} - -static void -gst_v4l2src_buffer_init (GTypeInstance * instance, gpointer g_class) -{ - -} - -static void -gst_v4l2src_buffer_finalize (GstV4l2SrcBuffer * v4l2src_buffer) -{ - GstV4l2Buffer *buf = v4l2src_buffer->buf; - - if (buf) { - GST_LOG ("freeing buffer %p (nr. %d)", buf, buf->buffer.index); - - if (!g_atomic_int_dec_and_test (&buf->refcount)) { - /* we're still in use, add to queue again - note: this might fail because the device is already stopped (race) */ - if (ioctl (buf->pool->video_fd, VIDIOC_QBUF, &buf->buffer) < 0) - GST_INFO ("readding to queue failed, assuming video device is stopped"); - } - if (g_atomic_int_dec_and_test (&buf->pool->refcount)) { - /* we're last thing that used all this */ - gst_v4l2src_buffer_pool_free (buf->pool, TRUE); - } - } -} - -/* Create a V4l2Src buffer from our mmap'd data area */ -GstBuffer * -gst_v4l2src_buffer_new (GstV4l2Src * v4l2src, guint size, guint8 * data, - GstV4l2Buffer * srcbuf) -{ - GstBuffer *buf; - GstClockTime timestamp, duration; - GstClock *clock; - - if (data == NULL) { - buf = gst_buffer_new_and_alloc (size); - } else { - buf = (GstBuffer *) gst_mini_object_new (GST_TYPE_V4L2SRC_BUFFER); - GST_BUFFER_DATA (buf) = data; - GST_V4L2SRC_BUFFER (buf)->buf = srcbuf; - GST_LOG_OBJECT (v4l2src, - "creating buffer %p (nr. %d)", srcbuf, srcbuf->buffer.index); - } - GST_BUFFER_SIZE (buf) = size; - - GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_READONLY); - - /* timestamps, LOCK to get clock and base time. */ - GST_OBJECT_LOCK (v4l2src); - if ((clock = GST_ELEMENT_CLOCK (v4l2src))) { - /* we have a clock, get base time and ref clock */ - timestamp = GST_ELEMENT (v4l2src)->base_time; - gst_object_ref (clock); - } else { - /* no clock, can't set timestamps */ - timestamp = GST_CLOCK_TIME_NONE; - } - GST_OBJECT_UNLOCK (v4l2src); - - if (clock) { - /* the time now is the time of the clock minus the base time */ - timestamp = gst_clock_get_time (clock) - timestamp; - gst_object_unref (clock); - } - - if (v4l2src->fps_n > 0) { - duration = - gst_util_uint64_scale_int (GST_SECOND, v4l2src->fps_d, v4l2src->fps_n); - } else { - duration = GST_CLOCK_TIME_NONE; - } - GST_BUFFER_TIMESTAMP (buf) = timestamp; - GST_BUFFER_DURATION (buf) = duration; - - /* offsets */ - GST_BUFFER_OFFSET (buf) = v4l2src->offset++; - GST_BUFFER_OFFSET_END (buf) = v4l2src->offset; - - /* the negotiate() method already set caps on the source pad */ - gst_buffer_set_caps (buf, GST_PAD_CAPS (GST_BASE_SRC_PAD (v4l2src))); - - return buf; -} diff --git a/sys/v4l2/v4l2src_calls.h b/sys/v4l2/v4l2src_calls.h deleted file mode 100644 index ea752ae7d8..0000000000 --- a/sys/v4l2/v4l2src_calls.h +++ /dev/null @@ -1,67 +0,0 @@ -/* GStreamer - * - * Copyright (C) 2002 Ronald Bultje - * 2006 Edgard Lima - * - * v4l2src.h - system calls - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __V4L2SRC_CALLS_H__ -#define __V4L2SRC_CALLS_H__ - -#include "gstv4l2src.h" -#include "v4l2_calls.h" - -gboolean gst_v4l2src_get_capture (GstV4l2Src * v4l2src); -gboolean gst_v4l2src_set_capture (GstV4l2Src * v4l2src, - struct v4l2_fmtdesc *fmt, - gint * width, gint * height, - guint *fps_n, guint * fps_d); - -gboolean gst_v4l2src_capture_init (GstV4l2Src * v4l2src); -gboolean gst_v4l2src_capture_start (GstV4l2Src * v4l2src); - -gint gst_v4l2src_grab_frame (GstV4l2Src * v4l2src); -gboolean gst_v4l2src_queue_frame (GstV4l2Src * v4l2src, guint i); - -gboolean gst_v4l2src_capture_stop (GstV4l2Src * v4l2src); -gboolean gst_v4l2src_capture_deinit (GstV4l2Src * v4l2src); - -gboolean gst_v4l2src_fill_format_list (GstV4l2Src * v4l2src); -gboolean gst_v4l2src_clear_format_list (GstV4l2Src * v4l2src); - -gboolean gst_v4l2src_get_size_limits (GstV4l2Src * v4l2src, - struct v4l2_fmtdesc *fmt, - gint * min_w, gint * max_w, - gint * min_h, gint * max_h); -/* buffers */ -GstBuffer* gst_v4l2src_buffer_new (GstV4l2Src * v4l2src, - guint size, guint8 * data, - GstV4l2Buffer * srcbuf); -void gst_v4l2src_free_buffer (GstBuffer * buffer); - -/* FPS stuff */ -gboolean gst_v4l2src_update_fps (GstV4l2Object * v4l2object); -gboolean gst_v4l2src_get_fps (GstV4l2Src * v4l2src, - guint * fps_n, guint * fps_d); -gboolean gst_v4l2src_set_fps (GstV4l2Src * v4l2src, - guint * fps_n, guint * fps_d); -GValue* gst_v4l2src_get_fps_list (GstV4l2Src * v4l2src); - - -#endif /* __V4L2SRC_CALLS_H__ */