/* * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
typedefstruct RefCount { /** * An uintptr_t is big enough to hold the address of every reference, * so no overflow can happen when incrementing the refcount as long as * the user does not throw away references.
*/
atomic_uintptr_t refcount;
AVRefStructOpaque opaque; void (*free_cb)(AVRefStructOpaque opaque, void *obj); void (*free)(void *ref);
constvoid *av_refstruct_ref_c(constvoid *obj)
{ /* Casting const away here is fine, as it is only supposed
* to apply to the user's data and not our bookkeeping data. */
RefCount *ref = get_refcount((void*)obj);
if (src == dst) return;
av_refstruct_unref(dstp); if (src) {
dst = av_refstruct_ref_c(src);
memcpy(dstp, &dst, sizeof(dst));
}
}
int av_refstruct_exclusive(constvoid *obj)
{ const RefCount *ref = cget_refcount(obj); /* Casting const away here is safe, because it is a load. * It is necessary because atomic_load_explicit() does not
* accept const atomics in C11 (see also N1807). */ return atomic_load_explicit((atomic_uintptr_t*)&ref->refcount, memory_order_acquire) == 1;
}
int uninited; unsigned entry_flags; unsigned pool_flags;
/** The number of outstanding entries not in available_entries. */
atomic_uintptr_t refcount; /** * This is a linked list of available entries; * the RefCount's opaque pointer is used as next pointer * for available entries. * While the entries are in use, the opaque is a pointer * to the corresponding AVRefStructPool.
*/
RefCount *available_entries;
AVMutex mutex;
};
staticvoid pool_free(AVRefStructPool *pool)
{
ff_mutex_destroy(&pool->mutex); if (pool->free_cb)
pool->free_cb(pool->opaque);
av_free(get_refcount(pool));
}
/** * Hint: The content of pool_unref() and refstruct_pool_uninit() * could currently be merged; they are only separate functions * in case we would ever introduce weak references.
*/ staticvoid pool_unref(void *ref)
{
AVRefStructPool *pool = get_userdata(ref); if (atomic_fetch_sub_explicit(&pool->refcount, 1, memory_order_acq_rel) == 1)
pool_free(pool);
}
if (flags & AV_REFSTRUCT_POOL_FLAG_ZERO_EVERY_TIME) { // We will zero the buffer before every use, so zeroing // upon allocating the buffer is unnecessary.
pool->entry_flags |= AV_REFSTRUCT_FLAG_NO_ZEROING;
}
atomic_init(&pool->refcount, 1);
err = ff_mutex_init(&pool->mutex, NULL); if (err) { // Don't call av_refstruct_uninit() on pool, as it hasn't been properly // set up and is just a POD right now.
av_free(get_refcount(pool)); return NULL;
} return pool;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.