diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-11-23 13:30:51 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-11-23 13:30:51 +0100 |
commit | 25ca8aef54b65c77ed36ab5a6877eba18560e6b8 (patch) | |
tree | 5e90ca85f7a2364a156154e8c9bbc8ca75018736 /libavutil/mem.c | |
parent | e9c372362cb736240dcd87658a027ecfb7b9d240 (diff) | |
parent | 4a606c830ae664013cea33800094d4d0f4ec62da (diff) | |
download | ffmpeg-25ca8aef54b65c77ed36ab5a6877eba18560e6b8.tar.gz |
Merge commit '4a606c830ae664013cea33800094d4d0f4ec62da'
* commit '4a606c830ae664013cea33800094d4d0f4ec62da':
av_memcpy_backptr: optimise some special cases
mpegvideo: simplify dxy calculation in hpel_motion()
build: add rules to generate preprocessed source files
Conflicts:
Makefile
libavutil/mem.c
library.mak
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavutil/mem.c')
-rw-r--r-- | libavutil/mem.c | 120 |
1 files changed, 103 insertions, 17 deletions
diff --git a/libavutil/mem.c b/libavutil/mem.c index f3853b0827..d73cddefd0 100644 --- a/libavutil/mem.c +++ b/libavutil/mem.c @@ -246,29 +246,93 @@ void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem) *nb_ptr = nb; } +static void fill16(uint8_t *dst, int len) +{ + uint32_t v = AV_RN16(dst - 2); + + v |= v << 16; + + while (len >= 4) { + AV_WN32(dst, v); + dst += 4; + len -= 4; + } + + while (len--) { + *dst = dst[-2]; + dst++; + } +} + +static void fill24(uint8_t *dst, int len) +{ +#if HAVE_BIGENDIAN + uint32_t v = AV_RB24(dst - 3); + uint32_t a = v << 8 | v >> 16; + uint32_t b = v << 16 | v >> 8; + uint32_t c = v << 24 | v; +#else + uint32_t v = AV_RL24(dst - 3); + uint32_t a = v | v << 24; + uint32_t b = v >> 8 | v << 16; + uint32_t c = v >> 16 | v << 8; +#endif + + while (len >= 12) { + AV_WN32(dst, a); + AV_WN32(dst + 4, b); + AV_WN32(dst + 8, c); + dst += 12; + len -= 12; + } + + if (len >= 4) { + AV_WN32(dst, a); + dst += 4; + len -= 4; + } + + if (len >= 4) { + AV_WN32(dst, b); + dst += 4; + len -= 4; + } + + while (len--) { + *dst = dst[-3]; + dst++; + } +} + +static void fill32(uint8_t *dst, int len) +{ + uint32_t v = AV_RN32(dst - 4); + + while (len >= 4) { + AV_WN32(dst, v); + dst += 4; + len -= 4; + } + + while (len--) { + *dst = dst[-4]; + dst++; + } +} + void av_memcpy_backptr(uint8_t *dst, int back, int cnt) { const uint8_t *src = &dst[-back]; if (back <= 1) { memset(dst, *src, cnt); + } else if (back == 2) { + fill16(dst, cnt); + } else if (back == 3) { + fill24(dst, cnt); + } else if (back == 4) { + fill32(dst, cnt); } else { - if (cnt >= 4) { - AV_COPY16U(dst, src); - AV_COPY16U(dst + 2, src + 2); - src += 4; - dst += 4; - cnt -= 4; - } - if (cnt >= 8) { - AV_COPY16U(dst, src); - AV_COPY16U(dst + 2, src + 2); - AV_COPY16U(dst + 4, src + 4); - AV_COPY16U(dst + 6, src + 6); - src += 8; - dst += 8; - cnt -= 8; - } - if (cnt > 0) { + if (cnt >= 16) { int blocklen = back; while (cnt > blocklen) { memcpy(dst, src, blocklen); @@ -277,7 +341,29 @@ void av_memcpy_backptr(uint8_t *dst, int back, int cnt) blocklen <<= 1; } memcpy(dst, src, cnt); + return; + } + if (cnt >= 8) { + AV_COPY32U(dst, src); + AV_COPY32U(dst + 4, src + 4); + src += 8; + dst += 8; + cnt -= 8; + } + if (cnt >= 4) { + AV_COPY32U(dst, src); + src += 4; + dst += 4; + cnt -= 4; + } + if (cnt >= 2) { + AV_COPY16U(dst, src); + src += 2; + dst += 2; + cnt -= 2; } + if (cnt) + *dst = *src; } } |