Commit 9edc0c03 authored by Edgard Gusmão Lima's avatar Edgard Gusmão Lima

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
*
* gstv4l2object.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_V4L2OBJECT_H__
#define __GST_V4L2OBJECT_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>
#include <gst/interfaces/propertyprobe.h>
G_BEGIN_DECLS
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 *stds;
GList *inputs;
/* properties */
gchar *std;
gchar *input;
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_v4l2object_get_type(void);
#define OPEN_V4L2OBJECT_PROPS \
enum { \
PROP_0, \
PROP_DEVICE, \
PROP_DEVICE_NAME, \
PROP_FLAGS, \
PROP_STD, \
PROP_INPUT, \
PROP_FREQUENCY
#define CLOSE_V4L2OBJECT_PROPS };
extern GstV4l2Object *
gst_v4l2object_new (GstElement * element,
GstV4l2GetInOutFunction get_in_out_func,
GstV4l2SetInOutFunction set_in_out_func,
GstV4l2UpdateFpsFunction update_fps_func);
extern void
gst_v4l2object_destroy (GstV4l2Object ** v4l2object);
extern void
gst_v4l2object_install_properties_helper (GObjectClass *gobject_class);
extern gboolean
gst_v4l2object_set_property_helper (GstV4l2Object *v4l2object,
guint prop_id, const GValue * value, GParamSpec * pspec);
extern gboolean
gst_v4l2object_get_property_helper (GstV4l2Object *v4l2object,
guint prop_id, GValue * value, GParamSpec * pspec);
extern gboolean gst_v4l2object_start (GstV4l2Object *v4l2object);
extern gboolean gst_v4l2object_stop (GstV4l2Object *v4l2object);
extern const GList *
gst_v4l2_probe_get_properties (GstPropertyProbe * probe);
extern void
gst_v4l2_probe_probe_property (GstPropertyProbe * probe,
guint prop_id,
const GParamSpec * pspec,
GList ** klass_devices);
extern gboolean
gst_v4l2_probe_needs_probe (GstPropertyProbe * probe,
guint prop_id,
const GParamSpec * pspec,
GList ** klass_devices);
extern 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_V4L2OBJECT_H__ */
......@@ -49,9 +49,11 @@
#include <string.h>
#include <sys/time.h>
#include "v4l2src_calls.h"
#include <sys/ioctl.h>
#include <unistd.h>
#include "gstv4l2colorbalance.h"
#include "gstv4l2tuner.h"
#include "gstv4l2xoverlay.h"
static const GstElementDetails gst_v4l2src_details =
GST_ELEMENT_DETAILS ("Video (video4linux2/raw) Source",
......@@ -65,14 +67,8 @@ GST_DEBUG_CATEGORY (v4l2src_debug);
#define GST_CAT_DEFAULT v4l2src_debug
enum
{
PROP_0,
PROP_USE_FIXED_FPS
};
static guint32 gst_v4l2_formats[] = {
OPEN_V4L2OBJECT_PROPS, PROP_USE_FIXED_FPS
CLOSE_V4L2OBJECT_PROPS static guint32 gst_v4l2_formats[] = {
/* from Linux 2.6.15 videodev2.h */
V4L2_PIX_FMT_RGB332,
V4L2_PIX_FMT_RGB555,
......@@ -130,8 +126,93 @@ static guint32 gst_v4l2_formats[] = {
#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
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);
#else
g_assert (iface_type == GST_TYPE_TUNER ||
iface_type == GST_TYPE_COLOR_BALANCE);
#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;
}
GST_BOILERPLATE (GstV4l2Src, gst_v4l2src, GstV4l2Element, GST_TYPE_V4L2ELEMENT);
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_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);