sys/v4l/v4lsrc_calls.*: Remove sync-related stuff.

Original commit message from CVS:
2005-07-07  Andy Wingo  <wingo@pobox.com>

* sys/v4l/v4lsrc_calls.h:
* sys/v4l/v4lsrc_calls.c: Remove sync-related stuff.
(gst_v4lsrc_get_fps_list): Moved here from gstv4lsrc.c.
(gst_v4lsrc_buffer_new): Totally derive from GstBuffer.

* sys/v4l/v4l_calls.h: Cast to V4lElement.
* sys/v4l/v4l_calls.c: Header loc fixen, don't load mjpeg, all
v4lelements are sources.

* sys/v4l/gstv4lxoverlay.h:
* sys/v4l/gstv4lxoverlay.c:
* sys/v4l/gstv4ltuner.h:
* sys/v4l/gstv4ltuner.c: Header loc fixen.

* sys/v4l/gstv4lsrc.h:
* sys/v4l/gstv4lsrc.c: Crucial GPL update. Clean up a bit, port to
PushSrc/BaseSrc. Removed most sync-related properties, videorate
or something should handle that. Made a live source.

* sys/v4l/gstv4lelement.h:
* sys/v4l/gstv4lelement.c: Derive from GstPushSrc. No more
signals. Some cleanups.

* sys/v4l/gstv4lcolorbalance.h: Interface header update.

* sys/v4l/gstv4l.c: Don't register v4lelement, or the jpeg/mjpeg
stuff.

* sys/v4l/Makefile.am: Build everything except the jpeg/mjpeg
stuff.

* sys/Makefile.am (SUBDIRS): Hit the V4L crack pipe.
This commit is contained in:
Andy Wingo 2005-07-07 11:29:29 +00:00
parent 1d1317186e
commit 84761c6a82
18 changed files with 688 additions and 1221 deletions

View file

@ -1,3 +1,38 @@
2005-07-07 Andy Wingo <wingo@pobox.com>
* sys/v4l/v4lsrc_calls.h:
* sys/v4l/v4lsrc_calls.c: Remove sync-related stuff.
(gst_v4lsrc_get_fps_list): Moved here from gstv4lsrc.c.
(gst_v4lsrc_buffer_new): Totally derive from GstBuffer.
* sys/v4l/v4l_calls.h: Cast to V4lElement.
* sys/v4l/v4l_calls.c: Header loc fixen, don't load mjpeg, all
v4lelements are sources.
* sys/v4l/gstv4lxoverlay.h:
* sys/v4l/gstv4lxoverlay.c:
* sys/v4l/gstv4ltuner.h:
* sys/v4l/gstv4ltuner.c: Header loc fixen.
* sys/v4l/gstv4lsrc.h:
* sys/v4l/gstv4lsrc.c: Crucial GPL update. Clean up a bit, port to
PushSrc/BaseSrc. Removed most sync-related properties, videorate
or something should handle that. Made a live source.
* sys/v4l/gstv4lelement.h:
* sys/v4l/gstv4lelement.c: Derive from GstPushSrc. No more
signals. Some cleanups.
* sys/v4l/gstv4lcolorbalance.h: Interface header update.
* sys/v4l/gstv4l.c: Don't register v4lelement, or the jpeg/mjpeg
stuff.
* sys/v4l/Makefile.am: Build everything except the jpeg/mjpeg
stuff.
* sys/Makefile.am (SUBDIRS): Hit the V4L crack pipe.
2005-07-07 Wim Taymans <wim@fluendo.com>
* ext/theora/theoradec.c: (theora_get_query_types),

View file

@ -27,7 +27,7 @@ an implementation of an audio ringbuffer
@samples_per_seg:
@empty_seg:
@state:
@segplayed:
@segdone:
@waiting:
<!-- ##### STRUCT GstRingBufferClass ##### -->
@ -38,7 +38,7 @@ an implementation of an audio ringbuffer
@parent_class:
@acquire:
@release:
@play:
@start:
@pause:
@resume:
@stop:
@ -82,7 +82,7 @@ an implementation of an audio ringbuffer
@Returns:
<!-- ##### FUNCTION gst_ringbuffer_play ##### -->
<!-- ##### FUNCTION gst_ringbuffer_start ##### -->
<para>
</para>
@ -118,7 +118,7 @@ an implementation of an audio ringbuffer
@Returns:
<!-- ##### FUNCTION gst_ringbuffer_played_samples ##### -->
<!-- ##### FUNCTION gst_ringbuffer_samples_done ##### -->
<para>
</para>

View file

@ -18,9 +18,8 @@ endif
SUBDIRS = \
$(XIMAGE_DIR) \
$(XVIMAGE_DIR)
# $(V4L_DIR)
$(XVIMAGE_DIR) \
$(V4L_DIR)
DIST_SUBDIRS = \
v4l \

View file

