add autoprobe option fixes use try_capture

Original commit message from CVS:
add autoprobe option
fixes
use try_capture
This commit is contained in:
Thomas Vander Stichele 2004-06-17 17:06:24 +00:00
parent 8f033f8591
commit b72439823e
6 changed files with 102 additions and 22 deletions

View file

@ -1,3 +1,20 @@
2004-06-17 Thomas Vander Stichele <thomas at apestaart dot org>
* sys/v4l/gstv4lsrc.c: (gst_v4lsrc_class_init), (gst_v4lsrc_init),
(gst_v4lsrc_open), (gst_v4lsrc_src_link), (gst_v4lsrc_getcaps),
(gst_v4lsrc_get), (gst_v4lsrc_set_property),
(gst_v4lsrc_get_property):
* sys/v4l/gstv4lsrc.h:
* sys/v4l/v4l_calls.c: (gst_v4l_set_window_properties),
(gst_v4l_open), (gst_v4l_get_picture), (gst_v4l_get_audio),
(gst_v4l_set_audio):
* sys/v4l/v4lsrc_calls.c: (gst_v4lsrc_grab_frame),
(gst_v4lsrc_try_capture):
* sys/v4l/v4lsrc_calls.h:
change try_palette to more general try_capture
add autoprobe option so we can turn off autoprobing
various fixes
2004-06-17 Thomas Vander Stichele <thomas at apestaart dot org> 2004-06-17 Thomas Vander Stichele <thomas at apestaart dot org>
* configure.ac: * configure.ac:

View file

