FFmpeg
Loading...
Searching...
No Matches
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 <stdatomic.h>
35#include <string.h>
36#if HAVE_MALLOC_H
37#include <malloc.h>
38#endif
39
40#include "attributes.h"
41#include "avassert.h"
42#include "dynarray.h"
43#include "error.h"
44#include "internal.h"
45#include "intreadwrite.h"
46#include "macros.h"
47#include "mem.h"
48#include "sanitizer.h"
49
50#ifdef MALLOC_PREFIX
51
52#define malloc AV_JOIN(MALLOC_PREFIX, malloc)
53#define memalign AV_JOIN(MALLOC_PREFIX, memalign)
54#define posix_memalign AV_JOIN(MALLOC_PREFIX, posix_memalign)
55#define realloc AV_JOIN(MALLOC_PREFIX, realloc)
56#define free AV_JOIN(MALLOC_PREFIX, free)
57
58void *malloc(size_t size);
59void *memalign(size_t align, size_t size);
60int posix_memalign(void **ptr, size_t align, size_t size);
61void *realloc(void *ptr, size_t size);
62void free(void *ptr);
63
64#endif /* MALLOC_PREFIX */
65
66#define ALIGN (HAVE_SIMD_ALIGN_64 ? 64 : (HAVE_SIMD_ALIGN_32 ? 32 : 16))
67
68#define FF_MEMORY_POISON 0x2a
69
70static void poison_memory(void *ptr, size_t size)
71{
72#if CONFIG_MEMORY_POISONING
73 memset(ptr, FF_MEMORY_POISON, size);
74#endif
76}
77
78/* The LLVM ASan runtime for Windows does not intercept the _aligned_malloc
79 * family, so the alignment slack around a block stays addressable and small
80 * overflows go unnoticed, while the runtime shipped with Visual Studio does
81 * intercept it. Which one is linked cannot be told at compile time, so probe
82 * once whether the byte after an aligned allocation is poisoned and align by
83 * hand only when it is not. */
84#if HAVE_ASAN && HAVE_ALIGNED_MALLOC && !HAVE_POSIX_MEMALIGN && !HAVE_MEMALIGN
85#define ASAN_ALIGNED_ALLOC 1
86
87static int asan_aligned_alloc_needed(void)
88{
89 static atomic_int needed = -1;
91
92 if (ret < 0) {
93 uint8_t *p = _aligned_malloc(16, ALIGN);
94 int probed = !p || !__asan_address_is_poisoned(p + 16);
95 _aligned_free(p);
96 /* Every block must be freed by the allocator that made it, so the
97 * first probe to finish decides for all callers. */
98 if (atomic_compare_exchange_strong_explicit(&needed, &ret, probed,
101 ret = probed;
102 }
103 return ret;
104}
105
106typedef struct AsanAlignedHeader {
107 void *base;
108 size_t size;
109} AsanAlignedHeader;
110
111static void *asan_aligned_malloc(size_t size)
112{
113 AsanAlignedHeader *hdr;
114 uint8_t *base, *ptr;
115 size_t total;
116
117 if (size > SIZE_MAX - ALIGN - sizeof(*hdr))
118 return NULL;
119 total = size + ALIGN + sizeof(*hdr);
120 base = malloc(total);
121 if (!base)
122 return NULL;
123 ptr = (uint8_t *)FFALIGN((uintptr_t)base + sizeof(*hdr), ALIGN);
124 hdr = (AsanAlignedHeader *)ptr - 1;
125 hdr->base = base;
126 hdr->size = size;
127 FF_ASAN_POISON(base, ptr - base);
128 FF_ASAN_POISON(ptr + size, base + total - (ptr + size));
129 return ptr;
130}
131
132static AsanAlignedHeader *asan_aligned_header(void *ptr)
133{
134 AsanAlignedHeader *hdr = (AsanAlignedHeader *)ptr - 1;
135 FF_ASAN_UNPOISON(hdr, sizeof(*hdr));
136 return hdr;
137}
138
139static void asan_aligned_free(void *ptr)
140{
141 if (ptr)
142 free(asan_aligned_header(ptr)->base);
143}
144
145static void *asan_aligned_realloc(void *ptr, size_t size)
146{
147 AsanAlignedHeader *hdr;
148 void *ret;
149
150 if (!ptr)
151 return asan_aligned_malloc(size);
152 ret = asan_aligned_malloc(size);
153 if (!ret)
154 return NULL;
155 hdr = asan_aligned_header(ptr);
156 memcpy(ret, ptr, FFMIN(size, hdr->size));
157 free(hdr->base);
158 return ret;
159}
160#else
161#define ASAN_ALIGNED_ALLOC 0
162#endif
163
164/* NOTE: if you want to override these functions with your own
165 * implementations (not recommended) you have to link libav* as
166 * dynamic libraries and remove -Wl,-Bsymbolic from the linker flags.
167 * Note that this will cost performance. */
168
170
174
175static int size_mult(size_t a, size_t b, size_t *r)
176{
177 size_t t;
178
179#if (!defined(__INTEL_COMPILER) && AV_GCC_VERSION_AT_LEAST(5,1)) || AV_HAS_BUILTIN(__builtin_mul_overflow)
180 if (__builtin_mul_overflow(a, b, &t))
181 return AVERROR(EINVAL);
182#else
183 t = a * b;
184 /* Hack inspired from glibc: don't try the division if nelem and elsize
185 * are both less than sqrt(SIZE_MAX). */
186 if ((a | b) >= ((size_t)1 << (sizeof(size_t) * 4)) && a && t / a != b)
187 return AVERROR(EINVAL);
188#endif
189 *r = t;
190 return 0;
191}
192
193void *av_malloc(size_t size)
194{
195 void *ptr = NULL;
196
198 return NULL;
199
200#if ASAN_ALIGNED_ALLOC
201 if (asan_aligned_alloc_needed())
202 ptr = asan_aligned_malloc(size);
203 else
204 ptr = _aligned_malloc(size, ALIGN);
205#elif HAVE_POSIX_MEMALIGN
206 if (size) //OS X on SDK 10.6 has a broken posix_memalign implementation
207 if (posix_memalign(&ptr, ALIGN, size))
208 ptr = NULL;
209#elif HAVE_ALIGNED_MALLOC
210 ptr = _aligned_malloc(size, ALIGN);
211#elif HAVE_MEMALIGN
212#ifndef __DJGPP__
213 ptr = memalign(ALIGN, size);
214#else
215 ptr = memalign(size, ALIGN);
216#endif
217 /* Why 64?
218 * Indeed, we should align it:
219 * on 4 for 386
220 * on 16 for 486
221 * on 32 for 586, PPro - K6-III
222 * on 64 for K7 (maybe for P3 too).
223 * Because L1 and L2 caches are aligned on those values.
224 * But I don't want to code such logic here!
225 */
226 /* Why 32?
227 * For AVX ASM. SSE / NEON needs only 16.
228 * Why not larger? Because I did not see a difference in benchmarks ...
229 */
230 /* benchmarks with P3
231 * memalign(64) + 1 3071, 3051, 3032
232 * memalign(64) + 2 3051, 3032, 3041
233 * memalign(64) + 4 2911, 2896, 2915
234 * memalign(64) + 8 2545, 2554, 2550
235 * memalign(64) + 16 2543, 2572, 2563
236 * memalign(64) + 32 2546, 2545, 2571
237 * memalign(64) + 64 2570, 2533, 2558
238 *
239 * BTW, malloc seems to do 8-byte alignment by default here.
240 */
241#else
242 ptr = malloc(size);
243#endif
244 if(!ptr && !size) {
245 size = 1;
246 ptr= av_malloc(1);
247 }
248 if (ptr)
249 poison_memory(ptr, size);
250 return ptr;
251}
252
253void *av_realloc(void *ptr, size_t size)
254{
255 void *ret;
257 return NULL;
258
259#if ASAN_ALIGNED_ALLOC
260 if (asan_aligned_alloc_needed())
261 ret = asan_aligned_realloc(ptr, size + !size);
262 else
263 ret = _aligned_realloc(ptr, size + !size, ALIGN);
264#elif HAVE_ALIGNED_MALLOC
265 ret = _aligned_realloc(ptr, size + !size, ALIGN);
266#else
267 ret = realloc(ptr, size + !size);
268#endif
269 if (ret && !ptr)
270 poison_memory(ret, size);
271 return ret;
272}
273
274void *av_realloc_f(void *ptr, size_t nelem, size_t elsize)
275{
276 size_t size;
277 void *r;
278
279 if (size_mult(elsize, nelem, &size)) {
280 av_free(ptr);
281 return NULL;
282 }
283 r = av_realloc(ptr, size);
284 if (!r)
285 av_free(ptr);
286 return r;
287}
288
289int av_reallocp(void *ptr, size_t size)
290{
291 void *val;
292
293 if (!size) {
294 av_freep(ptr);
295 return 0;
296 }
297
298 memcpy(&val, ptr, sizeof(val));
300
301 if (!val) {
302 av_freep(ptr);
303 return AVERROR(ENOMEM);
304 }
305
306 memcpy(ptr, &val, sizeof(val));
307 return 0;
308}
309
310void *av_malloc_array(size_t nmemb, size_t size)
311{
312 size_t result;
313 if (size_mult(nmemb, size, &result) < 0)
314 return NULL;
315 return av_malloc(result);
316}
317
318void *av_realloc_array(void *ptr, size_t nmemb, size_t size)
319{
320 size_t result;
321 if (size_mult(nmemb, size, &result) < 0)
322 return NULL;
323 return av_realloc(ptr, result);
324}
325
326int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
327{
328 void *val;
329
330 memcpy(&val, ptr, sizeof(val));
331 val = av_realloc_f(val, nmemb, size);
332 memcpy(ptr, &val, sizeof(val));
333 if (!val && nmemb && size)
334 return AVERROR(ENOMEM);
335
336 return 0;
337}
338
339void av_free(void *ptr)
340{
341#if ASAN_ALIGNED_ALLOC
342 if (asan_aligned_alloc_needed())
343 asan_aligned_free(ptr);
344 else
345 _aligned_free(ptr);
346#elif HAVE_ALIGNED_MALLOC
347 _aligned_free(ptr);
348#else
349 free(ptr);
350#endif
351}
352
353void av_freep(void *arg)
354{
355 void *val;
356
357 memcpy(&val, arg, sizeof(val));
358 memcpy(arg, &(void *){ NULL }, sizeof(val));
359 av_free(val);
360}
361
362void *av_mallocz(size_t size)
363{
364 void *ptr = av_malloc(size);
365 if (ptr)
366 memset(ptr, 0, size);
367 return ptr;
368}
369
370void *av_calloc(size_t nmemb, size_t size)
371{
372 size_t result;
373 if (size_mult(nmemb, size, &result) < 0)
374 return NULL;
375 return av_mallocz(result);
376}
377
378char *av_strdup(const char *s)
379{
380 char *ptr = NULL;
381 if (s) {
382 size_t len = strlen(s) + 1;
383 ptr = av_realloc(NULL, len);
384 if (ptr)
385 memcpy(ptr, s, len);
386 }
387 return ptr;
388}
389
390char *av_strndup(const char *s, size_t len)
391{
392 if (!s)
393 return NULL;
394
395 const char *end = memchr(s, 0, len);
396 if (end)
397 len = end - s;
398
399 char *ret = av_realloc(NULL, len + 1);
400 if (!ret)
401 return NULL;
402
403 memcpy(ret, s, len);
404 ret[len] = 0;
405 return ret;
406}
407
408void *av_memdup(const void *p, size_t size)
409{
410 void *ptr = NULL;
411 if (p) {
412 ptr = av_malloc(size);
413 if (ptr)
414 memcpy(ptr, p, size);
415 }
416 return ptr;
417}
418
419int av_dynarray_add_nofree(void *tab_ptr, int *nb_ptr, void *elem)
420{
421 void **tab;
422 memcpy(&tab, tab_ptr, sizeof(tab));
423
424 FF_DYNARRAY_ADD(INT_MAX, sizeof(*tab), tab, *nb_ptr, {
425 tab[*nb_ptr] = elem;
426 memcpy(tab_ptr, &tab, sizeof(tab));
427 }, {
428 return AVERROR(ENOMEM);
429 });
430 return 0;
431}
432
433void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem)
434{
435 void **tab;
436 memcpy(&tab, tab_ptr, sizeof(tab));
437
438 FF_DYNARRAY_ADD(INT_MAX, sizeof(*tab), tab, *nb_ptr, {
439 tab[*nb_ptr] = elem;
440 memcpy(tab_ptr, &tab, sizeof(tab));
441 }, {
442 *nb_ptr = 0;
443 av_freep(tab_ptr);
444 });
445}
446
447void *av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size,
448 const uint8_t *elem_data)
449{
450 uint8_t *tab_elem_data = NULL;
451
452 FF_DYNARRAY_ADD(INT_MAX, elem_size, *tab_ptr, *nb_ptr, {
453 tab_elem_data = (uint8_t *)*tab_ptr + (*nb_ptr) * elem_size;
454 if (elem_data)
455 memcpy(tab_elem_data, elem_data, elem_size);
456 else
457 poison_memory(tab_elem_data, elem_size);
458 }, {
459 av_freep(tab_ptr);
460 *nb_ptr = 0;
461 });
462 return tab_elem_data;
463}
464
465static void fill16(uint8_t *dst, int len)
466{
467 uint32_t v = AV_RN16(dst - 2);
468
469 v |= v << 16;
470
471 while (len >= 4) {
472 AV_WN32(dst, v);
473 dst += 4;
474 len -= 4;
475 }
476
477 while (len--) {
478 *dst = dst[-2];
479 dst++;
480 }
481}
482
483static void fill24(uint8_t *dst, int len)
484{
485#if HAVE_BIGENDIAN
486 uint32_t v = AV_RB24(dst - 3);
487 uint32_t a = v << 8 | v >> 16;
488 uint32_t b = v << 16 | v >> 8;
489 uint32_t c = v << 24 | v;
490#else
491 uint32_t v = AV_RL24(dst - 3);
492 uint32_t a = v | v << 24;
493 uint32_t b = v >> 8 | v << 16;
494 uint32_t c = v >> 16 | v << 8;
495#endif
496
497 while (len >= 12) {
498 AV_WN32(dst, a);
499 AV_WN32(dst + 4, b);
500 AV_WN32(dst + 8, c);
501 dst += 12;
502 len -= 12;
503 }
504
505 if (len >= 4) {
506 AV_WN32(dst, a);
507 dst += 4;
508 len -= 4;
509 }
510
511 if (len >= 4) {
512 AV_WN32(dst, b);
513 dst += 4;
514 len -= 4;
515 }
516
517 while (len--) {
518 *dst = dst[-3];
519 dst++;
520 }
521}
522
523static void fill32(uint8_t *dst, int len)
524{
525 uint32_t v = AV_RN32(dst - 4);
526
527#if HAVE_FAST_64BIT
528 uint64_t v2= v + ((uint64_t)v<<32);
529 while (len >= 32) {
530 AV_WN64(dst , v2);
531 AV_WN64(dst+ 8, v2);
532 AV_WN64(dst+16, v2);
533 AV_WN64(dst+24, v2);
534 dst += 32;
535 len -= 32;
536 }
537#endif
538
539 while (len >= 4) {
540 AV_WN32(dst, v);
541 dst += 4;
542 len -= 4;
543 }
544
545 while (len--) {
546 *dst = dst[-4];
547 dst++;
548 }
549}
550
551void av_memcpy_backptr(uint8_t *dst, int back, int cnt)
552{
553 const uint8_t *src = &dst[-back];
554 if (!back)
555 return;
556
557 if (back == 1) {
558 memset(dst, *src, cnt);
559 } else if (back == 2) {
560 fill16(dst, cnt);
561 } else if (back == 3) {
562 fill24(dst, cnt);
563 } else if (back == 4) {
564 fill32(dst, cnt);
565 } else {
566 if (cnt >= 16) {
567 int blocklen = back;
568 while (cnt > blocklen) {
569 memcpy(dst, src, blocklen);
570 dst += blocklen;
571 cnt -= blocklen;
572 blocklen <<= 1;
573 }
574 memcpy(dst, src, cnt);
575 return;
576 }
577 if (cnt >= 8) {
579 AV_COPY32U(dst + 4, src + 4);
580 src += 8;
581 dst += 8;
582 cnt -= 8;
583 }
584 if (cnt >= 4) {
586 src += 4;
587 dst += 4;
588 cnt -= 4;
589 }
590 if (cnt >= 2) {
592 src += 2;
593 dst += 2;
594 cnt -= 2;
595 }
596 if (cnt)
597 *dst = *src;
598 }
599}
600
601void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
602{
603 size_t max_size;
604
605 if (min_size <= *size)
606 return ptr;
607
609 /* *size is an unsigned, so the real maximum is <= UINT_MAX. */
610 max_size = FFMIN(max_size, UINT_MAX);
611
612 if (min_size > max_size) {
613 *size = 0;
614 return NULL;
615 }
616
617 min_size = FFMIN(max_size, FFMAX(min_size + min_size / 16 + 32, min_size));
618
619 ptr = av_realloc(ptr, min_size);
620 /* we could set this to the unmodified min_size but this is safer
621 * if the user lost the ptr and uses NULL now
622 */
623 if (!ptr)
624 min_size = 0;
625
626 *size = min_size;
627
628 return ptr;
629}
630
631static inline void fast_malloc(void *ptr, unsigned int *size, size_t min_size, int zero_realloc)
632{
633 size_t max_size;
634 void *val;
635
636 memcpy(&val, ptr, sizeof(val));
637 if (min_size <= *size) {
638 av_assert0(val || !min_size);
639 return;
640 }
641
643 /* *size is an unsigned, so the real maximum is <= UINT_MAX. */
644 max_size = FFMIN(max_size, UINT_MAX);
645
646 if (min_size > max_size) {
647 av_freep(ptr);
648 *size = 0;
649 return;
650 }
651 min_size = FFMIN(max_size, FFMAX(min_size + min_size / 16 + 32, min_size));
652 av_freep(ptr);
653 val = zero_realloc ? av_mallocz(min_size) : av_malloc(min_size);
654 memcpy(ptr, &val, sizeof(val));
655 if (!val)
656 min_size = 0;
657 *size = min_size;
658 return;
659}
660
661void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size)
662{
663 fast_malloc(ptr, size, min_size, 0);
664}
665
666void av_fast_mallocz(void *ptr, unsigned int *size, size_t min_size)
667{
668 fast_malloc(ptr, size, min_size, 1);
669}
670
671int av_size_mult(size_t a, size_t b, size_t *r)
672{
673 return size_mult(a, b, r);
674}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
static double val(void *priv, double ch)
Definition aeval.c:77
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
static const uint8_t *BS_FUNC align(BSCTX *bc)
Skip bits to a byte boundary.
#define s(width, name)
Definition cbs_vp9.c:198
#define NULL
Definition coverity.c:32
#define max(a, b)
#define FF_DYNARRAY_ADD(av_size_max, av_elt_size, av_array, av_size, av_success, av_failure)
Add an element to a dynamic array.
Definition dynarray.h:45
error code definitions
#define AVERROR(e)
Definition error.h:45
void * av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, const uint8_t *elem_data)
Add an element of size elem_size to a dynamic array.
Definition mem.c:447
void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem)
Add the pointer to an element to a dynamic array.
Definition mem.c:433
int av_dynarray_add_nofree(void *tab_ptr, int *nb_ptr, void *elem)
Add an element to a dynamic array.
Definition mem.c:419
void av_fast_mallocz(void *ptr, unsigned int *size, size_t min_size)
Allocate and clear a buffer, reusing the given one if large enough.
Definition mem.c:666
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition mem.c:601
char * av_strndup(const char *s, size_t len)
Duplicate a substring of a string.
Definition mem.c:390
void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size)
Allocate a buffer, reusing the given one if large enough.
Definition mem.c:661
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition mem.c:318
void av_memcpy_backptr(uint8_t *dst, int back, int cnt)
Overlapping memcpy() implementation.
Definition mem.c:551
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition mem.c:289
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Definition mem.c:408
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition mem.c:326
void av_max_alloc(size_t max)
Set the maximum size that may be allocated in one block.
Definition mem.c:171
int av_size_mult(size_t a, size_t b, size_t *r)
Multiply two size_t values checking for overflow.
Definition mem.c:671
int a
#define ALIGN
Definition hashtable.c:32
#define r
Definition input.c:42
#define b
Definition input.c:43
#define AV_COPY16U(d, s)
#define AV_RL24(x)
#define AV_WN32(p, v)
#define AV_RN32(p)
#define AV_COPY32U(d, s)
#define AV_WN64(p, v)
#define AV_RN16(p)
#define AV_RB24(x)
const char * arg
Definition jacosubdec.c:65
Macro definitions for various function/variable attributes.
common internal API header
Utility Preprocessor macros.
#define FFMIN(a, b)
Definition macros.h:49
#define FFMAX(a, b)
Definition macros.h:47
#define FFALIGN(x, a)
Definition macros.h:78
#define FF_MEMORY_POISON
Definition mem.c:68
static atomic_size_t max_alloc_size
Definition mem.c:169
static void fill32(uint8_t *dst, int len)
Definition mem.c:523
static void poison_memory(void *ptr, size_t size)
Definition mem.c:70
static int size_mult(size_t a, size_t b, size_t *r)
Definition mem.c:175
static void fill16(uint8_t *dst, int len)
Definition mem.c:465
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:370
static void fill24(uint8_t *dst, int len)
Definition mem.c:483
static void fast_malloc(void *ptr, unsigned int *size, size_t min_size, int zero_realloc)
Definition mem.c:631
Memory handling functions.
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
#define av_strdup(s)
Definition ops_static.c:55
#define av_realloc(p, s)
Definition ops_static.c:54
#define av_malloc(s)
Definition ops_static.c:52
#define FF_ASAN_POISON(ptr, size)
Definition sanitizer.h:55
#define FF_MEM_UNDEFINED(ptr, size)
Definition sanitizer.h:67
#define FF_ASAN_UNPOISON(ptr, size)
Definition sanitizer.h:56
@ memory_order_relaxed
Definition stdatomic.h:29
int atomic_int
Definition stdatomic.h:63
#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure)
Definition stdatomic.h:274
#define atomic_load_explicit(object, order)
Definition stdatomic.h:247
size_t atomic_size_t
Definition stdatomic.h:91
#define atomic_store_explicit(object, desired, order)
Definition stdatomic.h:253
#define av_free(p)
#define av_malloc_array(a, b)
#define av_mallocz(s)
#define av_realloc_f(p, o, n)
#define av_freep(p)
#define src
Definition vp8dsp.c:248
int size
static const struct twinvq_data tab
int len
uint8_t base
Definition vp3data.h:128
static double c[64]