rational.h 5.71 KB
Newer Older
Michael Niedermayer's avatar
Michael Niedermayer committed
1
/*
2
 * rational numbers
Michael Niedermayer's avatar
Michael Niedermayer committed
3 4
 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
 *
5 6 7
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
Michael Niedermayer's avatar
Michael Niedermayer committed
8 9
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
Michael Niedermayer's avatar
Michael Niedermayer committed
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
Michael Niedermayer's avatar
Michael Niedermayer committed
13 14 15 16 17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Michael Niedermayer's avatar
Michael Niedermayer committed
20
 */
21

Michael Niedermayer's avatar
Michael Niedermayer committed
22
/**
23
 * @file
Timothy Gu's avatar
Timothy Gu committed
24 25
 * @ingroup lavu_math_rational
 * Utilties for rational number calculation.
Michael Niedermayer's avatar
Michael Niedermayer committed
26 27 28
 * @author Michael Niedermayer <michaelni@gmx.at>
 */

29 30
#ifndef AVUTIL_RATIONAL_H
#define AVUTIL_RATIONAL_H
Michael Niedermayer's avatar
Michael Niedermayer committed
31

32
#include <stdint.h>
33
#include <limits.h>
34
#include "attributes.h"
35

36
/**
Timothy Gu's avatar
Timothy Gu committed
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
 * @defgroup lavu_math_rational AVRational
 * @ingroup lavu_math
 * Rational number calculation.
 *
 * While rational numbers can be expressed as floating-point numbers, the
 * conversion process is a lossy one, so are floating-point operations. On the
 * other hand, the nature of FFmpeg demands highly accurate calculation of
 * timestamps. This set of rational number utilities serves as a generic
 * interface for manipulating rational numbers as pairs of numerators and
 * denominators.
 *
 * Many of the functions that operate on AVRational's have the suffix `_q`, in
 * reference to the mathematical symbol "ℚ" (Q) which denotes the set of all
 * rational numbers.
 *
52 53 54
 * @{
 */

Michael Niedermayer's avatar
Michael Niedermayer committed
55
/**
Timothy Gu's avatar
Timothy Gu committed
56
 * Rational number (pair of numerator and denominator).
Michael Niedermayer's avatar
Michael Niedermayer committed
57
 */
Michael Niedermayer's avatar
Michael Niedermayer committed
58
typedef struct AVRational{
Timothy Gu's avatar
Timothy Gu committed
59 60
    int num; ///< Numerator
    int den; ///< Denominator
Michael Niedermayer's avatar
Michael Niedermayer committed
61 62
} AVRational;

63
/**
Timothy Gu's avatar
Timothy Gu committed
64 65
 * Create an AVRational.
 *
66
 * Useful for compilers that do not support compound literals.
Timothy Gu's avatar
Timothy Gu committed
67 68 69
 *
 * @note The return value is not reduced.
 * @see av_reduce()
70 71 72 73 74 75 76
 */
static inline AVRational av_make_q(int num, int den)
{
    AVRational r = { num, den };
    return r;
}

Michael Niedermayer's avatar
Michael Niedermayer committed
77
/**
78
 * Compare two rationals.
Timothy Gu's avatar
Timothy Gu committed
79 80 81 82 83 84 85 86 87
 *
 * @param a First rational
 * @param b Second rational
 *
 * @return One of the following values:
 *         - 0 if `a == b`
 *         - 1 if `a > b`
 *         - -1 if `a < b`
 *         - `INT_MIN` if one of the values is of the form `0 / 0`
Michael Niedermayer's avatar
Michael Niedermayer committed
88
 */
Michael Niedermayer's avatar
Michael Niedermayer committed
89 90 91
static inline int av_cmp_q(AVRational a, AVRational b){
    const int64_t tmp= a.num * (int64_t)b.den - b.num * (int64_t)a.den;

92
    if(tmp) return (int)((tmp ^ a.den ^ b.den)>>63)|1;
93 94 95
    else if(b.den && a.den) return 0;
    else if(a.num && b.num) return (a.num>>31) - (b.num>>31);
    else                    return INT_MIN;
Michael Niedermayer's avatar
Michael Niedermayer committed
96 97
}

Michael Niedermayer's avatar
Michael Niedermayer committed
98
/**
Timothy Gu's avatar
Timothy Gu committed
99 100 101 102
 * Convert an AVRational to a `double`.
 * @param a AVRational to convert
 * @return `a` in floating-point form
 * @see av_d2q()
Michael Niedermayer's avatar
Michael Niedermayer committed
103
 */
