mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 04:36:20 +00:00
sys/v4l2/v4l2_calls.c: Treat ENOTTY (driver does not implement ioctl) the same as
Original commit message from CVS: * sys/v4l2/v4l2_calls.c: (gst_v4l2_fill_lists): Treat ENOTTY (driver does not implement ioctl) the same as EINVAL since it implies there are no available standards. * sys/v4l2/v4l2src_calls.c: (gst_v4l2src_probe_caps_for_format), (gst_v4l2src_get_nearest_size): Replace gst_v4l2src_get_size_limits with 2 calls to new function gst_v4l2src_get_nearest_size, and get it to use VIDIOC_S_FMT to probe if the driver does not support VIDIOC_TRY_FMT for whatever reason, and if we aren't yet actively capturing. * sys/v4l2/v4l2src_calls.h: Remove replaced function declaration.
This commit is contained in:
parent
27d41809a0
commit
38baf136e6
4 changed files with 71 additions and 43 deletions
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
||||||
|
2008-01-31 Jan Schmidt <Jan.Schmidt@sun.com>
|
||||||
|
|
||||||
|
* sys/v4l2/v4l2_calls.c: (gst_v4l2_fill_lists):
|
||||||
|
Treat ENOTTY (driver does not implement ioctl) the same as
|
||||||
|
EINVAL since it implies there are no available standards.
|
||||||
|
|
||||||
|
* sys/v4l2/v4l2src_calls.c: (gst_v4l2src_probe_caps_for_format),
|
||||||
|
(gst_v4l2src_get_nearest_size):
|
||||||
|
Replace gst_v4l2src_get_size_limits with 2 calls to new function
|
||||||
|
gst_v4l2src_get_nearest_size, and get it to use VIDIOC_S_FMT to
|
||||||
|
probe if the driver does not support VIDIOC_TRY_FMT for whatever
|
||||||
|
reason, and if we aren't yet actively capturing.
|
||||||
|
|
||||||
|
* sys/v4l2/v4l2src_calls.h:
|
||||||
|
Remove replaced function declaration.
|
||||||
|
|
||||||
2008-01-31 Jan Schmidt <Jan.Schmidt@sun.com>
|
2008-01-31 Jan Schmidt <Jan.Schmidt@sun.com>
|
||||||
|
|
||||||
* configure.ac:
|
* configure.ac:
|
||||||
|
|
|
@ -185,7 +185,7 @@ gst_v4l2_fill_lists (GstV4l2Object * v4l2object)
|
||||||
standard.index = n;
|
standard.index = n;
|
||||||
|
|
||||||
if (ioctl (v4l2object->video_fd, VIDIOC_ENUMSTD, &standard) < 0) {
|
if (ioctl (v4l2object->video_fd, VIDIOC_ENUMSTD, &standard) < 0) {
|
||||||
if (errno == EINVAL)
|
if (errno == EINVAL || errno == ENOTTY)
|
||||||
break; /* end of enumeration */
|
break; /* end of enumeration */
|
||||||
else {
|
else {
|
||||||
GST_ELEMENT_ERROR (e, RESOURCE, SETTINGS,
|
GST_ELEMENT_ERROR (e, RESOURCE, SETTINGS,
|
||||||
|
|
|
@ -66,6 +66,12 @@ GST_DEBUG_CATEGORY_EXTERN (v4l2src_debug);
|
||||||
#define GST_IS_V4L2_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_V4L2_BUFFER))
|
#define GST_IS_V4L2_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_V4L2_BUFFER))
|
||||||
#define GST_V4L2_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_V4L2_BUFFER, GstV4l2Buffer))
|
#define GST_V4L2_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_V4L2_BUFFER, GstV4l2Buffer))
|
||||||
|
|
||||||
|
|
||||||
|
/* Local functions */
|
||||||
|
static gboolean
|
||||||
|
gst_v4l2src_get_nearest_size (GstV4l2Src * v4l2src, guint32 pixelformat,
|
||||||
|
gint * width, gint * height);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_v4l2_buffer_finalize (GstV4l2Buffer * buffer)
|
gst_v4l2_buffer_finalize (GstV4l2Buffer * buffer)
|
||||||
{
|
{
|
||||||
|
@ -853,11 +859,19 @@ default_frame_sizes:
|
||||||
gint min_w, max_w, min_h, max_h;
|
gint min_w, max_w, min_h, max_h;
|
||||||
|
|
||||||
/* This code is for Linux < 2.6.19 */
|
/* This code is for Linux < 2.6.19 */
|
||||||
if (!gst_v4l2src_get_size_limits (v4l2src, pixelformat, &min_w, &max_w,
|
min_w = min_h = 1;
|
||||||
&min_h, &max_h)) {
|
max_w = max_h = GST_V4L2_MAX_SIZE;
|
||||||
min_w = min_h = 1;
|
if (!gst_v4l2src_get_nearest_size (v4l2src, pixelformat, &min_w, &min_h)) {
|
||||||
max_w = max_h = GST_V4L2_MAX_SIZE;
|
GST_WARNING_OBJECT (v4l2src,
|
||||||
|
"Could not probe minimum capture size for pixelformat %"
|
||||||
|
GST_FOURCC_FORMAT, GST_FOURCC_ARGS (pixelformat));
|
||||||
}
|
}
|
||||||
|
if (!gst_v4l2src_get_nearest_size (v4l2src, pixelformat, &max_w, &max_h)) {
|
||||||
|
GST_WARNING_OBJECT (v4l2src,
|
||||||
|
"Could not probe maximum capture size for pixelformat %"
|
||||||
|
GST_FOURCC_FORMAT, GST_FOURCC_ARGS (pixelformat));
|
||||||
|
}
|
||||||
|
|
||||||
ret = gst_caps_new_empty ();
|
ret = gst_caps_new_empty ();
|
||||||
tmp = gst_structure_copy (template);
|
tmp = gst_structure_copy (template);
|
||||||
gst_structure_set (tmp,
|
gst_structure_set (tmp,
|
||||||
|
@ -1418,53 +1432,56 @@ gst_v4l2src_capture_deinit (GstV4l2Src * v4l2src)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*/
|
*/
|
||||||
gboolean
|
static gboolean
|
||||||
gst_v4l2src_get_size_limits (GstV4l2Src * v4l2src,
|
gst_v4l2src_get_nearest_size (GstV4l2Src * v4l2src, guint32 pixelformat,
|
||||||
guint32 pixelformat, gint * min_w, gint * max_w, gint * min_h, gint * max_h)
|
gint * width, gint * height)
|
||||||
{
|
{
|
||||||
|
|
||||||
struct v4l2_format fmt;
|
struct v4l2_format fmt;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
g_return_val_if_fail (width != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (height != NULL, FALSE);
|
||||||
|
|
||||||
GST_LOG_OBJECT (v4l2src,
|
GST_LOG_OBJECT (v4l2src,
|
||||||
"getting size limits with format %" GST_FOURCC_FORMAT,
|
"getting nearest size to %dx%d with format %" GST_FOURCC_FORMAT,
|
||||||
GST_FOURCC_ARGS (pixelformat));
|
*width, *height, GST_FOURCC_ARGS (pixelformat));
|
||||||
|
|
||||||
|
fd = v4l2src->v4l2object->video_fd;
|
||||||
|
|
||||||
/* get size delimiters */
|
/* get size delimiters */
|
||||||
memset (&fmt, 0, sizeof (fmt));
|
memset (&fmt, 0, sizeof (fmt));
|
||||||
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
fmt.fmt.pix.width = 0;
|
fmt.fmt.pix.width = *width;
|
||||||
fmt.fmt.pix.height = 0;
|
fmt.fmt.pix.height = *height;
|
||||||
fmt.fmt.pix.pixelformat = pixelformat;
|
fmt.fmt.pix.pixelformat = pixelformat;
|
||||||
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
|
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
|
||||||
if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_TRY_FMT, &fmt) < 0) {
|
|
||||||
GST_DEBUG_OBJECT (v4l2src, "failed to get min size: %s",
|
if (ioctl (fd, VIDIOC_TRY_FMT, &fmt) < 0) {
|
||||||
g_strerror (errno));
|
/* The driver might not implement TRY_FMT, in which case we will try
|
||||||
return FALSE;
|
S_FMT to probe */
|
||||||
|
if (errno != ENOTTY)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Only try S_FMT if we're not actively capturing yet, which we shouldn't
|
||||||
|
be, because we're still probing */
|
||||||
|
if (GST_V4L2_IS_ACTIVE (v4l2src->v4l2object))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (v4l2src,
|
||||||
|
"Failed to probe size limit with VIDIOC_TRY_FMT, trying VIDIOC_S_FMT");
|
||||||
|
|
||||||
|
fmt.fmt.pix.width = *width;
|
||||||
|
fmt.fmt.pix.height = *height;
|
||||||
|
|
||||||
|
if (ioctl (fd, VIDIOC_S_FMT, &fmt) < 0)
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (min_w)
|
|
||||||
*min_w = fmt.fmt.pix.width;
|
|
||||||
if (min_h)
|
|
||||||
*min_h = fmt.fmt.pix.height;
|
|
||||||
|
|
||||||
GST_LOG_OBJECT (v4l2src,
|
GST_LOG_OBJECT (v4l2src,
|
||||||
"got min size %dx%d", fmt.fmt.pix.width, fmt.fmt.pix.height);
|
"got nearest size %dx%d", fmt.fmt.pix.width, fmt.fmt.pix.height);
|
||||||
|
|
||||||
fmt.fmt.pix.width = GST_V4L2_MAX_SIZE;
|
*width = fmt.fmt.pix.width;
|
||||||
fmt.fmt.pix.height = GST_V4L2_MAX_SIZE;
|
*height = fmt.fmt.pix.height;
|
||||||
if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_TRY_FMT, &fmt) < 0) {
|
|
||||||
GST_DEBUG_OBJECT (v4l2src, "failed to get max size: %s",
|
|
||||||
g_strerror (errno));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (max_w)
|
|
||||||
*max_w = fmt.fmt.pix.width;
|
|
||||||
if (max_h)
|
|
||||||
*max_h = fmt.fmt.pix.height;
|
|
||||||
|
|
||||||
GST_LOG_OBJECT (v4l2src,
|
|
||||||
"got max size %dx%d", fmt.fmt.pix.width, fmt.fmt.pix.height);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,9 +47,4 @@ gboolean gst_v4l2src_clear_format_list (GstV4l2Src * v4l2src);
|
||||||
GstCaps* gst_v4l2src_probe_caps_for_format (GstV4l2Src * v4l2src, guint32 pixelformat,
|
GstCaps* gst_v4l2src_probe_caps_for_format (GstV4l2Src * v4l2src, guint32 pixelformat,
|
||||||
const GstStructure *template);
|
const GstStructure *template);
|
||||||
|
|
||||||
gboolean gst_v4l2src_get_size_limits (GstV4l2Src * v4l2src,
|
|
||||||
guint32 pixelformat,
|
|
||||||
gint * min_w, gint * max_w,
|
|
||||||
gint * min_h, gint * max_h);
|
|
||||||
|
|
||||||
#endif /* __V4L2SRC_CALLS_H__ */
|
#endif /* __V4L2SRC_CALLS_H__ */
|
||||||
|
|
Loading…
Reference in a new issue