[vlc-commits] v4l2: implement --v4l2-fps for real (fixes #7395)
Rémi Denis-Courmont
git at videolan.org
Sun Mar 9 21:30:57 CET 2014
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Mar 9 22:30:09 2014 +0200| [177078ba86f8e1615c2220b96f8c4a8c643c0a6d] | committer: Rémi Denis-Courmont
v4l2: implement --v4l2-fps for real (fixes #7395)
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=177078ba86f8e1615c2220b96f8c4a8c643c0a6d
---
modules/access/v4l2/v4l2.c | 9 ++++----
modules/access/v4l2/video.c | 50 ++++++++++++++++++++++++++++++++++++-------
2 files changed, 46 insertions(+), 13 deletions(-)
diff --git a/modules/access/v4l2/v4l2.c b/modules/access/v4l2/v4l2.c
index 20d1fe3..7807a8a 100644
--- a/modules/access/v4l2/v4l2.c
+++ b/modules/access/v4l2/v4l2.c
@@ -67,8 +67,8 @@
#define SIZE_LONGTEXT N_( \
"The specified pixel resolution is forced " \
"(if both width and height are strictly positive)." )
-/*#define FPS_TEXT N_( "Frame rate" )
-#define FPS_LONGTEXT N_( "Maximum frame rate to use (0 = no limits)." )*/
+#define FPS_TEXT N_( "Frame rate" )
+#define FPS_LONGTEXT N_( "Maximum frame rate to use (0 = no limits)." )
#define RADIO_DEVICE_TEXT N_( "Radio device" )
#define RADIO_DEVICE_LONGTEXT N_("Radio tuner device node." )
@@ -310,9 +310,8 @@ vlc_module_begin ()
add_string( CFG_PREFIX "aspect-ratio", "4:3", ASPECT_TEXT,
ASPECT_LONGTEXT, true )
change_safe()
- /*add_float( CFG_PREFIX "fps", 0, FPS_TEXT, FPS_LONGTEXT, true )*/
- add_obsolete_float( CFG_PREFIX "fps" )
- change_safe() /* since 2.1.0 */
+ add_string( CFG_PREFIX "fps", "60", FPS_TEXT, FPS_LONGTEXT, false )
+ change_safe()
add_obsolete_bool( CFG_PREFIX "use-libv4l2" ) /* since 2.1.0 */
set_section( N_( "Tuner" ), NULL )
diff --git a/modules/access/v4l2/video.c b/modules/access/v4l2/video.c
index c0b24fd..efd3c66 100644
--- a/modules/access/v4l2/video.c
+++ b/modules/access/v4l2/video.c
@@ -308,15 +308,19 @@ static int64_t fcmp (const struct v4l2_fract *a,
}
static const struct v4l2_fract infinity = { 1, 0 };
+static const struct v4l2_fract zero = { 0, 1 };
/**
- * Finds the highest frame rate possible of a certain V4L2 format.
+ * Finds the highest frame rate up to a specific limit possible with a certain
+ * V4L2 format.
* @param fmt V4L2 capture format [IN]
+ * @param min_it minimum frame internal [IN]
* @param it V4L2 frame interval [OUT]
* @return 0 on success, -1 on error.
*/
static int FindMaxRate (vlc_object_t *obj, int fd,
const struct v4l2_format *restrict fmt,
+ const struct v4l2_fract *restrict min_it,
struct v4l2_fract *restrict it)
{
struct v4l2_frmivalenum fie = {
@@ -354,7 +358,8 @@ static int FindMaxRate (vlc_object_t *obj, int fd,
*it = infinity;
do
{
- if (fcmp (&fie.discrete, it) < 0)
+ if (fcmp (&fie.discrete, min_it) >= 0
+ && fcmp (&fie.discrete, it) < 0)
*it = fie.discrete;
fie.index++;
}
@@ -374,7 +379,29 @@ static int FindMaxRate (vlc_object_t *obj, int fd,
msg_Dbg (obj, " with %"PRIu32"/%"PRIu32" step",
fie.stepwise.step.numerator,
fie.stepwise.step.denominator);
- *it = fie.stepwise.min;
+
+ if (fcmp (&fie.stepwise.max, min_it) < 0)
+ {
+ *it = infinity;
+ return -1;
+ }
+
+ if (fcmp (&fie.stepwise.min, min_it) >= 0)
+ {
+ *it = fie.stepwise.min;
+ break;
+ }
+
+ if (fie.type == V4L2_FRMIVAL_TYPE_CONTINUOUS)
+ {
+ *it = *min_it;
+ break;
+ }
+
+ it->numerator *= fie.stepwise.step.denominator;
+ it->denominator *= fie.stepwise.step.denominator;
+ while (fcmp (it, min_it) < 0)
+ it->numerator += fie.stepwise.step.numerator;
break;
}
return 0;
@@ -407,9 +434,16 @@ int SetupFormat (vlc_object_t *obj, int fd, uint32_t fourcc,
struct v4l2_frmsizeenum fse = {
.pixel_format = fourcc,
};
- struct v4l2_fract best_it = infinity;
+ struct v4l2_fract best_it = infinity, min_it;
uint64_t best_area = 0;
+ if (var_InheritURational(obj, &min_it.denominator, &min_it.numerator,
+ CFG_PREFIX"fps") == VLC_SUCCESS)
+ msg_Dbg (obj, " requested frame internal: %"PRIu32"/%"PRIu32,
+ min_it.numerator, min_it.denominator);
+ else
+ min_it = zero;
+
uint32_t width = var_InheritInteger (obj, CFG_PREFIX"width");
uint32_t height = var_InheritInteger (obj, CFG_PREFIX"height");
if (width > 0 && height > 0)
@@ -418,7 +452,7 @@ int SetupFormat (vlc_object_t *obj, int fd, uint32_t fourcc,
fmt->fmt.pix.height = height;
msg_Dbg (obj, " requested frame size: %"PRIu32"x%"PRIu32,
width, height);
- FindMaxRate (obj, fd, fmt, &best_it);
+ FindMaxRate (obj, fd, fmt, &min_it, &best_it);
}
else
if (v4l2_ioctl (fd, VIDIOC_ENUM_FRAMESIZES, &fse) < 0)
@@ -427,7 +461,7 @@ int SetupFormat (vlc_object_t *obj, int fd, uint32_t fourcc,
msg_Dbg (obj, " unknown frame sizes: %s", vlc_strerror_c(errno));
msg_Dbg (obj, " current frame size: %"PRIu32"x%"PRIu32,
fmt->fmt.pix.width, fmt->fmt.pix.height);
- FindMaxRate (obj, fd, fmt, &best_it);
+ FindMaxRate (obj, fd, fmt, &min_it, &best_it);
}
else
switch (fse.type)
@@ -439,7 +473,7 @@ 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);
- FindMaxRate (obj, fd, fmt, &cur_it);
+ FindMaxRate (obj, fd, fmt, &min_it, &cur_it);
int64_t c = fcmp (&cur_it, &best_it);
uint64_t area = fse.discrete.width * fse.discrete.height;
@@ -479,7 +513,7 @@ int SetupFormat (vlc_object_t *obj, int fd, uint32_t fourcc,
{
struct v4l2_fract cur_it;
- FindMaxRate (obj, fd, fmt, &cur_it);
+ FindMaxRate (obj, fd, fmt, &min_it, &cur_it);
int64_t c = fcmp (&cur_it, &best_it);
uint64_t area = width * height;
More information about the vlc-commits
mailing list