[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