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 @@ ...@@ -67,8 +67,8 @@
#define SIZE_LONGTEXT N_( \ #define SIZE_LONGTEXT N_( \
"The specified pixel resolution is forced " \ "The specified pixel resolution is forced " \
"(if both width and height are strictly positive)." ) "(if both width and height are strictly positive)." )
/*#define FPS_TEXT N_( "Frame rate" ) #define FPS_TEXT N_( "Frame rate" )
#define FPS_LONGTEXT N_( "Maximum frame rate to use (0 = no limits)." )*/ #define FPS_LONGTEXT N_( "Maximum frame rate to use (0 = no limits)." )
#define RADIO_DEVICE_TEXT N_( "Radio device" ) #define RADIO_DEVICE_TEXT N_( "Radio device" )
#define RADIO_DEVICE_LONGTEXT N_("Radio tuner device node." ) #define RADIO_DEVICE_LONGTEXT N_("Radio tuner device node." )
...@@ -310,9 +310,8 @@ vlc_module_begin () ...@@ -310,9 +310,8 @@ vlc_module_begin ()
add_string( CFG_PREFIX "aspect-ratio", "4:3", ASPECT_TEXT, add_string( CFG_PREFIX "aspect-ratio", "4:3", ASPECT_TEXT,
ASPECT_LONGTEXT, true ) ASPECT_LONGTEXT, true )
change_safe() change_safe()
/*add_float( CFG_PREFIX "fps", 0, FPS_TEXT, FPS_LONGTEXT, true )*/ add_string( CFG_PREFIX "fps", "60", FPS_TEXT, FPS_LONGTEXT, false )
add_obsolete_float( CFG_PREFIX "fps" ) change_safe()
change_safe() /* since 2.1.0 */
add_obsolete_bool( CFG_PREFIX "use-libv4l2" ) /* since 2.1.0 */ add_obsolete_bool( CFG_PREFIX "use-libv4l2" ) /* since 2.1.0 */
set_section( N_( "Tuner" ), NULL ) set_section( N_( "Tuner" ), NULL )
......
...@@ -308,15 +308,19 @@ static int64_t fcmp (const struct v4l2_fract *a, ...@@ -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 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 fmt V4L2 capture format [IN]
* @param min_it minimum frame internal [IN]
* @param it V4L2 frame interval [OUT] * @param it V4L2 frame interval [OUT]
* @return 0 on success, -1 on error. * @return 0 on success, -1 on error.
*/ */
static int FindMaxRate (vlc_object_t *obj, int fd, static int FindMaxRate (vlc_object_t *obj, int fd,
const struct v4l2_format *restrict fmt, const struct v4l2_format *restrict fmt,
const struct v4l2_fract *restrict min_it,
struct v4l2_fract *restrict it) struct v4l2_fract *restrict it)
{ {
struct v4l2_frmivalenum fie = { struct v4l2_frmivalenum fie = {
...@@ -354,7 +358,8 @@ static int FindMaxRate (vlc_object_t *obj, int fd, ...@@ -354,7 +358,8 @@ static int FindMaxRate (vlc_object_t *obj, int fd,
*it = infinity; *it = infinity;
do do
{ {
if (fcmp (&fie.discrete, it) < 0) if (fcmp (&fie.discrete, min_it) >= 0
&& fcmp (&fie.discrete, it) < 0)
*it = fie.discrete; *it = fie.discrete;
fie.index++; fie.index++;
} }
...@@ -374,9 +379,31 @@ static int FindMaxRate (vlc_object_t *obj, int fd, ...@@ -374,9 +379,31 @@ static int FindMaxRate (vlc_object_t *obj, int fd,
msg_Dbg (obj, " with %"PRIu32"/%"PRIu32" step", msg_Dbg (obj, " with %"PRIu32"/%"PRIu32" step",
fie.stepwise.step.numerator, fie.stepwise.step.numerator,
fie.stepwise.step.denominator); 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; *it = fie.stepwise.min;
break; 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; return 0;
} }
...@@ -407,9 +434,16 @@ int SetupFormat (vlc_object_t *obj, int fd, uint32_t fourcc, ...@@ -407,9 +434,16 @@ int SetupFormat (vlc_object_t *obj, int fd, uint32_t fourcc,
struct v4l2_frmsizeenum fse = { struct v4l2_frmsizeenum fse = {
.pixel_format = fourcc, .pixel_format = fourcc,
}; };
struct v4l2_fract best_it = infinity; struct v4l2_fract best_it = infinity, min_it;
uint64_t best_area = 0; 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 width = var_InheritInteger (obj, CFG_PREFIX"width");
uint32_t height = var_InheritInteger (obj, CFG_PREFIX"height"); uint32_t height = var_InheritInteger (obj, CFG_PREFIX"height");
if (width > 0 && height > 0) if (width > 0 && height > 0)
...@@ -418,7 +452,7 @@ int SetupFormat (vlc_object_t *obj, int fd, uint32_t fourcc, ...@@ -418,7 +452,7 @@ int SetupFormat (vlc_object_t *obj, int fd, uint32_t fourcc,
fmt->fmt.pix.height = height; fmt->fmt.pix.height = height;
msg_Dbg (obj, " requested frame size: %"PRIu32"x%"PRIu32, msg_Dbg (obj, " requested frame size: %"PRIu32"x%"PRIu32,
width, height); width, height);
FindMaxRate (obj, fd, fmt, &best_it); FindMaxRate (obj, fd, fmt, &min_it, &best_it);
} }
else else
if (v4l2_ioctl (fd, VIDIOC_ENUM_FRAMESIZES, &fse) < 0) if (v4l2_ioctl (fd, VIDIOC_ENUM_FRAMESIZES, &fse) < 0)
...@@ -427,7 +461,7 @@ int SetupFormat (vlc_object_t *obj, int fd, uint32_t fourcc, ...@@ -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, " unknown frame sizes: %s", vlc_strerror_c(errno));
msg_Dbg (obj, " current frame size: %"PRIu32"x%"PRIu32, msg_Dbg (obj, " current frame size: %"PRIu32"x%"PRIu32,
fmt->fmt.pix.width, fmt->fmt.pix.height); fmt->fmt.pix.width, fmt->fmt.pix.height);
FindMaxRate (obj, fd, fmt, &best_it); FindMaxRate (obj, fd, fmt, &min_it, &best_it);
} }
else else
switch (fse.type) switch (fse.type)
...@@ -439,7 +473,7 @@ int SetupFormat (vlc_object_t *obj, int fd, uint32_t fourcc, ...@@ -439,7 +473,7 @@ int SetupFormat (vlc_object_t *obj, int fd, uint32_t fourcc,
msg_Dbg (obj, " frame size %"PRIu32"x%"PRIu32, msg_Dbg (obj, " frame size %"PRIu32"x%"PRIu32,
fse.discrete.width, fse.discrete.height); 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); int64_t c = fcmp (&cur_it, &best_it);
uint64_t area = fse.discrete.width * fse.discrete.height; uint64_t area = fse.discrete.width * fse.discrete.height;
...@@ -479,7 +513,7 @@ int SetupFormat (vlc_object_t *obj, int fd, uint32_t fourcc, ...@@ -479,7 +513,7 @@ int SetupFormat (vlc_object_t *obj, int fd, uint32_t fourcc,
{ {
struct v4l2_fract cur_it; 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); int64_t c = fcmp (&cur_it, &best_it);
uint64_t area = width * height; 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