Commit 177078ba authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

v4l2: implement --v4l2-fps for real (fixes #7395)

parent e770901e
......@@ -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 )
......
......@@ -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,9 +379,31 @@ static int FindMaxRate (vlc_object_t *obj, int fd,
msg_Dbg (obj, " with %"PRIu32"/%"PRIu32" step",
fie.stepwise.step.numerator,
fie.stepwise.step.denominator);
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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment