mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 16:26:39 +00:00
sys/v4l/: Added a sync mode enum property to control v4lsrc timestamp method
Original commit message from CVS: * sys/v4l/gstv4lsrc.c: (gst_v4lsrc_sync_mode_get_type), (gst_v4lsrc_class_init), (gst_v4lsrc_init), (gst_v4lsrc_get_fps), (gst_v4lsrc_get), (gst_v4lsrc_set_property), (gst_v4lsrc_get_property): * sys/v4l/gstv4lsrc.h: * sys/v4l/v4l-overlay_calls.c: (gst_v4l_set_overlay): Added a sync mode enum property to control v4lsrc timestamp method Removed the use-fixed-fps property and moved functionality in the enum. Don't error on an error value from v4l-conf, it might not always be a real error.
This commit is contained in:
parent
9f47e5b258
commit
bb64d50ef8
4 changed files with 104 additions and 31 deletions
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
||||||
|
2004-06-16 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* sys/v4l/gstv4lsrc.c: (gst_v4lsrc_sync_mode_get_type),
|
||||||
|
(gst_v4lsrc_class_init), (gst_v4lsrc_init), (gst_v4lsrc_get_fps),
|
||||||
|
(gst_v4lsrc_get), (gst_v4lsrc_set_property),
|
||||||
|
(gst_v4lsrc_get_property):
|
||||||
|
* sys/v4l/gstv4lsrc.h:
|
||||||
|
* sys/v4l/v4l-overlay_calls.c: (gst_v4l_set_overlay):
|
||||||
|
Added a sync mode enum property to control v4lsrc timestamp method
|
||||||
|
Removed the use-fixed-fps property and moved functionality in
|
||||||
|
the enum.
|
||||||
|
Don't error on an error value from v4l-conf, it might not always
|
||||||
|
be a real error.
|
||||||
|
|
||||||
2004-06-16 Wim Taymans <wim@fluendo.com>
|
2004-06-16 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* gst/videorate/Makefile.am:
|
* gst/videorate/Makefile.am:
|
||||||
|
|
|
@ -58,7 +58,7 @@ enum
|
||||||
ARG_0,
|
ARG_0,
|
||||||
ARG_NUMBUFS,
|
ARG_NUMBUFS,
|
||||||
ARG_BUFSIZE,
|
ARG_BUFSIZE,
|
||||||
ARG_USE_FIXED_FPS
|
ARG_SYNC_MODE
|
||||||
};
|
};
|
||||||
|
|
||||||
GST_FORMATS_FUNCTION (GstPad *, gst_v4lsrc_get_formats,
|
GST_FORMATS_FUNCTION (GstPad *, gst_v4lsrc_get_formats,
|
||||||
|
@ -66,6 +66,28 @@ GST_FORMATS_FUNCTION (GstPad *, gst_v4lsrc_get_formats,
|
||||||
GST_QUERY_TYPE_FUNCTION (GstPad *, gst_v4lsrc_get_query_types,
|
GST_QUERY_TYPE_FUNCTION (GstPad *, gst_v4lsrc_get_query_types,
|
||||||
GST_QUERY_POSITION);
|
GST_QUERY_POSITION);
|
||||||
|
|
||||||
|
#define DEFAULT_SYNC_MODE GST_V4LSRC_SYNC_MODE_CLOCK
|
||||||
|
|
||||||
|
#define GST_TYPE_V4LSRC_SYNC_MODE (gst_v4lsrc_sync_mode_get_type())
|
||||||
|
static GType
|
||||||
|
gst_v4lsrc_sync_mode_get_type (void)
|
||||||
|
{
|
||||||
|
static GType v4lsrc_sync_mode_type = 0;
|
||||||
|
static GEnumValue v4lsrc_sync_mode[] = {
|
||||||
|
{GST_V4LSRC_SYNC_MODE_CLOCK, "0", "Sync to the pipeline clock"},
|
||||||
|
{GST_V4LSRC_SYNC_MODE_PRIVATE_CLOCK, "1", "Sync to a private clock"},
|
||||||
|
{GST_V4LSRC_SYNC_MODE_FIXED_FPS, "2", "Use Fixed fps"},
|
||||||
|
{GST_V4LSRC_SYNC_MODE_NONE, "3", "No Sync"},
|
||||||
|
{0, NULL, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!v4lsrc_sync_mode_type) {
|
||||||
|
v4lsrc_sync_mode_type =
|
||||||
|
g_enum_register_static ("GstV4lSrcSyncMode", v4lsrc_sync_mode);
|
||||||
|
}
|
||||||
|
return v4lsrc_sync_mode_type;
|
||||||
|
}
|
||||||
|
|
||||||
/* structure for buffer private data referencing element and frame number */
|
/* structure for buffer private data referencing element and frame number */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -175,11 +197,10 @@ gst_v4lsrc_class_init (GstV4lSrcClass * klass)
|
||||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BUFSIZE,
|
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BUFSIZE,
|
||||||
g_param_spec_int ("buffer_size", "Buffer Size", "Size of buffers",
|
g_param_spec_int ("buffer_size", "Buffer Size", "Size of buffers",
|
||||||
0, G_MAXINT, 0, G_PARAM_READABLE));
|
0, G_MAXINT, 0, G_PARAM_READABLE));
|
||||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_USE_FIXED_FPS,
|
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SYNC_MODE,
|
||||||
g_param_spec_boolean ("use_fixed_fps", "Use Fixed FPS",
|
g_param_spec_enum ("sync_mode", "Sync mode",
|
||||||
"Drop/Insert frames to reach a certain FPS (TRUE) "
|
"Method to use for timestamping captured frames",
|
||||||
"or adapt FPS to suit the number of grabbed frames",
|
GST_TYPE_V4LSRC_SYNC_MODE, DEFAULT_SYNC_MODE, G_PARAM_READWRITE));
|
||||||
TRUE, G_PARAM_READWRITE));
|
|
||||||
|
|
||||||
/* signals */
|
/* signals */
|
||||||
gst_v4lsrc_signals[SIGNAL_FRAME_CAPTURE] =
|
gst_v4lsrc_signals[SIGNAL_FRAME_CAPTURE] =
|
||||||
|
@ -238,7 +259,7 @@ gst_v4lsrc_init (GstV4lSrc * v4lsrc)
|
||||||
v4lsrc->colourspaces = NULL;
|
v4lsrc->colourspaces = NULL;
|
||||||
|
|
||||||
/* fps */
|
/* fps */
|
||||||
v4lsrc->use_fixed_fps = TRUE;
|
v4lsrc->syncmode = DEFAULT_SYNC_MODE;
|
||||||
|
|
||||||
v4lsrc->is_capturing = FALSE;
|
v4lsrc->is_capturing = FALSE;
|
||||||
}
|
}
|
||||||
|
@ -366,7 +387,8 @@ gst_v4lsrc_get_fps (GstV4lSrc * v4lsrc)
|
||||||
return current_fps;
|
return current_fps;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!v4lsrc->use_fixed_fps && v4lsrc->clock != NULL && v4lsrc->handled > 0) {
|
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 */
|
/* try to get time from clock master and calculate fps */
|
||||||
GstClockTime time =
|
GstClockTime time =
|
||||||
gst_clock_get_time (v4lsrc->clock) - v4lsrc->substract_time;
|
gst_clock_get_time (v4lsrc->clock) - v4lsrc->substract_time;
|
||||||
|
@ -773,20 +795,23 @@ gst_v4lsrc_get (GstPad * pad)
|
||||||
gdouble fps = 0.;
|
gdouble fps = 0.;
|
||||||
v4lsrc_private_t *v4lsrc_private = NULL;
|
v4lsrc_private_t *v4lsrc_private = NULL;
|
||||||
GstClockTime now, until;
|
GstClockTime now, until;
|
||||||
|
gboolean fixed_fps;
|
||||||
|
|
||||||
g_return_val_if_fail (pad != NULL, NULL);
|
g_return_val_if_fail (pad != NULL, NULL);
|
||||||
|
|
||||||
v4lsrc = GST_V4LSRC (gst_pad_get_parent (pad));
|
v4lsrc = GST_V4LSRC (gst_pad_get_parent (pad));
|
||||||
fps = gst_v4lsrc_get_fps (v4lsrc);
|
fps = gst_v4lsrc_get_fps (v4lsrc);
|
||||||
|
|
||||||
if (v4lsrc->use_fixed_fps && fps == 0.0)
|
fixed_fps = v4lsrc->syncmode == GST_V4LSRC_SYNC_MODE_FIXED_FPS;
|
||||||
|
|
||||||
|
if (fixed_fps && fps == 0.0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (v4lsrc->need_writes > 0) {
|
if (v4lsrc->need_writes > 0) {
|
||||||
/* use last frame */
|
/* use last frame */
|
||||||
num = v4lsrc->last_frame;
|
num = v4lsrc->last_frame;
|
||||||
v4lsrc->need_writes--;
|
v4lsrc->need_writes--;
|
||||||
} else if (v4lsrc->clock && v4lsrc->use_fixed_fps) {
|
} else if (v4lsrc->clock && fixed_fps) {
|
||||||
GstClockTime time;
|
GstClockTime time;
|
||||||
gboolean have_frame = FALSE;
|
gboolean have_frame = FALSE;
|
||||||
|
|
||||||
|
@ -854,20 +879,37 @@ gst_v4lsrc_get (GstPad * pad)
|
||||||
GST_BUFFER_DATA (buf) = gst_v4lsrc_get_buffer (v4lsrc, num);
|
GST_BUFFER_DATA (buf) = gst_v4lsrc_get_buffer (v4lsrc, num);
|
||||||
GST_BUFFER_MAXSIZE (buf) = v4lsrc->mbuf.size / v4lsrc->mbuf.frames;
|
GST_BUFFER_MAXSIZE (buf) = v4lsrc->mbuf.size / v4lsrc->mbuf.frames;
|
||||||
GST_BUFFER_SIZE (buf) = v4lsrc->buffer_size;
|
GST_BUFFER_SIZE (buf) = v4lsrc->buffer_size;
|
||||||
if (v4lsrc->use_fixed_fps) {
|
|
||||||
GST_BUFFER_TIMESTAMP (buf) = v4lsrc->handled * GST_SECOND / fps;
|
|
||||||
GST_BUFFER_DURATION (buf) = GST_SECOND / fps;
|
switch (v4lsrc->syncmode) {
|
||||||
} else {
|
case GST_V4LSRC_SYNC_MODE_FIXED_FPS:
|
||||||
/* calculate time based on our own clock */
|
GST_BUFFER_TIMESTAMP (buf) = v4lsrc->handled * GST_SECOND / fps;
|
||||||
GST_BUFFER_TIMESTAMP (buf) =
|
break;
|
||||||
v4lsrc->timestamp_sync - v4lsrc->substract_time;
|
case GST_V4LSRC_SYNC_MODE_PRIVATE_CLOCK:
|
||||||
/* FIXME: in this case we might calculate from the delta with last frame ? */
|
/* calculate time based on our own clock */
|
||||||
GST_BUFFER_DURATION (buf) = GST_SECOND / fps;
|
GST_BUFFER_TIMESTAMP (buf) =
|
||||||
|
v4lsrc->timestamp_sync - v4lsrc->substract_time;
|
||||||
|
break;
|
||||||
|
case GST_V4LSRC_SYNC_MODE_CLOCK:
|
||||||
|
if (v4lsrc->clock) {
|
||||||
|
GstClockTime time = gst_element_get_time (GST_ELEMENT (v4lsrc));
|
||||||
|
|
||||||
|
GST_BUFFER_TIMESTAMP (buf) = time;
|
||||||
|
} else {
|
||||||
|
GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GST_V4LSRC_SYNC_MODE_NONE:
|
||||||
|
GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
GST_BUFFER_DURATION (buf) = GST_SECOND / fps;
|
||||||
|
|
||||||
GST_LOG_OBJECT (v4lsrc, "outgoing buffer duration: %" GST_TIME_FORMAT,
|
GST_LOG_OBJECT (v4lsrc, "outgoing buffer duration: %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
|
GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
|
||||||
|
|
||||||
|
|
||||||
v4lsrc->handled++;
|
v4lsrc->handled++;
|
||||||
g_signal_emit (G_OBJECT (v4lsrc),
|
g_signal_emit (G_OBJECT (v4lsrc),
|
||||||
gst_v4lsrc_signals[SIGNAL_FRAME_CAPTURE], 0);
|
gst_v4lsrc_signals[SIGNAL_FRAME_CAPTURE], 0);
|
||||||
|
@ -925,9 +967,9 @@ gst_v4lsrc_set_property (GObject * object,
|
||||||
v4lsrc = GST_V4LSRC (object);
|
v4lsrc = GST_V4LSRC (object);
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case ARG_USE_FIXED_FPS:
|
case ARG_SYNC_MODE:
|
||||||
if (!GST_V4L_IS_ACTIVE (GST_V4LELEMENT (v4lsrc))) {
|
if (!GST_V4L_IS_ACTIVE (GST_V4LELEMENT (v4lsrc))) {
|
||||||
v4lsrc->use_fixed_fps = g_value_get_boolean (value);
|
v4lsrc->syncmode = g_value_get_enum (value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -960,8 +1002,8 @@ gst_v4lsrc_get_property (GObject * object,
|
||||||
v4lsrc->mbuf.size / (v4lsrc->mbuf.frames * 1024));
|
v4lsrc->mbuf.size / (v4lsrc->mbuf.frames * 1024));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARG_USE_FIXED_FPS:
|
case ARG_SYNC_MODE:
|
||||||
g_value_set_boolean (value, v4lsrc->use_fixed_fps);
|
g_value_set_enum (value, v4lsrc->syncmode);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -47,6 +47,14 @@ enum
|
||||||
QUEUE_STATE_SYNCED /* the frame is captured */
|
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
|
struct _GstV4lSrc
|
||||||
{
|
{
|
||||||
GstV4lElement v4lelement;
|
GstV4lElement v4lelement;
|
||||||
|
@ -91,8 +99,8 @@ struct _GstV4lSrc
|
||||||
/* list of supported colourspaces (as integers) */
|
/* list of supported colourspaces (as integers) */
|
||||||
GList *colourspaces;
|
GList *colourspaces;
|
||||||
|
|
||||||
/* how are we going to push buffers? */
|
/* how are we going to timestamp buffers? */
|
||||||
gboolean use_fixed_fps;
|
GstV4lSrcSyncMode syncmode;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstV4lSrcClass
|
struct _GstV4lSrcClass
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
@ -48,6 +49,7 @@ gst_v4l_set_overlay (GstV4lElement * v4lelement)
|
||||||
{
|
{
|
||||||
gchar *buff;
|
gchar *buff;
|
||||||
gchar *path;
|
gchar *path;
|
||||||
|
gint ret;
|
||||||
|
|
||||||
if (v4lelement->display)
|
if (v4lelement->display)
|
||||||
g_free (v4lelement->display);
|
g_free (v4lelement->display);
|
||||||
|
@ -69,10 +71,11 @@ gst_v4l_set_overlay (GstV4lElement * v4lelement)
|
||||||
}
|
}
|
||||||
g_free (path);
|
g_free (path);
|
||||||
|
|
||||||
buff = g_strdup_printf ("v4l-conf -q -c %s -d %s 2> /dev/null",
|
buff = g_strdup_printf ("v4l-conf -q -c %s -d %s",
|
||||||
v4lelement->videodev, v4lelement->display);
|
v4lelement->videodev, v4lelement->display);
|
||||||
|
|
||||||
switch (system (buff)) {
|
ret = system (buff);
|
||||||
|
switch (ret) {
|
||||||
case -1:
|
case -1:
|
||||||
GST_ELEMENT_ERROR (v4lelement, RESOURCE, FAILED,
|
GST_ELEMENT_ERROR (v4lelement, RESOURCE, FAILED,
|
||||||
(_("Could not start v4l-conf.")), GST_ERROR_SYSTEM);
|
(_("Could not start v4l-conf.")), GST_ERROR_SYSTEM);
|
||||||
|
@ -81,10 +84,16 @@ gst_v4l_set_overlay (GstV4lElement * v4lelement)
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
GST_ELEMENT_ERROR (v4lelement, RESOURCE, FAILED,
|
{
|
||||||
(_("Executing v4l-conf failed.")), GST_ERROR_SYSTEM);
|
/* if we get here, the system command did not fail but v4l-conf
|
||||||
|
* returned an error code, we just warn for now because it is not
|
||||||
|
* always fatal (like not having overlay support) */
|
||||||
|
gint status = WEXITSTATUS (ret);
|
||||||
|
|
||||||
|
g_warning ("v4l-conf returned %d.", status);
|
||||||
g_free (buff);
|
g_free (buff);
|
||||||
return FALSE;
|
return TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (buff);
|
g_free (buff);
|
||||||
|
|
Loading…
Reference in a new issue