---
libavcodec/ac3enc_fixed.c | 49 ++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 48 insertions(+), 1 deletions(-)
diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c
index 26bba0f..e64a252 100644
--- a/libavcodec/ac3enc_fixed.c
+++ b/libavcodec/ac3enc_fixed.c
@@ -114,11 +114,58 @@ static void clip_coefficients(DSPContext *dsp, int32_t
*coef, unsigned int len)
/**
+ * Calculate the integer square root of a 64-bit unsigned integer.
+ */
+static av_always_inline uint32_t isqrt64(uint64_t val)
+{
+ uint64_t temp, g = 0;
+
+#define INNER_SQRT(s) \
+ temp = (g << s) + (1ULL << (s * 2 - 2)); \
+ if (val >= temp) { \
+ g += 1ULL << (s - 1); \
+ val -= temp; \
+ }
+
+ if (!val)
+ return 0;
+
+ /* INNER_SQRT(32) */
+ if (val >= 0x4000000000000000ULL) {
+ g = 0x80000000ULL;
+ val -= 0x4000000000000000ULL;
+ }
+
+ INNER_SQRT(31); INNER_SQRT(30); INNER_SQRT(29); INNER_SQRT(28);
+ INNER_SQRT(27); INNER_SQRT(26); INNER_SQRT(25); INNER_SQRT(24);
+ INNER_SQRT(23); INNER_SQRT(22); INNER_SQRT(21); INNER_SQRT(20);
+ INNER_SQRT(19); INNER_SQRT(18); INNER_SQRT(17); INNER_SQRT(16);
+ INNER_SQRT(15); INNER_SQRT(14); INNER_SQRT(13); INNER_SQRT(12);
+ INNER_SQRT(11); INNER_SQRT(10); INNER_SQRT( 9); INNER_SQRT( 8);
+ INNER_SQRT( 7); INNER_SQRT( 6); INNER_SQRT( 5); INNER_SQRT( 4);
+ INNER_SQRT( 3); INNER_SQRT( 2);
+
+ /* INNER_SQRT(1) */
+ temp = 2 * g + 1;
+ if (val >= temp)
+ g++;
+
+ return FFMIN(g, UINT32_MAX);
+}
+
+
+/**
* Calculate a single coupling coordinate.
*/
static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl)
{
- return 1048576;
+ if (energy_cpl < COEF_MAX) {
+ return 1048576;
+ } else {
+ uint64_t coord = energy_ch / (energy_cpl >> 24);
+ coord = FFMIN(coord, 1073741824);
+ return FFMIN(isqrt64(coord) << 9, COEF_MAX);
+ }
}
--
1.7.1
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel