[media] solo6x10: Approximate frame intervals with non-standard denominator
authorIsmael Luceno <ismael.luceno@corp.bluecherry.net>
Fri, 3 May 2013 18:54:57 +0000 (15:54 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 21 May 2013 11:21:54 +0000 (08:21 -0300)
Instead of falling back to 1/25 (PAL) or 1/30 (NTSC).

Signed-off-by: Ismael Luceno <ismael.luceno@corp.bluecherry.net>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c

index 98e2902afd7471a7772b840b3a79d4b7e3472554..a4c589604b028d7d74e1a7f895b6ab3aecbeac75 100644 (file)
@@ -996,12 +996,11 @@ static int solo_g_parm(struct file *file, void *priv,
                       struct v4l2_streamparm *sp)
 {
        struct solo_enc_dev *solo_enc = video_drvdata(file);
-       struct solo_dev *solo_dev = solo_enc->solo_dev;
        struct v4l2_captureparm *cp = &sp->parm.capture;
 
        cp->capability = V4L2_CAP_TIMEPERFRAME;
        cp->timeperframe.numerator = solo_enc->interval;
-       cp->timeperframe.denominator = solo_dev->fps;
+       cp->timeperframe.denominator = solo_enc->solo_dev->fps;
        cp->capturemode = 0;
        /* XXX: Shouldn't we be able to get/set this from videobuf? */
        cp->readbuffers = 2;
@@ -1009,36 +1008,29 @@ static int solo_g_parm(struct file *file, void *priv,
        return 0;
 }
 
+static inline int calc_interval(u8 fps, u32 n, u32 d)
+{
+       if (!n || !d)
+               return 1;
+       if (d == fps)
+               return n;
+       n *= fps;
+       return min(15U, n / d + (n % d >= (fps >> 1)));
+}
+
 static int solo_s_parm(struct file *file, void *priv,
                       struct v4l2_streamparm *sp)
 {
        struct solo_enc_dev *solo_enc = video_drvdata(file);
-       struct solo_dev *solo_dev = solo_enc->solo_dev;
-       struct v4l2_captureparm *cp = &sp->parm.capture;
+       struct v4l2_fract *t = &sp->parm.capture.timeperframe;
+       u8 fps = solo_enc->solo_dev->fps;
 
        if (vb2_is_streaming(&solo_enc->vidq))
                return -EBUSY;
 
-       if ((cp->timeperframe.numerator == 0) ||
-           (cp->timeperframe.denominator == 0)) {
-               /* reset framerate */
-               cp->timeperframe.numerator = 1;
-               cp->timeperframe.denominator = solo_dev->fps;
-       }
-
-       if (cp->timeperframe.denominator != solo_dev->fps)
-               cp->timeperframe.denominator = solo_dev->fps;
-
-       if (cp->timeperframe.numerator > 15)
-               cp->timeperframe.numerator = 15;
-
-       solo_enc->interval = cp->timeperframe.numerator;
-
-       cp->capability = V4L2_CAP_TIMEPERFRAME;
-       cp->readbuffers = 2;
-
+       solo_enc->interval = calc_interval(fps, t->numerator, t->denominator);
        solo_update_mode(solo_enc);
-       return 0;
+       return solo_g_parm(file, priv, sp);
 }
 
 static long solo_enc_default(struct file *file, void *fh,