Index: libavcodec/mem.c =================================================================== RCS file: /cvsroot/ffmpeg/ffmpeg/libavcodec/mem.c,v retrieving revision 1.7 diff -u -r1.7 mem.c --- libavcodec/mem.c 6 Mar 2003 11:32:02 -0000 1.7 +++ libavcodec/mem.c 13 Apr 2004 09:04:57 -0000 @@ -1,6 +1,7 @@ /* * default memory allocator for libavcodec * Copyright (c) 2002 Fabrice Bellard. + * Copyright (c) 2004 Michel Bardiaux (for the HAVE_MMX code) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -37,6 +38,17 @@ memory allocator. You do not need to suppress this file because the linker will do it automatically */ +/* You can use the home-cooked av_malloc with 16-bytes alignment even if + your system does have memalign (thereby becoming a guinea pig for a + feature useful under MS-WINDOWS only); uncomment the following line: */ +//#undef HAVE_MEMALIGN +#if defined(HAVE_MMX) && !defined(HAVE_MEMALIGN) +typedef struct { + void* org_malloc; + unsigned int org_size; +} org_info; +#endif // MMX & !MEMALIGN + /** * Memory allocation of size byte with alignment suitable for all * memory accesses (including vectors if available on the @@ -74,6 +86,28 @@ btw, malloc seems to do 8 byte alignment by default here */ +#elif defined(HAVE_MMX) + // + // To ensure alignment on 16 bytes we will have to bump up the + // pointer from malloc by 1 to 15. But for av_free to work we + // have to stow the original pointer (for av_free) and the + // original size (for av_realloc).Which means the bump could be 16 bytes more + // than the minimum needed. Hence the margin in malloc. + // + { + unsigned int misalignment, bump; + org_info* pinfo; + void* malloced; + malloced = malloc(size+sizeof(org_info)+16); + misalignment = ((unsigned int)malloced) % 16; + bump = 16 - misalignment; + if(bumporg_malloc = malloced; + pinfo->org_size = size; + } #else ptr = malloc(size); #endif @@ -87,14 +121,47 @@ */ void *av_realloc(void *ptr, unsigned int size) { +#if defined (HAVE_MEMALIGN) + return realloc(ptr, size); +#elif defined(HAVE_MMX) + if(!ptr) { + if(!size) + return NULL; + else + return av_malloc(size); + } else { + if(!size) { + av_free(ptr); + return NULL; + } else { + org_info* pinfo; + void* new_ptr; + unsigned int smaller_size; + pinfo = ((org_info*)ptr)-1; + new_ptr = av_malloc(size); + smaller_size = FFMIN(size, pinfo->org_size); + memcpy(new_ptr, ptr, smaller_size); + av_free(ptr); + return new_ptr; + } + } +#else return realloc(ptr, size); +#endif } /* NOTE: ptr = NULL is explicetly allowed */ void av_free(void *ptr) { /* XXX: this test should not be needed on most libcs */ - if (ptr) - free(ptr); + if (!ptr) + return; +#if defined (HAVE_MEMALIGN) + free(ptr); +#elif defined(HAVE_MMX) + free(((org_info*)ptr)[-1].org_malloc); +#else + free(ptr); +#endif }