PipeWire  0.3.33
alloc.h
Go to the documentation of this file.
1 /* Simple Plugin API
2  * Copyright © 2018 Wim Taymans
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 #ifndef SPA_BUFFER_ALLOC_H
24 #define SPA_BUFFER_ALLOC_H
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 #include <spa/buffer/buffer.h>
31 
39 #define SPA_BUFFER_ALLOC_FLAG_INLINE_META (1<<0)
40 #define SPA_BUFFER_ALLOC_FLAG_INLINE_CHUNK (1<<1)
41 #define SPA_BUFFER_ALLOC_FLAG_INLINE_DATA (1<<2)
42 #define SPA_BUFFER_ALLOC_FLAG_INLINE_ALL 0b111
43 #define SPA_BUFFER_ALLOC_FLAG_NO_DATA (1<<3)
44  uint32_t flags;
45  uint32_t max_align;
46  uint32_t n_metas;
47  uint32_t n_datas;
48  struct spa_meta *metas;
49  struct spa_data *datas;
50  uint32_t *data_aligns;
51  size_t skel_size;
52  size_t meta_size;
53  size_t chunk_size;
54  size_t data_size;
55  size_t mem_size;
56 };
57 
79 /* static */ inline int spa_buffer_alloc_fill_info(struct spa_buffer_alloc_info *info,
80  uint32_t n_metas, struct spa_meta metas[],
81  uint32_t n_datas, struct spa_data datas[],
82  uint32_t data_aligns[])
83 {
84  size_t size, *target;
85  uint32_t i;
86 
87  info->n_metas = n_metas;
88  info->metas = metas;
89  info->n_datas = n_datas;
90  info->datas = datas;
91  info->data_aligns = data_aligns;
92  info->max_align = 16;
93  info->mem_size = 0;
94  /*
95  * The buffer skeleton is placed in memory like below and can
96  * be accessed as a regular structure.
97  *
98  * +==============================+
99  * | struct spa_buffer |
100  * | uint32_t n_metas | number of metas
101  * | uint32_t n_datas | number of datas
102  * +-| struct spa_meta *metas | pointer to array of metas
103  * +|-| struct spa_data *datas | pointer to array of datas
104  * || +------------------------------+
105  * |+>| struct spa_meta |
106  * | | uint32_t type | metadata
107  * | | uint32_t size | size of metadata
108  * +|--| void *data | pointer to metadata
109  * || | ... <n_metas> | more spa_meta follow
110  * || +------------------------------+
111  * |+->| struct spa_data |
112  * | | uint32_t type | memory type
113  * | | uint32_t flags |
114  * | | int fd | fd of shared memory block
115  * | | uint32_t mapoffset | offset in shared memory of data
116  * | | uint32_t maxsize | size of data block
117  * | +-| void *data | pointer to data
118  * |+|-| struct spa_chunk *chunk | pointer to chunk
119  * ||| | ... <n_datas> | more spa_data follow
120  * ||| +==============================+
121  * VVV
122  *
123  * metadata, chunk and memory can either be placed right
124  * after the skeleton (inlined) or in a separate piece of memory.
125  *
126  * vvv
127  * ||| +==============================+
128  * +-->| meta data memory | metadata memory, 8 byte aligned
129  * || | ... <n_metas> |
130  * || +------------------------------+
131  * +->| struct spa_chunk | memory for n_datas chunks
132  * | | uint32_t offset |
133  * | | uint32_t size |
134  * | | int32_t stride |
135  * | | int32_t dummy |
136  * | | ... <n_datas> chunks |
137  * | +------------------------------+
138  * +>| data | memory for n_datas data, aligned
139  * | ... <n_datas> blocks | according to alignments
140  * +==============================+
141  */
142  info->skel_size = sizeof(struct spa_buffer);
143  info->skel_size += n_metas * sizeof(struct spa_meta);
144  info->skel_size += n_datas * sizeof(struct spa_data);
145 
146  for (i = 0, size = 0; i < n_metas; i++)
147  size += SPA_ROUND_UP_N(metas[i].size, 8);
148  info->meta_size = size;
149 
151  target = &info->skel_size;
152  else
153  target = &info->mem_size;
154  *target += info->meta_size;
155 
156  info->chunk_size = n_datas * sizeof(struct spa_chunk);
158  target = &info->skel_size;
159  else
160  target = &info->mem_size;
161  *target += info->chunk_size;
162 
163  for (i = 0, size = 0; i < n_datas; i++) {
164  info->max_align = SPA_MAX(info->max_align, data_aligns[i]);
165  size = SPA_ROUND_UP_N(size, data_aligns[i]);
166  size += datas[i].maxsize;
167  }
168  info->data_size = size;
169 
172  target = &info->skel_size;
173  else
174  target = &info->mem_size;
175 
176  *target = SPA_ROUND_UP_N(*target, n_datas ? data_aligns[0] : 1);
177  *target += info->data_size;
178  *target = SPA_ROUND_UP_N(*target, info->max_align);
179 
180  return 0;
181 }
182 
199 /* static */ inline struct spa_buffer *
201  void *skel_mem, void *data_mem)
202 {
203  struct spa_buffer *b = (struct spa_buffer*)skel_mem;
204  size_t size;
205  uint32_t i;
206  void **dp, *skel, *data;
207  struct spa_chunk *cp;
208 
209  b->n_metas = info->n_metas;
210  b->metas = SPA_PTROFF(b, sizeof(struct spa_buffer), struct spa_meta);
211  b->n_datas = info->n_datas;
212  b->datas = SPA_PTROFF(b->metas, info->n_metas * sizeof(struct spa_meta), struct spa_data);
213 
214  skel = SPA_PTROFF(b->datas, info->n_datas * sizeof(struct spa_data), void);
215  data = data_mem;
216 
218  dp = &skel;
219  else
220  dp = &data;
221 
222  for (i = 0; i < info->n_metas; i++) {
223  struct spa_meta *m = &b->metas[i];
224  *m = info->metas[i];
225  m->data = *dp;
226  *dp = SPA_PTROFF(*dp, SPA_ROUND_UP_N(m->size, 8), void);
227  }
228 
229  size = info->n_datas * sizeof(struct spa_chunk);
231  cp = (struct spa_chunk*)skel;
232  skel = SPA_PTROFF(skel, size, void);
233  }
234  else {
235  cp = (struct spa_chunk*)data;
236  data = SPA_PTROFF(data, size, void);
237  }
238 
240  dp = &skel;
241  else
242  dp = &data;
243 
244  for (i = 0; i < info->n_datas; i++) {
245  struct spa_data *d = &b->datas[i];
246 
247  *d = info->datas[i];
248  d->chunk = &cp[i];
250  *dp = SPA_PTR_ALIGN(*dp, info->data_aligns[i], void);
251  d->data = *dp;
252  *dp = SPA_PTROFF(*dp, d->maxsize, void);
253  }
254  }
255  return b;
256 }
257 
277 /* static */ inline int
279  uint32_t n_buffers, struct spa_buffer *buffers[],
280  void *skel_mem, void *data_mem)
281 {
282  uint32_t i;
283  for (i = 0; i < n_buffers; i++) {
284  buffers[i] = spa_buffer_alloc_layout(info, skel_mem, data_mem);
285  skel_mem = SPA_PTROFF(skel_mem, info->skel_size, void);
286  data_mem = SPA_PTROFF(data_mem, info->mem_size, void);
287  }
288  return 0;
289 }
290 
312 /* static */ inline struct spa_buffer **
313 spa_buffer_alloc_array(uint32_t n_buffers, uint32_t flags,
314  uint32_t n_metas, struct spa_meta metas[],
315  uint32_t n_datas, struct spa_data datas[],
316  uint32_t data_aligns[])
317 {
318 
319  struct spa_buffer **buffers;
321  void *skel;
322 
324 
325  buffers = (struct spa_buffer **)calloc(1, info.max_align +
326  n_buffers * (sizeof(struct spa_buffer *) + info.skel_size));
327  if (buffers == NULL)
328  return NULL;
329 
330  skel = SPA_PTROFF(buffers, sizeof(struct spa_buffer *) * n_buffers, void);
331  skel = SPA_PTR_ALIGN(skel, info.max_align, void);
332 
333  spa_buffer_alloc_layout_array(&info, n_buffers, buffers, skel, NULL);
334 
335  return buffers;
336 }
337 
342 #ifdef __cplusplus
343 } /* extern "C" */
344 #endif
345 
346 #endif /* SPA_BUFFER_ALLOC_H */
SPA_MAX
#define SPA_MAX(a, b)
Definition: defs.h:129
client::impl
struct impl * impl
Definition: module-protocol-simple.c:104
spa_meta::data
void * data
pointer to metadata
Definition: meta.h:64
pw_properties_get
int int const char * pw_properties_get(const struct pw_properties *properties, const char *key)
Get a property.
Definition: properties.c:487
spa_data::maxsize
uint32_t maxsize
max size of data
Definition: buffer/buffer.h:87
SPA_BUFFER_ALLOC_FLAG_INLINE_CHUNK
#define SPA_BUFFER_ALLOC_FLAG_INLINE_CHUNK
add chunk data in the skeleton
Definition: alloc.h:40
client::active
unsigned int active
Definition: access-flatpak.c:60
sm_media_session_add_listener
int sm_media_session_add_listener(struct sm_media_session *sess, struct spa_hook *listener, const struct sm_media_session_events *events, void *data)
Definition: media-session.c:1519
sm_access_flatpak_start
int sm_access_flatpak_start(struct sm_media_session *session)
Definition: access-flatpak.c:179
spa_buffer_alloc_fill_info
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[])
Fill buffer allocation information.
Definition: alloc.h:79
spa_buffer::n_datas
uint32_t n_datas
number of data members
Definition: buffer/buffer.h:95
dbus.h
string.h
data
user data to add to an object
Definition: filter.c:75
impl::data
uint8_t data[MAX_BUFFER]
Definition: module-profiler.c:87
spa_streq
bool spa_streq(const char *s1, const char *s2)
Definition: string.h:50
SPA_BUFFER_ALLOC_FLAG_INLINE_ALL
#define SPA_BUFFER_ALLOC_FLAG_INLINE_ALL
Definition: alloc.h:42
spa_buffer_alloc_info::datas
struct spa_data * datas
Definition: alloc.h:49
spa_list_for_each
#define spa_list_for_each(pos, head, member)
Definition: list.h:111
spa_buffer_alloc_info::meta_size
size_t meta_size
size of the meta if not inlined
Definition: alloc.h:52
spa_buffer_alloc_info::chunk_size
size_t chunk_size
size of the chunk if not inlined
Definition: alloc.h:53
spa_buffer_alloc_info::n_metas
uint32_t n_metas
Definition: alloc.h:46
SPA_ROUND_UP_N
#define SPA_ROUND_UP_N(num, align)
Definition: defs.h:223
PW_PERM_R
#define PW_PERM_R
object can be seen and events can be received
Definition: permission.h:47
client::is_portal
unsigned int is_portal
Definition: access-portal.c:104
impl::listener
struct spa_hook listener
Definition: access-flatpak.c:46
impl
Definition: control.c:33
spa_buffer_alloc_info::data_size
size_t data_size
size of the data if not inlined
Definition: alloc.h:54
client::id
uint32_t id
Definition: access-flatpak.c:54
spa_list
Definition: list.h:37
SPA_PTROFF
#define SPA_PTROFF(ptr_, offset_, type_)
Return the address (buffer + offset) as pointer of type.
Definition: defs.h:159
pw_permission
Definition: permission.h:64
impl::id
uint32_t id
Definition: module-echo-cancel.c:139
props
const char * props
Definition: media-session.c:2382
impl::info
struct spa_audio_info_raw info
Definition: module-echo-cancel.c:145
NAME
#define NAME
Definition: access-flatpak.c:41
SPA_BUFFER_ALLOC_FLAG_NO_DATA
#define SPA_BUFFER_ALLOC_FLAG_NO_DATA
don't set data pointers
Definition: alloc.h:43
impl::client_list
struct spa_list client_list
Definition: access-flatpak.c:48
spa_buffer_alloc_info::data_aligns
uint32_t * data_aligns
Definition: alloc.h:50
spa_list_consume
#define spa_list_consume(pos, head, member)
Definition: list.h:96
client::listener
struct spa_hook listener
Definition: access-flatpak.c:59
client::obj
struct sm_client * obj
Definition: access-flatpak.c:52
spa_buffer::metas
struct spa_meta * metas
array of metadata
Definition: buffer/buffer.h:96
SESSION_KEY
#define SESSION_KEY
Definition: access-portal.c:75
dict.h
spa_list_remove
void spa_list_remove(struct spa_list *elem)
Definition: list.h:69
buffer.h
spa_buffer_alloc_info::flags
uint32_t flags
Definition: alloc.h:44
PW_TYPE_INTERFACE_Node
#define PW_TYPE_INTERFACE_Node
Definition: src/pipewire/node.h:50
SPA_BUFFER_ALLOC_FLAG_INLINE_META
#define SPA_BUFFER_ALLOC_FLAG_INLINE_META
add metadata data in the skeleton
Definition: alloc.h:39
spa_buffer::n_metas
uint32_t n_metas
number of metadata
Definition: buffer/buffer.h:94
spa_buffer
A Buffer.
Definition: buffer/buffer.h:93
PW_PERM_ALL
#define PW_PERM_ALL
Definition: permission.h:61
spa_hook
A hook, contains the structure with functions and the data passed to the functions.
Definition: hook.h:295
pw_permission::permissions
uint32_t permissions
bitmask of above permissions
Definition: permission.h:66
pw_client_info
The client information.
Definition: client.h:55
spa_buffer_alloc_array
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[])
Allocate an array of buffers.
Definition: alloc.h:313
pw_client_info::props
struct spa_dict * props
extra properties
Definition: client.h:60
sm_object_remove_data
int sm_object_remove_data(struct sm_object *obj, const char *id)
Definition: media-session.c:290
sm_object_get_data
void * sm_object_get_data(struct sm_object *obj, const char *id)
Definition: media-session.c:281
SPA_FLAG_IS_SET
#define SPA_FLAG_IS_SET(field, flag)
Definition: defs.h:73
NAME
#define NAME
Definition: access-portal.c:74
spa_list_init
void spa_list_init(struct spa_list *list)
Definition: list.h:44
spa_meta
A metadata element.
Definition: meta.h:61
spa_buffer_alloc_info::mem_size
size_t mem_size
size of the total memory if not inlined
Definition: alloc.h:55
media_role
media_role
Definition: access-portal.c:77
spa_data::chunk
struct spa_chunk * chunk
valid chunk of memory
Definition: buffer/buffer.h:89
spa_dict
Definition: utils/dict.h:48
sm_object_add_listener
int sm_object_add_listener(struct sm_object *obj, struct spa_hook *listener, const struct sm_object_events *events, void *data)
Definition: media-session.c:1512
spa_dict_lookup
const char * spa_dict_lookup(const struct spa_dict *dict, const char *key)
Definition: utils/dict.h:99
PW_KEY_MEDIA_CATEGORY
#define PW_KEY_MEDIA_CATEGORY
Media Category: Playback, Capture, Duplex, Monitor, Manager.
Definition: src/pipewire/keys.h:279
PW_PERMISSION_INIT
#define PW_PERMISSION_INIT(id, p)
Definition: permission.h:69
SPA_BUFFER_ALLOC_FLAG_INLINE_DATA
#define SPA_BUFFER_ALLOC_FLAG_INLINE_DATA
add buffer data to the skeleton
Definition: alloc.h:41
MEDIA_ROLE_CAMERA
@ MEDIA_ROLE_CAMERA
Definition: access-portal.c:80
spa_buffer_alloc_layout
struct spa_buffer * spa_buffer_alloc_layout(struct spa_buffer_alloc_info *info, void *skel_mem, void *data_mem)
Fill skeleton and data according to the allocation info.
Definition: alloc.h:200
pw_log_debug
#define pw_log_debug(...)
Definition: src/pipewire/log.h:89
client
Definition: module-protocol-native.c:103
spa_buffer_alloc_info::max_align
uint32_t max_align
max of all alignments
Definition: alloc.h:45
impl::session
struct sm_media_session * session
Definition: access-flatpak.c:45
client::app_id
char * app_id
Definition: access-portal.c:105
PW_ID_ANY
#define PW_ID_ANY
Definition: core.h:69
impl::bus
DBusConnection * bus
Definition: module-portal.c:89
spa_chunk::size
uint32_t size
size of valid data.
Definition: buffer/buffer.h:61
sm_object_add_data
void * sm_object_add_data(struct sm_object *obj, const char *id, size_t size)
Definition: media-session.c:261
spa_dbus_connection_get
#define spa_dbus_connection_get(c)
Definition: dbus.h:112
spa_buffer_alloc_layout_array
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)
Layout an array of buffers.
Definition: alloc.h:278
PW_TYPE_INTERFACE_Client
#define PW_TYPE_INTERFACE_Client
Definition: client.h:46
PW_PERM_X
#define PW_PERM_X
methods can be called on the object.
Definition: permission.h:49
pw_log_warn
#define pw_log_warn(...)
Definition: src/pipewire/log.h:87
spa_buffer::datas
struct spa_data * datas
array of data members
Definition: buffer/buffer.h:97
client::portal_managed
unsigned int portal_managed
Definition: access-portal.c:102
spa_data
Data for a buffer this stays constant for a buffer.
Definition: buffer/buffer.h:70
PW_KEY_ACCESS
#define PW_KEY_ACCESS
how the client access is controlled
Definition: src/pipewire/keys.h:48
spa_hook_remove
void spa_hook_remove(struct spa_hook *hook)
Remove a hook.
Definition: hook.h:336
spa_meta::size
uint32_t size
size of metadata
Definition: meta.h:63
SPA_PTR_ALIGN
#define SPA_PTR_ALIGN(p, align, type)
Definition: defs.h:227
pw_log_info
#define pw_log_info(...)
Definition: src/pipewire/log.h:88
MEDIA_ROLE_INVALID
@ MEDIA_ROLE_INVALID
Definition: access-portal.c:78
spa_buffer_alloc_info::skel_size
size_t skel_size
size of the struct spa_buffer and inlined meta/chunk/data
Definition: alloc.h:51
spa_data::data
void * data
optional data pointer
Definition: buffer/buffer.h:88
pipewire.h
spa_chunk
Chunk of memory, can change for each buffer.
Definition: buffer/buffer.h:57
pw_client_update_permissions
#define pw_client_update_permissions(c,...)
Definition: client.h:173
spa_buffer_alloc_info
information about the buffer layout
Definition: alloc.h:38
sm_access_portal_start
int sm_access_portal_start(struct sm_media_session *session)
Definition: access-portal.c:642
sm_media_session_for_each_object
int sm_media_session_for_each_object(struct sm_media_session *sess, int(*callback)(void *data, struct sm_object *object), void *data)
Definition: media-session.c:1552
client::allowed_media_roles
enum media_role allowed_media_roles
Definition: access-portal.c:107
client::link
struct spa_list link
link in impl client_list
Definition: module-protocol-simple.c:103
spa_buffer_alloc_info::n_datas
uint32_t n_datas
Definition: alloc.h:47
spa_buffer_alloc_info::metas
struct spa_meta * metas
Definition: alloc.h:48
client::media_roles
enum media_role media_roles
Definition: access-portal.c:106
client::setup_complete
unsigned int setup_complete
Definition: access-portal.c:103
pw_properties
Definition: properties.h:49
MEDIA_ROLE_NONE
@ MEDIA_ROLE_NONE
Definition: access-portal.c:79
PW_KEY_CLIENT_ACCESS
#define PW_KEY_CLIENT_ACCESS
how the client wants to be access controlled
Definition: src/pipewire/keys.h:49
pw_log_error
#define pw_log_error(...)
Definition: src/pipewire/log.h:86
MEDIA_ROLE_ALL
#define MEDIA_ROLE_ALL
Definition: access-portal.c:82
spa_list_append
#define spa_list_append(list, item)
Definition: list.h:81
SESSION_KEY
#define SESSION_KEY
Definition: access-flatpak.c:42