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

Stefano Sabatini stefano.sabatini-lala
Mon Sep 22 23:36:54 CEST 2008


On date Monday 2008-09-22 02:16:28 +0200, Michael Niedermayer encoded:
> On Sun, Sep 21, 2008 at 11:21:23PM +0200, Stefano Sabatini wrote:
> > On date Sunday 2008-09-21 22:16:56 +0200, Michael Niedermayer encoded:
> > > On Sun, Sep 21, 2008 at 06:52:23PM +0200, Stefano Sabatini wrote:
> > > > On date Sunday 2008-09-21 14:09:56 +0200, Michael Niedermayer encoded:
> > > > > On Sun, Sep 21, 2008 at 12:52:57PM +0200, Stefano Sabatini wrote:
> > > > [...]
> > > > > > 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
> > > > 
> > > > I see that the type of rounding choosen may change the result of the
> > > > comparation if the result isn't exact, but I can't currently figure
> > > > out which is the correct one to apply.
> > > > 
> > > > Can you suggest which should I use?
> > > 
> > > to test A*D/B > N
> > > the left side should be rounded toward inf
> > 
> > Sorry to insist on this, what if we have:
> > 
> > X = A*D/B
> > X'= rnd(A*D/B, up), X' > X
> > X < N but X' > N
> > 
> > Is this possible at all?
> 
> you have a real number r and a integer n
> r' = rnd(r) = the smallest element x of Z that is x >= r
> 
> if we assume that there exists a r and n for which r < n and r' > n
> then by the definition above r' is the smallest element of Z that is >= r
> but n < r' and n > r
> thus proof by contradiction
>
> > > > > > +        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
> > > > 
> > > > The first condition:
> > > > cmp(M, q) * cmp(q2, q1) == 1 
> > > > 
> > > > catches both the conditions:
> > > > q1 ... q ... M ... q2
> > > > M > q && q2 > q1
> > > > and 
> > > > q2 ... M ... q ... q1
> > > > M < q && q2 < q1
> > > > 
> > > > (x > q.num ? 1 : x < q.num ? -1 : 0) corresponds to cmp(M, q).
> > > > 
> > > > The second condition:
> > > > cmp(q, q1) * cmp(q1, q2) ==  1
> > > > cathes both the conditions:
> > > > q2 ... q1 ... q
> > > > q > q1 && q1 > q2
> > > > and 
> > > > q ... q1 ... q2
> > > > q < q1 && q1 < q2
> > > > 
> > > > I can't see how to simplify this...
> > > 
> > > what is the problem with the code for the first case handling the second?
> > 
> > Uh?
> > 
> > 1 if (q1 and q2 on opposite sides of q)
> > 2    if (q1 nearest than q2)  // opposite sides context
> > 3       return 1;
> > 4 else // q1 and q2 are on the same side of q
> > 5    if (q1 nearest than q2) // same side context)
> > 6       return 1;
> > 7 return 0;
> > 
> > Checks at points 1, 2 and 5 test different things, so I don't see how
> > it would be possible to reuse the code of one test for another
> > one. You we could make them parametric, but I'm not sure that would
> > simplify the code, rather it would make it more obfuscated.
> > 
> > But I feel like I'm misunderstanding your point...
> 
> you have 2 point q1 and q2, the point exactly between them seperate
> the 2 areas where q1 and q2 are closer.
> Thus the code that finds out on whoch side of this seperating line q is
> is sufficient and does not need a second special case to handly the case
> of q1 and q2 being of the same side of q

Wow, thanks so much for the explanations Michael!

Now the code really looks simple and beatiful :-).

Regards.
-- 
FFmpeg = Frightening Friendly MultiPurpose Evil God
-------------- next part --------------
A non-text attachment was scrubbed...
Name: implement-nearest-q-05.patch
Type: text/x-diff
Size: 2796 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20080922/b49d5570/attachment.patch>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: implement-force-fps-00.patch
Type: text/x-diff
Size: 2203 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20080922/b49d5570/attachment-0001.patch>



More information about the ffmpeg-devel mailing list