mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 08:17:01 +00:00
sys/v4l2/v4l2src_calls.c: Fix framerate detection code some more.
Original commit message from CVS: * sys/v4l2/v4l2src_calls.c: (gst_v4l2src_probe_caps_for_format_and_size): Fix framerate detection code some more. Handle the case where there is a weird step in the stepwise framerates. Don't overwrite the min interval with the framerate, use a temp variable instead. Use max in the Continuous framerate intervals instead of step, which is 1 according to the docs. Fixes #475424.
This commit is contained in:
parent
4b25ca6267
commit
3b78ab50ef
2 changed files with 73 additions and 40 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
||||||
|
2007-09-11 Wim Taymans <wim.taymans@gmail.com>
|
||||||
|
|
||||||
|
* sys/v4l2/v4l2src_calls.c:
|
||||||
|
(gst_v4l2src_probe_caps_for_format_and_size):
|
||||||
|
Fix framerate detection code some more.
|
||||||
|
Handle the case where there is a weird step in the stepwise framerates.
|
||||||
|
Don't overwrite the min interval with the framerate, use a temp variable
|
||||||
|
instead.
|
||||||
|
Use max in the Continuous framerate intervals instead of step, which is
|
||||||
|
1 according to the docs. Fixes #475424.
|
||||||
|
|
||||||
2007-09-10 Wim Taymans <wim.taymans@gmail.com>
|
2007-09-10 Wim Taymans <wim.taymans@gmail.com>
|
||||||
|
|
||||||
* gst/udp/gstudpsrc.c: (gst_udpsrc_init), (gst_udpsrc_create):
|
* gst/udp/gstudpsrc.c: (gst_udpsrc_init), (gst_udpsrc_create):
|
||||||
|
|
|
@ -452,7 +452,7 @@ gst_v4l2src_probe_caps_for_format_and_size (GstV4l2Src * v4l2src,
|
||||||
struct v4l2_frmivalenum ival;
|
struct v4l2_frmivalenum ival;
|
||||||
guint32 num, denom;
|
guint32 num, denom;
|
||||||
GstStructure *s;
|
GstStructure *s;
|
||||||
GValue rate = { 0, };
|
GValue rates = { 0, };
|
||||||
|
|
||||||
ret = gst_caps_new_empty ();
|
ret = gst_caps_new_empty ();
|
||||||
|
|
||||||
|
@ -471,10 +471,10 @@ gst_v4l2src_probe_caps_for_format_and_size (GstV4l2Src * v4l2src,
|
||||||
goto enum_frameintervals_failed;
|
goto enum_frameintervals_failed;
|
||||||
|
|
||||||
if (ival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
|
if (ival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
|
||||||
GValue frac = { 0, };
|
GValue rate = { 0, };
|
||||||
|
|
||||||
g_value_init (&rate, GST_TYPE_LIST);
|
g_value_init (&rates, GST_TYPE_LIST);
|
||||||
g_value_init (&frac, GST_TYPE_FRACTION);
|
g_value_init (&rate, GST_TYPE_FRACTION);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
num = ival.discrete.numerator;
|
num = ival.discrete.numerator;
|
||||||
|
@ -488,65 +488,85 @@ gst_v4l2src_probe_caps_for_format_and_size (GstV4l2Src * v4l2src,
|
||||||
|
|
||||||
GST_LOG_OBJECT (v4l2src, "adding discrete framerate: %d/%d", denom, num);
|
GST_LOG_OBJECT (v4l2src, "adding discrete framerate: %d/%d", denom, num);
|
||||||
|
|
||||||
gst_value_set_fraction (&frac, denom, num);
|
/* swap to get the framerate */
|
||||||
gst_value_list_append_value (&rate, &frac);
|
gst_value_set_fraction (&rate, denom, num);
|
||||||
|
gst_value_list_append_value (&rates, &rate);
|
||||||
|
|
||||||
ival.index++;
|
ival.index++;
|
||||||
} while (ioctl (fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival) >= 0);
|
} while (ioctl (fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival) >= 0);
|
||||||
} else if (ival.type == V4L2_FRMIVAL_TYPE_STEPWISE) {
|
} else if (ival.type == V4L2_FRMIVAL_TYPE_STEPWISE) {
|
||||||
GValue frac = { 0, };
|
GValue min = { 0, };
|
||||||
GValue step = { 0, };
|
GValue step = { 0, };
|
||||||
GValue max = { 0, };
|
GValue max = { 0, };
|
||||||
gboolean added = FALSE;
|
gboolean added = FALSE;
|
||||||
|
guint32 minnum, mindenom;
|
||||||
|
guint32 maxnum, maxdenom;
|
||||||
|
|
||||||
g_value_init (&rate, GST_TYPE_LIST);
|
g_value_init (&rates, GST_TYPE_LIST);
|
||||||
|
|
||||||
g_value_init (&frac, GST_TYPE_FRACTION);
|
g_value_init (&min, GST_TYPE_FRACTION);
|
||||||
g_value_init (&step, GST_TYPE_FRACTION);
|
g_value_init (&step, GST_TYPE_FRACTION);
|
||||||
g_value_init (&max, GST_TYPE_FRACTION);
|
g_value_init (&max, GST_TYPE_FRACTION);
|
||||||
|
|
||||||
num = ival.stepwise.min.numerator;
|
/* get the min */
|
||||||
denom = ival.stepwise.min.denominator;
|
minnum = ival.stepwise.min.numerator;
|
||||||
if (num > G_MAXINT || denom > G_MAXINT) {
|
mindenom = ival.stepwise.min.denominator;
|
||||||
num >>= 1;
|
if (minnum > G_MAXINT || mindenom > G_MAXINT) {
|
||||||
denom >>= 1;
|
minnum >>= 1;
|
||||||
|
mindenom >>= 1;
|
||||||
}
|
}
|
||||||
GST_LOG_OBJECT (v4l2src, "stepwise min frame interval: %d/%d", num, denom);
|
GST_LOG_OBJECT (v4l2src, "stepwise min frame interval: %d/%d", minnum,
|
||||||
gst_value_set_fraction (&frac, num, denom);
|
mindenom);
|
||||||
|
gst_value_set_fraction (&min, minnum, mindenom);
|
||||||
|
|
||||||
|
/* get the max */
|
||||||
|
maxnum = ival.stepwise.max.numerator;
|
||||||
|
maxdenom = ival.stepwise.max.denominator;
|
||||||
|
if (maxnum > G_MAXINT || maxdenom > G_MAXINT) {
|
||||||
|
maxnum >>= 1;
|
||||||
|
maxdenom >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (v4l2src, "stepwise max frame interval: %d/%d", maxnum,
|
||||||
|
maxdenom);
|
||||||
|
gst_value_set_fraction (&max, maxnum, maxdenom);
|
||||||
|
|
||||||
|
/* get the step */
|
||||||
num = ival.stepwise.step.numerator;
|
num = ival.stepwise.step.numerator;
|
||||||
denom = ival.stepwise.step.denominator;
|
denom = ival.stepwise.step.denominator;
|
||||||
if (num > G_MAXINT || denom > G_MAXINT) {
|
if (num > G_MAXINT || denom > G_MAXINT) {
|
||||||
num >>= 1;
|
num >>= 1;
|
||||||
denom >>= 1;
|
denom >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (num == 0 || denom == 0) {
|
||||||
|
/* in this case we have a wrong fraction or no step, set the step to max
|
||||||
|
* so that we only add the min value in the loop below */
|
||||||
|
num = maxnum;
|
||||||
|
denom = maxdenom;
|
||||||
|
}
|
||||||
|
|
||||||
/* since we only have gst_value_fraction_subtract and not add, negate the
|
/* since we only have gst_value_fraction_subtract and not add, negate the
|
||||||
numerator */
|
* numerator */
|
||||||
GST_LOG_OBJECT (v4l2src, "stepwise step frame interval: %d/%d", num, denom);
|
GST_LOG_OBJECT (v4l2src, "stepwise step frame interval: %d/%d", num, denom);
|
||||||
gst_value_set_fraction (&step, -num, denom);
|
gst_value_set_fraction (&step, -num, denom);
|
||||||
|
|
||||||
num = ival.stepwise.max.numerator;
|
while (gst_value_compare (&min, &max) <= 0) {
|
||||||
denom = ival.stepwise.max.denominator;
|
GValue rate = { 0, };
|
||||||
if (num > G_MAXINT || denom > G_MAXINT) {
|
|
||||||
num >>= 1;
|
|
||||||
denom >>= 1;
|
|
||||||
}
|
|
||||||
GST_LOG_OBJECT (v4l2src, "stepwise max frame interval: %d/%d", num, denom);
|
|
||||||
gst_value_set_fraction (&max, num, denom);
|
|
||||||
|
|
||||||
while (gst_value_compare (&frac, &max) <= 0) {
|
num = gst_value_get_fraction_numerator (&min);
|
||||||
num = gst_value_get_fraction_numerator (&frac);
|
denom = gst_value_get_fraction_denominator (&min);
|
||||||
denom = gst_value_get_fraction_denominator (&frac);
|
|
||||||
GST_LOG_OBJECT (v4l2src, "adding stepwise framerate: %d/%d", denom, num);
|
GST_LOG_OBJECT (v4l2src, "adding stepwise framerate: %d/%d", denom, num);
|
||||||
|
|
||||||
/* invert to get the framerate */
|
/* invert to get the framerate */
|
||||||
gst_value_set_fraction (&frac, denom, num);
|
g_value_init (&rate, GST_TYPE_FRACTION);
|
||||||
gst_value_list_append_value (&rate, &frac);
|
gst_value_set_fraction (&rate, denom, num);
|
||||||
|
gst_value_list_append_value (&rates, &rate);
|
||||||
added = TRUE;
|
added = TRUE;
|
||||||
|
|
||||||
/* we're actually adding because step was negated above. This is because
|
/* we're actually adding because step was negated above. This is because
|
||||||
* there is no _add function... */
|
* there is no _add function... */
|
||||||
if (!gst_value_fraction_subtract (&frac, &frac, &step)) {
|
if (!gst_value_fraction_subtract (&min, &min, &step)) {
|
||||||
GST_WARNING_OBJECT (v4l2src, "could not step fraction!");
|
GST_WARNING_OBJECT (v4l2src, "could not step fraction!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -554,13 +574,14 @@ gst_v4l2src_probe_caps_for_format_and_size (GstV4l2Src * v4l2src,
|
||||||
if (!added) {
|
if (!added) {
|
||||||
/* no range was added, make a default range */
|
/* no range was added, make a default range */
|
||||||
GST_WARNING_OBJECT (v4l2src, "no range added, setting 0/1 to 100/1");
|
GST_WARNING_OBJECT (v4l2src, "no range added, setting 0/1 to 100/1");
|
||||||
g_value_init (&rate, GST_TYPE_FRACTION_RANGE);
|
g_value_unset (&rates);
|
||||||
gst_value_set_fraction_range_full (&rate, 0, 1, 100, 1);
|
g_value_init (&rates, GST_TYPE_FRACTION_RANGE);
|
||||||
|
gst_value_set_fraction_range_full (&rates, 0, 1, 100, 1);
|
||||||
}
|
}
|
||||||
} else if (ival.type == V4L2_FRMIVAL_TYPE_CONTINUOUS) {
|
} else if (ival.type == V4L2_FRMIVAL_TYPE_CONTINUOUS) {
|
||||||
guint32 maxnum, maxdenom;
|
guint32 maxnum, maxdenom;
|
||||||
|
|
||||||
g_value_init (&rate, GST_TYPE_FRACTION_RANGE);
|
g_value_init (&rates, GST_TYPE_FRACTION_RANGE);
|
||||||
|
|
||||||
num = ival.stepwise.min.numerator;
|
num = ival.stepwise.min.numerator;
|
||||||
denom = ival.stepwise.min.denominator;
|
denom = ival.stepwise.min.denominator;
|
||||||
|
@ -569,9 +590,8 @@ gst_v4l2src_probe_caps_for_format_and_size (GstV4l2Src * v4l2src,
|
||||||
denom >>= 1;
|
denom >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME? doesn't it make more sense to have min and max as the range? */
|
maxnum = ival.stepwise.max.numerator;
|
||||||
maxnum = ival.stepwise.step.numerator;
|
maxdenom = ival.stepwise.max.denominator;
|
||||||
maxdenom = ival.stepwise.step.denominator;
|
|
||||||
if (maxnum > G_MAXINT || maxdenom > G_MAXINT) {
|
if (maxnum > G_MAXINT || maxdenom > G_MAXINT) {
|
||||||
maxnum >>= 1;
|
maxnum >>= 1;
|
||||||
maxdenom >>= 1;
|
maxdenom >>= 1;
|
||||||
|
@ -580,7 +600,7 @@ gst_v4l2src_probe_caps_for_format_and_size (GstV4l2Src * v4l2src,
|
||||||
GST_LOG_OBJECT (v4l2src, "continuous frame interval %d/%d to %d/%d",
|
GST_LOG_OBJECT (v4l2src, "continuous frame interval %d/%d to %d/%d",
|
||||||
maxdenom, maxnum, denom, num);
|
maxdenom, maxnum, denom, num);
|
||||||
|
|
||||||
gst_value_set_fraction_range_full (&rate, maxdenom, maxnum, denom, num);
|
gst_value_set_fraction_range_full (&rates, maxdenom, maxnum, denom, num);
|
||||||
} else {
|
} else {
|
||||||
goto unknown_type;
|
goto unknown_type;
|
||||||
}
|
}
|
||||||
|
@ -588,10 +608,12 @@ gst_v4l2src_probe_caps_for_format_and_size (GstV4l2Src * v4l2src,
|
||||||
s = gst_structure_copy (template);
|
s = gst_structure_copy (template);
|
||||||
gst_structure_set (s, "width", G_TYPE_INT, (gint) width,
|
gst_structure_set (s, "width", G_TYPE_INT, (gint) width,
|
||||||
"height", G_TYPE_INT, (gint) height, NULL);
|
"height", G_TYPE_INT, (gint) height, NULL);
|
||||||
gst_structure_set_value (s, "framerate", &rate);
|
gst_structure_set_value (s, "framerate", &rates);
|
||||||
g_value_unset (&rate);
|
g_value_unset (&rates);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
enum_frameintervals_failed:
|
enum_frameintervals_failed:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (v4l2src,
|
GST_DEBUG_OBJECT (v4l2src,
|
||||||
|
|
Loading…
Reference in a new issue