Commit 4a606c83 authored by Mans Rullgard's avatar Mans Rullgard

av_memcpy_backptr: optimise some special cases

- Add special cases for offsets of 2, 3, or 4 bytes.  This means the
  offset is always >4 in the generic case, allowing 32-bit copies to
  be used there.
- Don't use memcpy() for sizes less than 16 bytes.
Signed-off-by: 's avatarMans Rullgard <mans@mansr.com>
parent 5e39bb07
...@@ -180,29 +180,93 @@ char *av_strdup(const char *s) ...@@ -180,29 +180,93 @@ char *av_strdup(const char *s)
return ptr; return ptr;
} }
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) void av_memcpy_backptr(uint8_t *dst, int back, int cnt)
{ {
const uint8_t *src = &dst[-back]; const uint8_t *src = &dst[-back];
if (back == 1) { if (back == 1) {
memset(dst, *src, cnt); 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 { } else {
if (cnt >= 4) { if (cnt >= 16) {
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) {
int blocklen = back; int blocklen = back;
while (cnt > blocklen) { while (cnt > blocklen) {
memcpy(dst, src, blocklen); memcpy(dst, src, blocklen);
...@@ -211,6 +275,28 @@ void av_memcpy_backptr(uint8_t *dst, int back, int cnt) ...@@ -211,6 +275,28 @@ void av_memcpy_backptr(uint8_t *dst, int back, int cnt)
blocklen <<= 1; blocklen <<= 1;
} }
memcpy(dst, src, cnt); 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;
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment