mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-01 22:58:50 -04:00
alloc: document alloc functions
This commit is contained in:
parent
93e8074b2c
commit
7a8412e81a
2 changed files with 144 additions and 79 deletions
|
|
@ -29,6 +29,7 @@ extern "C" {
|
|||
|
||||
#include <spa/buffer/buffer.h>
|
||||
|
||||
/** information about the buffer layout */
|
||||
struct spa_buffer_alloc_info {
|
||||
#define SPA_BUFFER_ALLOC_FLAG_INLINE_META (1<<0) /**< add metadata data in the skeleton */
|
||||
#define SPA_BUFFER_ALLOC_FLAG_INLINE_CHUNK (1<<1) /**< add chunk data in the skeleton */
|
||||
|
|
@ -49,12 +50,33 @@ struct spa_buffer_alloc_info {
|
|||
size_t mem_size; /**< size of the total memory if not inlined */
|
||||
};
|
||||
|
||||
/**
|
||||
* Fill buffer allocation information
|
||||
*
|
||||
* Fill \a info with allocation information needed to allocate buffers
|
||||
* with the given number of metadata and data members.
|
||||
*
|
||||
* The required size of the skeleton (the struct spa_buffer) information
|
||||
* and the memory (for the metadata, chunk and buffer memory) will be
|
||||
* calculated.
|
||||
*
|
||||
* The flags member in \a info should be configured before calling this
|
||||
* functions.
|
||||
*
|
||||
* \param info the information to fill
|
||||
* \param n_metas the number of metadatas for the buffer
|
||||
* \param metas an array of metadata items
|
||||
* \param n_datas the number of datas for the buffer
|
||||
* \param datas an array of \a n_datas items
|
||||
* \param data_aligns \a n_datas alignments
|
||||
* \return 0 on success.
|
||||
* */
|
||||
static inline int spa_buffer_alloc_fill_info(struct spa_buffer_alloc_info *info,
|
||||
uint32_t n_metas, struct spa_meta metas[],
|
||||
uint32_t n_datas, struct spa_data datas[],
|
||||
uint32_t data_aligns[])
|
||||
{
|
||||
size_t size;
|
||||
size_t size, *target;
|
||||
uint32_t i;
|
||||
|
||||
info->n_metas = n_metas;
|
||||
|
|
@ -64,7 +86,54 @@ static inline int spa_buffer_alloc_fill_info(struct spa_buffer_alloc_info *info,
|
|||
info->data_aligns = data_aligns;
|
||||
info->max_align = 16;
|
||||
info->mem_size = 0;
|
||||
|
||||
/*
|
||||
* The buffer skeleton is placed in memory like below and can
|
||||
* be accessed as a regular structure.
|
||||
*
|
||||
* +==============================+
|
||||
* | struct spa_buffer |
|
||||
* | uint32_t n_metas | number of metas
|
||||
* | uint32_t n_datas | number of datas
|
||||
* +-| struct spa_meta *metas | pointer to array of metas
|
||||
* +|-| struct spa_data *datas | pointer to array of datas
|
||||
* || +------------------------------+
|
||||
* |+>| struct spa_meta |
|
||||
* | | uint32_t type | metadata
|
||||
* | | uint32_t size | size of metadata
|
||||
* +|--| void *data | pointer to metadata
|
||||
* || | ... <n_metas> | more spa_meta follow
|
||||
* || +------------------------------+
|
||||
* |+->| struct spa_data |
|
||||
* | | uint32_t type | memory type
|
||||
* | | uint32_t flags |
|
||||
* | | int fd | fd of shared memory block
|
||||
* | | uint32_t mapoffset | offset in shared memory of data
|
||||
* | | uint32_t maxsize | size of data block
|
||||
* | +-| void *data | pointer to data
|
||||
* |+|-| struct spa_chunk *chunk | pointer to chunk
|
||||
* ||| | ... <n_datas> | more spa_data follow
|
||||
* ||| +==============================+
|
||||
* VVV
|
||||
*
|
||||
* metadata, chunk and memory can either be placed right
|
||||
* after the skeleton (inlined) or in a separate piece of memory.
|
||||
*
|
||||
* vvv
|
||||
* ||| +==============================+
|
||||
* +-->| meta data memory | metadata memory, 8 byte aligned
|
||||
* || | ... <n_metas> |
|
||||
* || +------------------------------+
|
||||
* +->| struct spa_chunk | memory for n_datas chunks
|
||||
* | | uint32_t offset |
|
||||
* | | uint32_t size |
|
||||
* | | int32_t stride |
|
||||
* | | int32_t dummy |
|
||||
* | | ... <n_datas> chunks |
|
||||
* | +------------------------------+
|
||||
* +>| data | memory for n_datas data, aligned
|
||||
* | ... <n_datas> blocks | according to alignments
|
||||
* +==============================+
|
||||
*/
|
||||
info->skel_size = sizeof(struct spa_buffer);
|
||||
info->skel_size += n_metas * sizeof(struct spa_meta);
|
||||
info->skel_size += n_datas * sizeof(struct spa_data);
|
||||
|
|
@ -74,15 +143,17 @@ static inline int spa_buffer_alloc_fill_info(struct spa_buffer_alloc_info *info,
|
|||
info->meta_size = size;
|
||||
|
||||
if (SPA_FLAG_CHECK(info->flags, SPA_BUFFER_ALLOC_FLAG_INLINE_META))
|
||||
info->skel_size += info->meta_size;
|
||||
target = &info->skel_size;
|
||||
else
|
||||
info->mem_size += info->meta_size;
|
||||
target = &info->mem_size;
|
||||
*target += info->meta_size;
|
||||
|
||||
info->chunk_size = n_datas * sizeof(struct spa_chunk);
|
||||
if (SPA_FLAG_CHECK(info->flags, SPA_BUFFER_ALLOC_FLAG_INLINE_CHUNK))
|
||||
info->skel_size += info->chunk_size;
|
||||
target = &info->skel_size;
|
||||
else
|
||||
info->mem_size += info->chunk_size;
|
||||
target = &info->mem_size;
|
||||
*target += info->chunk_size;
|
||||
|
||||
for (i = 0, size = 0; i < n_datas; i++) {
|
||||
info->max_align = SPA_MAX(info->max_align, data_aligns[i]);
|
||||
|
|
@ -92,20 +163,34 @@ static inline int spa_buffer_alloc_fill_info(struct spa_buffer_alloc_info *info,
|
|||
info->data_size = size;
|
||||
|
||||
if (!SPA_FLAG_CHECK(info->flags, SPA_BUFFER_ALLOC_FLAG_NO_DATA) &&
|
||||
SPA_FLAG_CHECK(info->flags, SPA_BUFFER_ALLOC_FLAG_INLINE_DATA)) {
|
||||
info->skel_size = SPA_ROUND_UP_N(info->skel_size, n_datas ? data_aligns[0] : 1);
|
||||
info->skel_size += info->data_size;
|
||||
info->skel_size = SPA_ROUND_UP_N(info->skel_size, info->max_align);
|
||||
}
|
||||
else {
|
||||
info->mem_size = SPA_ROUND_UP_N(info->mem_size, n_datas ? data_aligns[0] : 1);
|
||||
info->mem_size += info->data_size;
|
||||
info->mem_size = SPA_ROUND_UP_N(info->mem_size, info->max_align);
|
||||
}
|
||||
SPA_FLAG_CHECK(info->flags, SPA_BUFFER_ALLOC_FLAG_INLINE_DATA))
|
||||
target = &info->skel_size;
|
||||
else
|
||||
target = &info->mem_size;
|
||||
|
||||
*target = SPA_ROUND_UP_N(*target, n_datas ? data_aligns[0] : 1);
|
||||
*target += info->data_size;
|
||||
*target = SPA_ROUND_UP_N(*target, info->max_align);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill skeleton and data according to the allocation info
|
||||
*
|
||||
* Use the allocation info to create a \ref struct spa_buffer into
|
||||
* \a skel_mem and \a data_mem.
|
||||
*
|
||||
* Depending on the flags given when calling \ref
|
||||
* spa_buffer_alloc_fill_info(), the buffer meta, chunk and memory
|
||||
* will be referenced in either skel_mem or data_mem.
|
||||
*
|
||||
* \param info an allocation info
|
||||
* \param skel_mem memory to hold the \ref struct spa_buffer and the
|
||||
* pointers to meta, chunk and memory.
|
||||
* \param data_mem memory to hold the meta, chunk and memory
|
||||
* \return a \ref struct spa_buffer in \a skel_mem
|
||||
*/
|
||||
static inline struct spa_buffer *
|
||||
spa_buffer_alloc_layout(struct spa_buffer_alloc_info *info,
|
||||
void *skel_mem, void *data_mem)
|
||||
|
|
@ -165,6 +250,25 @@ spa_buffer_alloc_layout(struct spa_buffer_alloc_info *info,
|
|||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Layout an array of buffers
|
||||
*
|
||||
* Use the allocation info to layout the memory of an array of buffers.
|
||||
*
|
||||
* \a skel_mem should point to at least info->skel_size * \a n_buffers bytes
|
||||
* of memory.
|
||||
* \a data_mem should point to at least info->mem_size * \a n_buffers bytes
|
||||
* of memory.
|
||||
*
|
||||
* \param info the allocation info for one buffer
|
||||
* \param n_buffers the number of buffers to create
|
||||
* \param buffer a array with space to hold \a n_buffers pointers to buffers
|
||||
* \param skel_mem memory for the \ref struct spa_buffer
|
||||
* \param data_mem memory for the meta, chunk, memory of the buffer if not
|
||||
* inlined in the skeleton.
|
||||
* \return 0 on success.
|
||||
*
|
||||
*/
|
||||
static inline int
|
||||
spa_buffer_alloc_layout_array(struct spa_buffer_alloc_info *info,
|
||||
uint32_t n_buffers, struct spa_buffer *buffers[],
|
||||
|
|
@ -179,6 +283,27 @@ spa_buffer_alloc_layout_array(struct spa_buffer_alloc_info *info,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate an array of buffers
|
||||
*
|
||||
* Allocate \a n_buffers with the given metadata, memory and alignment
|
||||
* information.
|
||||
*
|
||||
* The buffer array, structures, data and metadata will all be allocated
|
||||
* in one block of memory with the proper requested alignment.
|
||||
*
|
||||
* \param n_buffers the number of buffers to create
|
||||
* \param flags extra flags
|
||||
* \param n_metas number of metadatas
|
||||
* \param metas \a n_metas metadata specification
|
||||
* \param n_datas number of datas
|
||||
* \param datas \a n_datas memory specification
|
||||
* \param data_aligns \a n_datas alignment specifications
|
||||
* \returns an array of \a n_buffers pointers to \ref struct spa_buffer
|
||||
* with the given metadata, data and alignment or NULL when
|
||||
* allocation failed.
|
||||
*
|
||||
*/
|
||||
static inline struct spa_buffer **
|
||||
spa_buffer_alloc_array(uint32_t n_buffers, uint32_t flags,
|
||||
uint32_t n_metas, struct spa_meta metas[],
|
||||
|
|
@ -194,6 +319,8 @@ spa_buffer_alloc_array(uint32_t n_buffers, uint32_t flags,
|
|||
|
||||
buffers = (struct spa_buffer **)calloc(1, info.max_align +
|
||||
n_buffers * (sizeof(struct spa_buffer *) + info.skel_size));
|
||||
if (buffers == NULL)
|
||||
return NULL;
|
||||
|
||||
skel = SPA_MEMBER(buffers, sizeof(struct spa_buffer *) * n_buffers, void);
|
||||
skel = SPA_PTR_ALIGN(skel, info.max_align, void);
|
||||
|
|
|
|||
|
|
@ -350,69 +350,7 @@ static struct spa_pod *find_param(struct spa_pod **params, uint32_t n_params, ui
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate an array of buffers that can be shared.
|
||||
*
|
||||
* All information will be allocated in \a mem. A pointer to a
|
||||
* newly allocated memory with an array of buffer pointers is
|
||||
* returned.
|
||||
*
|
||||
* \return an array of freshly allocated buffer pointers. free()
|
||||
* after usage.
|
||||
*
|
||||
* Array of allocated buffers:
|
||||
*
|
||||
* +==============================+
|
||||
* +-| struct spa_buffer * | array of n_buffers of pointers
|
||||
* | | ... <n_buffers> |
|
||||
* | +==============================+
|
||||
* +>| struct spa_buffer |
|
||||
* | uint32_t id | id of buffer
|
||||
* | uint32_t n_metas | number of metas
|
||||
* +-| struct spa_meta *metas | pointer to array of metas
|
||||
* | | uint32_t n_datas | number of datas
|
||||
* +|-| struct spa_data *datas | pointer to array of datas
|
||||
* || +------------------------------+
|
||||
* |+>| struct spa_meta |
|
||||
* | | uint32_t type | metadata
|
||||
* +|--| void *data | pointer to mmaped metadata in shared memory
|
||||
* || | uint32_t size | size of metadata
|
||||
* || | ... <n_metas> | more metas follow
|
||||
* || +------------------------------+
|
||||
* |+->| struct spa_data |
|
||||
* | | uint32_t type | memory type, either MemFd or INVALID
|
||||
* | | uint32_t flags |
|
||||
* | | int fd | fd of shared memory block
|
||||
* | | uint32_t mapoffset | offset in shared memory of data
|
||||
* | | uint32_t maxsize | size of data block
|
||||
* | +-| void *data | pointer to mmaped data in shared memory
|
||||
* |+|-| struct spa_chunk *chunk | pointer to mmaped chunk in shared memory
|
||||
* ||| | ... <n_datas> | more datas follow
|
||||
* ||| +==============================+
|
||||
* ||| | ... <n_buffers> | more buffer/meta/data definitions follow
|
||||
* ||| +==============================+
|
||||
* |||
|
||||
* |||
|
||||
* ||| shared memory block:
|
||||
* |||
|
||||
* ||| +==============================+
|
||||
* +-->| meta data memory | metadata memory
|
||||
* || | ... <n_metas> |
|
||||
* || +------------------------------+
|
||||
* +->| struct spa_chunk | memory for n_datas chunks
|
||||
* | | uint32_t offset |
|
||||
* | | uint32_t size |
|
||||
* | | int32_t stride |
|
||||
* | | ... <n_datas> chunks |
|
||||
* | +------------------------------+
|
||||
* +>| data | memory for n_datas data
|
||||
* | ... <n_datas> blocks |
|
||||
* +==============================+
|
||||
* | ... <n_buffers> | repeated for each buffer
|
||||
* +==============================+
|
||||
*
|
||||
* The shared memory block should not contain any types or structure,
|
||||
* just the actual metadata contents.
|
||||
*/
|
||||
/* Allocate an array of buffers that can be shared */
|
||||
static int alloc_buffers(struct pw_link *this,
|
||||
uint32_t n_buffers,
|
||||
uint32_t n_params,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue