[FFmpeg-devel] [PATCH] Implement in lavc a flag which makes avcodec_open() to choose the best framerate

Michael Niedermayer michaelni
Sun Sep 21 14:09:56 CEST 2008


On Sun, Sep 21, 2008 at 12:52:57PM +0200, Stefano Sabatini wrote:
> On date Saturday 2008-09-20 23:16:11 +0200, Michael Niedermayer encoded:
> > On Sat, Sep 20, 2008 at 06:38:22PM +0200, Stefano Sabatini wrote:
> > > On date Friday 2008-09-19 01:13:51 +0200, Michael Niedermayer encoded:
> > > [...]
> > > > This implementation isnt exact, it in many corner cases will not
> > > > return the correct element.
> > > > Examples would be, when it is farther away than INT_MAX
> > > > another example may be a list of
> > > > 1/INT_MAX, 1/(INT_MAX-1), ...
> > > > compared to INT_MAX
> > > > your code would fail to be to seperate them
> > > 
> > > As for the second problem, in that case the error will be the same for
> > > all that values, but it is still possible to understand which is
> > > nearest to the value if they are both greater or lesser than q.
> > > 
> > > q= target value
> > > q1= nearest value already found
> > > q2= new value to check
> > > 
> > > 1) q1 ...  q2  ... q
> > > q > q1 && q2 > q1 => choose q2
> > > 
> > > 2) q ... q2 ... q1
> > > q < q1 && q2 < q1 => choose q2
> > > 
> > > Both conditions are catched by the expression
> > > cmp(q1, q) * cmp(q2, q1) == 1
> > > 
> > > In the case:
> > > 3) q1 ... q ... q2
> > > and
> > > 4) q2 ... q ... q1
> > > 
> > > always q2 is choosen.
> > > 
> > > For these last two cases I'm not sure if we can do something better.
> > 
> > iam not sure if its worth it but it surely can be done, one way is ...
> > 
> > to decide
> > n1/d1 ... N/D ... n2/d2
> > 
> > you have to decide on which side of (n1/d1 + n2/d2)/2,  N/D is.
> > 
> > (n1/d1 + n2/d2)/2 = (n1d2 + n2d1)/(2d1d2) = A/B
> > A and B here are 64bit
> > 
> > To know which of the 2 points is closer we need to awnser A/B < N/D
> > 
> > which is the same as
> > 
> > (AD)/B < N
> > 
> > (AD)/B can be calculated with av_rescale2() and is exact for our purpose
> > when the correct rounding mode is used.
> > 
> > But as said, iam not sure if this is worth it, in practice the simple
> > variant is likely sufficient, it mostly depends on how ugly above would
> > look in C ...
> 
> It's still looks nice if we introduce a new function, like in the
> patch below.
> 
> Regards.
> -- 
> FFmpeg = Fostering Frightening Mythic Portable Elaborated Guru

> Index: libavutil/rational.h
> ===================================================================
> --- libavutil/rational.h	(revision 15372)
> +++ libavutil/rational.h	(working copy)
> @@ -113,4 +113,17 @@
>   */
>  AVRational av_d2q(double d, int max) av_const;
>  
> +/**
> + * Tells if \p q1 is nearest to \p q than \p q2.
> + * @return 1 if \q1 is nearest to \p than \p q2, 0 otherwise.
> + */
> +int av_is_nearest_q(AVRational q, AVRational q1, AVRational q2);
> +
> +/**
> + * Finds the nearest value in \p q_list to \p q.
> + * @param q_list an array of rationals terminated by {0, 0}
> + * @return the index of the nearest value found in the array
> + */
> +int av_find_nearest_q_idx(AVRational q, const AVRational* q_list);
> +
>  #endif /* AVUTIL_RATIONAL_H */
> Index: libavutil/rational.c
> ===================================================================
> --- libavutil/rational.c	(revision 15372)
> +++ libavutil/rational.c	(working copy)
> @@ -101,3 +101,81 @@
>  
>      return a;
>  }
> +
> +int av_is_nearest_q(AVRational q, AVRational q1, AVRational q2)
> +{
> +    if (av_cmp_q(q1, q) * av_cmp_q(q, q2) > 0) {
> +        /* q1 and q2 on the opposite sides of q */
> +        /* N/D is q, A/B is the median between q1 and q2, A/B > N/D <=> A*D/B > N */

> +        int64_t x = av_rescale(q1.num * (int64_t)q2.den + q2.num * (int64_t)q1.den, q.den, 2 * (int64_t)q1.den * q2.den);

the rounding is not correct


> +        if (((x > q.num ? 1 : x < q.num ? -1 : 0) * av_cmp_q(q2, q1)) > 0)
> +            return 1;
> +    }

> +    /* q1 and q2 on the same side of q */
> +    else if (av_cmp_q(q, q1) * av_cmp_q(q1, q2) > 0)

i dont see why these special cases would be needed

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Many that live deserve death. And some that die deserve life. Can you give
it to them? Then do not be too eager to deal out death in judgement. For
even the very wise cannot see all ends. -- Gandalf
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20080921/789467ba/attachment.pgp>



More information about the ffmpeg-devel mailing list