Michael Niedermayer's avatar
Michael Niedermayer committed
104 105 106 107
static inline double av_q2d(AVRational a){
    return a.num / (double) a.den;
}

108
/**
109
 * Reduce a fraction.
Timothy Gu's avatar
Timothy Gu committed
110
 *
111
 * This is useful for framerate calculations.
Timothy Gu's avatar
Timothy Gu committed
112 113 114 115 116 117 118
 *
 * @param[out] dst_num Destination numerator
 * @param[out] dst_den Destination denominator
 * @param[in]      num Source numerator
 * @param[in]      den Source denominator
 * @param[in]      max Maximum allowed values for `dst_num` & `dst_den`
 * @return 1 if the operation is exact, 0 otherwise
119
 */
120
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max);
121

122
/**
123
 * Multiply two rationals.
Timothy Gu's avatar
Timothy Gu committed
124 125
 * @param b First rational
 * @param c Second rational
126
 * @return b*c
127
 */
128
AVRational av_mul_q(AVRational b, AVRational c) av_const;
129 130

/**
131
 * Divide one rational by another.
Timothy Gu's avatar
Timothy Gu committed
132 133
 * @param b First rational
 * @param c Second rational
134
 * @return b/c
135
 */
136
AVRational av_div_q(AVRational b, AVRational c) av_const;
137 138

/**
139
 * Add two rationals.
Timothy Gu's avatar
Timothy Gu committed
140 141
 * @param b First rational
 * @param c Second rational
142
 * @return b+c
143
 */
144
AVRational av_add_q(AVRational b, AVRational c) av_const;
145 146

/**
147
 * Subtract one rational from another.
Timothy Gu's avatar
Timothy Gu committed
148 149
 * @param b First rational
 * @param c Second rational
150
 * @return b-c
151
 */
152
AVRational av_sub_q(AVRational b, AVRational c) av_const;
153

154 155 156 157 158 159 160 161 162 163 164
/**
 * Invert a rational.
 * @param q value
 * @return 1 / q
 */
static av_always_inline AVRational av_inv_q(AVRational q)
{
    AVRational r = { q.den, q.num };
    return r;
}

165
/**
166
 * Convert a double precision floating point number to a rational.
167
 *
Timothy Gu's avatar
Timothy Gu committed
168 169 170 171 172 173 174
 * In case of infinity, the returned value is expressed as `{1, 0}` or
 * `{-1, 0}` depending on the sign.
 *
 * @param d   `double` to convert
 * @param max Maximum allowed numerator and denominator
 * @return `d` in AVRational form
 * @see av_q2d()
175
 */
176
AVRational av_d2q(double d, int max) av_const;
Michael Niedermayer's avatar
Michael Niedermayer committed
177

178
/**
Timothy Gu's avatar
Timothy Gu committed
179 180 181 182 183 184 185 186
 * Find which of the two rationals is closer to another rational.
 *
 * @param q     Rational to be compared against
 * @param q1,q2 Rationals to be tested
 * @return One of the following values:
 *         - 1 if `q1` is nearer to `q` than `q2`
 *         - -1 if `q2` is nearer to `q` than `q1`
 *         - 0 if they have the same distance
187 188 189 190
 */
int av_nearer_q(AVRational q, AVRational q1, AVRational q2);

/**
Timothy Gu's avatar
Timothy Gu committed
191 192 193 194 195
 * Find the value in a list of rationals nearest a given reference rational.
 *
 * @param q      Reference rational
 * @param q_list Array of rationals terminated by `{0, 0}`
 * @return Index of the nearest value found in the array
196 197 198
 */
int av_find_nearest_q_idx(AVRational q, const AVRational* q_list);

199
/**
Timothy Gu's avatar
Timothy Gu committed
200 201
 * Convert an AVRational to a IEEE 32-bit `float` expressed in fixed-point
 * format.
202
 *
Timothy Gu's avatar
Timothy Gu committed
203 204 205 206
 * @param q Rational to be converted
 * @return Equivalent floating-point value, expressed as an unsigned 32-bit
 *         integer.
 * @note The returned value is platform-indepedant.
207 208 209
 */
uint32_t av_q2intfloat(AVRational q);

210 211 212 213
/**
 * @}
 */

214
#endif /* AVUTIL_RATIONAL_H */