| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * This file is part of FFmpeg. | ||
| 3 | * | ||
| 4 | * FFmpeg is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU Lesser General Public | ||
| 6 | * License as published by the Free Software Foundation; either | ||
| 7 | * version 2.1 of the License, or (at your option) any later version. | ||
| 8 | * | ||
| 9 | * FFmpeg is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 12 | * Lesser General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU Lesser General Public | ||
| 15 | * License along with FFmpeg; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <stdatomic.h> | ||
| 20 | #include <stdint.h> | ||
| 21 | #include <string.h> | ||
| 22 | |||
| 23 | #include "avassert.h" | ||
| 24 | #include "buffer_internal.h" | ||
| 25 | #include "common.h" | ||
| 26 | #include "mem.h" | ||
| 27 | #include "sanitizer.h" | ||
| 28 | #include "thread.h" | ||
| 29 | |||
| 30 | 5358291 | static AVBufferRef *buffer_create(AVBuffer *buf, uint8_t *data, size_t size, | |
| 31 | void (*free)(void *opaque, uint8_t *data), | ||
| 32 | void *opaque, int flags) | ||
| 33 | { | ||
| 34 | 5358291 | AVBufferRef *ref = NULL; | |
| 35 | |||
| 36 | 5358291 | buf->data = data; | |
| 37 | 5358291 | buf->size = size; | |
| 38 |
2/2✓ Branch 0 taken 5348586 times.
✓ Branch 1 taken 9705 times.
|
5358291 | buf->free = free ? free : av_buffer_default_free; |
| 39 | 5358291 | buf->opaque = opaque; | |
| 40 | |||
| 41 | 5358291 | atomic_init(&buf->refcount, 1); | |
| 42 | |||
| 43 | 5358291 | buf->flags = flags; | |
| 44 | |||
| 45 | 5358291 | ref = av_mallocz(sizeof(*ref)); | |
| 46 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5358291 times.
|
5358291 | if (!ref) |
| 47 | ✗ | return NULL; | |
| 48 | |||
| 49 | 5358291 | ref->buffer = buf; | |
| 50 | 5358291 | ref->data = data; | |
| 51 | 5358291 | ref->size = size; | |
| 52 | |||
| 53 | 5358291 | return ref; | |
| 54 | } | ||
| 55 | |||
| 56 | 3885805 | AVBufferRef *av_buffer_create(uint8_t *data, size_t size, | |
| 57 | void (*free)(void *opaque, uint8_t *data), | ||
| 58 | void *opaque, int flags) | ||
| 59 | { | ||
| 60 | AVBufferRef *ret; | ||
| 61 | 3885805 | AVBuffer *buf = av_mallocz(sizeof(*buf)); | |
| 62 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3885805 times.
|
3885805 | if (!buf) |
| 63 | ✗ | return NULL; | |
| 64 | |||
| 65 | 3885805 | ret = buffer_create(buf, data, size, free, opaque, flags); | |
| 66 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3885805 times.
|
3885805 | if (!ret) { |
| 67 | ✗ | av_free(buf); | |
| 68 | ✗ | return NULL; | |
| 69 | } | ||
| 70 | 3885805 | return ret; | |
| 71 | } | ||
| 72 | |||
| 73 | 2227062 | void av_buffer_default_free(void *opaque, uint8_t *data) | |
| 74 | { | ||
| 75 | 2227062 | av_free(data); | |
| 76 | 2227062 | } | |
| 77 | |||
| 78 | 686421 | AVBufferRef *av_buffer_alloc(size_t size) | |
| 79 | { | ||
| 80 | 686421 | AVBufferRef *ret = NULL; | |
| 81 | 686421 | uint8_t *data = NULL; | |
| 82 | |||
| 83 | 686421 | data = av_malloc(size); | |
| 84 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 686414 times.
|
686421 | if (!data) |
| 85 | 7 | return NULL; | |
| 86 | |||
| 87 | 686414 | ret = av_buffer_create(data, size, av_buffer_default_free, NULL, 0); | |
| 88 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 686414 times.
|
686414 | if (!ret) |
| 89 | ✗ | av_freep(&data); | |
| 90 | |||
| 91 | 686414 | return ret; | |
| 92 | } | ||
| 93 | |||
| 94 | 23206 | AVBufferRef *av_buffer_allocz(size_t size) | |
| 95 | { | ||
| 96 | 23206 | AVBufferRef *ret = av_buffer_alloc(size); | |
| 97 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 23205 times.
|
23206 | if (!ret) |
| 98 | 1 | return NULL; | |
| 99 | |||
| 100 | 23205 | memset(ret->data, 0, size); | |
| 101 | 23205 | return ret; | |
| 102 | } | ||
| 103 | |||
| 104 | 5527387 | AVBufferRef *av_buffer_ref(const AVBufferRef *buf) | |
| 105 | { | ||
| 106 | 5527387 | AVBufferRef *ret = av_mallocz(sizeof(*ret)); | |
| 107 | |||
| 108 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5527386 times.
|
5527387 | if (!ret) |
| 109 | 1 | return NULL; | |
| 110 | |||
| 111 | 5527386 | *ret = *buf; | |
| 112 | |||
| 113 | 5527386 | atomic_fetch_add_explicit(&buf->buffer->refcount, 1, memory_order_relaxed); | |
| 114 | |||
| 115 | 5527386 | return ret; | |
| 116 | } | ||
| 117 | |||
| 118 | 10885677 | static void buffer_replace(AVBufferRef **dst, AVBufferRef **src) | |
| 119 | { | ||
| 120 | AVBuffer *b; | ||
| 121 | |||
| 122 | 10885677 | b = (*dst)->buffer; | |
| 123 | |||
| 124 |
2/2✓ Branch 0 taken 4641 times.
✓ Branch 1 taken 10881036 times.
|
10885677 | if (src) { |
| 125 | 4641 | **dst = **src; | |
| 126 | 4641 | av_freep(src); | |
| 127 | } else | ||
| 128 | 10881036 | av_freep(dst); | |
| 129 | |||
| 130 |
2/2✓ Branch 0 taken 5358291 times.
✓ Branch 1 taken 5527386 times.
|
10885677 | if (atomic_fetch_sub_explicit(&b->refcount, 1, memory_order_acq_rel) == 1) { |
| 131 | /* b->free below might already free the structure containing *b, | ||
| 132 | * so we have to read the flag now to avoid use-after-free. */ | ||
| 133 | 5358291 | int free_avbuffer = !(b->flags_internal & BUFFER_FLAG_NO_FREE); | |
| 134 | 5358291 | b->free(b->opaque, b->data); | |
| 135 |
2/2✓ Branch 0 taken 3885805 times.
✓ Branch 1 taken 1472486 times.
|
5358291 | if (free_avbuffer) |
| 136 | 3885805 | av_free(b); | |
| 137 | } | ||
| 138 | 10885677 | } | |
| 139 | |||
| 140 | 110213540 | void av_buffer_unref(AVBufferRef **buf) | |
| 141 | { | ||
| 142 |
3/4✓ Branch 0 taken 110213540 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 99332504 times.
✓ Branch 3 taken 10881036 times.
|
110213540 | if (!buf || !*buf) |
| 143 | 99332504 | return; | |
| 144 | |||
| 145 | 10881036 | buffer_replace(buf, NULL); | |
| 146 | } | ||
| 147 | |||
| 148 | 2803252 | int av_buffer_is_writable(const AVBufferRef *buf) | |
| 149 | { | ||
| 150 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2803251 times.
|
2803252 | if (buf->buffer->flags & AV_BUFFER_FLAG_READONLY) |
| 151 | 1 | return 0; | |
| 152 | |||
| 153 | 2803251 | return atomic_load(&buf->buffer->refcount) == 1; | |
| 154 | } | ||
| 155 | |||
| 156 | 1 | void *av_buffer_get_opaque(const AVBufferRef *buf) | |
| 157 | { | ||
| 158 | 1 | return buf->buffer->opaque; | |
| 159 | } | ||
| 160 | |||
| 161 | 145680 | int av_buffer_get_ref_count(const AVBufferRef *buf) | |
| 162 | { | ||
| 163 | 145680 | return atomic_load(&buf->buffer->refcount); | |
| 164 | } | ||
| 165 | |||
| 166 | 223 | int av_buffer_make_writable(AVBufferRef **pbuf) | |
| 167 | { | ||
| 168 | 223 | AVBufferRef *newbuf, *buf = *pbuf; | |
| 169 | |||
| 170 |
2/2✓ Branch 1 taken 26 times.
✓ Branch 2 taken 197 times.
|
223 | if (av_buffer_is_writable(buf)) |
| 171 | 26 | return 0; | |
| 172 | |||
| 173 | 197 | newbuf = av_buffer_alloc(buf->size); | |
| 174 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 197 times.
|
197 | if (!newbuf) |
| 175 | ✗ | return AVERROR(ENOMEM); | |
| 176 | |||
| 177 | 197 | memcpy(newbuf->data, buf->data, buf->size); | |
| 178 | |||
| 179 | 197 | buffer_replace(pbuf, &newbuf); | |
| 180 | |||
| 181 | 197 | return 0; | |
| 182 | } | ||
| 183 | |||
| 184 | 1539153 | int av_buffer_realloc(AVBufferRef **pbuf, size_t size) | |
| 185 | { | ||
| 186 | 1539153 | AVBufferRef *buf = *pbuf; | |
| 187 | uint8_t *tmp; | ||
| 188 | int ret; | ||
| 189 | |||
| 190 |
2/2✓ Branch 0 taken 1530899 times.
✓ Branch 1 taken 8254 times.
|
1539153 | if (!buf) { |
| 191 | /* allocate a new buffer with av_realloc(), so it will be reallocatable | ||
| 192 | * later */ | ||
| 193 | 1530899 | uint8_t *data = av_realloc(NULL, size); | |
| 194 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1530898 times.
|
1530899 | if (!data) |
| 195 | 1 | return AVERROR(ENOMEM); | |
| 196 | |||
| 197 | 1530898 | buf = av_buffer_create(data, size, av_buffer_default_free, NULL, 0); | |
| 198 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1530898 times.
|
1530898 | if (!buf) { |
| 199 | ✗ | av_freep(&data); | |
| 200 | ✗ | return AVERROR(ENOMEM); | |
| 201 | } | ||
| 202 | |||
| 203 | 1530898 | buf->buffer->flags_internal |= BUFFER_FLAG_REALLOCATABLE; | |
| 204 | 1530898 | *pbuf = buf; | |
| 205 | |||
| 206 | 1530898 | return 0; | |
| 207 |
2/2✓ Branch 0 taken 41 times.
✓ Branch 1 taken 8213 times.
|
8254 | } else if (buf->size == size) |
| 208 | 41 | return 0; | |
| 209 | |||
| 210 |
4/4✓ Branch 0 taken 3906 times.
✓ Branch 1 taken 4307 times.
✓ Branch 2 taken 3768 times.
✓ Branch 3 taken 138 times.
|
12119 | if (!(buf->buffer->flags_internal & BUFFER_FLAG_REALLOCATABLE) || |
| 211 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3768 times.
|
7674 | !av_buffer_is_writable(buf) || buf->data != buf->buffer->data) { |
| 212 | /* cannot realloc, allocate a new reallocable buffer and copy data */ | ||
| 213 | 4445 | AVBufferRef *new = NULL; | |
| 214 | |||
| 215 | 4445 | ret = av_buffer_realloc(&new, size); | |
| 216 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4444 times.
|
4445 | if (ret < 0) |
| 217 | 1 | return ret; | |
| 218 | |||
| 219 | 4444 | memcpy(new->data, buf->data, FFMIN(size, buf->size)); | |
| 220 | |||
| 221 | 4444 | buffer_replace(pbuf, &new); | |
| 222 | 4444 | return 0; | |
| 223 | } | ||
| 224 | |||
| 225 | 3768 | tmp = av_realloc(buf->buffer->data, size); | |
| 226 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3768 times.
|
3768 | if (!tmp) |
| 227 | ✗ | return AVERROR(ENOMEM); | |
| 228 | |||
| 229 | 3768 | buf->buffer->data = buf->data = tmp; | |
| 230 | 3768 | buf->buffer->size = buf->size = size; | |
| 231 | 3768 | return 0; | |
| 232 | } | ||
| 233 | |||
| 234 | 3373768 | int av_buffer_replace(AVBufferRef **pdst, const AVBufferRef *src) | |
| 235 | { | ||
| 236 | 3373768 | AVBufferRef *dst = *pdst; | |
| 237 | AVBufferRef *tmp; | ||
| 238 | |||
| 239 |
2/2✓ Branch 0 taken 324945 times.
✓ Branch 1 taken 3048823 times.
|
3373768 | if (!src) { |
| 240 | 324945 | av_buffer_unref(pdst); | |
| 241 | 324945 | return 0; | |
| 242 | } | ||
| 243 | |||
| 244 |
4/4✓ Branch 0 taken 12705 times.
✓ Branch 1 taken 3036118 times.
✓ Branch 2 taken 76 times.
✓ Branch 3 taken 12629 times.
|
3048823 | if (dst && dst->buffer == src->buffer) { |
| 245 | /* make sure the data pointers match */ | ||
| 246 | 76 | dst->data = src->data; | |
| 247 | 76 | dst->size = src->size; | |
| 248 | 76 | return 0; | |
| 249 | } | ||
| 250 | |||
| 251 | 3048747 | tmp = av_buffer_ref(src); | |
| 252 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3048747 times.
|
3048747 | if (!tmp) |
| 253 | ✗ | return AVERROR(ENOMEM); | |
| 254 | |||
| 255 | 3048747 | av_buffer_unref(pdst); | |
| 256 | 3048747 | *pdst = tmp; | |
| 257 | 3048747 | return 0; | |
| 258 | } | ||
| 259 | |||
| 260 | 1 | AVBufferPool *av_buffer_pool_init2(size_t size, void *opaque, | |
| 261 | AVBufferRef* (*alloc)(void *opaque, size_t size), | ||
| 262 | void (*pool_free)(void *opaque)) | ||
| 263 | { | ||
| 264 | 1 | AVBufferPool *pool = av_mallocz(sizeof(*pool)); | |
| 265 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (!pool) |
| 266 | ✗ | return NULL; | |
| 267 | |||
| 268 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if (ff_mutex_init(&pool->mutex, NULL)) { |
| 269 | ✗ | av_free(pool); | |
| 270 | ✗ | return NULL; | |
| 271 | } | ||
| 272 | |||
| 273 | 1 | pool->size = size; | |
| 274 | 1 | pool->opaque = opaque; | |
| 275 | 1 | pool->alloc2 = alloc; | |
| 276 | 1 | pool->alloc = av_buffer_alloc; // fallback | |
| 277 | 1 | pool->pool_free = pool_free; | |
| 278 | |||
| 279 | 1 | atomic_init(&pool->refcount, 1); | |
| 280 | |||
| 281 | 1 | return pool; | |
| 282 | } | ||
| 283 | |||
| 284 | 155236 | AVBufferPool *av_buffer_pool_init(size_t size, AVBufferRef* (*alloc)(size_t size)) | |
| 285 | { | ||
| 286 | 155236 | AVBufferPool *pool = av_mallocz(sizeof(*pool)); | |
| 287 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 155235 times.
|
155236 | if (!pool) |
| 288 | 1 | return NULL; | |
| 289 | |||
| 290 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 155235 times.
|
155235 | if (ff_mutex_init(&pool->mutex, NULL)) { |
| 291 | ✗ | av_free(pool); | |
| 292 | ✗ | return NULL; | |
| 293 | } | ||
| 294 | |||
| 295 | 155235 | pool->size = size; | |
| 296 |
2/2✓ Branch 0 taken 14013 times.
✓ Branch 1 taken 141222 times.
|
155235 | pool->alloc = alloc ? alloc : av_buffer_alloc; |
| 297 | |||
| 298 | 155235 | atomic_init(&pool->refcount, 1); | |
| 299 | |||
| 300 | 155235 | return pool; | |
| 301 | } | ||
| 302 | |||
| 303 | 310472 | static void buffer_pool_flush(AVBufferPool *pool) | |
| 304 | { | ||
| 305 |
2/2✓ Branch 0 taken 224873 times.
✓ Branch 1 taken 310472 times.
|
535345 | while (pool->pool) { |
| 306 | 224873 | BufferPoolEntry *buf = pool->pool; | |
| 307 | 224873 | pool->pool = buf->next; | |
| 308 | |||
| 309 | 224873 | if (buf->free == av_buffer_default_free) | |
| 310 | FF_ASAN_UNPOISON(buf->data, pool->size); | ||
| 311 | 224873 | buf->free(buf->opaque, buf->data); | |
| 312 | 224873 | av_freep(&buf); | |
| 313 | } | ||
| 314 | 310472 | } | |
| 315 | |||
| 316 | /* | ||
| 317 | * This function gets called when the pool has been uninited and | ||
| 318 | * all the buffers returned to it. | ||
| 319 | */ | ||
| 320 | 155236 | static void buffer_pool_free(AVBufferPool *pool) | |
| 321 | { | ||
| 322 | 155236 | buffer_pool_flush(pool); | |
| 323 | 155236 | ff_mutex_destroy(&pool->mutex); | |
| 324 | |||
| 325 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 155235 times.
|
155236 | if (pool->pool_free) |
| 326 | 1 | pool->pool_free(pool->opaque); | |
| 327 | |||
| 328 | 155236 | av_freep(&pool); | |
| 329 | 155236 | } | |
| 330 | |||
| 331 | 888395 | void av_buffer_pool_uninit(AVBufferPool **ppool) | |
| 332 | { | ||
| 333 | AVBufferPool *pool; | ||
| 334 | |||
| 335 |
3/4✓ Branch 0 taken 888395 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 733159 times.
✓ Branch 3 taken 155236 times.
|
888395 | if (!ppool || !*ppool) |
| 336 | 733159 | return; | |
| 337 | 155236 | pool = *ppool; | |
| 338 | 155236 | *ppool = NULL; | |
| 339 | |||
| 340 | 155236 | ff_mutex_lock(&pool->mutex); | |
| 341 | 155236 | buffer_pool_flush(pool); | |
| 342 | 155236 | ff_mutex_unlock(&pool->mutex); | |
| 343 | |||
| 344 |
2/2✓ Branch 0 taken 125003 times.
✓ Branch 1 taken 30233 times.
|
155236 | if (atomic_fetch_sub_explicit(&pool->refcount, 1, memory_order_acq_rel) == 1) |
| 345 | 125003 | buffer_pool_free(pool); | |
| 346 | } | ||
| 347 | |||
| 348 | 1697359 | static void pool_release_buffer(void *opaque, uint8_t *data) | |
| 349 | { | ||
| 350 | 1697359 | BufferPoolEntry *buf = opaque; | |
| 351 | 1697359 | AVBufferPool *pool = buf->pool; | |
| 352 | |||
| 353 | 1697359 | if (buf->free == av_buffer_default_free) | |
| 354 | FF_ASAN_POISON(buf->data, pool->size); | ||
| 355 | |||
| 356 | 1697359 | ff_mutex_lock(&pool->mutex); | |
| 357 | 1697359 | buf->next = pool->pool; | |
| 358 | 1697359 | pool->pool = buf; | |
| 359 | 1697359 | ff_mutex_unlock(&pool->mutex); | |
| 360 | |||
| 361 |
2/2✓ Branch 0 taken 30233 times.
✓ Branch 1 taken 1667126 times.
|
1697359 | if (atomic_fetch_sub_explicit(&pool->refcount, 1, memory_order_acq_rel) == 1) |
| 362 | 30233 | buffer_pool_free(pool); | |
| 363 | 1697359 | } | |
| 364 | |||
| 365 | /* allocate a new buffer and override its free() callback so that | ||
| 366 | * it is returned to the pool on free */ | ||
| 367 | 224873 | static AVBufferRef *pool_alloc_buffer(AVBufferPool *pool) | |
| 368 | { | ||
| 369 | BufferPoolEntry *buf; | ||
| 370 | AVBufferRef *ret; | ||
| 371 | |||
| 372 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 224873 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
224873 | av_assert0(pool->alloc || pool->alloc2); |
| 373 | |||
| 374 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 224872 times.
|
224873 | ret = pool->alloc2 ? pool->alloc2(pool->opaque, pool->size) : |
| 375 | 224872 | pool->alloc(pool->size); | |
| 376 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 224873 times.
|
224873 | if (!ret) |
| 377 | ✗ | return NULL; | |
| 378 | |||
| 379 | 224873 | buf = av_mallocz(sizeof(*buf)); | |
| 380 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 224873 times.
|
224873 | if (!buf) { |
| 381 | ✗ | av_buffer_unref(&ret); | |
| 382 | ✗ | return NULL; | |
| 383 | } | ||
| 384 | |||
| 385 | 224873 | buf->data = ret->buffer->data; | |
| 386 | 224873 | buf->opaque = ret->buffer->opaque; | |
| 387 | 224873 | buf->free = ret->buffer->free; | |
| 388 | 224873 | buf->pool = pool; | |
| 389 | |||
| 390 | 224873 | ret->buffer->opaque = buf; | |
| 391 | 224873 | ret->buffer->free = pool_release_buffer; | |
| 392 | |||
| 393 | 224873 | return ret; | |
| 394 | } | ||
| 395 | |||
| 396 | 1697359 | AVBufferRef *av_buffer_pool_get(AVBufferPool *pool) | |
| 397 | { | ||
| 398 | AVBufferRef *ret; | ||
| 399 | BufferPoolEntry *buf; | ||
| 400 | |||
| 401 | 1697359 | ff_mutex_lock(&pool->mutex); | |
| 402 | 1697359 | buf = pool->pool; | |
| 403 |
2/2✓ Branch 0 taken 1472486 times.
✓ Branch 1 taken 224873 times.
|
1697359 | if (buf) { |
| 404 | 1472486 | memset(&buf->buffer, 0, sizeof(buf->buffer)); | |
| 405 | 1472486 | ret = buffer_create(&buf->buffer, buf->data, pool->size, | |
| 406 | pool_release_buffer, buf, 0); | ||
| 407 |
1/2✓ Branch 0 taken 1472486 times.
✗ Branch 1 not taken.
|
1472486 | if (ret) { |
| 408 | 1472486 | pool->pool = buf->next; | |
| 409 | 1472486 | buf->next = NULL; | |
| 410 | 1472486 | buf->buffer.flags_internal |= BUFFER_FLAG_NO_FREE; | |
| 411 |
1/2✓ Branch 0 taken 1472486 times.
✗ Branch 1 not taken.
|
1472486 | if (buf->free == av_buffer_default_free) { |
| 412 | FF_ASAN_UNPOISON(buf->data, pool->size); | ||
| 413 | /* A pool that zeroes its buffers may be relied upon for never | ||
| 414 | * written regions staying zero, so only mark a reused buffer | ||
| 415 | * undefined when nothing was ever promised about its contents. */ | ||
| 416 |
3/4✓ Branch 0 taken 1472486 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1192298 times.
✓ Branch 3 taken 280188 times.
|
1472486 | if (!pool->alloc2 && pool->alloc == av_buffer_alloc) |
| 417 | 1192298 | FF_MEM_UNDEFINED(buf->data, pool->size); | |
| 418 | } | ||
| 419 | } | ||
| 420 | } else { | ||
| 421 | 224873 | ret = pool_alloc_buffer(pool); | |
| 422 | } | ||
| 423 | 1697359 | ff_mutex_unlock(&pool->mutex); | |
| 424 | |||
| 425 |
1/2✓ Branch 0 taken 1697359 times.
✗ Branch 1 not taken.
|
1697359 | if (ret) |
| 426 | 1697359 | atomic_fetch_add_explicit(&pool->refcount, 1, memory_order_relaxed); | |
| 427 | |||
| 428 | 1697359 | return ret; | |
| 429 | } | ||
| 430 | |||
| 431 | 1 | void *av_buffer_pool_buffer_get_opaque(const AVBufferRef *ref) | |
| 432 | { | ||
| 433 | 1 | BufferPoolEntry *buf = ref->buffer->opaque; | |
| 434 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | av_assert0(buf); |
| 435 | 1 | return buf->opaque; | |
| 436 | } | ||
| 437 |