this is not for git, just for testing, unless someone wants to turn it into a pretty test
Sponsored-by: Sovereign Tech Fund Signed-off-by: Michael Niedermayer <mich...@niedermayer.cc> --- libavcodec/tests/rangecoder.c | 152 +++++++++++++++++++++++++++++++++- 1 file changed, 151 insertions(+), 1 deletion(-) diff --git a/libavcodec/tests/rangecoder.c b/libavcodec/tests/rangecoder.c index fd858535a5b..3555138db85 100644 --- a/libavcodec/tests/rangecoder.c +++ b/libavcodec/tests/rangecoder.c @@ -22,6 +22,7 @@ #include "libavutil/error.h" #include "libavutil/lfg.h" #include "libavutil/log.h" +#include "libavutil/common.h" #include "libavcodec/rangecoder.h" @@ -53,13 +54,129 @@ static int rac_check_termination(RangeCoder *c, int version) return 0; } +static av_always_inline av_flatten void put_symbol_inline(RangeCoder *c, + uint8_t *state, int v, + int is_signed, + uint64_t rc_stat[256][2], + uint64_t rc_stat2[32][2]) +{ + int i; + +#define put_rac(C, S, B) \ + do { \ + if (rc_stat) { \ + rc_stat[*(S)][B]++; \ + rc_stat2[(S) - state][B]++; \ + } \ + put_rac(C, S, B); \ + } while (0) + + if (v) { + const unsigned a = is_signed ? FFABS(v) : v; + const int e = av_log2(a); + put_rac(c, state + 0, 0); + if (e <= 9) { + for (i = 0; i < e; i++) + put_rac(c, state + 1 + i, 1); // 1..10 + put_rac(c, state + 1 + i, 0); + + for (i = e - 1; i >= 0; i--) + put_rac(c, state + 22 + i, (a >> i) & 1); // 22..31 + + if (is_signed) + put_rac(c, state + 11 + e, v < 0); // 11..21 + } else { + for (i = 0; i < e; i++) + put_rac(c, state + 1 + FFMIN(i, 9), 1); // 1..10 + put_rac(c, state + 1 + 9, 0); + + for (i = e - 1; i >= 0; i--) + put_rac(c, state + 22 + FFMIN(i, 9), (a >> i) & 1); // 22..31 + + if (is_signed) + put_rac(c, state + 11 + 10, v < 0); // 11..21 + } + } else { + put_rac(c, state + 0, 1); + } +#undef put_rac +} + +static inline av_flatten int get_symbol_inline(RangeCoder *c, uint8_t *state, + int is_signed) +{ + if (get_rac(c, state + 0)) + return 0; + else { + int e; + unsigned a; + e = 0; + while (get_rac(c, state + 1 + FFMIN(e, 9))) { // 1..10 + e++; + if (e > 31) + return AVERROR_INVALIDDATA; + } + + a = 1; + for (int i = e - 1; i >= 0; i--) + a += a + get_rac(c, state + 22 + FFMIN(i, 9)); // 22..31 + + e = -(is_signed && get_rac(c, state + 11 + FFMIN(e, 10))); // 11..21 + return (a ^ e) - e; + } +} + int main(void) { RangeCoder c; uint8_t b[9 * SIZE] = {0}; uint8_t r[9 * SIZE]; + int32_t sym[] = { + 0, + 1, + 2, + 3, + 4, + 5, + 0x00000007, 0x00000008, 0x00000009, + 0x0000000F, 0x00000010, 0x00000011, + 0x0000001F, 0x00000020, 0x00000021, + 0x0000003F, 0x00000040, 0x00000041, + 0x0000007F, 0x00000080, 0x00000081, + 0x000000FF, 0x00000100, 0x00000101, + + 0x000001FF, 0x00000200, 0x00000201, + 0x000003FF, 0x00000400, 0x00000401, + 0x000007FF, 0x00000800, 0x00000801, + 0x00000FFF, 0x00001000, 0x00001001, + 0x00001FFF, 0x00002000, 0x00002001, + 0x00003FFF, 0x00004000, 0x00004001, + 0x00007FFF, 0x00008000, 0x00008001, + 0x0000FFFF, 0x00010000, 0x00010001, + + 0x0001FFFF, 0x00020000, 0x00020001, + 0x0003FFFF, 0x00040000, 0x00040001, + 0x0007FFFF, 0x00080000, 0x00080001, + 0x000FFFFF, 0x00100000, 0x00100001, + 0x001FFFFF, 0x00200000, 0x00200001, + 0x003FFFFF, 0x00400000, 0x00400001, + 0x007FFFFF, 0x00800000, 0x00800001, + 0x00FFFFFF, 0x01000000, 0x01000001, + + 0x00FFFFFF, 0x01000000, 0x01000001, + 0x01FFFFFF, 0x02000000, 0x02000001, + 0x03FFFFFF, 0x04000000, 0x04000001, + 0x07FFFFFF, 0x08000000, 0x08000001, + 0x0FFFFFFF, 0x10000000, 0x10000001, + + 0x0FFFFFFF, 0x10000000, 0x10000001, + 0x1FFFFFFF, 0x20000000, 0x20000001, + 0x3FFFFFFF, 0x40000000, 0x40000001, + 0x7FFFFFFF, 0x80000000, 0x80000001, + 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFD, + }; int i, p, actual_length, version; - uint8_t state[10]; + uint8_t state[100]; AVLFG prng; av_lfg_init(&prng, 1); @@ -76,6 +193,15 @@ int main(void) for (i = 0; i < SIZE; i++) put_rac(&c, state, r[i] & 1); + for (i = 0; i<FF_ARRAY_ELEMS(sym); i++) + put_symbol_inline(&c,state, sym[i], 1, NULL, NULL); + + for (i = 0; i<FF_ARRAY_ELEMS(sym); i++) + put_symbol_inline(&c,state, -sym[i], 1, NULL, NULL); + + for (i = 0; i<FF_ARRAY_ELEMS(sym); i++) + put_symbol_inline(&c,state, sym[i], 0, NULL, NULL); + actual_length = ff_rac_terminate(&c, version); ff_init_range_decoder(&c, b, version ? SIZE : actual_length); @@ -88,6 +214,30 @@ int main(void) return 1; } + for (i = 0; i<FF_ARRAY_ELEMS(sym); i++) { + int v = get_symbol_inline(&c, state, 1); + if (v != sym[i]) { + av_log(NULL, AV_LOG_ERROR, "symbol S failure %X %X\n", v, sym[i]); + return 1; + } + } + + for (i = 0; i<FF_ARRAY_ELEMS(sym); i++) { + int v = -get_symbol_inline(&c, state, 1); + if (v != sym[i]) { + av_log(NULL, AV_LOG_ERROR, "symbol -S failure %X %X\n", v, sym[i]); + return 1; + } + } + + for (i = 0; i<FF_ARRAY_ELEMS(sym); i++) { + int v = get_symbol_inline(&c, state, 0); + if (v != sym[i]) { + av_log(NULL, AV_LOG_ERROR, "symbol U failure %X %X\n", v, sym[i]); + return 1; + } + } + if (rac_check_termination(&c, version) < 0) { av_log(NULL, AV_LOG_ERROR, "rac failure at termination pass %d version %d\n", p, version); return 1; -- 2.47.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".