@ -9,18 +9,22 @@ xv_libs =
endif
libgstvideo4linux_la_SOURCES = \
gstv4lelement.c v4l_calls.c \
gstv4lsrc.c v4lsrc_calls.c \
gstv4ljpegsrc.c \
gstv4lmjpegsrc.c v4lmjpegsrc_calls.c \
gstv4lmjpegsink.c v4lmjpegsink_calls.c \
gstv4l.c \
gstv4lcolorbalance.c \
gstv4lelement.c \
gstv4lsrc.c \
gstv4ltuner.c \
$(xv_source) \
gstv4lcolorbalance.c
libgstvideo4linux_la_CFLAGS = $(GST_CFLAGS) $(X_CFLAGS)
v4l_calls.c \
v4lsrc_calls.c $(xv_source)
# gstv4ljpegsrc.c \
# gstv4lmjpegsrc.c v4lmjpegsrc_calls.c \
# gstv4lmjpegsink.c v4lmjpegsink_calls.c
libgstvideo4linux_la_CFLAGS = $(GST_CFLAGS) $(X_CFLAGS) -I$(top_srcdir)/gst-libs
libgstvideo4linux_la_LIBADD = \
$(top_builddir)/gst-libs/gst/libgstinterfaces-@GST_MAJORMINOR@.la
$(top_builddir)/gst-libs/gst/interfaces/libgstinterfaces-@GST_MAJORMINOR@.la \
$(GST_BASE_LIBS)
libgstvideo4linux_la_LDFLAGS = \
$(GST_PLUGIN_LDFLAGS) \
$(xv_libs)

View file

