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(bump<sizeof(org_info))
+	    bump += 16;
+        ptr = ((char*)malloced) + bump;
+        pinfo = ((org_info*)ptr)-1;
+	pinfo->org_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
 }
 
