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