summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2015-05-24 14:19:57 +0200
committerMichael Niedermayer <michaelni@gmx.at>2015-05-26 18:31:53 +0200
commit1fb9b2a2832444935c4c2fd5679266b0629d1bfd (patch)
tree9baac009633492f6c6b4d2e587ee7a7723d5b3b4
parent894d8cf418aafc5f6dd697f57e24f3e96b6af2f3 (diff)
avutil: Add av_q2intfloat()
This function allows writing AVRationals as IEEE floats without the need of platform dependant float operations Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--doc/APIchanges3
-rw-r--r--libavutil/rational.c48
-rw-r--r--libavutil/rational.h7
-rw-r--r--libavutil/version.h2
4 files changed, 59 insertions, 1 deletions
diff --git a/doc/APIchanges b/doc/APIchanges
index 3cca3890cb..b0c69dcdb0 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -15,6 +15,9 @@ libavutil: 2014-08-09
API changes, most recent first:
+2015-05-26 - xxxxxxx - lavu 54.25.100 - rational.h
+ Add av_q2intfloat().
+
2015-05-13 - xxxxxxx - lavc 56.39.100 / 56.23.0
Add av_vda_default_init2.
diff --git a/libavutil/rational.c b/libavutil/rational.c
index 594a6f81e6..21d2bb72c3 100644
--- a/libavutil/rational.c
+++ b/libavutil/rational.c
@@ -148,6 +148,40 @@ int av_find_nearest_q_idx(AVRational q, const AVRational* q_list)
return nearest_q_idx;
}
+uint32_t av_q2intfloat(AVRational q) {
+ int64_t n;
+ int shift;
+ int sign = 0;
+
+ if (q.den < 0) {
+ q.den *= -1;
+ q.num *= -1;
+ }
+ if (q.num < 0) {
+ q.num *= -1;
+ sign = 1;
+ }
+
+ if (!q.num && !q.den) return 0xFFC00000;
+ if (!q.num) return 0;
+ if (!q.den) return 0x7F800000 | (q.num & 0x80000000);
+
+ shift = 23 + av_log2(q.den) - av_log2(q.num);
+ if (shift >= 0) n = av_rescale(q.num, 1LL<<shift, q.den);
+ else n = av_rescale(q.num, 1, ((int64_t)q.den) << -shift);
+
+ shift -= n >= (1<<24);
+ shift += n < (1<<23);
+
+ if (shift >= 0) n = av_rescale(q.num, 1LL<<shift, q.den);
+ else n = av_rescale(q.num, 1, ((int64_t)q.den) << -shift);
+
+ av_assert1(n < (1<<24));
+ av_assert1(n >= (1<<23));
+
+ return sign<<31 | (150-shift)<<23 | (n - (1<<23));
+}
+
#ifdef TEST
int main(void)
{
@@ -202,6 +236,20 @@ int main(void)
}
}
}
+
+ for (a.den = 1; a.den < 0x100000000U/3; a.den*=3) {
+ for (a.num = -1; a.num < (1<<27); a.num += 1 + a.num/100) {
+ float f = av_int2float(av_q2intfloat(a));
+ float f2 = av_q2d(a);
+ if (fabs(f - f2) > fabs(f)/5000000) {
+ av_log(NULL, AV_LOG_ERROR, "%d/%d %f %f\n", a.num,
+ a.den, f, f2);
+ return 1;
+ }
+
+ }
+ }
+
return 0;
}
#endif
diff --git a/libavutil/rational.h b/libavutil/rational.h
index 7439701db2..2897469680 100644
--- a/libavutil/rational.h
+++ b/libavutil/rational.h
@@ -160,6 +160,13 @@ int av_nearer_q(AVRational q, AVRational q1, AVRational q2);
int av_find_nearest_q_idx(AVRational q, const AVRational* q_list);
/**
+ * Converts a AVRational to a IEEE 32bit float.
+ *
+ * The float is returned in a uint32_t and its value is platform indepenant.
+ */
+uint32_t av_q2intfloat(AVRational q);
+
+/**
* @}
*/
diff --git a/libavutil/version.h b/libavutil/version.h
index eeafcfab6c..4a5e47d7a0 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -56,7 +56,7 @@
*/
#define LIBAVUTIL_VERSION_MAJOR 54
-#define LIBAVUTIL_VERSION_MINOR 24
+#define LIBAVUTIL_VERSION_MINOR 25
#define LIBAVUTIL_VERSION_MICRO 100
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \