[vlc-commits] v4l2: rationalize/factorize frame rate handling
Rémi Denis-Courmont
git at videolan.org
Mon Apr 9 18:36:45 CEST 2012
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Apr 7 22:49:33 2012 +0300| [cd4578a1dc6796a191a94314ef86845be3a37188] | committer: Rémi Denis-Courmont
v4l2: rationalize/factorize frame rate handling
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=cd4578a1dc6796a191a94314ef86845be3a37188
---
modules/access/v4l2/video.c | 72 ++++++++++++++++++++++---------------------
1 files changed, 37 insertions(+), 35 deletions(-)
diff --git a/modules/access/v4l2/video.c b/modules/access/v4l2/video.c
index 96698b4..c75bc2f 100644
--- a/modules/access/v4l2/video.c
+++ b/modules/access/v4l2/video.c
@@ -765,21 +765,25 @@ int SetupInput (vlc_object_t *obj, int fd)
}
/** Compares two V4L2 fractions. */
-static int64_t fcmp (struct v4l2_fract a, struct v4l2_fract b)
+static int64_t fcmp (const struct v4l2_fract *a,
+ const struct v4l2_fract *b)
{
- return (uint64_t)a.numerator * b.denominator
- - (uint64_t)b.numerator * a.denominator;
+ return (uint64_t)a->numerator * b->denominator
+ - (uint64_t)b->numerator * a->denominator;
}
+static const struct v4l2_fract infinity = { 1, 0 };
+
/**
* Finds the highest frame rate possible of a certain V4L2 format.
* @param fmt V4L2 capture format [IN]
+ * @param parm V4L2 capture streaming parameters [IN]
* @param it V4L2 frame interval [OUT]
- * @return 0 on success, -1 on failure.
*/
-static int FindMaxRate (vlc_object_t *obj, int fd,
- const struct v4l2_format *restrict fmt,
- struct v4l2_fract *restrict it)
+static void FindMaxRate (vlc_object_t *obj, int fd,
+ const struct v4l2_format *restrict fmt,
+ const struct v4l2_streamparm *restrict parm,
+ struct v4l2_fract *restrict it)
{
struct v4l2_frmivalenum fie = {
.pixel_format = fmt->fmt.pix.pixelformat,
@@ -787,21 +791,30 @@ static int FindMaxRate (vlc_object_t *obj, int fd,
.height = fmt->fmt.pix.height,
};
/* Mind that maximum rate means minimum interval */
- struct v4l2_fract min = { 1, 0 }; /* infinity */
+ if (!(parm->parm.capture.capability & V4L2_CAP_TIMEPERFRAME))
+ {
+ *it = parm->parm.capture.timeperframe;
+ msg_Dbg (obj, " constant frame interval: %"PRIu32"/%"PRIu32,
+ it->numerator, it->denominator);
+ }
+ else
if (v4l2_ioctl (fd, VIDIOC_ENUM_FRAMEINTERVALS, &fie) < 0)
{
- msg_Dbg (obj, " unknown frame internals: %m");
- return -1;
+ msg_Warn (obj, " unknown frame intervals: %m");
+ *it = parm->parm.capture.timeperframe;
+ msg_Dbg (obj, " default frame interval: %"PRIu32"/%"PRIu32,
+ it->numerator, it->denominator);
}
-
+ else
switch (fie.type)
{
case V4L2_FRMIVAL_TYPE_DISCRETE:
+ *it = infinity;
do
{
- if (fcmp (fie.discrete, min) < 0)
- min = fie.discrete;
+ if (fcmp (&fie.discrete, it) < 0)
+ *it = fie.discrete;
msg_Dbg (obj, " discrete frame interval: %"PRIu32"/%"PRIu32,
fie.discrete.numerator, fie.discrete.denominator);
fie.index++;
@@ -809,7 +822,7 @@ static int FindMaxRate (vlc_object_t *obj, int fd,
while (v4l2_ioctl (fd, VIDIOC_ENUM_FRAMEINTERVALS, &fie) >= 0);
msg_Dbg (obj, " best discrete frame interval: %"PRIu32"/%"PRIu32,
- min.numerator, min.denominator);
+ it->numerator, it->denominator);
break;
case V4L2_FRMIVAL_TYPE_STEPWISE:
@@ -822,12 +835,9 @@ static int FindMaxRate (vlc_object_t *obj, int fd,
msg_Dbg (obj, " with %"PRIu32"/%"PRIu32" step",
fie.stepwise.step.numerator,
fie.stepwise.step.denominator);
- min = fie.stepwise.min;
+ *it = fie.stepwise.min;
break;
}
-
- *it = min;
- return 0;
}
#undef SetupFormat
@@ -865,7 +875,7 @@ int SetupFormat (vlc_object_t *obj, int fd, uint32_t fourcc,
struct v4l2_frmsizeenum fse = {
.pixel_format = fourcc,
};
- struct v4l2_fract best_it = { 1, 0 }; /* infinity */
+ struct v4l2_fract best_it = infinity;
uint64_t best_area = 0;
if (v4l2_ioctl (fd, VIDIOC_ENUM_FRAMESIZES, &fse) < 0)
@@ -874,13 +884,7 @@ int SetupFormat (vlc_object_t *obj, int fd, uint32_t fourcc,
msg_Dbg (obj, " unknown frame sizes: %m");
msg_Dbg (obj, " default frame size: %"PRIu32"x%"PRIu32,
fmt->fmt.pix.width, fmt->fmt.pix.height);
- if (!(parm->parm.capture.capability & V4L2_CAP_TIMEPERFRAME)
- || FindMaxRate (obj, fd, fmt, &best_it))
- {
- best_it = parm->parm.capture.timeperframe;
- msg_Dbg (obj, " constant frame interval: %"PRIu32"/%"PRIu32,
- best_it.numerator, best_it.denominator);
- }
+ FindMaxRate (obj, fd, fmt, parm, &best_it);
}
else
switch (fse.type)
@@ -892,11 +896,9 @@ int SetupFormat (vlc_object_t *obj, int fd, uint32_t fourcc,
msg_Dbg (obj, " frame size %"PRIu32"x%"PRIu32,
fse.discrete.width, fse.discrete.height);
- if (FindMaxRate (obj, fd, fmt, &cur_it))
- /* If frame rate is not known, find largest resolution */
- cur_it.denominator = 0;
+ FindMaxRate (obj, fd, fmt, parm, &cur_it);
- int64_t c = fcmp (cur_it, best_it);
+ int64_t c = fcmp (&cur_it, &best_it);
uint64_t area = fse.discrete.width * fse.discrete.height;
if (c < 0 || (c == 0 && area > best_area))
{
@@ -934,10 +936,9 @@ int SetupFormat (vlc_object_t *obj, int fd, uint32_t fourcc,
{
struct v4l2_fract cur_it;
- if (FindMaxRate (obj, fd, fmt, &cur_it))
- continue;
+ FindMaxRate (obj, fd, fmt, parm, &cur_it);
- int64_t c = fcmp (cur_it, best_it);
+ int64_t c = fcmp (&cur_it, &best_it);
uint64_t area = width * height;
if (c < 0 || (c == 0 && area > best_area))
@@ -954,15 +955,16 @@ int SetupFormat (vlc_object_t *obj, int fd, uint32_t fourcc,
break;
}
+ parm->parm.capture.timeperframe = best_it;
+
if (v4l2_ioctl (fd, VIDIOC_S_FMT, fmt) < 0)
{
msg_Err (obj, "cannot set format: %m");
return -1;
}
-
- parm->parm.capture.timeperframe = best_it;
if (v4l2_ioctl (fd, VIDIOC_S_PARM, parm) < 0)
msg_Warn (obj, "cannot set streaming parameters: %m");
+
return 0;
}
More information about the vlc-commits
mailing list