| 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 "thread.h" | ||
| 28 | |||
| 29 | 4522111 | static AVBufferRef *buffer_create(AVBuffer *buf, uint8_t *data, size_t size, | |
| 30 | void (*free)(void *opaque, uint8_t *data), | ||
| 31 | void *opaque, int flags) | ||
| 32 | { | ||
| 33 | 4522111 | AVBufferRef *ref = NULL; | |
| 34 | |||
| 35 | 4522111 | buf->data = data; | |
| 36 | 4522111 | buf->size = size; | |
| 37 |
2/2✓ Branch 0 taken 4512671 times.
✓ Branch 1 taken 9440 times.
|
4522111 | buf->free = free ? free : av_buffer_default_free; |
| 38 | 4522111 | buf->opaque = opaque; | |
| 39 | |||
| 40 | 4522111 | atomic_init(&buf->refcount, 1); | |
| 41 | |||
| 42 | 4522111 | buf->flags = flags; | |
| 43 | |||
| 44 | 4522111 | ref = av_mallocz(sizeof(*ref)); | |
| 45 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4522111 times.
|
4522111 | if (!ref) |
| 46 | ✗ | return NULL; | |
| 47 | |||
| 48 | 4522111 | ref->buffer = buf; | |
| 49 | 4522111 | ref->data = data; | |
| 50 | 4522111 | ref->size = size; | |
| 51 | |||
| 52 | 4522111 | return ref; | |
| 53 | } | ||
| 54 | |||
| 55 | 3331066 | AVBufferRef *av_buffer_create(uint8_t *data, size_t size, | |
| 56 | void (*free)(void *opaque, uint8_t *data), | ||
| 57 | void *opaque, int flags) | ||
| 58 | { | ||
| 59 | AVBufferRef *ret; | ||
| 60 | 3331066 | AVBuffer *buf = av_mallocz(sizeof(*buf)); | |
| 61 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3331066 times.
|
3331066 | if (!buf) |
| 62 | ✗ | return NULL; | |
| 63 | |||
| 64 | 3331066 | ret = buffer_create(buf, data, size, free, opaque, flags); | |
| 65 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3331066 times.
|
3331066 | if (!ret) { |
| 66 | ✗ | av_free(buf); | |
| 67 | ✗ | return NULL; | |
| 68 | } | ||
| 69 | 3331066 | return ret; | |
| 70 | } | ||
| 71 | |||
| 72 | 1878202 | void av_buffer_default_free(void *opaque, uint8_t *data) | |
| 73 | { | ||
| 74 | 1878202 | av_free(data); | |
| 75 | 1878202 | } | |
| 76 | |||
| 77 | 475116 | AVBufferRef *av_buffer_alloc(size_t size) | |
| 78 | { | ||
| 79 | 475116 | AVBufferRef *ret = NULL; | |
| 80 | 475116 | uint8_t *data = NULL; | |
| 81 | |||
| 82 | 475116 | data = av_malloc(size); | |
| 83 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 475116 times.
|
475116 | if (!data) |
| 84 | ✗ | return NULL; | |
| 85 | |||
| 86 | 475116 | ret = av_buffer_create(data, size, av_buffer_default_free, NULL, 0); | |
| 87 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 475116 times.
|
475116 | if (!ret) |
| 88 | ✗ | av_freep(&data); | |
| 89 | |||
| 90 | 475116 | return ret; | |
| 91 | } | ||
| 92 | |||
| 93 | 3145 | AVBufferRef *av_buffer_allocz(size_t size) | |
| 94 | { | ||
| 95 | 3145 | AVBufferRef *ret = av_buffer_alloc(size); | |
| 96 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3145 times.
|
3145 | if (!ret) |
| 97 | ✗ | return NULL; | |
| 98 | |||
| 99 | 3145 | memset(ret->data, 0, size); | |
| 100 | 3145 | return ret; | |
| 101 | } | ||
| 102 | |||
| 103 | 4949892 | AVBufferRef *av_buffer_ref(const AVBufferRef *buf) | |
| 104 | { | ||
| 105 | 4949892 | AVBufferRef *ret = av_mallocz(sizeof(*ret)); | |
| 106 | |||
| 107 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4949892 times.
|
4949892 | if (!ret) |
| 108 | ✗ | return NULL; | |
| 109 | |||
| 110 | 4949892 | *ret = *buf; | |
| 111 | |||
| 112 | 4949892 | atomic_fetch_add_explicit(&buf->buffer->refcount, 1, memory_order_relaxed); | |
| 113 | |||
| 114 | 4949892 | return ret; | |
| 115 | } | ||
| 116 | |||
| 117 | 9472003 | static void buffer_replace(AVBufferRef **dst, AVBufferRef **src) | |
| 118 | { | ||
| 119 | AVBuffer *b; | ||
| 120 | |||
| 121 | 9472003 | b = (*dst)->buffer; | |
| 122 | |||
| 123 |
2/2✓ Branch 0 taken 6408 times.
✓ Branch 1 taken 9465595 times.
|
9472003 | if (src) { |
| 124 | 6408 | **dst = **src; | |
| 125 | 6408 | av_freep(src); | |
| 126 | } else | ||
| 127 | 9465595 | av_freep(dst); | |
| 128 | |||
| 129 |
2/2✓ Branch 0 taken 4522111 times.
✓ Branch 1 taken 4949892 times.
|
9472003 | if (atomic_fetch_sub_explicit(&b->refcount, 1, memory_order_acq_rel) == 1) { |
| 130 | /* b->free below might already free the structure containing *b, | ||
| 131 | * so we have to read the flag now to avoid use-after-free. */ | ||
| 132 | 4522111 | int free_avbuffer = !(b->flags_internal & BUFFER_FLAG_NO_FREE); | |
| 133 | 4522111 | b->free(b->opaque, b->data); | |
| 134 |
2/2✓ Branch 0 taken 3331066 times.
✓ Branch 1 taken 1191045 times.
|
4522111 | if (free_avbuffer) |
| 135 | 3331066 | av_free(b); | |
| 136 | } | ||
| 137 | 9472003 | } | |
| 138 | |||
| 139 | 96259360 | void av_buffer_unref(AVBufferRef **buf) | |
| 140 | { | ||
| 141 |
3/4✓ Branch 0 taken 96259360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 86793765 times.
✓ Branch 3 taken 9465595 times.
|
96259360 | if (!buf || !*buf) |
| 142 | 86793765 | return; | |
| 143 | |||
| 144 | 9465595 | buffer_replace(buf, NULL); | |
| 145 | } | ||
| 146 | |||
| 147 | 2454968 | int av_buffer_is_writable(const AVBufferRef *buf) | |
| 148 | { | ||
| 149 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2454968 times.
|
2454968 | if (buf->buffer->flags & AV_BUFFER_FLAG_READONLY) |
| 150 | ✗ | return 0; | |
| 151 | |||
| 152 | 2454968 | return atomic_load(&buf->buffer->refcount) == 1; | |
| 153 | } | ||
| 154 | |||
| 155 | ✗ | void *av_buffer_get_opaque(const AVBufferRef *buf) | |
| 156 | { | ||
| 157 | ✗ | return buf->buffer->opaque; | |
| 158 | } | ||
| 159 | |||
| 160 | 141380 | int av_buffer_get_ref_count(const AVBufferRef *buf) | |
| 161 | { | ||
| 162 | 141380 | return atomic_load(&buf->buffer->refcount); | |
| 163 | } | ||
| 164 | |||
| 165 | 222 | int av_buffer_make_writable(AVBufferRef **pbuf) | |
| 166 | { | ||
| 167 | 222 | AVBufferRef *newbuf, *buf = *pbuf; | |
| 168 | |||
| 169 |
2/2✓ Branch 1 taken 26 times.
✓ Branch 2 taken 196 times.
|
222 | if (av_buffer_is_writable(buf)) |
| 170 | 26 | return 0; | |
| 171 | |||
| 172 | 196 | newbuf = av_buffer_alloc(buf->size); | |
| 173 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 196 times.
|
196 | if (!newbuf) |
| 174 | ✗ | return AVERROR(ENOMEM); | |
| 175 | |||
| 176 | 196 | memcpy(newbuf->data, buf->data, buf->size); | |
| 177 | |||
| 178 | 196 | buffer_replace(pbuf, &newbuf); | |
| 179 | |||
| 180 | 196 | return 0; | |
| 181 | } | ||
| 182 | |||
| 183 | 1403576 | int av_buffer_realloc(AVBufferRef **pbuf, size_t size) | |
| 184 | { | ||
| 185 | 1403576 | AVBufferRef *buf = *pbuf; | |
| 186 | uint8_t *tmp; | ||
| 187 | int ret; | ||
| 188 | |||
| 189 |
2/2✓ Branch 0 taken 1393601 times.
✓ Branch 1 taken 9975 times.
|
1403576 | if (!buf) { |
| 190 | /* allocate a new buffer with av_realloc(), so it will be reallocatable | ||
| 191 | * later */ | ||
| 192 | 1393601 | uint8_t *data = av_realloc(NULL, size); | |
| 193 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1393601 times.
|
1393601 | if (!data) |
| 194 | ✗ | return AVERROR(ENOMEM); | |
| 195 | |||
| 196 | 1393601 | buf = av_buffer_create(data, size, av_buffer_default_free, NULL, 0); | |
| 197 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1393601 times.
|
1393601 | if (!buf) { |
| 198 | ✗ | av_freep(&data); | |
| 199 | ✗ | return AVERROR(ENOMEM); | |
| 200 | } | ||
| 201 | |||
| 202 | 1393601 | buf->buffer->flags_internal |= BUFFER_FLAG_REALLOCATABLE; | |
| 203 | 1393601 | *pbuf = buf; | |
| 204 | |||
| 205 | 1393601 | return 0; | |
| 206 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9975 times.
|
9975 | } else if (buf->size == size) |
| 207 | ✗ | return 0; | |
| 208 | |||
| 209 |
4/4✓ Branch 0 taken 3901 times.
✓ Branch 1 taken 6074 times.
✓ Branch 2 taken 3763 times.
✓ Branch 3 taken 138 times.
|
13876 | if (!(buf->buffer->flags_internal & BUFFER_FLAG_REALLOCATABLE) || |
| 210 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3763 times.
|
7664 | !av_buffer_is_writable(buf) || buf->data != buf->buffer->data) { |
| 211 | /* cannot realloc, allocate a new reallocable buffer and copy data */ | ||
| 212 | 6212 | AVBufferRef *new = NULL; | |
| 213 | |||
| 214 | 6212 | ret = av_buffer_realloc(&new, size); | |
| 215 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6212 times.
|
6212 | if (ret < 0) |
| 216 | ✗ | return ret; | |
| 217 | |||
| 218 | 6212 | memcpy(new->data, buf->data, FFMIN(size, buf->size)); | |
| 219 | |||
| 220 | 6212 | buffer_replace(pbuf, &new); | |
| 221 | 6212 | return 0; | |
| 222 | } | ||
| 223 | |||
| 224 | 3763 | tmp = av_realloc(buf->buffer->data, size); | |
| 225 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3763 times.
|
3763 | if (!tmp) |
| 226 | ✗ | return AVERROR(ENOMEM); | |
| 227 | |||
| 228 | 3763 | buf->buffer->data = buf->data = tmp; | |
| 229 | 3763 | buf->buffer->size = buf->size = size; | |
| 230 | 3763 | return 0; | |
| 231 | } | ||
| 232 | |||
| 233 | 2902960 | int av_buffer_replace(AVBufferRef **pdst, const AVBufferRef *src) | |
| 234 | { | ||
| 235 | 2902960 | AVBufferRef *dst = *pdst; | |
| 236 | AVBufferRef *tmp; | ||
| 237 | |||
| 238 |
2/2✓ Branch 0 taken 240034 times.
✓ Branch 1 taken 2662926 times.
|
2902960 | if (!src) { |
| 239 | 240034 | av_buffer_unref(pdst); | |
| 240 | 240034 | return 0; | |
| 241 | } | ||
| 242 | |||
| 243 |
4/4✓ Branch 0 taken 12661 times.
✓ Branch 1 taken 2650265 times.
✓ Branch 2 taken 75 times.
✓ Branch 3 taken 12586 times.
|
2662926 | if (dst && dst->buffer == src->buffer) { |
| 244 | /* make sure the data pointers match */ | ||
| 245 | 75 | dst->data = src->data; | |
| 246 | 75 | dst->size = src->size; | |
| 247 | 75 | return 0; | |
| 248 | } | ||
| 249 | |||
| 250 | 2662851 | tmp = av_buffer_ref(src); | |
| 251 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2662851 times.
|
2662851 | if (!tmp) |
| 252 | ✗ | return AVERROR(ENOMEM); | |
| 253 | |||
| 254 | 2662851 | av_buffer_unref(pdst); | |
| 255 | 2662851 | *pdst = tmp; | |
| 256 | 2662851 | return 0; | |
| 257 | } | ||
| 258 | |||
| 259 | ✗ | AVBufferPool *av_buffer_pool_init2(size_t size, void *opaque, | |
| 260 | AVBufferRef* (*alloc)(void *opaque, size_t size), | ||
| 261 | void (*pool_free)(void *opaque)) | ||
| 262 | { | ||
| 263 | ✗ | AVBufferPool *pool = av_mallocz(sizeof(*pool)); | |
| 264 | ✗ | if (!pool) | |
| 265 | ✗ | return NULL; | |
| 266 | |||
| 267 | ✗ | if (ff_mutex_init(&pool->mutex, NULL)) { | |
| 268 | ✗ | av_free(pool); | |
| 269 | ✗ | return NULL; | |
| 270 | } | ||
| 271 | |||
| 272 | ✗ | pool->size = size; | |
| 273 | ✗ | pool->opaque = opaque; | |
| 274 | ✗ | pool->alloc2 = alloc; | |
| 275 | ✗ | pool->alloc = av_buffer_alloc; // fallback | |
| 276 | ✗ | pool->pool_free = pool_free; | |
| 277 | |||
| 278 | ✗ | atomic_init(&pool->refcount, 1); | |
| 279 | |||
| 280 | ✗ | return pool; | |
| 281 | } | ||
| 282 | |||
| 283 | 54229 | AVBufferPool *av_buffer_pool_init(size_t size, AVBufferRef* (*alloc)(size_t size)) | |
| 284 | { | ||
| 285 | 54229 | AVBufferPool *pool = av_mallocz(sizeof(*pool)); | |
| 286 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 54229 times.
|
54229 | if (!pool) |
| 287 | ✗ | return NULL; | |
| 288 | |||
| 289 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 54229 times.
|
54229 | if (ff_mutex_init(&pool->mutex, NULL)) { |
| 290 | ✗ | av_free(pool); | |
| 291 | ✗ | return NULL; | |
| 292 | } | ||
| 293 | |||
| 294 | 54229 | pool->size = size; | |
| 295 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 54229 times.
|
54229 | pool->alloc = alloc ? alloc : av_buffer_alloc; |
| 296 | |||
| 297 | 54229 | atomic_init(&pool->refcount, 1); | |
| 298 | |||
| 299 | 54229 | return pool; | |
| 300 | } | ||
| 301 | |||
| 302 | 108458 | static void buffer_pool_flush(AVBufferPool *pool) | |
| 303 | { | ||
| 304 |
2/2✓ Branch 0 taken 134793 times.
✓ Branch 1 taken 108458 times.
|
243251 | while (pool->pool) { |
| 305 | 134793 | BufferPoolEntry *buf = pool->pool; | |
| 306 | 134793 | pool->pool = buf->next; | |
| 307 | |||
| 308 | 134793 | buf->free(buf->opaque, buf->data); | |
| 309 | 134793 | av_freep(&buf); | |
| 310 | } | ||
| 311 | 108458 | } | |
| 312 | |||
| 313 | /* | ||
| 314 | * This function gets called when the pool has been uninited and | ||
| 315 | * all the buffers returned to it. | ||
| 316 | */ | ||
| 317 | 54229 | static void buffer_pool_free(AVBufferPool *pool) | |
| 318 | { | ||
| 319 | 54229 | buffer_pool_flush(pool); | |
| 320 | 54229 | ff_mutex_destroy(&pool->mutex); | |
| 321 | |||
| 322 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 54229 times.
|
54229 | if (pool->pool_free) |
| 323 | ✗ | pool->pool_free(pool->opaque); | |
| 324 | |||
| 325 | 54229 | av_freep(&pool); | |
| 326 | 54229 | } | |
| 327 | |||
| 328 | 114956 | void av_buffer_pool_uninit(AVBufferPool **ppool) | |
| 329 | { | ||
| 330 | AVBufferPool *pool; | ||
| 331 | |||
| 332 |
3/4✓ Branch 0 taken 114956 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60727 times.
✓ Branch 3 taken 54229 times.
|
114956 | if (!ppool || !*ppool) |
| 333 | 60727 | return; | |
| 334 | 54229 | pool = *ppool; | |
| 335 | 54229 | *ppool = NULL; | |
| 336 | |||
| 337 | 54229 | ff_mutex_lock(&pool->mutex); | |
| 338 | 54229 | buffer_pool_flush(pool); | |
| 339 | 54229 | ff_mutex_unlock(&pool->mutex); | |
| 340 | |||
| 341 |
2/2✓ Branch 0 taken 27135 times.
✓ Branch 1 taken 27094 times.
|
54229 | if (atomic_fetch_sub_explicit(&pool->refcount, 1, memory_order_acq_rel) == 1) |
| 342 | 27135 | buffer_pool_free(pool); | |
| 343 | } | ||
| 344 | |||
| 345 | 1325838 | static void pool_release_buffer(void *opaque, uint8_t *data) | |
| 346 | { | ||
| 347 | 1325838 | BufferPoolEntry *buf = opaque; | |
| 348 | 1325838 | AVBufferPool *pool = buf->pool; | |
| 349 | |||
| 350 | 1325838 | ff_mutex_lock(&pool->mutex); | |
| 351 | 1325838 | buf->next = pool->pool; | |
| 352 | 1325838 | pool->pool = buf; | |
| 353 | 1325838 | ff_mutex_unlock(&pool->mutex); | |
| 354 | |||
| 355 |
2/2✓ Branch 0 taken 27094 times.
✓ Branch 1 taken 1298744 times.
|
1325838 | if (atomic_fetch_sub_explicit(&pool->refcount, 1, memory_order_acq_rel) == 1) |
| 356 | 27094 | buffer_pool_free(pool); | |
| 357 | 1325838 | } | |
| 358 | |||
| 359 | /* allocate a new buffer and override its free() callback so that | ||
| 360 | * it is returned to the pool on free */ | ||
| 361 | 134793 | static AVBufferRef *pool_alloc_buffer(AVBufferPool *pool) | |
| 362 | { | ||
| 363 | BufferPoolEntry *buf; | ||
| 364 | AVBufferRef *ret; | ||
| 365 | |||
| 366 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 134793 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
134793 | av_assert0(pool->alloc || pool->alloc2); |
| 367 | |||
| 368 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 134793 times.
|
134793 | ret = pool->alloc2 ? pool->alloc2(pool->opaque, pool->size) : |
| 369 | 134793 | pool->alloc(pool->size); | |
| 370 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 134793 times.
|
134793 | if (!ret) |
| 371 | ✗ | return NULL; | |
| 372 | |||
| 373 | 134793 | buf = av_mallocz(sizeof(*buf)); | |
| 374 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 134793 times.
|
134793 | if (!buf) { |
| 375 | ✗ | av_buffer_unref(&ret); | |
| 376 | ✗ | return NULL; | |
| 377 | } | ||
| 378 | |||
| 379 | 134793 | buf->data = ret->buffer->data; | |
| 380 | 134793 | buf->opaque = ret->buffer->opaque; | |
| 381 | 134793 | buf->free = ret->buffer->free; | |
| 382 | 134793 | buf->pool = pool; | |
| 383 | |||
| 384 | 134793 | ret->buffer->opaque = buf; | |
| 385 | 134793 | ret->buffer->free = pool_release_buffer; | |
| 386 | |||
| 387 | 134793 | return ret; | |
| 388 | } | ||
| 389 | |||
| 390 | 1325838 | AVBufferRef *av_buffer_pool_get(AVBufferPool *pool) | |
| 391 | { | ||
| 392 | AVBufferRef *ret; | ||
| 393 | BufferPoolEntry *buf; | ||
| 394 | |||
| 395 | 1325838 | ff_mutex_lock(&pool->mutex); | |
| 396 | 1325838 | buf = pool->pool; | |
| 397 |
2/2✓ Branch 0 taken 1191045 times.
✓ Branch 1 taken 134793 times.
|
1325838 | if (buf) { |
| 398 | 1191045 | memset(&buf->buffer, 0, sizeof(buf->buffer)); | |
| 399 | 1191045 | ret = buffer_create(&buf->buffer, buf->data, pool->size, | |
| 400 | pool_release_buffer, buf, 0); | ||
| 401 |
1/2✓ Branch 0 taken 1191045 times.
✗ Branch 1 not taken.
|
1191045 | if (ret) { |
| 402 | 1191045 | pool->pool = buf->next; | |
| 403 | 1191045 | buf->next = NULL; | |
| 404 | 1191045 | buf->buffer.flags_internal |= BUFFER_FLAG_NO_FREE; | |
| 405 | } | ||
| 406 | } else { | ||
| 407 | 134793 | ret = pool_alloc_buffer(pool); | |
| 408 | } | ||
| 409 | 1325838 | ff_mutex_unlock(&pool->mutex); | |
| 410 | |||
| 411 |
1/2✓ Branch 0 taken 1325838 times.
✗ Branch 1 not taken.
|
1325838 | if (ret) |
| 412 | 1325838 | atomic_fetch_add_explicit(&pool->refcount, 1, memory_order_relaxed); | |
| 413 | |||
| 414 | 1325838 | return ret; | |
| 415 | } | ||
| 416 | |||
| 417 | ✗ | void *av_buffer_pool_buffer_get_opaque(const AVBufferRef *ref) | |
| 418 | { | ||
| 419 | ✗ | BufferPoolEntry *buf = ref->buffer->opaque; | |
| 420 | ✗ | av_assert0(buf); | |
| 421 | ✗ | return buf->opaque; | |
| 422 | } | ||
| 423 |