summaryrefslogtreecommitdiffstats
path: root/third_party/pipewire/spa/buffer
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--third_party/pipewire/spa/buffer/alloc.h346
-rw-r--r--third_party/pipewire/spa/buffer/buffer.h131
-rw-r--r--third_party/pipewire/spa/buffer/meta.h163
-rw-r--r--third_party/pipewire/spa/buffer/type-info.h93
4 files changed, 733 insertions, 0 deletions
diff --git a/third_party/pipewire/spa/buffer/alloc.h b/third_party/pipewire/spa/buffer/alloc.h
new file mode 100644
index 0000000000..6417073838
--- /dev/null
+++ b/third_party/pipewire/spa/buffer/alloc.h
@@ -0,0 +1,346 @@
+/* Simple Plugin API
+ * Copyright © 2018 Wim Taymans
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#ifndef SPA_BUFFER_ALLOC_H
+#define SPA_BUFFER_ALLOC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <spa/buffer/buffer.h>
+
+/**
+ * \addtogroup spa_buffer
+ * \{
+ */
+
+/** 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 */
+#define SPA_BUFFER_ALLOC_FLAG_INLINE_DATA (1<<2) /**< add buffer data to the skeleton */
+#define SPA_BUFFER_ALLOC_FLAG_INLINE_ALL 0b111
+#define SPA_BUFFER_ALLOC_FLAG_NO_DATA (1<<3) /**< don't set data pointers */
+ uint32_t flags;
+ uint32_t max_align; /**< max of all alignments */
+ uint32_t n_metas;
+ uint32_t n_datas;
+ struct spa_meta *metas;
+ struct spa_data *datas;
+ uint32_t *data_aligns;
+ size_t skel_size; /**< size of the struct spa_buffer and inlined meta/chunk/data */
+ size_t meta_size; /**< size of the meta if not inlined */
+ size_t chunk_size; /**< size of the chunk if not inlined */
+ size_t data_size; /**< size of the data if not inlined */
+ 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, *target;
+ uint32_t i;
+
+ info->n_metas = n_metas;
+ info->metas = metas;
+ info->n_datas = n_datas;
+ info->datas = datas;
+ 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);
+
+ for (i = 0, size = 0; i < n_metas; i++)
+ size += SPA_ROUND_UP_N(metas[i].size, 8);
+ info->meta_size = size;
+
+ if (SPA_FLAG_IS_SET(info->flags, SPA_BUFFER_ALLOC_FLAG_INLINE_META))
+ target = &info->skel_size;
+ else
+ target = &info->mem_size;
+ *target += info->meta_size;
+
+ info->chunk_size = n_datas * sizeof(struct spa_chunk);
+ if (SPA_FLAG_IS_SET(info->flags, SPA_BUFFER_ALLOC_FLAG_INLINE_CHUNK))
+ target = &info->skel_size;
+ else
+ 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]);
+ size = SPA_ROUND_UP_N(size, data_aligns[i]);
+ size += datas[i].maxsize;
+ }
+ info->data_size = size;
+
+ if (!SPA_FLAG_IS_SET(info->flags, SPA_BUFFER_ALLOC_FLAG_NO_DATA) &&
+ SPA_FLAG_IS_SET(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 struct \ref 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 struct \ref spa_buffer and the
+ * pointers to meta, chunk and memory.
+ * \param data_mem memory to hold the meta, chunk and memory
+ * \return a struct \ref 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)
+{
+ struct spa_buffer *b = (struct spa_buffer*)skel_mem;
+ size_t size;
+ uint32_t i;
+ void **dp, *skel, *data;
+ struct spa_chunk *cp;
+
+ b->n_metas = info->n_metas;
+ b->metas = SPA_PTROFF(b, sizeof(struct spa_buffer), struct spa_meta);
+ b->n_datas = info->n_datas;
+ b->datas = SPA_PTROFF(b->metas, info->n_metas * sizeof(struct spa_meta), struct spa_data);
+
+ skel = SPA_PTROFF(b->datas, info->n_datas * sizeof(struct spa_data), void);
+ data = data_mem;
+
+ if (SPA_FLAG_IS_SET(info->flags, SPA_BUFFER_ALLOC_FLAG_INLINE_META))
+ dp = &skel;
+ else
+ dp = &data;
+
+ for (i = 0; i < info->n_metas; i++) {
+ struct spa_meta *m = &b->metas[i];
+ *m = info->metas[i];
+ m->data = *dp;
+ *dp = SPA_PTROFF(*dp, SPA_ROUND_UP_N(m->size, 8), void);
+ }
+
+ size = info->n_datas * sizeof(struct spa_chunk);
+ if (SPA_FLAG_IS_SET(info->flags, SPA_BUFFER_ALLOC_FLAG_INLINE_CHUNK)) {
+ cp = (struct spa_chunk*)skel;
+ skel = SPA_PTROFF(skel, size, void);
+ }
+ else {
+ cp = (struct spa_chunk*)data;
+ data = SPA_PTROFF(data, size, void);
+ }
+
+ if (SPA_FLAG_IS_SET(info->flags, SPA_BUFFER_ALLOC_FLAG_INLINE_DATA))
+ dp = &skel;
+ else
+ dp = &data;
+
+ for (i = 0; i < info->n_datas; i++) {
+ struct spa_data *d = &b->datas[i];
+
+ *d = info->datas[i];
+ d->chunk = &cp[i];
+ if (!SPA_FLAG_IS_SET(info->flags, SPA_BUFFER_ALLOC_FLAG_NO_DATA)) {
+ *dp = SPA_PTR_ALIGN(*dp, info->data_aligns[i], void);
+ d->data = *dp;
+ *dp = SPA_PTROFF(*dp, d->maxsize, void);
+ }
+ }
+ 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 buffers a array with space to hold \a n_buffers pointers to buffers
+ * \param skel_mem memory for the struct \ref 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[],
+ void *skel_mem, void *data_mem)
+{
+ uint32_t i;
+ for (i = 0; i < n_buffers; i++) {
+ buffers[i] = spa_buffer_alloc_layout(info, skel_mem, data_mem);
+ skel_mem = SPA_PTROFF(skel_mem, info->skel_size, void);
+ data_mem = SPA_PTROFF(data_mem, info->mem_size, void);
+ }
+ 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 struct \ref 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[],
+ uint32_t n_datas, struct spa_data datas[],
+ uint32_t data_aligns[])
+{
+
+ struct spa_buffer **buffers;
+ struct spa_buffer_alloc_info info = { flags | SPA_BUFFER_ALLOC_FLAG_INLINE_ALL, };
+ void *skel;
+
+ spa_buffer_alloc_fill_info(&info, n_metas, metas, n_datas, datas, data_aligns);
+
+ 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_PTROFF(buffers, sizeof(struct spa_buffer *) * n_buffers, void);
+ skel = SPA_PTR_ALIGN(skel, info.max_align, void);
+
+ spa_buffer_alloc_layout_array(&info, n_buffers, buffers, skel, NULL);
+
+ return buffers;
+}
+
+/**
+ * \}
+ */
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* SPA_BUFFER_ALLOC_H */
diff --git a/third_party/pipewire/spa/buffer/buffer.h b/third_party/pipewire/spa/buffer/buffer.h
new file mode 100644
index 0000000000..47204acbcf
--- /dev/null
+++ b/third_party/pipewire/spa/buffer/buffer.h
@@ -0,0 +1,131 @@
+/* Simple Plugin API
+ * Copyright © 2018 Wim Taymans
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef SPA_BUFFER_H
+#define SPA_BUFFER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <spa/utils/defs.h>
+#include <spa/buffer/meta.h>
+
+/** \defgroup spa_buffer Buffers
+ *
+ * Buffers describe the data and metadata that is exchanged between
+ * ports of a node.
+ */
+
+/**
+ * \addtogroup spa_buffer
+ * \{
+ */
+
+enum spa_data_type {
+ SPA_DATA_Invalid,
+ SPA_DATA_MemPtr, /**< pointer to memory, the data field in
+ * struct spa_data is set. */
+ SPA_DATA_MemFd, /**< generic fd, mmap to get to memory */
+ SPA_DATA_DmaBuf, /**< fd to dmabuf memory */
+ SPA_DATA_MemId, /**< memory is identified with an id */
+
+ _SPA_DATA_LAST, /**< not part of ABI */
+};
+
+/** Chunk of memory, can change for each buffer */
+struct spa_chunk {
+ uint32_t offset; /**< offset of valid data. Should be taken
+ * modulo the data maxsize to get the offset
+ * in the data memory. */
+ uint32_t size; /**< size of valid data. Should be clamped to
+ * maxsize. */
+ int32_t stride; /**< stride of valid data */
+#define SPA_CHUNK_FLAG_NONE 0
+#define SPA_CHUNK_FLAG_CORRUPTED (1u<<0) /**< chunk data is corrupted in some way */
+#define SPA_CHUNK_FLAG_EMPTY (1u<<1) /**< chunk data is empty with media specific
+ * neutral data such as silence or black. This
+ * could be used to optimize processing. */
+ int32_t flags; /**< chunk flags */
+};
+
+/** Data for a buffer this stays constant for a buffer */
+struct spa_data {
+ uint32_t type; /**< memory type, one of enum spa_data_type, when
+ * allocating memory, the type contains a bitmask
+ * of allowed types. SPA_ID_INVALID is a special
+ * value for the allocator to indicate that the
+ * other side did not explicitly specify any
+ * supported data types. It should probably use
+ * a memory type that does not require special
+ * handling in addition to simple mmap/munmap. */
+#define SPA_DATA_FLAG_NONE 0
+#define SPA_DATA_FLAG_READABLE (1u<<0) /**< data is readable */
+#define SPA_DATA_FLAG_WRITABLE (1u<<1) /**< data is writable */
+#define SPA_DATA_FLAG_DYNAMIC (1u<<2) /**< data pointer can be changed */
+#define SPA_DATA_FLAG_READWRITE (SPA_DATA_FLAG_READABLE|SPA_DATA_FLAG_WRITABLE)
+ uint32_t flags; /**< data flags */
+ int64_t fd; /**< optional fd for data */
+ uint32_t mapoffset; /**< offset to map fd at */
+ uint32_t maxsize; /**< max size of data */
+ void *data; /**< optional data pointer */
+ struct spa_chunk *chunk; /**< valid chunk of memory */
+};
+
+/** A Buffer */
+struct spa_buffer {
+ uint32_t n_metas; /**< number of metadata */
+ uint32_t n_datas; /**< number of data members */
+ struct spa_meta *metas; /**< array of metadata */
+ struct spa_data *datas; /**< array of data members */
+};
+
+/** Find metadata in a buffer */
+static inline struct spa_meta *spa_buffer_find_meta(const struct spa_buffer *b, uint32_t type)
+{
+ uint32_t i;
+
+ for (i = 0; i < b->n_metas; i++)
+ if (b->metas[i].type == type)
+ return &b->metas[i];
+
+ return NULL;
+}
+
+static inline void *spa_buffer_find_meta_data(const struct spa_buffer *b, uint32_t type, size_t size)
+{
+ struct spa_meta *m;
+ if ((m = spa_buffer_find_meta(b, type)) && m->size >= size)
+ return m->data;
+ return NULL;
+}
+
+/**
+ * \}
+ */
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* SPA_BUFFER_H */
diff --git a/third_party/pipewire/spa/buffer/meta.h b/third_party/pipewire/spa/buffer/meta.h
new file mode 100644
index 0000000000..ae72ef970e
--- /dev/null
+++ b/third_party/pipewire/spa/buffer/meta.h
@@ -0,0 +1,163 @@
+/* Simple Plugin API
+ *
+ * Copyright © 2018 Wim Taymans
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef SPA_META_H
+#define SPA_META_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <spa/utils/defs.h>
+#include <spa/pod/pod.h>
+
+/**
+ * \addtogroup spa_buffer
+ * \{
+ */
+
+enum spa_meta_type {
+ SPA_META_Invalid,
+ SPA_META_Header, /**< struct spa_meta_header */
+ SPA_META_VideoCrop, /**< struct spa_meta_region with cropping data */
+ SPA_META_VideoDamage, /**< array of struct spa_meta_region with damage, where an invalid entry or end-of-array marks the end. */
+ SPA_META_Bitmap, /**< struct spa_meta_bitmap */
+ SPA_META_Cursor, /**< struct spa_meta_cursor */
+ SPA_META_Control, /**< metadata contains a spa_meta_control
+ * associated with the data */
+ SPA_META_Busy, /**< don't write to buffer when count > 0 */
+
+ _SPA_META_LAST, /**< not part of ABI/API */
+};
+
+/**
+ * A metadata element.
+ *
+ * This structure is available on the buffer structure and contains
+ * the type of the metadata and a pointer/size to the actual metadata
+ * itself.
+ */
+struct spa_meta {
+ uint32_t type; /**< metadata type, one of enum spa_meta_type */
+ uint32_t size; /**< size of metadata */
+ void *data; /**< pointer to metadata */
+};
+
+#define spa_meta_first(m) ((m)->data)
+#define spa_meta_end(m) SPA_PTROFF((m)->data,(m)->size,void)
+#define spa_meta_check(p,m) (SPA_PTROFF(p,sizeof(*p),void) <= spa_meta_end(m))
+
+/**
+ * Describes essential buffer header metadata such as flags and
+ * timestamps.
+ */
+struct spa_meta_header {
+#define SPA_META_HEADER_FLAG_DISCONT (1 << 0) /**< data is not continuous with previous buffer */
+#define SPA_META_HEADER_FLAG_CORRUPTED (1 << 1) /**< data might be corrupted */
+#define SPA_META_HEADER_FLAG_MARKER (1 << 2) /**< media specific marker */
+#define SPA_META_HEADER_FLAG_HEADER (1 << 3) /**< data contains a codec specific header */
+#define SPA_META_HEADER_FLAG_GAP (1 << 4) /**< data contains media neutral data */
+#define SPA_META_HEADER_FLAG_DELTA_UNIT (1 << 5) /**< cannot be decoded independently */
+ uint32_t flags; /**< flags */
+ uint32_t offset; /**< offset in current cycle */
+ int64_t pts; /**< presentation timestamp in nanoseconds */
+ int64_t dts_offset; /**< decoding timestamp as a difference with pts */
+ uint64_t seq; /**< sequence number, increments with a
+ * media specific frequency */
+};
+
+/** metadata structure for Region or an array of these for RegionArray */
+struct spa_meta_region {
+ struct spa_region region;
+};
+
+#define spa_meta_region_is_valid(m) ((m)->region.size.width != 0 && (m)->region.size.height != 0)
+
+/** iterate all the items in a metadata */
+#define spa_meta_for_each(pos,meta) \
+ for (pos = (__typeof(pos))spa_meta_first(meta); \
+ spa_meta_check(pos, meta); \
+ (pos)++)
+
+#define spa_meta_bitmap_is_valid(m) ((m)->format != 0)
+
+/**
+ * Bitmap information
+ *
+ * This metadata contains a bitmap image in the given format and size.
+ * It is typically used for cursor images or other small images that are
+ * better transferred inline.
+ */
+struct spa_meta_bitmap {
+ uint32_t format; /**< bitmap video format, one of enum spa_video_format. 0 is
+ * and invalid format and should be handled as if there is
+ * no new bitmap information. */
+ struct spa_rectangle size; /**< width and height of bitmap */
+ int32_t stride; /**< stride of bitmap data */
+ uint32_t offset; /**< offset of bitmap data in this structure. An offset of
+ * 0 means no image data (invisible), an offset >=
+ * sizeof(struct spa_meta_bitmap) contains valid bitmap
+ * info. */
+};
+
+#define spa_meta_cursor_is_valid(m) ((m)->id != 0)
+
+/**
+ * Cursor information
+ *
+ * Metadata to describe the position and appearance of a pointing device.
+ */
+struct spa_meta_cursor {
+ uint32_t id; /**< cursor id. an id of 0 is an invalid id and means that
+ * there is no new cursor data */
+ uint32_t flags; /**< extra flags */
+ struct spa_point position; /**< position on screen */
+ struct spa_point hotspot; /**< offsets for hotspot in bitmap, this field has no meaning
+ * when there is no valid bitmap (see below) */
+ uint32_t bitmap_offset; /**< offset of bitmap meta in this structure. When the offset
+ * is 0, there is no new bitmap information. When the offset is
+ * >= sizeof(struct spa_meta_cursor) there is a
+ * struct spa_meta_bitmap at the offset. */
+};
+
+/** a timed set of events associated with the buffer */
+struct spa_meta_control {
+ struct spa_pod_sequence sequence;
+};
+
+/** a busy counter for the buffer */
+struct spa_meta_busy {
+ uint32_t flags;
+ uint32_t count; /**< number of users busy with the buffer */
+};
+
+/**
+ * \}
+ */
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* SPA_META_H */
diff --git a/third_party/pipewire/spa/buffer/type-info.h b/third_party/pipewire/spa/buffer/type-info.h
new file mode 100644
index 0000000000..50f436b864
--- /dev/null
+++ b/third_party/pipewire/spa/buffer/type-info.h
@@ -0,0 +1,93 @@
+/* Simple Plugin API
+ *
+ * Copyright © 2018 Wim Taymans
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef SPA_BUFFER_TYPES_H
+#define SPA_BUFFER_TYPES_H
+
+/**
+ * \addtogroup spa_buffer
+ * \{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <spa/buffer/buffer.h>
+#include <spa/buffer/meta.h>
+#include <spa/utils/type.h>
+
+#define SPA_TYPE_INFO_Buffer SPA_TYPE_INFO_POINTER_BASE "Buffer"
+#define SPA_TYPE_INFO_BUFFER_BASE SPA_TYPE_INFO_Buffer ":"
+
+/** Buffers contain data of a certain type */
+#define SPA_TYPE_INFO_Data SPA_TYPE_INFO_ENUM_BASE "Data"
+#define SPA_TYPE_INFO_DATA_BASE SPA_TYPE_INFO_Data ":"
+
+/** base type for fd based memory */
+#define SPA_TYPE_INFO_DATA_Fd SPA_TYPE_INFO_DATA_BASE "Fd"
+#define SPA_TYPE_INFO_DATA_FD_BASE SPA_TYPE_INFO_DATA_Fd ":"
+
+static const struct spa_type_info spa_type_data_type[] = {
+ { SPA_DATA_Invalid, SPA_TYPE_Int, SPA_TYPE_INFO_DATA_BASE "Invalid", NULL },
+ { SPA_DATA_MemPtr, SPA_TYPE_Int, SPA_TYPE_INFO_DATA_BASE "MemPtr", NULL },
+ { SPA_DATA_MemFd, SPA_TYPE_Int, SPA_TYPE_INFO_DATA_FD_BASE "MemFd", NULL },
+ { SPA_DATA_DmaBuf, SPA_TYPE_Int, SPA_TYPE_INFO_DATA_FD_BASE "DmaBuf", NULL },
+ { SPA_DATA_MemId, SPA_TYPE_Int, SPA_TYPE_INFO_DATA_BASE "MemId", NULL },
+ { 0, 0, NULL, NULL },
+};
+
+#define SPA_TYPE_INFO_Meta SPA_TYPE_INFO_POINTER_BASE "Meta"
+#define SPA_TYPE_INFO_META_BASE SPA_TYPE_INFO_Meta ":"
+
+#define SPA_TYPE_INFO_META_Array SPA_TYPE_INFO_META_BASE "Array"
+#define SPA_TYPE_INFO_META_ARRAY_BASE SPA_TYPE_INFO_META_Array ":"
+
+#define SPA_TYPE_INFO_META_Region SPA_TYPE_INFO_META_BASE "Region"
+#define SPA_TYPE_INFO_META_REGION_BASE SPA_TYPE_INFO_META_Region ":"
+
+#define SPA_TYPE_INFO_META_ARRAY_Region SPA_TYPE_INFO_META_ARRAY_BASE "Region"
+#define SPA_TYPE_INFO_META_ARRAY_REGION_BASE SPA_TYPE_INFO_META_ARRAY_Region ":"
+
+static const struct spa_type_info spa_type_meta_type[] = {
+ { SPA_META_Invalid, SPA_TYPE_Pointer, SPA_TYPE_INFO_META_BASE "Invalid", NULL },
+ { SPA_META_Header, SPA_TYPE_Pointer, SPA_TYPE_INFO_META_BASE "Header", NULL },
+ { SPA_META_VideoCrop, SPA_TYPE_Pointer, SPA_TYPE_INFO_META_REGION_BASE "VideoCrop", NULL },
+ { SPA_META_VideoDamage, SPA_TYPE_Pointer, SPA_TYPE_INFO_META_ARRAY_REGION_BASE "VideoDamage", NULL },
+ { SPA_META_Bitmap, SPA_TYPE_Pointer, SPA_TYPE_INFO_META_BASE "Bitmap", NULL },
+ { SPA_META_Cursor, SPA_TYPE_Pointer, SPA_TYPE_INFO_META_BASE "Cursor", NULL },
+ { SPA_META_Control, SPA_TYPE_Pointer, SPA_TYPE_INFO_META_BASE "Control", NULL },
+ { SPA_META_Busy, SPA_TYPE_Pointer, SPA_TYPE_INFO_META_BASE "Busy", NULL },
+ { 0, 0, NULL, NULL },
+};
+
+/**
+ * \}
+ */
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* SPA_BUFFER_TYPES_H */