mem.c
Go to the documentation of this file.
1 /*
2  * default memory allocator for libavutil
3  * Copyright (c) 2002 Fabrice Bellard
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /**
23  * @file
24  * default memory allocator for libavutil
25  */
26 
27 #define _XOPEN_SOURCE 600
28 
29 #include "config.h"
30 
31 #include <limits.h>
32 #include <stdint.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #if HAVE_MALLOC_H
36 #include <malloc.h>
37 #endif
38 
39 #include "avassert.h"
40 #include "avutil.h"
41 #include "intreadwrite.h"
42 #include "mem.h"
43 
44 #ifdef MALLOC_PREFIX
45 
46 #define malloc AV_JOIN(MALLOC_PREFIX, malloc)
47 #define memalign AV_JOIN(MALLOC_PREFIX, memalign)
48 #define posix_memalign AV_JOIN(MALLOC_PREFIX, posix_memalign)
49 #define realloc AV_JOIN(MALLOC_PREFIX, realloc)
50 #define free AV_JOIN(MALLOC_PREFIX, free)
51 
52 void *malloc(size_t size);
53 void *memalign(size_t align, size_t size);
54 int posix_memalign(void **ptr, size_t align, size_t size);
55 void *realloc(void *ptr, size_t size);
56 void free(void *ptr);
57 
58 #endif /* MALLOC_PREFIX */
59 
60 #define ALIGN (HAVE_AVX ? 32 : 16)
61 
62 /* NOTE: if you want to override these functions with your own
63  * implementations (not recommended) you have to link libav* as
64  * dynamic libraries and remove -Wl,-Bsymbolic from the linker flags.
65  * Note that this will cost performance. */
66 
67 static size_t max_alloc_size= INT_MAX;
68 
69 void av_max_alloc(size_t max){
71 }
72 
73 void *av_malloc(size_t size)
74 {
75  void *ptr = NULL;
76 #if CONFIG_MEMALIGN_HACK
77  long diff;
78 #endif
79 
80  /* let's disallow possible ambiguous cases */
81  if (size > (max_alloc_size - 32))
82  return NULL;
83 
84 #if CONFIG_MEMALIGN_HACK
85  ptr = malloc(size + ALIGN);
86  if (!ptr)
87  return ptr;
88  diff = ((~(long)ptr)&(ALIGN - 1)) + 1;
89  ptr = (char *)ptr + diff;
90  ((char *)ptr)[-1] = diff;
91 #elif HAVE_POSIX_MEMALIGN
92  if (size) //OS X on SDK 10.6 has a broken posix_memalign implementation
93  if (posix_memalign(&ptr, ALIGN, size))
94  ptr = NULL;
95 #elif HAVE_ALIGNED_MALLOC
96  ptr = _aligned_malloc(size, ALIGN);
97 #elif HAVE_MEMALIGN
98 #ifndef __DJGPP__
99  ptr = memalign(ALIGN, size);
100 #else
101  ptr = memalign(size, ALIGN);
102 #endif
103  /* Why 64?
104  * Indeed, we should align it:
105  * on 4 for 386
106  * on 16 for 486
107  * on 32 for 586, PPro - K6-III
108  * on 64 for K7 (maybe for P3 too).
109  * Because L1 and L2 caches are aligned on those values.
110  * But I don't want to code such logic here!
111  */
112  /* Why 32?
113  * For AVX ASM. SSE / NEON needs only 16.
114  * Why not larger? Because I did not see a difference in benchmarks ...
115  */
116  /* benchmarks with P3
117  * memalign(64) + 1 3071, 3051, 3032
118  * memalign(64) + 2 3051, 3032, 3041
119  * memalign(64) + 4 2911, 2896, 2915
120  * memalign(64) + 8 2545, 2554, 2550
121  * memalign(64) + 16 2543, 2572, 2563
122  * memalign(64) + 32 2546, 2545, 2571
123  * memalign(64) + 64 2570, 2533, 2558
124  *
125  * BTW, malloc seems to do 8-byte alignment by default here.
126  */
127 #else
128  ptr = malloc(size);
129 #endif
130  if(!ptr && !size) {
131  size = 1;
132  ptr= av_malloc(1);
133  }
134 #if CONFIG_MEMORY_POISONING
135  if (ptr)
136  memset(ptr, 0x2a, size);
137 #endif
138  return ptr;
139 }
140 
141 void *av_realloc(void *ptr, size_t size)
142 {
143 #if CONFIG_MEMALIGN_HACK
144  int diff;
145 #endif
146 
147  /* let's disallow possible ambiguous cases */
148  if (size > (max_alloc_size - 32))
149  return NULL;
150 
151 #if CONFIG_MEMALIGN_HACK
152  //FIXME this isn't aligned correctly, though it probably isn't needed
153  if (!ptr)
154  return av_malloc(size);
155  diff = ((char *)ptr)[-1];
156  av_assert0(diff>0 && diff<=ALIGN);
157  ptr = realloc((char *)ptr - diff, size + diff);
158  if (ptr)
159  ptr = (char *)ptr + diff;
160  return ptr;
161 #elif HAVE_ALIGNED_MALLOC
162  return _aligned_realloc(ptr, size + !size, ALIGN);
163 #else
164  return realloc(ptr, size + !size);
165 #endif
166 }
167 
168 void *av_realloc_f(void *ptr, size_t nelem, size_t elsize)
169 {
170  size_t size;
171  void *r;
172 
173  if (av_size_mult(elsize, nelem, &size)) {
174  av_free(ptr);
175  return NULL;
176  }
177  r = av_realloc(ptr, size);
178  if (!r && size)
179  av_free(ptr);
180  return r;
181 }
182 
183 void av_free(void *ptr)
184 {
185 #if CONFIG_MEMALIGN_HACK
186  if (ptr) {
187  int v= ((char *)ptr)[-1];
188  av_assert0(v>0 && v<=ALIGN);
189  free((char *)ptr - v);
190  }
191 #elif HAVE_ALIGNED_MALLOC
192  _aligned_free(ptr);
193 #else
194  free(ptr);
195 #endif
196 }
197 
198 void av_freep(void *arg)
199 {
200  void **ptr = (void **)arg;
201  av_free(*ptr);
202  *ptr = NULL;
203 }
204 
205 void *av_mallocz(size_t size)
206 {
207  void *ptr = av_malloc(size);
208  if (ptr)
209  memset(ptr, 0, size);
210  return ptr;
211 }
212 
213 void *av_calloc(size_t nmemb, size_t size)
214 {
215  if (size <= 0 || nmemb >= INT_MAX / size)
216  return NULL;
217  return av_mallocz(nmemb * size);
218 }
219 
220 char *av_strdup(const char *s)
221 {
222  char *ptr = NULL;
223  if (s) {
224  int len = strlen(s) + 1;
225  ptr = av_malloc(len);
226  if (ptr)
227  memcpy(ptr, s, len);
228  }
229  return ptr;
230 }
231 
232 /* add one element to a dynamic array */
233 void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem)
234 {
235  /* see similar ffmpeg.c:grow_array() */
236  int nb, nb_alloc;
237  intptr_t *tab;
238 
239  nb = *nb_ptr;
240  tab = *(intptr_t**)tab_ptr;
241  if ((nb & (nb - 1)) == 0) {
242  if (nb == 0)
243  nb_alloc = 1;
244  else
245  nb_alloc = nb * 2;
246  tab = av_realloc(tab, nb_alloc * sizeof(intptr_t));
247  *(intptr_t**)tab_ptr = tab;
248  }
249  tab[nb++] = (intptr_t)elem;
250  *nb_ptr = nb;
251 }
252 
253 static void fill16(uint8_t *dst, int len)
254 {
255  uint32_t v = AV_RN16(dst - 2);
256 
257  v |= v << 16;
258 
259  while (len >= 4) {
260  AV_WN32(dst, v);
261  dst += 4;
262  len -= 4;
263  }
264 
265  while (len--) {
266  *dst = dst[-2];
267  dst++;
268  }
269 }
270 
271 static void fill24(uint8_t *dst, int len)
272 {
273 #if HAVE_BIGENDIAN
274  uint32_t v = AV_RB24(dst - 3);
275  uint32_t a = v << 8 | v >> 16;
276  uint32_t b = v << 16 | v >> 8;
277  uint32_t c = v << 24 | v;
278 #else
279  uint32_t v = AV_RL24(dst - 3);
280  uint32_t a = v | v << 24;
281  uint32_t b = v >> 8 | v << 16;
282  uint32_t c = v >> 16 | v << 8;
283 #endif
284 
285  while (len >= 12) {
286  AV_WN32(dst, a);
287  AV_WN32(dst + 4, b);
288  AV_WN32(dst + 8, c);
289  dst += 12;
290  len -= 12;
291  }
292 
293  if (len >= 4) {
294  AV_WN32(dst, a);
295  dst += 4;
296  len -= 4;
297  }
298 
299  if (len >= 4) {
300  AV_WN32(dst, b);
301  dst += 4;
302  len -= 4;
303  }
304 
305  while (len--) {
306  *dst = dst[-3];
307  dst++;
308  }
309 }
310 
311 static void fill32(uint8_t *dst, int len)
312 {
313  uint32_t v = AV_RN32(dst - 4);
314 
315  while (len >= 4) {
316  AV_WN32(dst, v);
317  dst += 4;
318  len -= 4;
319  }
320 
321  while (len--) {
322  *dst = dst[-4];
323  dst++;
324  }
325 }
326 
327 void av_memcpy_backptr(uint8_t *dst, int back, int cnt)
328 {
329  const uint8_t *src = &dst[-back];
330  if (!back)
331  return;
332 
333  if (back == 1) {
334  memset(dst, *src, cnt);
335  } else if (back == 2) {
336  fill16(dst, cnt);
337  } else if (back == 3) {
338  fill24(dst, cnt);
339  } else if (back == 4) {
340  fill32(dst, cnt);
341  } else {
342  if (cnt >= 16) {
343  int blocklen = back;
344  while (cnt > blocklen) {
345  memcpy(dst, src, blocklen);
346  dst += blocklen;
347  cnt -= blocklen;
348  blocklen <<= 1;
349  }
350  memcpy(dst, src, cnt);
351  return;
352  }
353  if (cnt >= 8) {
354  AV_COPY32U(dst, src);
355  AV_COPY32U(dst + 4, src + 4);
356  src += 8;
357  dst += 8;
358  cnt -= 8;
359  }
360  if (cnt >= 4) {
361  AV_COPY32U(dst, src);
362  src += 4;
363  dst += 4;
364  cnt -= 4;
365  }
366  if (cnt >= 2) {
367  AV_COPY16U(dst, src);
368  src += 2;
369  dst += 2;
370  cnt -= 2;
371  }
372  if (cnt)
373  *dst = *src;
374  }
375 }
376 
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
float v
const char * s
Definition: avisynth_c.h:668
void * av_realloc_f(void *ptr, size_t nelem, size_t elsize)
Allocate or reallocate a block of memory.
Definition: mem.c:168
memory handling functions
if max(w)>1 w=0.9 *w/max(w)
#define AV_RB24
external API header
void * av_realloc(void *ptr, size_t size)
Allocate or reallocate a block of memory.
Definition: mem.c:141
void av_max_alloc(size_t max)
Set the maximum size that may me allocated in one block.
Definition: mem.c:69
static void fill16(uint8_t *dst, int len)
Definition: mem.c:253
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
uint8_t
static void fill32(uint8_t *dst, int len)
Definition: mem.c:311
#define b
Definition: input.c:42
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
#define AV_COPY16U(d, s)
Definition: intreadwrite.h:545
const char * r
Definition: vf_curves.c:94
const char * arg
simple assert() macros that are a bit more flexible than ISO C assert().
void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem)
Add an element to a dynamic array.
Definition: mem.c:233
int size
static int av_size_mult(size_t a, size_t b, size_t *r)
Multiply two size_t values checking for overflow.
Definition: mem.h:204
#define AV_COPY32U(d, s)
Definition: intreadwrite.h:549
#define diff(a, as, b, bs)
Definition: vf_phase.c:80
const AVS_VideoInfo int align
Definition: avisynth_c.h:695
NULL
Definition: eval.c:55
AVS_Value src
Definition: avisynth_c.h:523
char * av_strdup(const char *s)
Duplicate the string s.
Definition: mem.c:220
#define AV_RN16(p)
Definition: intreadwrite.h:352
#define ALIGN
Definition: mem.c:60
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
static size_t max_alloc_size
Definition: mem.c:67
#define AV_RN32(p)
Definition: intreadwrite.h:356
void * av_calloc(size_t nmemb, size_t size)
Allocate a block of nmemb * size bytes with alignment suitable for all memory accesses (including vec...
Definition: mem.c:213
#define AV_RL24
static void fill24(uint8_t *dst, int len)
Definition: mem.c:271
#define AV_WN32(p, v)
Definition: intreadwrite.h:368
static double c[64]
int len
else dst[i][x+y *dst_stride[i]]
Definition: vf_mcdeint.c:160
static const struct twinvq_data tab
void av_memcpy_backptr(uint8_t *dst, int back, int cnt)
deliberately overlapping memcpy implementation
Definition: mem.c:327
MUSIC TECHNOLOGY GROUP UNIVERSITAT POMPEU FABRA Free Non Commercial Binary License Agreement UNIVERSITAT POMPEU OR INDICATING ACCEPTANCE BY SELECTING THE ACCEPT BUTTON ON ANY DOWNLOAD OR INSTALL YOU ACCEPT THE TERMS OF THE LICENSE SUMMARY TABLE Software MELODIA Melody Extraction vamp plug in Licensor Music Technology Group Universitat Pompeu Plaça de la Spain Permitted purposes Non commercial internal research and validation and educational purposes only All commercial uses in a production either internal or are prohibited by this license and require an additional commercial exploitation license TERMS AND CONDITIONS SOFTWARE Software means the software programs identified herein in binary any other machine readable any updates or error corrections provided by and any user programming guides and other documentation provided to you by UPF under this Agreement LICENSE Subject to the terms and conditions of this UPF grants you a royalty free