@ -30,9 +30,9 @@
#include "gstv4lelement.h"
#include "gstv4lsrc.h"
#include "gstv4ljpegsrc.h"
#include "gstv4lmjpegsrc.h"
#include "gstv4lmjpegsink.h"
/* #include "gstv4ljpegsrc.h" */
/* #include "gstv4lmjpegsrc.h" */
/* #include "gstv4lmjpegsink.h" */
GST_DEBUG_CATEGORY (v4l_debug); /* used in v4l_calls.c and v4lsrc_calls.c */
@ -41,16 +41,13 @@ plugin_init (GstPlugin * plugin)
{
GST_DEBUG_CATEGORY_INIT (v4l_debug, "v4l", 0, "V4L API calls");
if (!gst_element_register (plugin, "v4lelement",
GST_RANK_NONE, GST_TYPE_V4LELEMENT) ||
!gst_element_register (plugin, "v4lsrc",
GST_RANK_NONE, GST_TYPE_V4LSRC) ||
!gst_element_register (plugin, "v4ljpegsrc",
GST_RANK_NONE, GST_TYPE_V4LJPEGSRC) ||
!gst_element_register (plugin, "v4lmjpegsrc",
GST_RANK_NONE, GST_TYPE_V4LMJPEGSRC) ||
!gst_element_register (plugin, "v4lmjpegsink",
GST_RANK_NONE, GST_TYPE_V4LMJPEGSINK))
if (!gst_element_register (plugin, "v4lsrc", GST_RANK_NONE, GST_TYPE_V4LSRC))
/* !gst_element_register (plugin, "v4ljpegsrc", */
/* GST_RANK_NONE, GST_TYPE_V4LJPEGSRC) || */
/* !gst_element_register (plugin, "v4lmjpegsrc", */
/* GST_RANK_NONE, GST_TYPE_V4LMJPEGSRC) || */
/* !gst_element_register (plugin, "v4lmjpegsink", */
/* GST_RANK_NONE, GST_TYPE_V4LMJPEGSINK)) */
return FALSE;
#ifdef ENABLE_NLS

View file

@ -24,7 +24,7 @@
#define __GST_V4L_COLOR_BALANCE_H__
#include <gst/gst.h>
#include <gst/colorbalance/colorbalance.h>
#include <gst/interfaces/colorbalance.h>
#include "v4l_calls.h"
G_BEGIN_DECLS

View file

@ -28,8 +28,10 @@
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <gst/interfaces/propertyprobe.h>
#include "v4l_calls.h"
#include "gstv4ltuner.h"
#ifdef HAVE_XVIDEO
@ -37,49 +39,34 @@
#endif
#include "gstv4lcolorbalance.h"
#include <gst/propertyprobe/propertyprobe.h>
/* elementfactory information */
static GstElementDetails gst_v4lelement_details =
GST_ELEMENT_DETAILS ("Generic video4linux Element",
"Generic/Video",
"Generic plugin for handling common video4linux calls",
"Ronald Bultje <rbultje@ronald.bitfreak.net>");
/* V4lElement signals and args */
enum
{
/* FILL ME */
SIGNAL_OPEN,
SIGNAL_CLOSE,
LAST_SIGNAL
};
enum
{
ARG_0,
ARG_DEVICE,
ARG_DEVICE_NAME,
ARG_FLAGS
PROP_0,
PROP_DEVICE,
PROP_DEVICE_NAME,
PROP_FLAGS
};
static void gst_v4lelement_base_init (gpointer g_class);
static void gst_v4lelement_class_init (GstV4lElementClass * klass);
static void gst_v4lelement_init (GstV4lElement * v4lelement);
static void gst_v4lelement_dispose (GObject * object);
static void gst_v4lelement_set_property (GObject * object,
static void gst_v4lelement_init_interfaces (GType type);
GST_BOILERPLATE_FULL (GstV4lElement, gst_v4lelement, GstPushSrc,
GST_TYPE_PUSHSRC, gst_v4lelement_init_interfaces)
static void gst_v4lelement_dispose (GObject * object);
static void gst_v4lelement_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_v4lelement_get_property (GObject * object,
static void gst_v4lelement_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec);
static GstElementStateReturn gst_v4lelement_change_state (GstElement * element);
static gboolean gst_v4lelement_start (GstBaseSrc * src);
static gboolean gst_v4lelement_stop (GstBaseSrc * src);
static GstElementClass *parent_class = NULL;
static guint gst_v4lelement_signals[LAST_SIGNAL] = { 0 };
static gboolean
gst_v4l_iface_supported (GstImplementsInterface * iface, GType iface_type)
static gboolean
gst_v4l_iface_supported (GstImplementsInterface * iface,
GType iface_type)
{
GstV4lElement *v4lelement = GST_V4LELEMENT (iface);
@ -176,7 +163,7 @@ gst_v4l_probe_probe_property (GstPropertyProbe * probe,
GstV4lElementClass *klass = GST_V4LELEMENT_GET_CLASS (probe);
switch (prop_id) {
case ARG_DEVICE:
case PROP_DEVICE:
gst_v4l_class_probe_devices (klass, FALSE);
break;
default:
@ -193,7 +180,7 @@ gst_v4l_probe_needs_probe (GstPropertyProbe * probe,
gboolean ret = FALSE;
switch (prop_id) {
case ARG_DEVICE:
case PROP_DEVICE:
ret = !gst_v4l_class_probe_devices (klass, TRUE);
break;
default:
@ -238,7 +225,7 @@ gst_v4l_probe_get_values (GstPropertyProbe * probe,
GValueArray *array = NULL;
switch (prop_id) {
case ARG_DEVICE:
case PROP_DEVICE:
array = gst_v4l_class_list_devices (klass);
break;
default:
@ -283,122 +270,82 @@ gst_v4l_device_get_type (void)
return v4l_device_type;
}
GType
gst_v4lelement_get_type (void)
static void
gst_v4lelement_init_interfaces (GType type)
{
static GType v4lelement_type = 0;
if (!v4lelement_type) {
static const GTypeInfo v4lelement_info = {
sizeof (GstV4lElementClass),
gst_v4lelement_base_init,
NULL,
(GClassInitFunc) gst_v4lelement_class_init,
NULL,
NULL,
sizeof (GstV4lElement),
0,
(GInstanceInitFunc) gst_v4lelement_init,
NULL
};
static const GInterfaceInfo v4liface_info = {
(GInterfaceInitFunc) gst_v4l_interface_init,
NULL,
NULL,
};
static const GInterfaceInfo v4l_tuner_info = {
(GInterfaceInitFunc) gst_v4l_tuner_interface_init,
NULL,
NULL,
};
static const GInterfaceInfo v4liface_info = {
(GInterfaceInitFunc) gst_v4l_interface_init,
NULL,
NULL,
};
static const GInterfaceInfo v4l_tuner_info = {
(GInterfaceInitFunc) gst_v4l_tuner_interface_init,
NULL,
NULL,
};
#ifdef HAVE_XVIDEO
static const GInterfaceInfo v4l_xoverlay_info = {
(GInterfaceInitFunc) gst_v4l_xoverlay_interface_init,
NULL,
NULL,
};
static const GInterfaceInfo v4l_xoverlay_info = {
(GInterfaceInitFunc) gst_v4l_xoverlay_interface_init,
NULL,
NULL,
};
#endif
static const GInterfaceInfo v4l_colorbalance_info = {
(GInterfaceInitFunc) gst_v4l_color_balance_interface_init,
NULL,
NULL,
};
static const GInterfaceInfo v4l_propertyprobe_info = {
(GInterfaceInitFunc) gst_v4l_property_probe_interface_init,
NULL,
NULL,
};
static const GInterfaceInfo v4l_colorbalance_info = {
(GInterfaceInitFunc) gst_v4l_color_balance_interface_init,
NULL,
NULL,
};
static const GInterfaceInfo v4l_propertyprobe_info = {
(GInterfaceInitFunc) gst_v4l_property_probe_interface_init,
NULL,
NULL,
};
v4lelement_type = g_type_register_static (GST_TYPE_ELEMENT,
"GstV4lElement", &v4lelement_info, 0);
g_type_add_interface_static (v4lelement_type,
GST_TYPE_IMPLEMENTS_INTERFACE, &v4liface_info);
g_type_add_interface_static (v4lelement_type,
GST_TYPE_TUNER, &v4l_tuner_info);
g_type_add_interface_static (type,
GST_TYPE_IMPLEMENTS_INTERFACE, &v4liface_info);
g_type_add_interface_static (type, GST_TYPE_TUNER, &v4l_tuner_info);
#ifdef HAVE_XVIDEO
g_type_add_interface_static (v4lelement_type,
GST_TYPE_X_OVERLAY, &v4l_xoverlay_info);
g_type_add_interface_static (type, GST_TYPE_X_OVERLAY, &v4l_xoverlay_info);
#endif
g_type_add_interface_static (v4lelement_type,
GST_TYPE_COLOR_BALANCE, &v4l_colorbalance_info);
g_type_add_interface_static (v4lelement_type,
GST_TYPE_PROPERTY_PROBE, &v4l_propertyprobe_info);
}
return v4lelement_type;
g_type_add_interface_static (type,
GST_TYPE_COLOR_BALANCE, &v4l_colorbalance_info);
g_type_add_interface_static (type,
GST_TYPE_PROPERTY_PROBE, &v4l_propertyprobe_info);
}
static void
gst_v4lelement_base_init (gpointer g_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
GstV4lElementClass *klass = GST_V4LELEMENT_CLASS (g_class);
klass->devices = NULL;
gst_element_class_set_details (gstelement_class, &gst_v4lelement_details);
}
static void
gst_v4lelement_class_init (GstV4lElementClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
GstBaseSrcClass *basesrc_class;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DEVICE,
g_param_spec_string ("device", "Device", "Device location",
NULL, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_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), ARG_FLAGS,
g_param_spec_flags ("flags", "Flags", "Device type flags",
GST_TYPE_V4L_DEVICE_FLAGS, 0, G_PARAM_READABLE));
/* signals */
gst_v4lelement_signals[SIGNAL_OPEN] =
g_signal_new ("open", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstV4lElementClass, open),
NULL, NULL, g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE, 1, G_TYPE_STRING);
gst_v4lelement_signals[SIGNAL_CLOSE] =
g_signal_new ("close", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstV4lElementClass, close),
NULL, NULL, g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE, 1, G_TYPE_STRING);
basesrc_class = (GstBaseSrcClass *) klass;
gobject_class->set_property = gst_v4lelement_set_property;
gobject_class->get_property = gst_v4lelement_get_property;
gstelement_class->change_state = gst_v4lelement_change_state;
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DEVICE,
g_param_spec_string ("device", "Device", "Device location",
NULL, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), 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_param_spec_flags ("flags", "Flags", "Device type flags",
GST_TYPE_V4L_DEVICE_FLAGS, 0, G_PARAM_READABLE));
basesrc_class->start = gst_v4lelement_start;
basesrc_class->stop = gst_v4lelement_stop;
gobject_class->dispose = gst_v4lelement_dispose;
}
@ -439,13 +386,10 @@ static void
gst_v4lelement_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec)
{
GstV4lElement *v4lelement;
g_return_if_fail (GST_IS_V4LELEMENT (object));
v4lelement = GST_V4LELEMENT (object);
GstV4lElement *v4lelement = GST_V4LELEMENT (object);
switch (prop_id) {
case ARG_DEVICE:
case PROP_DEVICE:
if (v4lelement->videodev)
g_free (v4lelement->videodev);
v4lelement->videodev = g_strdup (g_value_get_string (value));
@ -461,16 +405,13 @@ static void
gst_v4lelement_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec)
{
GstV4lElement *v4lelement;
g_return_if_fail (GST_IS_V4LELEMENT (object));
v4lelement = GST_V4LELEMENT (object);
GstV4lElement *v4lelement = GST_V4LELEMENT (object);
switch (prop_id) {
case ARG_DEVICE:
case PROP_DEVICE:
g_value_set_string (value, v4lelement->videodev);
break;
case ARG_DEVICE_NAME:{
case PROP_DEVICE_NAME:{
gchar *new = NULL;
if (GST_V4L_IS_OPEN (v4lelement))
@ -478,7 +419,7 @@ gst_v4lelement_get_property (GObject * object,
g_value_set_string (value, new);
break;
}
case ARG_FLAGS:{
case PROP_FLAGS:{
guint flags = 0;
if (GST_V4L_IS_OPEN (v4lelement)) {
@ -495,47 +436,32 @@ gst_v4lelement_get_property (GObject * object,
}
}
static GstElementStateReturn
gst_v4lelement_change_state (GstElement * element)
static gboolean
gst_v4lelement_start (GstBaseSrc * src)
{
GstV4lElement *v4lelement;
GstV4lElement *v4lelement = GST_V4LELEMENT (src);
g_return_val_if_fail (GST_IS_V4LELEMENT (element), GST_STATE_FAILURE);
v4lelement = GST_V4LELEMENT (element);
/* if going down into NULL state, close the device if it's open
* if going to READY, open the device (and set some options)
*/
switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_NULL_TO_READY:
if (!gst_v4l_open (v4lelement))
return GST_STATE_FAILURE;
if (!gst_v4l_open (v4lelement))
return FALSE;
#ifdef HAVE_XVIDEO
gst_v4l_xoverlay_open (v4lelement);
gst_v4l_xoverlay_open (v4lelement);
#endif
g_signal_emit (G_OBJECT (v4lelement),
gst_v4lelement_signals[SIGNAL_OPEN], 0, v4lelement->videodev);
break;
case GST_STATE_READY_TO_NULL:
#ifdef HAVE_XVIDEO
gst_v4l_xoverlay_close (v4lelement);
#endif
if (!gst_v4l_close (v4lelement))
return GST_STATE_FAILURE;
g_signal_emit (G_OBJECT (v4lelement),
gst_v4lelement_signals[SIGNAL_CLOSE], 0, v4lelement->videodev);
break;
}
if (GST_ELEMENT_CLASS (parent_class)->change_state)
return GST_ELEMENT_CLASS (parent_class)->change_state (element);
return GST_STATE_SUCCESS;
return TRUE;
}
static gboolean
gst_v4lelement_stop (GstBaseSrc * src)
{
GstV4lElement *v4lelement = GST_V4LELEMENT (src);
#ifdef HAVE_XVIDEO
gst_v4l_xoverlay_close (v4lelement);
#endif
if (!gst_v4l_close (v4lelement))
return FALSE;
return TRUE;
}

View file

@ -23,9 +23,6 @@
#ifndef __GST_V4LELEMENT_H__
#define __GST_V4LELEMENT_H__
#include <gst/gst.h>
#include <gst/xwindowlistener/xwindowlistener.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
@ -41,7 +38,10 @@
#include <sys/types.h>
#define _LINUX_TIME_H
#include <linux/videodev.h>
#include <gst/gst.h>
#include <gst/base/gstpushsrc.h>
G_BEGIN_DECLS
@ -63,7 +63,7 @@ typedef struct _GstV4lElementClass GstV4lElementClass;
typedef struct _GstV4lXv GstV4lXv;
struct _GstV4lElement {
GstElement element;
GstPushSrc element;
/* the video device */
char *videodev;
@ -94,17 +94,11 @@ struct _GstV4lElement {
};
struct _GstV4lElementClass {
GstElementClass parent_class;
GstPushSrcClass parent_class;
/* probed devices */
GList *devices;
/* signals */
void (*open) (GstElement *element,
const gchar *device);
void (*close) (GstElement *element,
const gchar *device);
/* actions */
gboolean (*get_attribute) (GstElement *element,
const gchar *attr_name,

File diff suppressed because it is too large Load diff

View file

@ -23,9 +23,13 @@
#ifndef __GST_V4LSRC_H__
#define __GST_V4LSRC_H__
#include <gstv4lelement.h>
G_BEGIN_DECLS
#define GST_TYPE_V4LSRC \
(gst_v4lsrc_get_type())
#define GST_V4LSRC(obj) \
@ -36,9 +40,12 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_V4LSRC))
#define GST_IS_V4LSRC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_V4LSRC))
typedef struct _GstV4lSrc GstV4lSrc;
typedef struct _GstV4lSrcClass GstV4lSrcClass;
enum
{
QUEUE_STATE_ERROR = -1,
@ -47,13 +54,6 @@ enum
QUEUE_STATE_SYNCED /* the frame is captured */
};
typedef enum
{
GST_V4LSRC_SYNC_MODE_CLOCK,
GST_V4LSRC_SYNC_MODE_PRIVATE_CLOCK,
GST_V4LSRC_SYNC_MODE_FIXED_FPS,
GST_V4LSRC_SYNC_MODE_NONE,
} GstV4lSrcSyncMode;
struct _GstV4lSrc
{
@ -76,34 +76,17 @@ struct _GstV4lSrc
gint num_queued;
gint sync_frame, queue_frame;
gboolean is_capturing;
GstClockTimeDiff latency_offset;
GstClockTimeDiff timestamp_offset;
/* True if we want to stop */
gboolean quit;
/* A/V sync... frame counter and internal cache */
gulong handled;
gint last_frame;
gint need_writes;
gboolean need_discont;
GstClockTime last_discont; /* gst_element_get_time () of last discont send */
gint offset;
gfloat fps;
/* clock */
GstClock *clock;
/* list of supported colorspaces (as integers) */
GList *colorspaces;
/* time to substract from clock time to get back to timestamp */
GstClockTime substract_time;
/* how often are we going to use each frame? */
gint *use_num_times;
/* list of supported colourspaces (as integers) */
GList *colourspaces;
/* how are we going to timestamp buffers? */
GstV4lSrcSyncMode syncmode;
gboolean copy_mode;
gboolean autoprobe; /* probe features on startup ? */
gboolean autoprobe_fps; /* probe fps on startup ? */
@ -113,14 +96,13 @@ struct _GstV4lSrc
struct _GstV4lSrcClass
{
GstV4lElementClass parent_class;
void (*frame_capture) (GObject * object);
void (*frame_drop) (GObject * object);
void (*frame_insert) (GObject * object);
};
GType gst_v4lsrc_get_type (void);
G_END_DECLS
#endif /* __GST_V4LSRC_H__ */

View file

@ -25,7 +25,6 @@
#endif
#include <gst/gst.h>
#include <gst/tuner/tuner.h>
#include "gstv4ltuner.h"
#include "gstv4lelement.h"

View file

@ -24,7 +24,7 @@
#define __GST_V4L_TUNER_H__
#include <gst/gst.h>
#include <gst/tuner/tuner.h>
#include <gst/interfaces/tuner.h>
G_BEGIN_DECLS

View file

@ -25,13 +25,12 @@
#endif
#include <string.h>
#include <gst/gst.h>
#include <gst/xoverlay/xoverlay.h>
#include <sys/stat.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xv.h>
#include <X11/extensions/Xvlib.h>
#include <sys/stat.h>
#include "gstv4lxoverlay.h"
#include "gstv4lelement.h"

View file

@ -24,7 +24,7 @@
#define __GST_V4L_X_OVERLAY_H__
#include <gst/gst.h>
#include <gst/xoverlay/xoverlay.h>
#include <gst/interfaces/xoverlay.h>
#include "gstv4lelement.h"

View file

@ -34,16 +34,16 @@
#include <unistd.h>
#include <gst/gst.h>
#include <gst/tuner/tuner.h>
#include <gst/colorbalance/colorbalance.h>
#include <gst/interfaces/tuner.h>
#include <gst/interfaces/colorbalance.h>
#include "v4l_calls.h"
#include "gstv4ltuner.h"
#include "gstv4lcolorbalance.h"
#include "gstv4lsrc.h"
#include "gstv4lmjpegsrc.h"
#include "gstv4lmjpegsink.h"
/* #include "gstv4lmjpegsrc.h" */
/* #include "gstv4lmjpegsink.h" */
GST_DEBUG_CATEGORY_EXTERN (v4l_debug);
#define GST_CAT_DEFAULT v4l_debug
@ -183,11 +183,11 @@ gst_v4l_open (GstV4lElement * v4lelement)
/* device type check */
if ((GST_IS_V4LSRC (v4lelement) &&
!(v4lelement->vcap.type & VID_TYPE_CAPTURE)) ||
(GST_IS_V4LMJPEGSRC (v4lelement) &&
!(v4lelement->vcap.type & VID_TYPE_MJPEG_ENCODER)) ||
(GST_IS_V4LMJPEGSINK (v4lelement) &&
!(v4lelement->vcap.type & VID_TYPE_MJPEG_DECODER))) {
!(v4lelement->vcap.type & VID_TYPE_CAPTURE))) {
/* (GST_IS_V4LMJPEGSRC (v4lelement) && */
/* !(v4lelement->vcap.type & VID_TYPE_MJPEG_ENCODER)) || */
/* (GST_IS_V4LMJPEGSINK (v4lelement) && */
/* !(v4lelement->vcap.type & VID_TYPE_MJPEG_DECODER))) { */
GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
("Device opened, but wrong type (0x%x)", v4lelement->vcap.type));
close (v4lelement->video_fd);
@ -286,7 +286,6 @@ GList *
gst_v4l_get_chan_names (GstV4lElement * v4lelement)
{
struct video_channel vchan;
const GList *pads = gst_element_get_pad_list (GST_ELEMENT (v4lelement));
GList *list = NULL;
gint i;
@ -295,11 +294,6 @@ gst_v4l_get_chan_names (GstV4lElement * v4lelement)
if (!GST_V4L_IS_OPEN (v4lelement))
return NULL;
/* sinks don't have inputs in v4l */
if (pads && g_list_length ((GList *) pads) == 1)
if (GST_PAD_DIRECTION (GST_PAD (pads->data)) == GST_PAD_SINK)
return NULL;
for (i = 0; i < gst_v4l_get_num_chans (v4lelement); i++) {
GstV4lTunerChannel *v4lchannel = g_object_new (GST_TYPE_V4L_TUNER_CHANNEL,
NULL);

View file

@ -26,25 +26,24 @@
#include "gstv4lelement.h"
#include "gst/gst-i18n-plugin.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
G_BEGIN_DECLS
/* simple check whether the device is open */
#define GST_V4L_IS_OPEN(element) \
(element->video_fd > 0)
(GST_V4LELEMENT (element)->video_fd > 0)
/* check whether the device is 'active' */
#define GST_V4L_IS_ACTIVE(element) \
(element->buffer != NULL)
(GST_V4LELEMENT (element)->buffer != NULL)
#define GST_V4L_IS_OVERLAY(element) \
(element->vcap.type & VID_TYPE_OVERLAY)
(GST_V4LELEMENT (element)->vcap.type & VID_TYPE_OVERLAY)
/* checks whether the current v4lelement has already been open()'ed or not */
#define GST_V4L_CHECK_OPEN(element) \
if (element->video_fd <= 0) \
if (!GST_V4L_IS_OPEN (element)) \
{ \
GST_ELEMENT_ERROR (element, RESOURCE, TOO_LAZY, \
(_("Device is not open.")), (NULL)); \
@ -53,7 +52,7 @@ extern "C" {
/* checks whether the current v4lelement is close()'ed or whether it is still open */
#define GST_V4L_CHECK_NOT_OPEN(element) \
if (element->video_fd != -1) \
if (GST_V4L_IS_OPEN (element)) \
{ \
GST_ELEMENT_ERROR (element, RESOURCE, TOO_LAZY, \
(_("Device is open.")), (NULL)); \
@ -71,7 +70,7 @@ extern "C" {
/* checks whether we're in capture mode or not */
#define GST_V4L_CHECK_ACTIVE(element) \
if (element->buffer == NULL) \
if (!GST_V4L_IS_ACTIVE (element)) \
{ \
GST_ELEMENT_ERROR (element, RESOURCE, SETTINGS, \
(NULL), ("Device is not in streaming mode")); \
@ -80,7 +79,7 @@ extern "C" {
/* checks whether we're out of capture mode or not */
#define GST_V4L_CHECK_NOT_ACTIVE(element) \
if (element->buffer != NULL) \
if (GST_V4L_IS_ACTIVE (element)) \
{ \
GST_ELEMENT_ERROR (element, RESOURCE, SETTINGS, \
(NULL), ("Device is in streaming mode")); \
@ -148,8 +147,8 @@ gboolean gst_v4l_set_audio (GstV4lElement *v4lelement,
gboolean gst_v4l_set_window_properties (GstV4lElement * v4lelement);
gboolean gst_v4l_get_capabilities (GstV4lElement * v4lelement);
#ifdef __cplusplus
}
#endif /* __cplusplus */
G_END_DECLS
#endif /* __V4L_CALLS_H__ */

View file

@ -128,15 +128,6 @@ gst_v4lsrc_sync_frame (GstV4lSrc * v4lsrc, gint num)
}
GST_LOG_OBJECT (v4lsrc, "VIOIOCSYNC on frame %d done", num);
if (v4lsrc->clock) {
v4lsrc->timestamp_sync = gst_clock_get_time (v4lsrc->clock);
} else {
GTimeVal time;
g_get_current_time (&time);
v4lsrc->timestamp_sync = GST_TIMEVAL_TO_TIME (time);
}
v4lsrc->frame_queue_state[num] = QUEUE_STATE_SYNCED;
v4lsrc->num_queued--;
@ -201,10 +192,6 @@ gst_v4lsrc_capture_init (GstV4lSrc * v4lsrc)
v4lsrc->frame_queue_state = (gint8 *)
g_malloc (sizeof (gint8) * v4lsrc->mbuf.frames);
/* track how often to use each frame */
v4lsrc->use_num_times = (gint *)
g_malloc (sizeof (gint) * v4lsrc->mbuf.frames);
/* lock for the frame_state */
v4lsrc->mutex_queue_state = g_mutex_new ();
v4lsrc->cond_queue_state = g_cond_new ();
@ -308,9 +295,6 @@ gst_v4lsrc_grab_frame (GstV4lSrc * v4lsrc, gint * num)
}
v4lsrc->sync_frame = (v4lsrc->sync_frame + 1) % v4lsrc->mbuf.frames;
GST_LOG_OBJECT (v4lsrc, "(%" GST_TIME_FORMAT ") grabbed frame %d",
GST_TIME_ARGS (gst_clock_get_time (v4lsrc->clock)), *num);
g_mutex_unlock (v4lsrc->mutex_queue_state);
return TRUE;
@ -427,8 +411,6 @@ gst_v4lsrc_capture_deinit (GstV4lSrc * v4lsrc)
v4lsrc->cond_queue_state = NULL;
g_free (v4lsrc->frame_queue_state);
v4lsrc->frame_queue_state = NULL;
g_free (v4lsrc->use_num_times);
v4lsrc->use_num_times = NULL;
/* unmap the buffer */
if (munmap (GST_V4LELEMENT (v4lsrc)->buffer, v4lsrc->mbuf.size) == -1) {
@ -542,13 +524,7 @@ gst_v4lsrc_get_fps (GstV4lSrc * v4lsrc)
return current_fps;
}
if (!(v4lsrc->syncmode == GST_V4LSRC_SYNC_MODE_FIXED_FPS) &&
v4lsrc->clock != NULL && v4lsrc->handled > 0) {
/* try to get time from clock master and calculate fps */
GstClockTime time =
gst_clock_get_time (v4lsrc->clock) - v4lsrc->substract_time;
return v4lsrc->handled * GST_SECOND / time;
}
/* removed fps estimation code here */
/* if that failed ... */
@ -565,3 +541,175 @@ gst_v4lsrc_get_fps (GstV4lSrc * v4lsrc)
return fps;
}
/* get a list of possible framerates
* this is only done for webcams;
* other devices return NULL here.
* this function takes a LONG time to execute.
*/
GValue *
gst_v4lsrc_get_fps_list (GstV4lSrc * v4lsrc)
{
gint fps_index;
gfloat fps;
struct video_window *vwin = &GST_V4LELEMENT (v4lsrc)->vwin;
GstV4lElement *v4lelement = GST_V4LELEMENT (v4lsrc);
/* check if we have vwin window properties giving a framerate,
* as is done for webcams
* See http://www.smcc.demon.nl/webcam/api.html
* which is used for the Philips and qce-ga drivers */
fps_index = (vwin->flags >> 16) & 0x3F; /* 6 bit index for framerate */
/* webcams have a non-zero fps_index */
if (fps_index == 0) {
GST_DEBUG_OBJECT (v4lsrc, "fps_index is 0, no webcam");
return NULL;
}
GST_DEBUG_OBJECT (v4lsrc, "fps_index is %d, so webcam", fps_index);
{
gfloat current_fps;
int i;
GValue *list = NULL;
GValue value = { 0 };
/* webcam detected, so try all framerates and return a list */
list = g_new0 (GValue, 1);
g_value_init (list, GST_TYPE_LIST);
/* index of 16 corresponds to 15 fps */
current_fps = fps_index * 15.0 / 16;
GST_DEBUG_OBJECT (v4lsrc, "device reports fps of %.4f", current_fps);
for (i = 0; i < 63; ++i) {
/* set bits 16 to 21 to 0 */
vwin->flags &= (0x3F00 - 1);
/* set bits 16 to 21 to the index */
vwin->flags |= i << 16;
if (gst_v4l_set_window_properties (v4lelement)) {
/* setting it succeeded. FIXME: get it and check. */
fps = i * 15.0 / 16;
g_value_init (&value, G_TYPE_DOUBLE);
g_value_set_double (&value, fps);
gst_value_list_append_value (list, &value);
g_value_unset (&value);
}
}
/* FIXME: set back the original fps_index */
vwin->flags &= (0x3F00 - 1);
vwin->flags |= fps_index << 16;
gst_v4l_set_window_properties (v4lelement);
return list;
}
return NULL;
}
#define GST_TYPE_V4LSRC_BUFFER (gst_v4lsrc_buffer_get_type())
#define GST_IS_V4LSRC_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_V4LSRC_BUFFER))
#define GST_V4LSRC_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_V4LSRC_BUFFER, GstV4lSrcBuffer))
typedef struct _GstV4lSrcBuffer
{
GstBuffer buffer;
GstV4lSrc *v4lsrc;
gint num;
} GstV4lSrcBuffer;
static void gst_v4lsrc_buffer_class_init (gpointer g_class,
gpointer class_data);
static void gst_v4lsrc_buffer_init (GTypeInstance * instance, gpointer g_class);
static void gst_v4lsrc_buffer_finalize (GstV4lSrcBuffer * v4lsrc_buffer);
GType
gst_v4lsrc_buffer_get_type (void)
{
static GType _gst_v4lsrc_buffer_type;
if (G_UNLIKELY (_gst_v4lsrc_buffer_type == 0)) {
static const GTypeInfo v4lsrc_buffer_info = {
sizeof (GstBufferClass),
NULL,
NULL,
gst_v4lsrc_buffer_class_init,
NULL,
NULL,
sizeof (GstV4lSrcBuffer),
0,
gst_v4lsrc_buffer_init,
NULL
};
_gst_v4lsrc_buffer_type = g_type_register_static (GST_TYPE_BUFFER,
"GstV4lSrcBuffer", &v4lsrc_buffer_info, 0);
}
return _gst_v4lsrc_buffer_type;
}
static void
gst_v4lsrc_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_v4lsrc_buffer_finalize;
}
static void
gst_v4lsrc_buffer_init (GTypeInstance * instance, gpointer g_class)
{
}
static void
gst_v4lsrc_buffer_finalize (GstV4lSrcBuffer * v4lsrc_buffer)
{
GstV4lSrc *v4lsrc;
gint num;
v4lsrc = v4lsrc_buffer->v4lsrc;
num = v4lsrc_buffer->num;
GST_LOG_OBJECT (v4lsrc, "freeing buffer %p for frame %d", v4lsrc_buffer, num);
/* only requeue if we still have an mmap buffer */
if (GST_V4LELEMENT (v4lsrc)->buffer) {
GST_LOG_OBJECT (v4lsrc, "requeueing frame %d", num);
gst_v4lsrc_requeue_frame (v4lsrc, num);
}
gst_object_unref (v4lsrc);
}
/* Create a V4lSrc buffer from our mmap'd data area */
GstBuffer *
gst_v4lsrc_buffer_new (GstV4lSrc * v4lsrc, gint num)
{
GstBuffer *buf;
GST_DEBUG_OBJECT (v4lsrc, "creating buffer for frame %d", num);
buf = (GstBuffer *) gst_mini_object_new (GST_TYPE_V4LSRC_BUFFER);
GST_V4LSRC_BUFFER (buf)->num = num;
GST_V4LSRC_BUFFER (buf)->v4lsrc = gst_object_ref (v4lsrc);
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_READONLY);
GST_BUFFER_DATA (buf) = gst_v4lsrc_get_buffer (v4lsrc, num);
GST_BUFFER_SIZE (buf) = v4lsrc->buffer_size;
GST_BUFFER_OFFSET (buf) = v4lsrc->offset++;
GST_BUFFER_TIMESTAMP (buf) = gst_clock_get_time (GST_ELEMENT (v4lsrc)->clock);
GST_BUFFER_TIMESTAMP (buf) -= GST_ELEMENT (v4lsrc)->base_time;
/* fixme: this is a most ghetto timestamp/duration */
if (!v4lsrc->fps)
v4lsrc->fps = gst_v4lsrc_get_fps (v4lsrc);
if (v4lsrc->fps)
GST_BUFFER_DURATION (buf) = GST_SECOND / v4lsrc->fps;
/* the negotiate() method already set caps on the source pad */
gst_buffer_set_caps (buf, GST_PAD_CAPS (GST_BASE_SRC_PAD (v4lsrc)));
return buf;
}

View file

@ -26,9 +26,8 @@
#include "gstv4lsrc.h"
#include "v4l_calls.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
G_BEGIN_DECLS
/* frame grabbing/capture (palette = VIDEO_PALETTE_* - see videodev.h) */
@ -41,6 +40,8 @@ gboolean gst_v4lsrc_requeue_frame (GstV4lSrc *v4lsrc, gint num);
gboolean gst_v4lsrc_capture_stop (GstV4lSrc *v4lsrc);
gboolean gst_v4lsrc_capture_deinit (GstV4lSrc *v4lsrc);
gfloat gst_v4lsrc_get_fps (GstV4lSrc * v4lsrc);
GValue * gst_v4lsrc_get_fps_list (GstV4lSrc * v4lsrc);
GstBuffer *gst_v4lsrc_buffer_new (GstV4lSrc * v4lsrc, gint num);
/* "the ugliest hack ever, now available at your local mirror" */
gboolean gst_v4lsrc_try_capture (GstV4lSrc *v4lsrc, gint width, gint height, gint palette);
@ -48,8 +49,8 @@ gboolean gst_v4lsrc_try_capture (GstV4lSrc *v4lsrc, gint width, gint height,
/* For debug purposes, share the palette names */
const char *gst_v4lsrc_palette_name (int i);
#ifdef __cplusplus
}
#endif /* __cplusplus */
G_END_DECLS
#endif /* __V4L_SRC_CALLS_H__ */