Commit 9edc0c03 authored by Edgard Lima's avatar Edgard Lima
Browse files

Changes proposed by Wingo in bug #338818.

Original commit message from CVS:
Changes proposed by Wingo in bug #338818.
parent a3c4acec
......@@ -10,7 +10,7 @@ endif
libgstvideo4linux2_la_SOURCES = gstv4l2.c \
gstv4l2colorbalance.c \
gstv4l2element.c \
gstv4l2object.c \
gstv4l2src.c \
gstv4l2tuner.c \
v4l2_calls.c \
......@@ -30,7 +30,7 @@ libgstvideo4linux2_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) \
$(xv_libs) \
-lgstinterfaces-$(GST_MAJORMINOR)
noinst_HEADERS = gstv4l2element.h v4l2_calls.h \
noinst_HEADERS = gstv4l2object.h v4l2_calls.h \
gstv4l2src.h v4l2src_calls.h \
gstv4l2tuner.h gstv4l2xoverlay.h \
gstv4l2colorbalance.h
......@@ -3,6 +3,7 @@
* gstv4l2.c: plugin for v4l2 elements
*
* Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
* Copyright (C) 2001-2002 Edgard Lima <edgard.lima@indt.org.br>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
......@@ -28,7 +29,7 @@
#include <gst/gst.h>
#include "gstv4l2element.h"
#include "gstv4l2object.h"
#include "gstv4l2src.h"
/* #include "gstv4l2jpegsrc.h" */
/* #include "gstv4l2mjpegsrc.h" */
......
/* GStreamer Color Balance interface implementation
* Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
* Copyright (C) 2006 Edgard Lima <edgard.lima@indt.org.br>
*
* gstv4l2colorbalance.c: color balance interface implementation for V4L2
*
......@@ -25,15 +26,7 @@
#include <gst/gst.h>
#include "gstv4l2colorbalance.h"
#include "gstv4l2element.h"
static const GList *gst_v4l2_color_balance_list_channels (GstColorBalance *
balance);
static void gst_v4l2_color_balance_set_value (GstColorBalance * balance,
GstColorBalanceChannel * channel, gint value);
static gint gst_v4l2_color_balance_get_value (GstColorBalance * balance,
GstColorBalanceChannel * channel);
#include "gstv4l2object.h"
GST_BOILERPLATE (GstV4l2ColorBalanceChannel,
gst_v4l2_color_balance_channel,
......@@ -59,67 +52,55 @@ gst_v4l2_color_balance_channel_init (GstV4l2ColorBalanceChannel * channel,
channel->id = (guint32) - 1;
}
void
gst_v4l2_color_balance_interface_init (GstColorBalanceClass * klass)
{
GST_COLOR_BALANCE_TYPE (klass) = GST_COLOR_BALANCE_HARDWARE;
/* default virtual functions */
klass->list_channels = gst_v4l2_color_balance_list_channels;
klass->set_value = gst_v4l2_color_balance_set_value;
klass->get_value = gst_v4l2_color_balance_get_value;
}
static G_GNUC_UNUSED gboolean
gst_v4l2_color_balance_contains_channel (GstV4l2Element * v4l2element,
gst_v4l2_color_balance_contains_channel (GstV4l2Object * v4l2object,
GstV4l2ColorBalanceChannel * v4l2channel)
{
const GList *item;
for (item = v4l2element->colors; item != NULL; item = item->next)
for (item = v4l2object->colors; item != NULL; item = item->next)
if (item->data == v4l2channel)
return TRUE;
return FALSE;
}
static const GList *
gst_v4l2_color_balance_list_channels (GstColorBalance * balance)
const GList *
gst_v4l2_color_balance_list_channels (GstV4l2Object * v4l2object)
{
return GST_V4L2ELEMENT (balance)->colors;
return v4l2object->colors;
}
static void
gst_v4l2_color_balance_set_value (GstColorBalance * balance,
void
gst_v4l2_color_balance_set_value (GstV4l2Object * v4l2object,
GstColorBalanceChannel * channel, gint value)
{
GstV4l2Element *v4l2element = GST_V4L2ELEMENT (balance);
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 (v4l2element));
g_return_if_fail (gst_v4l2_color_balance_contains_channel (v4l2element,
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 (v4l2element, v4l2channel->id, value);
gst_v4l2_set_attribute (v4l2object, v4l2channel->id, value);
}
static gint
gst_v4l2_color_balance_get_value (GstColorBalance * balance,
gint
gst_v4l2_color_balance_get_value (GstV4l2Object * v4l2object,
GstColorBalanceChannel * channel)
{
GstV4l2Element *v4l2element = GST_V4L2ELEMENT (balance);
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 (v4l2element), 0);
g_return_val_if_fail (gst_v4l2_color_balance_contains_channel (v4l2element,
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 (v4l2element, v4l2channel->id, &value))
if (!gst_v4l2_get_attribute (v4l2object, v4l2channel->id, &value))
return 0;
return value;
......
/* G-Streamer generic V4L2 element - Color Balance interface implementation
* Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
* Copyright (C) 2006 Edgard Lima <edgard.lima@indt.org.br>
*
* gstv4l2colorbalance.h: color balance interface implementation for V4L2
*
......@@ -53,6 +54,52 @@ typedef struct _GstV4l2ColorBalanceChannelClass {
GType gst_v4l2_color_balance_channel_get_type (void);
void gst_v4l2_color_balance_interface_init (GstColorBalanceClass *klass);
extern const GList *
gst_v4l2_color_balance_list_channels (GstV4l2Object * v4l2object);
extern void
gst_v4l2_color_balance_set_value (GstV4l2Object * v4l2object,
GstColorBalanceChannel * channel, gint value);
extern 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__ */
/* GStreamer
*
* gstv4l2element.h: base class for V4L2 elements
*
* Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
* Copyright (C) 2006 Edgard Lima <edgard.lima@indt.org.br>
*
* 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_V4L2ELEMENT_H__
#define __GST_V4L2ELEMENT_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 <sys/types.h>
#include <linux/types.h>
#define _LINUX_TIME_H
#define __user
#include <linux/videodev2.h>
#include <gst/gst.h>
#include <gst/base/gstpushsrc.h>
G_BEGIN_DECLS
#define GST_TYPE_V4L2ELEMENT \
(gst_v4l2element_get_type())
#define GST_V4L2ELEMENT(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_V4L2ELEMENT,GstV4l2Element))
#define GST_V4L2ELEMENT_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_V4L2ELEMENT,GstV4l2ElementClass))
#define GST_IS_V4L2ELEMENT(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_V4L2ELEMENT))
#define GST_IS_V4L2ELEMENT_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_V4L2ELEMENT))
#define GST_V4L2ELEMENT_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_V4L2ELEMENT, GstV4l2ElementClass))
typedef struct _GstV4l2Element GstV4l2Element;
typedef struct _GstV4l2ElementClass GstV4l2ElementClass;
typedef struct _GstV4l2Xv GstV4l2Xv;
struct _GstV4l2Element {
GstPushSrc 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 *stds;
GList *inputs;
/* properties */
gchar *std;
gchar *input;
gulong frequency;
/* X-overlay */
GstV4l2Xv *xv;
gulong xwindow_id;
};
struct _GstV4l2ElementClass {
GstPushSrcClass parent_class;
/* probed devices */
GList *devices;
/* actions */
gboolean (*get_attribute) (GstElement *element,
const gchar *attr_name,
int *value);
gboolean (*set_attribute) (GstElement *element,
const gchar *attr_name,
const int value);
};
GType gst_v4l2element_get_type(void);
G_END_DECLS
#endif /* __GST_V4L2ELEMENT_H__ */
/*
* GStreamer gstv4l2element.c: base class for V4L2 elements
* GStreamer gstv4l2object.c: base class for V4L2 elements
* Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
* Copyright (C) 2006 Edgard Lima <edgard.lima@indt.org.br>
*
* 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
......@@ -25,8 +26,6 @@
#include <unistd.h>
#include <string.h>
#include <gst/interfaces/propertyprobe.h>
#include "v4l2_calls.h"
#include "gstv4l2tuner.h"
#ifdef HAVE_XVIDEO
......@@ -34,67 +33,7 @@
#endif
#include "gstv4l2colorbalance.h"
enum
{
PROP_0,
PROP_DEVICE,
PROP_DEVICE_NAME,
PROP_FLAGS,
PROP_STD,
PROP_INPUT,
PROP_FREQUENCY
};
static void gst_v4l2element_init_interfaces (GType type);
GST_BOILERPLATE_FULL (GstV4l2Element, gst_v4l2element, GstPushSrc,
GST_TYPE_PUSH_SRC, gst_v4l2element_init_interfaces);
static void gst_v4l2element_dispose (GObject * object);
static void gst_v4l2element_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_v4l2element_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec);
static gboolean gst_v4l2element_start (GstBaseSrc * src);
static gboolean gst_v4l2element_stop (GstBaseSrc * src);
static gboolean
gst_v4l2_iface_supported (GstImplementsInterface * iface, GType iface_type)
{
GstV4l2Element *v4l2element = GST_V4L2ELEMENT (iface);
#ifdef HAVE_XVIDEO
g_assert (iface_type == GST_TYPE_TUNER ||
iface_type == GST_TYPE_X_OVERLAY || iface_type == GST_TYPE_COLOR_BALANCE);
#else
g_assert (iface_type == GST_TYPE_TUNER ||
iface_type == GST_TYPE_COLOR_BALANCE);
#endif
if (v4l2element->video_fd == -1)
return FALSE;
#ifdef HAVE_XVIDEO
if (iface_type == GST_TYPE_X_OVERLAY && !GST_V4L2_IS_OVERLAY (v4l2element))
return FALSE;
#endif
return TRUE;
}
static void
gst_v4l2_interface_init (GstImplementsInterfaceClass * klass)
{
/*
* default virtual functions
*/
klass->supported = gst_v4l2_iface_supported;
}
static const GList *
OPEN_V4L2OBJECT_PROPS CLOSE_V4L2OBJECT_PROPS const GList *
gst_v4l2_probe_get_properties (GstPropertyProbe * probe)
{
GObjectClass *klass = G_OBJECT_GET_CLASS (probe);
......@@ -114,7 +53,8 @@ gst_v4l2_probe_get_properties (GstPropertyProbe * probe)
}
static gboolean
gst_v4l2_class_probe_devices (GstV4l2ElementClass * klass, gboolean check)
gst_v4l2_class_probe_devices (GstElementClass * klass, gboolean check,
GList ** klass_devices)
{
static gboolean init = FALSE;
static GList *devices = NULL;
......@@ -166,20 +106,20 @@ gst_v4l2_class_probe_devices (GstV4l2ElementClass * klass, gboolean check)
init = TRUE;
}
klass->devices = devices;
*klass_devices = devices;
return init;
}
static void
void
gst_v4l2_probe_probe_property (GstPropertyProbe * probe,
guint prop_id, const GParamSpec * pspec)
guint prop_id, const GParamSpec * pspec, GList ** klass_devices)
{
GstV4l2ElementClass *klass = GST_V4L2ELEMENT_GET_CLASS (probe);
GstElementClass *klass = GST_ELEMENT_GET_CLASS (probe);
switch (prop_id) {
case PROP_DEVICE:
gst_v4l2_class_probe_devices (klass, FALSE);
gst_v4l2_class_probe_devices (klass, FALSE, klass_devices);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
......@@ -187,16 +127,16 @@ gst_v4l2_probe_probe_property (GstPropertyProbe * probe,
}
}
static gboolean
gboolean
gst_v4l2_probe_needs_probe (GstPropertyProbe * probe,
guint prop_id, const GParamSpec * pspec)
guint prop_id, const GParamSpec * pspec, GList ** klass_devices)
{
GstV4l2ElementClass *klass = GST_V4L2ELEMENT_GET_CLASS (probe);
GstElementClass *klass = GST_ELEMENT_GET_CLASS (probe);
gboolean ret = FALSE;
switch (prop_id) {
case PROP_DEVICE:
ret = !gst_v4l2_class_probe_devices (klass, TRUE);
ret = !gst_v4l2_class_probe_devices (klass, TRUE, klass_devices);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
......@@ -204,20 +144,21 @@ gst_v4l2_probe_needs_probe (GstPropertyProbe * probe,
}
return ret;
}
static GValueArray *
gst_v4l2_class_list_devices (GstV4l2ElementClass * klass)
gst_v4l2_class_list_devices (GstElementClass * klass, GList ** klass_devices)
{
GValueArray *array;
GValue value = { 0 };
GList *item;
if (!klass->devices)
if (!*klass_devices)
return NULL;
array = g_value_array_new (g_list_length (klass->devices));
item = klass->devices;
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;
......@@ -232,16 +173,16 @@ gst_v4l2_class_list_devices (GstV4l2ElementClass * klass)
return array;
}
static GValueArray *
GValueArray *
gst_v4l2_probe_get_values (GstPropertyProbe * probe,
guint prop_id, const GParamSpec * pspec)
guint prop_id, const GParamSpec * pspec, GList ** klass_devices)
{
GstV4l2ElementClass *klass = GST_V4L2ELEMENT_GET_CLASS (probe);
GstElementClass *klass = GST_ELEMENT_GET_CLASS (probe);
GValueArray *array = NULL;
switch (prop_id) {
case PROP_DEVICE:
array = gst_v4l2_class_list_devices (klass);
array = gst_v4l2_class_list_devices (klass, klass_devices);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
......@@ -251,15 +192,6 @@ gst_v4l2_probe_get_values (GstPropertyProbe * probe,
return array;
}
static void
gst_v4l2_property_probe_interface_init (GstPropertyProbeInterface * iface)
{
iface->get_properties = gst_v4l2_probe_get_properties;
iface->probe_property = gst_v4l2_probe_probe_property;
iface->needs_probe = gst_v4l2_probe_needs_probe;
iface->get_values = gst_v4l2_probe_get_values;
}
#define GST_TYPE_V4L2_DEVICE_FLAGS (gst_v4l2_device_get_type ())
GType
gst_v4l2_device_get_type (void)
......@@ -295,219 +227,181 @@ gst_v4l2_device_get_type (void)
return v4l2_device_type;
}
static void
gst_v4l2element_init_interfaces (GType type)
{
static const GInterfaceInfo v4l2iface_info = {
(GInterfaceInitFunc) gst_v4l2_interface_init,
NULL,
NULL,
};
static const GInterfaceInfo v4l2_tuner_info = {
(GInterfaceInitFunc) gst_v4l2_tuner_interface_init,
NULL,
NULL,
};
#ifdef HAVE_XVIDEO
static const GInterfaceInfo v4l2_xoverlay_info = {
(GInterfaceInitFunc) gst_v4l2_xoverlay_interface_init,
NULL,
NULL,
};
#endif
static const GInterfaceInfo v4l2_colorbalance_info = {
(GInterfaceInitFunc) gst_v4l2_color_balance_interface_init,
NULL,
NULL,
};
static const GInterfaceInfo v4l2_propertyprobe_info = {
(GInterfaceInitFunc) gst_v4l2_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_PROPERTY_PROBE,
&v4l2_propertyprobe_info);
}
static void
gst_v4l2element_base_init (gpointer g_class)
void
gst_v4l2object_install_properties_helper (GObjectClass * gobject_class)
{
GstV4l2ElementClass *klass = GST_V4L2ELEMENT_CLASS (g_class);
klass->devices = NULL;
}
static void
gst_v4l2element_class_init (GstV4l2ElementClass * klass)
{
GObjectClass *gobject_class;
GstBaseSrcClass *basesrc_class;
gobject_class = (GObjectClass *) klass;
basesrc_class = (GstBaseSrcClass *) klass;
gobject_class->set_property = gst_v4l2element_set_property;
gobject_class->get_property = gst_v4l2element_get_property;
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DEVICE,
g_object_class_install_property
(G_OBJECT_CLASS (gobject_class), PROP_DEVICE,
g_param_spec_string ("device",
"Device", "Device location", NULL, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass),
g_object_class_install_property
(G_OBJECT_CLASS (gobject_class),
PROP_DEVICE_NAME,
g_param_spec_string ("device_name",
"Device name", "Name of the device", NULL, G_PARAM_READABLE));
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_FLAGS,
g_object_class_install_property
(G_OBJECT_CLASS (gobject_class), PROP_FLAGS,
g_param_spec_flags ("flags", "Flags",
"Device type flags",
GST_TYPE_V4L2_DEVICE_FLAGS, 0, G_PARAM_READABLE));
g_object_class_install_property (gobject_class, PROP_STD,
g_object_class_install_property