diff options
author | Mans Rullgard <mans@mansr.com> | 2010-12-22 12:57:53 +0000 |
---|---|---|
committer | Mans Rullgard <mans@mansr.com> | 2011-02-11 15:48:10 +0000 |
commit | 7da48fd0111adf504cfcfc5ebda7fd0681968041 (patch) | |
tree | f5244f9af0430fcb50a9d06d76efb3fc772af253 /libavcodec/arm | |
parent | aa8ac53b51cd8b9446b50404660685041060fa4f (diff) | |
download | ffmpeg-7da48fd0111adf504cfcfc5ebda7fd0681968041.tar.gz |
ARM optimised vp56_rac_get_prob()
Approximately 3% faster on Cortex-A8.
Signed-off-by: Mans Rullgard <mans@mansr.com>
Diffstat (limited to 'libavcodec/arm')
-rw-r--r-- | libavcodec/arm/vp56_arith.h | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/libavcodec/arm/vp56_arith.h b/libavcodec/arm/vp56_arith.h new file mode 100644 index 0000000000..9bcb466bdc --- /dev/null +++ b/libavcodec/arm/vp56_arith.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2010 Mans Rullgard <mans@mansr.com> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * 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 + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_ARM_VP56_ARITH_H +#define AVCODEC_ARM_VP56_ARITH_H + +#if HAVE_ARMV6 && HAVE_INLINE_ASM + +#define vp56_rac_get_prob vp56_rac_get_prob_armv6 +static inline int vp56_rac_get_prob_armv6(VP56RangeCoder *c, int pr) +{ + unsigned shift = ff_vp56_norm_shift[c->high]; + unsigned code_word = c->code_word << shift; + unsigned high = c->high << shift; + unsigned bit; + + __asm__ volatile ("adds %3, %3, %0 \n" + "cmpcs %7, %4 \n" + "ldrcsh %2, [%4], #2 \n" + "rsb %0, %6, #256 \n" + "smlabb %0, %5, %6, %0 \n" + "rev16cs %2, %2 \n" + "orrcs %1, %1, %2, lsl %3 \n" + "subcs %3, %3, #16 \n" + "lsr %0, %0, #8 \n" + "cmp %1, %0, lsl #16 \n" + "subge %1, %1, %0, lsl #16 \n" + "subge %0, %5, %0 \n" + "movge %2, #1 \n" + "movlt %2, #0 \n" + : "=&r"(c->high), "=&r"(c->code_word), "=&r"(bit), + "+&r"(c->bits), "+&r"(c->buffer) + : "r"(high), "r"(pr), "r"(c->end - 1), + "0"(shift), "1"(code_word)); + + return bit; +} + +#define vp56_rac_get_prob_branchy vp56_rac_get_prob_branchy_armv6 +static inline int vp56_rac_get_prob_branchy_armv6(VP56RangeCoder *c, int pr) +{ + unsigned shift = ff_vp56_norm_shift[c->high]; + unsigned code_word = c->code_word << shift; + unsigned high = c->high << shift; + unsigned low; + unsigned tmp; + + __asm__ volatile ("adds %3, %3, %0 \n" + "cmpcs %7, %4 \n" + "ldrcsh %2, [%4], #2 \n" + "rsb %0, %6, #256 \n" + "smlabb %0, %5, %6, %0 \n" + "rev16cs %2, %2 \n" + "orrcs %1, %1, %2, lsl %3 \n" + "subcs %3, %3, #16 \n" + "lsr %0, %0, #8 \n" + "lsl %2, %0, #16 \n" + : "=&r"(low), "+&r"(code_word), "=&r"(tmp), + "+&r"(c->bits), "+&r"(c->buffer) + : "r"(high), "r"(pr), "r"(c->end - 1), "0"(shift)); + + if (code_word >= tmp) { + c->high = high - low; + c->code_word = code_word - tmp; + return 1; + } + + c->high = low; + c->code_word = code_word; + return 0; +} + +#endif + +#endif |