~ubuntu-branches/debian/sid/mplayer/sid

« back to all changes in this revision

Viewing changes to libavutil/rational.c

  • Committer: Bazaar Package Importer
  • Author(s): A Mennucc1
  • Date: 2009-03-23 10:05:45 UTC
  • mfrom: (4.1.4 sid)
  • Revision ID: james.westby@ubuntu.com-20090323100545-x8h79obawnnte7kk
Tags: 1.0~rc2+svn20090303-5
debian/control : move docbook-xml,docbook-xsl,xsltproc from 
Build-Depends-Indep to Build-Depends, since they are needed to run
configure

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Rational numbers
 
2
 * rational numbers
3
3
 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
4
4
 *
5
5
 * This file is part of FFmpeg.
20
20
 */
21
21
 
22
22
/**
23
 
 * @file rational.c
24
 
 * Rational numbers
 
23
 * @file libavutil/rational.c
 
24
 * rational numbers
25
25
 * @author Michael Niedermayer <michaelni@gmx.at>
26
26
 */
27
27
 
 
28
#include <assert.h>
28
29
//#include <math.h>
29
30
#include <limits.h>
30
31
 
32
33
#include "mathematics.h"
33
34
#include "rational.h"
34
35
 
35
 
int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max){
 
36
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max){
36
37
    AVRational a0={0,1}, a1={1,0};
37
 
    int sign= (nom<0) ^ (den<0);
38
 
    int64_t gcd= ff_gcd(FFABS(nom), FFABS(den));
 
38
    int sign= (num<0) ^ (den<0);
 
39
    int64_t gcd= av_gcd(FFABS(num), FFABS(den));
39
40
 
40
41
    if(gcd){
41
 
        nom = FFABS(nom)/gcd;
 
42
        num = FFABS(num)/gcd;
42
43
        den = FFABS(den)/gcd;
43
44
    }
44
 
    if(nom<=max && den<=max){
45
 
        a1= (AVRational){nom, den};
 
45
    if(num<=max && den<=max){
 
46
        a1= (AVRational){num, den};
46
47
        den=0;
47
48
    }
48
49
 
49
50
    while(den){
50
 
        uint64_t x      = nom / den;
51
 
        int64_t next_den= nom - den*x;
 
51
        uint64_t x      = num / den;
 
52
        int64_t next_den= num - den*x;
52
53
        int64_t a2n= x*a1.num + a0.num;
53
54
        int64_t a2d= x*a1.den + a0.den;
54
55
 
56
57
            if(a1.num) x= (max - a0.num) / a1.num;
57
58
            if(a1.den) x= FFMIN(x, (max - a0.den) / a1.den);
58
59
 
59
 
            if (den*(2*x*a1.den + a0.den) > nom*a1.den)
 
60
            if (den*(2*x*a1.den + a0.den) > num*a1.den)
60
61
                a1 = (AVRational){x*a1.num + a0.num, x*a1.den + a0.den};
61
62
            break;
62
63
        }
63
64
 
64
65
        a0= a1;
65
66
        a1= (AVRational){a2n, a2d};
66
 
        nom= den;
 
67
        num= den;
67
68
        den= next_den;
68
69
    }
69
 
    assert(ff_gcd(a1.num, a1.den) <= 1U);
 
70
    assert(av_gcd(a1.num, a1.den) <= 1U);
70
71
 
71
 
    *dst_nom = sign ? -a1.num : a1.num;
 
72
    *dst_num = sign ? -a1.num : a1.num;
72
73
    *dst_den = a1.den;
73
74
 
74
75
    return den==0;
101
102
 
102
103
    return a;
103
104
}
 
105
 
 
106
int av_nearer_q(AVRational q, AVRational q1, AVRational q2)
 
107
{
 
108
    /* n/d is q, a/b is the median between q1 and q2 */
 
109
    int64_t a = q1.num * (int64_t)q2.den + q2.num * (int64_t)q1.den;
 
110
    int64_t b = 2 * (int64_t)q1.den * q2.den;
 
111
 
 
112
    /* rnd_up(a*d/b) > n => a*d/b > n */
 
113
    int64_t x_up = av_rescale_rnd(a, q.den, b, AV_ROUND_UP);
 
114
 
 
115
    /* rnd_down(a*d/b) < n => a*d/b < n */
 
116
    int64_t x_down = av_rescale_rnd(a, q.den, b, AV_ROUND_DOWN);
 
117
 
 
118
    return ((x_up > q.num) - (x_down < q.num)) * av_cmp_q(q2, q1);
 
119
}
 
120
 
 
121
int av_find_nearest_q_idx(AVRational q, const AVRational* q_list)
 
122
{
 
123
    int i, nearest_q_idx = 0;
 
124
    for(i=0; q_list[i].den; i++)
 
125
        if (av_nearer_q(q, q_list[i], q_list[nearest_q_idx]) > 0)
 
126
            nearest_q_idx = i;
 
127
 
 
128
    return nearest_q_idx;
 
129
}