@ -31,6 +31,7 @@
/* FIXME: small cheat */ /* FIXME: small cheat */
gboolean gst_v4l_set_window_properties (GstV4lElement * v4lelement); gboolean gst_v4l_set_window_properties (GstV4lElement * v4lelement);
gboolean gst_v4l_get_capabilities (GstV4lElement * v4lelement);
/* elementfactory information */ /* elementfactory information */
static GstElementDetails gst_v4lsrc_details = static GstElementDetails gst_v4lsrc_details =
@ -61,7 +62,8 @@ enum
ARG_NUMBUFS, ARG_NUMBUFS,
ARG_BUFSIZE, ARG_BUFSIZE,
ARG_SYNC_MODE, ARG_SYNC_MODE,
ARG_COPY_MODE ARG_COPY_MODE,
ARG_AUTOPROBE
}; };
GST_FORMATS_FUNCTION (GstPad *, gst_v4lsrc_get_formats, GST_FORMATS_FUNCTION (GstPad *, gst_v4lsrc_get_formats,
@ -114,7 +116,7 @@ static gboolean gst_v4lsrc_src_query (GstPad * pad,
GstQueryType type, GstFormat * format, gint64 * value); GstQueryType type, GstFormat * format, gint64 * value);
/* buffer functions */ /* buffer functions */
static GstPadLinkReturn gst_v4lsrc_srcconnect (GstPad * pad, static GstPadLinkReturn gst_v4lsrc_src_link (GstPad * pad,
const GstCaps * caps); const GstCaps * caps);
static GstCaps *gst_v4lsrc_fixate (GstPad * pad, const GstCaps * caps); static GstCaps *gst_v4lsrc_fixate (GstPad * pad, const GstCaps * caps);
static GstCaps *gst_v4lsrc_getcaps (GstPad * pad); static GstCaps *gst_v4lsrc_getcaps (GstPad * pad);
@ -206,6 +208,10 @@ gst_v4lsrc_class_init (GstV4lSrcClass * klass)
g_param_spec_boolean ("copy_mode", "Copy mode", g_param_spec_boolean ("copy_mode", "Copy mode",
"Don't send out HW buffers, send copy instead", DEFAULT_COPY_MODE, "Don't send out HW buffers, send copy instead", DEFAULT_COPY_MODE,
G_PARAM_READWRITE)); G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_AUTOPROBE,
g_param_spec_boolean ("autoprobe", "Autoprobe",
"Whether the device should be probed for all possible features",
TRUE, G_PARAM_READWRITE));
/* signals */ /* signals */
gst_v4lsrc_signals[SIGNAL_FRAME_CAPTURE] = gst_v4lsrc_signals[SIGNAL_FRAME_CAPTURE] =
@ -233,7 +239,6 @@ gst_v4lsrc_class_init (GstV4lSrcClass * klass)
v4lelement_class->close = gst_v4lsrc_close; v4lelement_class->close = gst_v4lsrc_close;
} }
static void static void
gst_v4lsrc_init (GstV4lSrc * v4lsrc) gst_v4lsrc_init (GstV4lSrc * v4lsrc)
{ {
@ -249,7 +254,7 @@ gst_v4lsrc_init (GstV4lSrc * v4lsrc)
gst_pad_set_get_function (v4lsrc->srcpad, gst_v4lsrc_get); gst_pad_set_get_function (v4lsrc->srcpad, gst_v4lsrc_get);
gst_pad_set_getcaps_function (v4lsrc->srcpad, gst_v4lsrc_getcaps); gst_pad_set_getcaps_function (v4lsrc->srcpad, gst_v4lsrc_getcaps);
gst_pad_set_fixate_function (v4lsrc->srcpad, gst_v4lsrc_fixate); gst_pad_set_fixate_function (v4lsrc->srcpad, gst_v4lsrc_fixate);
gst_pad_set_link_function (v4lsrc->srcpad, gst_v4lsrc_srcconnect); gst_pad_set_link_function (v4lsrc->srcpad, gst_v4lsrc_src_link);
gst_pad_set_convert_function (v4lsrc->srcpad, gst_v4lsrc_src_convert); gst_pad_set_convert_function (v4lsrc->srcpad, gst_v4lsrc_src_convert);
gst_pad_set_formats_function (v4lsrc->srcpad, gst_v4lsrc_get_formats); gst_pad_set_formats_function (v4lsrc->srcpad, gst_v4lsrc_get_formats);
gst_pad_set_query_function (v4lsrc->srcpad, gst_v4lsrc_src_query); gst_pad_set_query_function (v4lsrc->srcpad, gst_v4lsrc_src_query);
@ -267,12 +272,17 @@ gst_v4lsrc_init (GstV4lSrc * v4lsrc)
v4lsrc->copy_mode = DEFAULT_COPY_MODE; v4lsrc->copy_mode = DEFAULT_COPY_MODE;
v4lsrc->is_capturing = FALSE; v4lsrc->is_capturing = FALSE;
v4lsrc->autoprobe = TRUE;
} }
static void static void
gst_v4lsrc_open (GstElement * element, const gchar * device) gst_v4lsrc_open (GstElement * element, const gchar * device)
{ {
GstV4lSrc *v4lsrc = GST_V4LSRC (element); GstV4lSrc *v4lsrc = GST_V4LSRC (element);
GstV4lElement *v4l = GST_V4LELEMENT (v4lsrc);
gint width = v4l->vcap.minwidth;
gint height = v4l->vcap.minheight;
int palette[] = { int palette[] = {
VIDEO_PALETTE_YUV422, VIDEO_PALETTE_YUV422,
VIDEO_PALETTE_YUV420P, VIDEO_PALETTE_YUV420P,
@ -290,7 +300,7 @@ gst_v4lsrc_open (GstElement * element, const gchar * device)
for (i = 0; palette[i] != -1; i++) { for (i = 0; palette[i] != -1; i++) {
/* try palette out */ /* try palette out */
if (!gst_v4lsrc_try_palette (v4lsrc, palette[i])) if (!gst_v4lsrc_try_capture (v4lsrc, width, height, palette[i]))
continue; continue;
v4lsrc->colourspaces = g_list_append (v4lsrc->colourspaces, v4lsrc->colourspaces = g_list_append (v4lsrc->colourspaces,
GINT_TO_POINTER (palette[i])); GINT_TO_POINTER (palette[i]));
@ -575,7 +585,7 @@ gst_v4lsrc_palette_to_caps (int palette)
static GstPadLinkReturn static GstPadLinkReturn
gst_v4lsrc_srcconnect (GstPad * pad, const GstCaps * vscapslist) gst_v4lsrc_src_link (GstPad * pad, const GstCaps * vscapslist)
{ {
GstV4lSrc *v4lsrc; GstV4lSrc *v4lsrc;
guint32 fourcc; guint32 fourcc;
@ -583,8 +593,10 @@ gst_v4lsrc_srcconnect (GstPad * pad, const GstCaps * vscapslist)
gdouble fps; gdouble fps;
GstStructure *structure; GstStructure *structure;
gboolean was_capturing; gboolean was_capturing;
struct video_window *vwin;
v4lsrc = GST_V4LSRC (gst_pad_get_parent (pad)); v4lsrc = GST_V4LSRC (gst_pad_get_parent (pad));
vwin = &GST_V4LELEMENT (v4lsrc)->vwin;
was_capturing = v4lsrc->is_capturing; was_capturing = v4lsrc->is_capturing;
/* in case the buffers are active (which means that we already /* in case the buffers are active (which means that we already
@ -614,7 +626,6 @@ gst_v4lsrc_srcconnect (GstPad * pad, const GstCaps * vscapslist)
/* set framerate if it's not already correct */ /* set framerate if it's not already correct */
if (fps != gst_v4lsrc_get_fps (v4lsrc)) { if (fps != gst_v4lsrc_get_fps (v4lsrc)) {
int fps_index = fps / 15.0 * 16; int fps_index = fps / 15.0 * 16;
struct video_window *vwin = &GST_V4LELEMENT (v4lsrc)->vwin;
GST_DEBUG_OBJECT (v4lsrc, "Trying to set fps index %d", fps_index); GST_DEBUG_OBJECT (v4lsrc, "Trying to set fps index %d", fps_index);
/* set bits 16 to 21 to 0 */ /* set bits 16 to 21 to 0 */
@ -689,11 +700,46 @@ gst_v4lsrc_srcconnect (GstPad * pad, const GstCaps * vscapslist)
break; break;
} }
if (palette == -1) if (palette == -1) {
GST_WARN_OBJECT (v4lsrc, "palette is -1, refusing link");
return GST_PAD_LINK_REFUSED; return GST_PAD_LINK_REFUSED;
}
if (!gst_v4lsrc_set_capture (v4lsrc, w, h, palette)) GST_DEBUG_OBJECT (v4lsrc, "trying to set_capture %dx%d, palette %d",
w, h, palette);
if (!gst_v4lsrc_set_capture (v4lsrc, w, h, palette)) {
GST_WARN_OBJECT (v4lsrc, "could not set_capture %dx%d, palette %d",
w, h, palette);
return GST_PAD_LINK_REFUSED; return GST_PAD_LINK_REFUSED;
}
/* first try the negotiated settings using try_capture */
if (!gst_v4lsrc_try_capture (v4lsrc, w, h, palette)) {
GST_DEBUG_OBJECT (v4lsrc, "failed trying palette %d for w/h", palette);
return GST_PAD_LINK_REFUSED;
}
if (!gst_v4l_get_capabilities (GST_V4LELEMENT (v4lsrc)))
GST_DEBUG_OBJECT (v4lsrc, "failed getting capabilities");
GST_DEBUG_OBJECT (v4lsrc, "done checking, with w %d h %d palette %d\n",
vwin->width, vwin->height, palette);
if (vwin->width != v4lsrc->mmap.width) {
/* We consider this a device error since it was called with fixed
* caps that the device doesn't accept. Still, there should be
* a way to handle this more gracefully, maybe provide a fixate
* function */
GST_ELEMENT_ERROR (v4lsrc, RESOURCE, SETTINGS, (NULL),
("Tried setting %dx%d but got %dx%d back as suggestion",
v4lsrc->mmap.width, v4lsrc->mmap.height, vwin->width,
vwin->height));
return GST_PAD_LINK_REFUSED;
}
if (vwin->height != v4lsrc->mmap.height) {
GST_ELEMENT_ERROR (v4lsrc, RESOURCE, SETTINGS, (NULL),
("Tried setting %dx%d but got %dx%d back as suggestion",
v4lsrc->mmap.width, v4lsrc->mmap.height, vwin->width,
vwin->height));
return GST_PAD_LINK_REFUSED;
}
if (!gst_v4lsrc_capture_init (v4lsrc)) if (!gst_v4lsrc_capture_init (v4lsrc))
return GST_PAD_LINK_REFUSED; return GST_PAD_LINK_REFUSED;
@ -752,6 +798,11 @@ gst_v4lsrc_getcaps (GstPad * pad)
if (!GST_V4L_IS_OPEN (GST_V4LELEMENT (v4lsrc))) { if (!GST_V4L_IS_OPEN (GST_V4LELEMENT (v4lsrc))) {
return gst_caps_new_any (); return gst_caps_new_any ();
} }
if (!v4lsrc->autoprobe) {
/* FIXME: query current caps and return those, with _any appended */
return gst_caps_new_any ();
}
/* if not cached from last run, get it */ /* if not cached from last run, get it */
if (!fps_list) if (!fps_list)
fps_list = gst_v4lsrc_get_fps_list (v4lsrc); fps_list = gst_v4lsrc_get_fps_list (v4lsrc);
@ -907,7 +958,8 @@ gst_v4lsrc_get (GstPad * pad)
if (v4lsrc->clock) { if (v4lsrc->clock) {
GstClockTime time = gst_element_get_time (GST_ELEMENT (v4lsrc)); GstClockTime time = gst_element_get_time (GST_ELEMENT (v4lsrc));
GST_BUFFER_TIMESTAMP (buf) = time; /* FIXME: figure out a way to add the capture latency here */
GST_BUFFER_TIMESTAMP (buf) = time /* + 0.5 * GST_SECOND / fps */ ;
} else { } else {
GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE; GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
} }
@ -990,6 +1042,12 @@ gst_v4lsrc_set_property (GObject * object,
v4lsrc->copy_mode = g_value_get_boolean (value); v4lsrc->copy_mode = g_value_get_boolean (value);
break; break;
case ARG_AUTOPROBE:
if (!GST_V4L_IS_ACTIVE (GST_V4LELEMENT (v4lsrc))) {
v4lsrc->autoprobe = g_value_get_boolean (value);
}
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -1027,6 +1085,10 @@ gst_v4lsrc_get_property (GObject * object,
g_value_set_boolean (value, v4lsrc->copy_mode); g_value_set_boolean (value, v4lsrc->copy_mode);
break; break;
case ARG_AUTOPROBE:
g_value_set_boolean (value, v4lsrc->autoprobe);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;

View file

@ -103,6 +103,7 @@ struct _GstV4lSrc
GstV4lSrcSyncMode syncmode; GstV4lSrcSyncMode syncmode;
gboolean copy_mode; gboolean copy_mode;
gboolean autoprobe; /* probe on startup ? */
}; };
struct _GstV4lSrcClass struct _GstV4lSrcClass

View file

@ -76,7 +76,7 @@ static const char *norm_name[] = {
* return value: TRUE on success, FALSE on error * return value: TRUE on success, FALSE on error
******************************************************/ ******************************************************/
static gboolean gboolean
gst_v4l_get_capabilities (GstV4lElement * v4lelement) gst_v4l_get_capabilities (GstV4lElement * v4lelement)
{ {
GST_DEBUG_OBJECT (v4lelement, "getting capabilities"); GST_DEBUG_OBJECT (v4lelement, "getting capabilities");
@ -194,7 +194,7 @@ gst_v4l_open (GstV4lElement * v4lelement)
return FALSE; return FALSE;
} }
GST_INFO_OBJECT (v4lelement, "Opened device \'%s\' (\'%s\') successfully\n", GST_INFO_OBJECT (v4lelement, "Opened device \'%s\' (\'%s\') successfully",
v4lelement->vcap.name, v4lelement->videodev); v4lelement->vcap.name, v4lelement->videodev);
/* norms + inputs, for the tuner interface */ /* norms + inputs, for the tuner interface */

View file

@ -274,7 +274,7 @@ gst_v4lsrc_capture_start (GstV4lSrc * v4lsrc)
gboolean gboolean
gst_v4lsrc_grab_frame (GstV4lSrc * v4lsrc, gint * num) gst_v4lsrc_grab_frame (GstV4lSrc * v4lsrc, gint * num)
{ {
GST_LOG_OBJECT (v4lsrc, "grabbing frame"); GST_LOG_OBJECT (v4lsrc, "grabbing frame %d", num);
GST_V4L_CHECK_OPEN (GST_V4LELEMENT (v4lsrc)); GST_V4L_CHECK_OPEN (GST_V4LELEMENT (v4lsrc));
GST_V4L_CHECK_ACTIVE (GST_V4LELEMENT (v4lsrc)); GST_V4L_CHECK_ACTIVE (GST_V4LELEMENT (v4lsrc));
@ -443,10 +443,9 @@ gst_v4lsrc_capture_deinit (GstV4lSrc * v4lsrc)
return TRUE; return TRUE;
} }
/****************************************************** /******************************************************
* gst_v4lsrc_try_palette(): * gst_v4lsrc_try_capture():
* try out a palette on the device * try out a capture on the device
* This has to be done before initializing the * This has to be done before initializing the
* actual capture system, to make sure we don't * actual capture system, to make sure we don't
* mess up anything. So we need to mini-mmap() * mess up anything. So we need to mini-mmap()
@ -461,7 +460,8 @@ gst_v4lsrc_capture_deinit (GstV4lSrc * v4lsrc)
******************************************************/ ******************************************************/
gboolean gboolean
gst_v4lsrc_try_palette (GstV4lSrc * v4lsrc, gint palette) gst_v4lsrc_try_capture (GstV4lSrc * v4lsrc, gint width, gint height,
gint palette)
{ {
/* so, we need a buffer and some more stuff */ /* so, we need a buffer and some more stuff */
int frame = 0; int frame = 0;
@ -469,8 +469,8 @@ gst_v4lsrc_try_palette (GstV4lSrc * v4lsrc, gint palette)
struct video_mbuf vmbuf; struct video_mbuf vmbuf;
struct video_mmap vmmap; struct video_mmap vmmap;
GST_DEBUG_OBJECT (v4lsrc, "gonna try out palette format %d (%s)", GST_DEBUG_OBJECT (v4lsrc, "try out %dx%d, palette format %d (%s)",
palette, palette_name[palette]); width, height, palette, palette_name[palette]);
GST_V4L_CHECK_OPEN (GST_V4LELEMENT (v4lsrc)); GST_V4L_CHECK_OPEN (GST_V4LELEMENT (v4lsrc));
GST_V4L_CHECK_NOT_ACTIVE (GST_V4LELEMENT (v4lsrc)); GST_V4L_CHECK_NOT_ACTIVE (GST_V4LELEMENT (v4lsrc));
@ -490,8 +490,8 @@ gst_v4lsrc_try_palette (GstV4lSrc * v4lsrc, gint palette)
} }
/* now that we have a buffer, let's try out our format */ /* now that we have a buffer, let's try out our format */
vmmap.width = GST_V4LELEMENT (v4lsrc)->vcap.minwidth; vmmap.width = width;
vmmap.height = GST_V4LELEMENT (v4lsrc)->vcap.minheight; vmmap.height = height;
vmmap.format = palette; vmmap.format = palette;
vmmap.frame = frame; vmmap.frame = frame;
if (ioctl (GST_V4LELEMENT (v4lsrc)->video_fd, VIDIOCMCAPTURE, &vmmap) < 0) { if (ioctl (GST_V4LELEMENT (v4lsrc)->video_fd, VIDIOCMCAPTURE, &vmmap) < 0) {

View file

@ -42,7 +42,7 @@ gboolean gst_v4lsrc_capture_stop (GstV4lSrc *v4lsrc);
gboolean gst_v4lsrc_capture_deinit (GstV4lSrc *v4lsrc); gboolean gst_v4lsrc_capture_deinit (GstV4lSrc *v4lsrc);
/* "the ugliest hack ever, now available at your local mirror" */ /* "the ugliest hack ever, now available at your local mirror" */
gboolean gst_v4lsrc_try_palette (GstV4lSrc *v4lsrc, gint palette); gboolean gst_v4lsrc_try_capture (GstV4lSrc *v4lsrc, gint width, gint height, gint palette);
#ifdef __cplusplus #ifdef __cplusplus